diff --git a/automation/ModesRegistry.php b/automation/ModesRegistry.php
index 0f35028..dc908ef 100644
--- a/automation/ModesRegistry.php
+++ b/automation/ModesRegistry.php
@@ -35,6 +35,10 @@
'label' => 'Кино',
'description' => 'Приглушённый свет в гостиной, отключены звуковые уведомления.',
],
+ 'guest' => [
+ 'label' => 'Гости',
+ 'description' => 'В доме гости. Основное освещение и уведомления активны, тихие режимы отключены.',
+ ],
];
}
}
diff --git a/automation/Scopes/SleepScope.php b/automation/Scopes/SleepScope.php
deleted file mode 100644
index 2801e28..0000000
--- a/automation/Scopes/SleepScope.php
+++ /dev/null
@@ -1,222 +0,0 @@
- register_global_device_sync_map();
- }
-
- public function register_events_handlers(): void {
- // No per-button event handlers needed; we mute channels in activate_sleep.
- }
-
- public function register_actions_scripts(): void {
- $this -> add_action_script([
- "alias" => "activate_sleep",
- "name" => "Режим сна",
- "description" => "Включить режим сна: выключить всё indoor-освещение и заблокировать кнопки",
- "author" => "Eugene Sukhodolskiy",
- "icon" => '',
- "danger_level" => "cautious",
- "state_callback" => function() {
- $isSleep = $this -> mode() -> is('sleep');
- return [
- ["label" => $isSleep ? "On" : "Off", "variant" => $isSleep ? "success" : "secondary"]
- ];
- },
- ], function($params) {
- $this -> mode() -> enable('sleep');
-
- // 1. Turn everything off immediately
- $results = $this -> helper() -> group_set_state(self::INDOOR_RELAYS, false, $this -> sync_map());
-
- // 2. Mute indoor button channels so physical presses are ignored
- $this -> set_indoor_buttons_mute(true);
-
- return [
- "mode_enabled" => true,
- "lights_turned_off" => $results,
- ];
- });
-
- $this -> add_action_script([
- "alias" => "deactivate_sleep",
- "name" => "Выход из сна",
- "description" => "Отключить режим сна и разблокировать кнопки",
- "author" => "Eugene Sukhodolskiy",
- "icon" => '',
- "danger_level" => "safe",
- "state_callback" => function() {
- $isSleep = $this -> mode() -> is('sleep');
- return [
- ["label" => $isSleep ? "On" : "Off", "variant" => $isSleep ? "success" : "secondary"]
- ];
- },
- ], function($params) {
- $this -> mode() -> disable('sleep');
-
- // Unmute buttons and sync their indicators back to relay states
- $this -> set_indoor_buttons_mute(false);
-
- return [
- "mode_disabled" => true,
- ];
- });
- }
-
- public function register_regular_scripts(): void {
- // Guard script: if sleep mode is active and someone turned a light on via
- // web client (or any other way), turn it back off immediately.
- $this -> add_regular_script([
- "alias" => "sleep_guard",
- "name" => "Sleep guard",
- "description" => "Принудительно гасит indoor-свет, пока активен режим сна",
- "author" => "Eugene Sukhodolskiy",
- ], function() {
- if (!$this -> mode() -> is('sleep')) {
- return;
- }
-
- foreach (self::INDOOR_RELAYS as $target) {
- $parts = explode(":", $target, 2);
- $alias = $parts[0];
- $channel = isset($parts[1]) ? intval($parts[1]) : null;
-
- $relay = $this -> devices() -> by_alias($alias);
- if (!$relay) {
- continue;
- }
-
- $relay_api = $relay -> device_api();
- if (!($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay)) {
- continue;
- }
-
- $status = $relay_api -> get_status();
- $ch = $channel ?? 0;
- $state = $status["channels"][$ch]["state"] ?? "off";
-
- if ($state === "on") {
- if ($channel === null) {
- $relay_api -> set_state(false);
- } else {
- $relay_api -> set_channel_state(false, $channel);
- }
- $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $alias);
- }
- }
- });
- }
-
- /**
- * Mute or unmute button channels that are wired to INDOOR relays.
- * When muted, physical button presses on the device are ignored.
- * When unmuted, we restore enabled/disabled state from the linked relay.
- */
- protected function set_indoor_buttons_mute(bool $mute): void {
- $indoor_map = [];
- foreach (self::INDOOR_RELAYS as $target) {
- $parts = explode(":", $target, 2);
- $indoor_map[$parts[0]] = isset($parts[1]) ? intval($parts[1]) : null;
- }
-
- $sync_map = $this -> sync_map();
- if (!isset($sync_map["connections"])) {
- return;
- }
-
- foreach ($sync_map["connections"] as $connection) {
- $has_indoor = false;
- $btn_entries = [];
-
- foreach ($connection as $entry) {
- $type = $entry["type"] ?? "";
- $alias = $entry["alias"] ?? "";
- $channel = $entry["channel"] ?? 0;
-
- if ($type === "relay" && isset($indoor_map[$alias])) {
- $expected = $indoor_map[$alias];
- if ($expected === null || $expected === $channel) {
- $has_indoor = true;
- }
- } elseif ($type === "button") {
- $btn_entries[] = $entry;
- }
- }
-
- if (!$has_indoor || empty($btn_entries)) {
- continue;
- }
-
- foreach ($btn_entries as $btn) {
- $btn_device = $this -> devices() -> by_alias($btn["alias"]);
- if (!$btn_device) {
- continue;
- }
-
- $btn_api = $btn_device -> device_api();
- if (!($btn_api instanceof \SHServ\Tools\DeviceAPI\Button)) {
- continue;
- }
-
- $btn_channel = $btn["channel"] ?? 0;
-
- if ($mute) {
- $btn_api -> set_channel_state("mute", $btn_channel);
- } else {
- // Unmute: figure out whether the linked relay is on or off
- $sync_state = "disabled";
- foreach ($connection as $e) {
- if (($e["type"] ?? "") === "relay" && isset($indoor_map[$e["alias"]])) {
- $expected = $indoor_map[$e["alias"]];
- $relay_ch = $e["channel"] ?? 0;
- if ($expected === null || $expected === $relay_ch) {
- $relay = $this -> devices() -> by_alias($e["alias"]);
- if ($relay) {
- $relay_api = $relay -> device_api();
- if ($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
- $status = $relay_api -> get_status();
- $st = $status["channels"][$relay_ch]["state"] ?? "off";
- $sync_state = ($st === "on") ? "enabled" : "disabled";
- }
- }
- break;
- }
- }
- }
- $btn_api -> set_channel_state($sync_state, $btn_channel);
- }
- }
- }
- }
-}