Skip to content
These pages describe Stewart 1.x. Read the docs for the latest release, and how to upgrade.

Door left open

Five minutes after the back door opens, you get a notification. Every ten minutes after that, you get another one, until someone closes the door.

You need a door sensor and a working notify.notify service (for example the Home Assistant app on your phone).

apps/DoorReminder.php
<?php
declare(strict_types=1);
namespace App;
use Stewart\Contracts\App;
use Stewart\Contracts\Automation;
use Stewart\Contracts\HaContext;
use Stewart\Contracts\Schedule\ScheduledTask;
use Stewart\Contracts\Schedule\Scheduler;
use Stewart\Contracts\Time\Duration;
#[Automation(id: 'door-reminder')]
final class DoorReminder implements App
{
private ?ScheduledTask $reminders = null;
public function __construct(
private readonly HaContext $ha,
private readonly Scheduler $scheduler,
private readonly string $door = 'binary_sensor.back_door',
private readonly int $firstAfterMinutes = 5,
private readonly int $repeatEveryMinutes = 10,
) {}
public function initialize(): void
{
$this->ha->watchStateChanges($this->door)
->whenChangedTo('on', for: Duration::minutes($this->firstAfterMinutes))
->subscribe(function (): void {
$this->remind();
$this->reminders = $this->scheduler->runEvery(Duration::minutes($this->repeatEveryMinutes), $this->remind(...));
});
$this->ha->watchStateChanges($this->door)
->whenChangedTo('off')
->subscribe(function (): void {
$this->reminders?->cancel();
$this->reminders = null;
});
}
private function remind(): void
{
$name = $this->ha->getState($this->door)?->getFriendlyName() ?? $this->door;
$this->ha->callAction('notify.notify', ['title' => 'Door open', 'message' => "{$name} is still open."]);
}
}
apps:
door-reminder:
options:
door: binary_sensor.back_door
firstAfterMinutes: 5
repeatEveryMinutes: 10
  • whenChangedTo('on', for: …) sends the first reminder once the door has been open for 5 minutes.
  • runEvery() then repeats it. The app keeps the returned ScheduledTask, so it can cancel() it when the door closes.
  • The message uses the door’s friendly name from Home Assistant.
tests/DoorReminderTest.php
<?php
declare(strict_types=1);
namespace App\Tests;
use App\DoorReminder;
use PHPUnit\Framework\TestCase;
use Stewart\Contracts\Time\Duration;
use Stewart\Testing\App\AppHarness;
final class DoorReminderTest extends TestCase
{
private AppHarness $harness;
protected function setUp(): void
{
$this->harness = new AppHarness();
$this->harness->ha->seedState('binary_sensor.back_door', 'off', ['friendly_name' => 'Back door']);
$this->harness->startApp(DoorReminder::class);
}
public function testAnOpenDoorIsRemindedAboutUntilItCloses(): void
{
$this->harness->ha->pushState('binary_sensor.back_door', 'on', ['friendly_name' => 'Back door']);
$this->harness->advanceTime(Duration::minutes(25));
self::assertCount(3, $this->harness->ha->calls);
self::assertSame('Back door is still open.', $this->harness->ha->getLastCall()->data['message'] ?? null);
$this->harness->ha->pushState('binary_sensor.back_door', 'off', ['friendly_name' => 'Back door']);
$this->harness->advanceTime(Duration::hours(1));
self::assertCount(3, $this->harness->ha->calls);
}
}
  • Several doors: watch binary_sensor.*_door, and keep one task per entity ID in an array.
  • Send it to one phone: set the service to notify.mobile_app_<your phone>.