Skip to content

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;
});
}
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: 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>.