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).
<?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; }); }
public function dispose(): void {}
private function remind(): void { $name = $this->ha->getState($this->door)?->getFriendlyName() ?? $this->door; $this->ha->callService('notify', 'notify', ['title' => 'Door open', 'message' => "{$name} is still open."]); }}apps: door-reminder: options: door: binary_sensor.back_door firstAfterMinutes: 5 repeatEveryMinutes: 10How it works
Section titled “How it works”whenChangedTo('on', for: …)sends the first reminder once the door has been open for 5 minutes.runEvery()then repeats it. The app keeps the returnedScheduledTask, so it cancancel()it when the door closes.- The message uses the door’s friendly name from Home Assistant.
<?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); }}Make it yours
Section titled “Make it yours”- 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>.