Skip to content

Guest mode switch

Creates a Guest mode switch in Home Assistant. Turning it on sets the guest room’s heating to comfort, and saves the mode where every other app can read it, so they can behave differently while guests stay.

You need the Stewart integration in Home Assistant, a thermostat with presets, and persistence.

apps/GuestMode.php
<?php
declare(strict_types=1);
namespace App;
use Stewart\Contracts\App;
use Stewart\Contracts\Automation;
use Stewart\Contracts\Exposure\Command\SwitchCommand;
use Stewart\Contracts\Exposure\EntityExposure;
use Stewart\Contracts\Exposure\SwitchConfig;
use Stewart\Contracts\HaContext;
use Stewart\Contracts\Service\ServiceTarget;
use Stewart\Contracts\Store\GlobalStore;
use Stewart\Contracts\Store\Store;
#[Automation(id: 'guest-mode')]
final readonly class GuestMode implements App
{
public function __construct(
private HaContext $ha,
private EntityExposure $entities,
#[GlobalStore]
private Store $house,
private string $guestRoomThermostat = 'climate.guest_room',
) {}
public function initialize(): void
{
$switch = $this->entities->exposeSwitch('guest_mode', new SwitchConfig(name: 'Guest mode', icon: 'mdi:account-multiple'));
$this->house->set('guest_mode', $switch->getValue() === true);
$switch->watchCommands()->subscribe(function (SwitchCommand $command): void {
$this->house->set('guest_mode', $command->isTurnOn());
$this->ha->callService(
'climate',
'set_preset_mode',
['preset_mode' => $command->isTurnOn() ? 'comfort' : 'eco'],
ServiceTarget::forEntities($this->guestRoomThermostat),
);
});
}
public function dispose(): void {}
}

Any other app reads the mode from the shared store:

public function __construct(#[GlobalStore] private ReadableStore $house) {}
// in a handler
if ($this->house->getBool('guest_mode') === true) {
return;
}
  • exposeSwitch() creates the switch. After a restart, Home Assistant restores its last state, which the app copies into the store at start.
  • When someone flips the switch, the handler writes the mode and sets the preset. Returning from the handler accepts the command, and the switch shows the new state.
  • #[GlobalStore] is the store all apps share; other apps read it with a ReadableStore.
tests/GuestModeTest.php
<?php
declare(strict_types=1);
namespace App\Tests;
use App\GuestMode;
use PHPUnit\Framework\TestCase;
use Stewart\Contracts\Exposure\Command\SwitchAction;
use Stewart\Contracts\Exposure\Command\SwitchCommand;
use Stewart\Contracts\State\EventContext;
use Stewart\Testing\App\AppHarness;
final class GuestModeTest extends TestCase
{
public function testTurningGuestModeOnWarmsTheGuestRoomAndTellsOtherApps(): void
{
$harness = new AppHarness();
$harness->startApp(GuestMode::class);
$harness->entities->requireSwitch('guest_mode')->pushCommand(new SwitchCommand(SwitchAction::TurnOn, new EventContext('ui')));
self::assertTrue($harness->stores->openGlobalStore()->getBool('guest_mode'));
self::assertSame(['preset_mode' => 'comfort'], $harness->ha->getLastCall()->data);
}
}
  • Turn guest mode off on its own after the guests leave: schedule runAfter(Duration::hours(72), …) when it turns on.
  • Use it in the motion light to keep the guest room’s light dim.