diff --git a/automation/Common.php b/automation/Common.php
new file mode 100644
index 0000000..e1e6b60
--- /dev/null
+++ b/automation/Common.php
@@ -0,0 +1,60 @@
+ add_sync_connection($connection);
+ }
+ }
+
+ public function btn_on_online(String $alias, Array $muted = []): void {
+ $this -> add_event_handler("button@{$alias}.online", function(Device $btns_block, Array $data) use ($muted) {
+ $btns_block_api = $btns_block -> device_api();
+ if($btns_block_api instanceof \SHServ\Tools\DeviceAPI\Button) {
+ foreach($muted as $ch) {
+ $btns_block_api -> set_channel_state("mute", $ch);
+ }
+ }
+
+ $this -> helper() -> sync_btn_channels($this -> sync_map(), $btns_block -> alias);
+ });
+ }
+
+ public function set_btns_click_handlers($alias): void {
+ $self = $this;
+ $buttons = $this -> helper() -> prepare_sync_map_by_alias($this -> sync_map(), $alias);
+
+ foreach($buttons as $btn_channel => $entry) {
+ if($entry[0]["type"] != "relay") {
+ continue;
+ }
+
+ $relay_alias = $entry[0]["alias"];
+ $relay_channel = $entry[0]["channel"];
+
+ $this -> add_event_handler("button@{$alias}({$btn_channel}).press", function(Device $btns_block, Array $data) use ($self, $btn_channel, $relay_alias, $relay_channel) {
+ $btns_block_api = $btns_block -> device_api();
+ $relay_api = $this -> devices() -> by_alias($relay_alias) -> device_api();
+
+ if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay and $btns_block_api instanceof \SHServ\Tools\DeviceAPI\Button) {
+ $relay_api -> toggle_channel($relay_channel);
+ $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $relay_alias);
+ }
+ });
+ }
+ }
+}
diff --git a/automation/Scopes/LightHubScope.php b/automation/Scopes/LightHubScope.php
new file mode 100644
index 0000000..de9da3b
--- /dev/null
+++ b/automation/Scopes/LightHubScope.php
@@ -0,0 +1,164 @@
+ register_global_device_sync_map();
+ }
+
+ public function register_events_handlers(): void {
+ $this -> btn_on_online("master_room_btns", [2, 3]);
+ $this -> btn_on_online("btns_hall2_1");
+ $this -> btn_on_online("hall_secondary");
+ $this -> btn_on_online("bed_btns_right_1");
+ $this -> btn_on_online("bed_btns_left");
+ $this -> btn_on_online("kitchen_buttons_1");
+ $this -> btn_on_online("kitchen_buttons_2");
+ $this -> btn_on_online("first_hall_buttons1", [3]);
+ $this -> btn_on_online("first_hall_buttons2");
+ $this -> set_btns_click_handlers("master_room_btns");
+ $this -> set_btns_click_handlers("btns_hall2_1");
+ $this -> set_btns_click_handlers("hall_secondary");
+ $this -> set_btns_click_handlers("bed_btns_right_1");
+ $this -> set_btns_click_handlers("bed_btns_left");
+ $this -> set_btns_click_handlers("kitchen_buttons_1");
+ $this -> set_btns_click_handlers("kitchen_buttons_2");
+ $this -> set_btns_click_handlers("first_hall_buttons1");
+ $this -> set_btns_click_handlers("first_hall_buttons2");
+
+
+
+
+ $this -> btn_on_online("plants_room_btns", [1]);
+ $this -> set_btns_click_handlers("plants_room_btns");
+
+ }
+
+ public function register_actions_scripts(): void {
+ $this -> add_action_script([
+ "alias" => "master_room_lamp_switcher",
+ "name" => "Осн. свет в спальне",
+ "icon" => '',
+ "description" => "Включить/выключить основной свет в спальне",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return $this -> lamp_switch("light_hub_1", 1);
+ });
+
+ $this -> add_action_script([
+ "alias" => "hallway2_lamp_switcher",
+ "name" => "Осн. свет в холе, эт2",
+ "icon" => '',
+ "description" => "Включить/выключить основной свет в холе на втором этаже",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return $this -> lamp_switch("light_hub_1", 2);
+ });
+
+ $this -> add_action_script([
+ "alias" => "bathroom2_lamp_switcher",
+ "name" => "Осн. свет в ванной 2",
+ "icon" => '',
+ "description" => "Включить/выключить основной свет в ванной комнате на верху",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return $this -> lamp_switch("light_hub_1", 3);
+ });
+
+ // ---
+
+ $this -> add_action_script([
+ "alias" => "hall1_light_switcher",
+ "name" => "Свет в прихожей",
+ "icon" => '',
+ "description" => "Включить/выключить свет в прихожей",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return
+ $this -> lamp_switch("fisrt_floor_big_relay", 3) and $this -> lamp_switch("fisrt_floor_big_relay", 4);
+ });
+
+ $this -> add_action_script([
+ "alias" => "kitchen_light_switcher",
+ "name" => "Полный свет на кухне",
+ "icon" => '',
+ "description" => "Включить/выключить весь имеющийся свет на кухне",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return
+ $this -> lamp_switch("fisrt_floor_big_relay", 0) and $this -> lamp_switch("fisrt_floor_big_relay", 1);
+ });
+
+ $this -> add_action_script([
+ "alias" => "hatch_open",
+ "name" => "Открыть люк",
+ "icon" => '',
+ "description" => "Открыть люк на кухне",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return
+ $this -> hatch_open("kitchen_hatch", 100);
+ });
+
+ $this -> add_action_script([
+ "alias" => "hatch_close",
+ "name" => "Закрыть люк",
+ "icon" => '',
+ "description" => "Закрыть люк на кухне",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return
+ $this -> hatch_close("kitchen_hatch", 100);
+ });
+ }
+
+ public function register_regular_scripts(): void {
+ }
+
+ // ACTIONS
+
+ protected function lamp_switch(String $relay_alias, int $channel): Array {
+ $relay_api = $this -> devices() -> by_alias($relay_alias) -> device_api();
+
+ $result = false;
+ if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
+ $result = $relay_api -> toggle_channel($channel);
+ $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $relay_alias);
+ }
+
+ return [
+ "result" => $result
+ ];
+ }
+
+ protected function hatch_do(String $hatch_alias, String $operation = "open", int $percent = 100): Array | bool {
+ $hatch_api = $this -> devices() -> by_alias($hatch_alias) -> device_api();
+
+ $result = false;
+ if($hatch_api instanceof \SHServ\Tools\DeviceAPI\Hatch) {
+ switch($operation) {
+ case "open": $result = $hatch_api -> open($percent);
+ break;
+ case "close": $result = $hatch_api -> close($percent);
+ break;
+ }
+ }
+
+ return $result;
+ }
+
+ protected function hatch_open(String $hatch_alias, int $percent = 100) {
+ return $this -> hatch_do($hatch_alias, "open", $percent);
+ }
+
+ protected function hatch_close(String $hatch_alias, int $percent = 100) {
+ return $this -> hatch_do($hatch_alias, "close", $percent);
+ }
+
+}
diff --git a/automation/Scopes/OfficeRoomScope.php b/automation/Scopes/OfficeRoomScope.php
new file mode 100644
index 0000000..8d6d36a
--- /dev/null
+++ b/automation/Scopes/OfficeRoomScope.php
@@ -0,0 +1,71 @@
+ register_global_device_sync_map();
+ }
+
+ public function register_events_handlers(): void {
+ $this -> btn_on_online("buttons_office_room");
+ $this -> set_btns_click_handlers("buttons_office_room");
+ }
+
+ public function register_actions_scripts(): void {
+ $this -> add_action_script([
+ "alias" => "computer_table_lamp_switch",
+ "name" => "Комп. лампа",
+ "icon" => '',
+ "description" => "Вкл/Выкл. настольную компьютерную лампу",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return $this -> lamp_switch("computer_table_lamp", 0);
+ });
+
+ $this -> add_action_script([
+ "alias" => "craft_table_lamp_switch",
+ "name" => "Крафт. лампа",
+ "icon" => '',
+ "description" => "Вкл/Выкл. настольную лампу на столе для крафта",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return $this -> lamp_switch("craft_table_lamp", 0);
+ });
+
+ $this -> add_action_script([
+ "alias" => "main_lamps_switcher",
+ "name" => "Осн. свет в кабинете",
+ "icon" => '',
+ "description" => "Включить/выключить основной свет в кабинете",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return $this -> lamp_switch("light_hub_1", 0);
+ });
+ }
+
+ public function register_regular_scripts(): void {
+ }
+
+ // ACTIONS
+
+ protected function lamp_switch(String $relay_alias, int $channel): Array {
+ $btns_block_api = $this -> devices() -> by_alias("buttons_office_room") -> device_api();
+ $relay_api = $this -> devices() -> by_alias($relay_alias) -> device_api();
+
+ $result = false;
+ if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
+ $result = $relay_api -> toggle_channel($channel);
+ $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $relay_alias);
+ }
+
+ return [
+ "result" => $result
+ ];
+ }
+
+}
diff --git a/automation/Scopes/SpotlightsScope.php b/automation/Scopes/SpotlightsScope.php
new file mode 100644
index 0000000..269c19d
--- /dev/null
+++ b/automation/Scopes/SpotlightsScope.php
@@ -0,0 +1,117 @@
+ register_global_device_sync_map();
+ }
+
+ public function register_events_handlers(): void {
+ $this -> set_btns_click_handlers("buttons_backdoor");
+ $this -> set_btns_click_handlers("master_door_btns");
+ $this -> btn_on_online("buttons_backdoor", [3]);
+ $this -> btn_on_online("master_door_btns", [2]);
+ }
+
+ public function register_actions_scripts(): void {
+ $this -> add_action_script([
+ "alias" => "spotlights_on",
+ "name" => "All Spotlights On",
+ "icon" => '',
+ "description" => "Включить все прожекторы",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return $this -> all_spotlight_switch(true);
+ });
+
+ $this -> add_action_script([
+ "alias" => "spotlights_off",
+ "name" => "All Spotlights Off",
+ "icon" => '',
+ "description" => "Выключить все прожекторы",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return $this -> all_spotlight_switch(false);
+ });
+
+ $this -> add_action_script([
+ "alias" => "front_spotlight_on",
+ "name" => "ВКЛ фронтальный прожектор",
+ "icon" => '',
+ "description" => "Включить только фронтальный прожектор на главном входе",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return $this -> spotlight_switch("spotlight_main_front_1", true);
+ });
+
+ $this -> add_action_script([
+ "alias" => "front_spotlight_off",
+ "name" => "ВЫКЛ фронтальный прожектор",
+ "icon" => '',
+ "description" => "Выключить только фронтальный прожектор на главном входе",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ return $this -> spotlight_switch("spotlight_main_front_1", false);
+ });
+ }
+
+ public function register_regular_scripts(): void {
+ $this -> add_regular_script([
+ "alias" => "spotlights_by_time",
+ "name" => "Spotlights by Time",
+ "description" => "Управление уличными прожекторами по времени",
+ "author" => "Eugene Sukhodolskiy"
+ ], function () {
+ });
+ }
+
+ // ACTIONS
+
+ protected function spotlight_switch(String $relay_alias, Bool $state = false) {
+ $device_entries = $this -> helper() -> get_sync_entries_by_type($this -> sync_map(), "relay");
+
+ $relay_api = $this -> devices() -> by_alias($relay_alias) -> device_api();
+ $result = false;
+ if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
+ $result = $relay_api -> set_state($state);
+ $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $relay_alias);
+ }
+
+ return [
+ "result" => $result
+ ];
+ }
+
+ protected function all_spotlight_switch(Bool $state = false): Array {
+ $results = [];
+ $device_entries = $this -> helper() -> get_sync_entries_by_type($this -> sync_map(), "relay");
+
+ foreach($device_entries as $device_entry) {
+ $relay_api = $this -> devices() -> by_alias($device_entry["alias"]) -> device_api();
+ $result = false;
+ $ch = $device_entry["channel"];
+
+ if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
+ $status = $relay_api -> get_status();
+
+ if(isset($status["channels"][$ch]["state"]) and $status["channels"][$ch]["state"] != ($state ? "on" : "off")) {
+ $result = $relay_api -> set_state($state);
+ }
+ }
+
+ $results[$device_entry["alias"]] = $result;
+ $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $device_entry["alias"]);
+ }
+
+
+ return [
+ "devices" => $results
+ ];
+ }
+
+}
diff --git a/automation/Scopes/TestScriptsScope.php b/automation/Scopes/TestScriptsScope.php
new file mode 100644
index 0000000..1fa3994
--- /dev/null
+++ b/automation/Scopes/TestScriptsScope.php
@@ -0,0 +1,33 @@
+ add_action_script([
+ "alias" => "stand_relay_toggle",
+ "icon" => '',
+ "name" => "Toggle Stang Relay",
+ "description" => "Управление тестовым стендом у меня на столе. Просто переключатель",
+ "author" => "Eugene Sukhodolskiy"
+ ], function($params) {
+ $device = $this -> devices() -> by_alias("test_stand_relay");
+ return [
+ "device_response" => $device -> device_api() -> toggle_channel(),
+ ];
+ });
+ }
+
+ public function register_regular_scripts(): void {
+ }
+
+}
\ No newline at end of file
diff --git a/automation/scopes-manifest.json b/automation/scopes-manifest.json
new file mode 100644
index 0000000..5f034fd
--- /dev/null
+++ b/automation/scopes-manifest.json
@@ -0,0 +1,8 @@
+{
+ "scopes": [
+ "LightHubScope",
+ "OfficeRoomScope",
+ "SpotlightsScope",
+ "TestScriptsScope"
+ ]
+}
diff --git a/automation/sync-map.json b/automation/sync-map.json
new file mode 100644
index 0000000..02e0879
--- /dev/null
+++ b/automation/sync-map.json
@@ -0,0 +1,88 @@
+[
+ [
+ {"type": "relay", "alias": "spotlight_main_back_1", "channel": 0},
+ {"type": "button", "alias": "buttons_backdoor", "channel": 2},
+ {"type": "button", "alias": "master_door_btns", "channel": 1},
+ {"type": "button", "alias": "bed_btns_left", "channel": 0}
+ ],
+ [
+ {"type": "relay", "alias": "spotlight_main_back_2", "channel": 0},
+ {"type": "button", "alias": "buttons_backdoor", "channel": 1},
+ {"type": "button", "alias": "master_door_btns", "channel": 0}
+ ],
+ [
+ {"type": "relay", "alias": "spotlight_main_front_1", "channel": 0},
+ {"type": "button", "alias": "buttons_backdoor", "channel": 0},
+ {"type": "button", "alias": "master_door_btns", "channel": 3}
+ ],
+ [
+ {"type": "relay", "alias": "light_hub_1", "channel": 0},
+ {"type": "button", "alias": "buttons_office_room", "channel": 3}
+ ],
+ [
+ {"type": "relay", "alias": "craft_table_lamp", "channel": 0},
+ {"type": "button", "alias": "buttons_office_room", "channel": 2}
+ ],
+ [
+ {"type": "relay", "alias": "computer_table_lamp", "channel": 0},
+ {"type": "button", "alias": "buttons_office_room", "channel": 1}
+ ],
+ [
+ {"type": "relay", "alias": "light_hub_1", "channel": 2},
+ {"type": "button", "alias": "buttons_office_room", "channel": 0},
+ {"type": "button", "alias": "master_room_btns", "channel": 1},
+ {"type": "button", "alias": "btns_hall2_1", "channel": 0},
+ {"type": "button", "alias": "hall_secondary", "channel": 0},
+ {"type": "button", "alias": "bed_btns_right_1", "channel": 0}
+ ],
+ [
+ {"type": "relay", "alias": "light_hub_1", "channel": 1},
+ {"type": "button", "alias": "master_room_btns", "channel": 0},
+ {"type": "button", "alias": "bed_btns_right_1", "channel": 1},
+ {"type": "button", "alias": "bed_btns_left", "channel": 1}
+ ],
+ [
+ {"type": "relay", "alias": "bathroom_2_light", "channel": 0},
+ {"type": "button", "alias": "hall_secondary", "channel": 1}
+ ],
+ [
+ {"type": "relay", "alias": "plants_room_light", "channel": 0},
+ {"type": "button", "alias": "plants_room_btns", "channel": 3}
+ ],
+ [
+ {"type": "relay", "alias": "italy_lamp_relay", "channel": 0},
+ {"type": "button", "alias": "plants_room_btns", "channel": 2}
+ ],
+ [
+ {"type": "relay", "alias": "floor_lamp_relay", "channel": 0},
+ {"type": "button", "alias": "plants_room_btns", "channel": 0}
+ ],
+ [
+ {"type": "relay", "alias": "server_room_light", "channel": 0},
+ {"type": "button", "alias": "btns_hall2_1", "channel": 1}
+ ],
+ [
+ {"type": "relay", "alias": "fisrt_floor_big_relay", "channel": 0},
+ {"type": "button", "alias": "kitchen_buttons_1", "channel": 0},
+ {"type": "button", "alias": "kitchen_buttons_2", "channel": 0}
+ ],
+ [
+ {"type": "relay", "alias": "fisrt_floor_big_relay", "channel": 1},
+ {"type": "button", "alias": "kitchen_buttons_1", "channel": 1},
+ {"type": "button", "alias": "kitchen_buttons_2", "channel": 1}
+ ],
+ [
+ {"type": "relay", "alias": "fisrt_floor_big_relay", "channel": 2},
+ {"type": "button", "alias": "first_hall_buttons1", "channel": 0}
+ ],
+ [
+ {"type": "relay", "alias": "fisrt_floor_big_relay", "channel": 3},
+ {"type": "button", "alias": "first_hall_buttons1", "channel": 1},
+ {"type": "button", "alias": "first_hall_buttons2", "channel": 0}
+ ],
+ [
+ {"type": "relay", "alias": "fisrt_floor_big_relay", "channel": 4},
+ {"type": "button", "alias": "first_hall_buttons1", "channel": 2},
+ {"type": "button", "alias": "first_hall_buttons2", "channel": 1}
+ ]
+]
\ No newline at end of file
diff --git a/server/ControlScripts/Common.php b/server/ControlScripts/Common.php
deleted file mode 100644
index e1e6b60..0000000
--- a/server/ControlScripts/Common.php
+++ /dev/null
@@ -1,60 +0,0 @@
- add_sync_connection($connection);
- }
- }
-
- public function btn_on_online(String $alias, Array $muted = []): void {
- $this -> add_event_handler("button@{$alias}.online", function(Device $btns_block, Array $data) use ($muted) {
- $btns_block_api = $btns_block -> device_api();
- if($btns_block_api instanceof \SHServ\Tools\DeviceAPI\Button) {
- foreach($muted as $ch) {
- $btns_block_api -> set_channel_state("mute", $ch);
- }
- }
-
- $this -> helper() -> sync_btn_channels($this -> sync_map(), $btns_block -> alias);
- });
- }
-
- public function set_btns_click_handlers($alias): void {
- $self = $this;
- $buttons = $this -> helper() -> prepare_sync_map_by_alias($this -> sync_map(), $alias);
-
- foreach($buttons as $btn_channel => $entry) {
- if($entry[0]["type"] != "relay") {
- continue;
- }
-
- $relay_alias = $entry[0]["alias"];
- $relay_channel = $entry[0]["channel"];
-
- $this -> add_event_handler("button@{$alias}({$btn_channel}).press", function(Device $btns_block, Array $data) use ($self, $btn_channel, $relay_alias, $relay_channel) {
- $btns_block_api = $btns_block -> device_api();
- $relay_api = $this -> devices() -> by_alias($relay_alias) -> device_api();
-
- if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay and $btns_block_api instanceof \SHServ\Tools\DeviceAPI\Button) {
- $relay_api -> toggle_channel($relay_channel);
- $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $relay_alias);
- }
- });
- }
- }
-}
diff --git a/server/ControlScripts/Scopes/LightHubScope.php b/server/ControlScripts/Scopes/LightHubScope.php
deleted file mode 100644
index de9da3b..0000000
--- a/server/ControlScripts/Scopes/LightHubScope.php
+++ /dev/null
@@ -1,164 +0,0 @@
- register_global_device_sync_map();
- }
-
- public function register_events_handlers(): void {
- $this -> btn_on_online("master_room_btns", [2, 3]);
- $this -> btn_on_online("btns_hall2_1");
- $this -> btn_on_online("hall_secondary");
- $this -> btn_on_online("bed_btns_right_1");
- $this -> btn_on_online("bed_btns_left");
- $this -> btn_on_online("kitchen_buttons_1");
- $this -> btn_on_online("kitchen_buttons_2");
- $this -> btn_on_online("first_hall_buttons1", [3]);
- $this -> btn_on_online("first_hall_buttons2");
- $this -> set_btns_click_handlers("master_room_btns");
- $this -> set_btns_click_handlers("btns_hall2_1");
- $this -> set_btns_click_handlers("hall_secondary");
- $this -> set_btns_click_handlers("bed_btns_right_1");
- $this -> set_btns_click_handlers("bed_btns_left");
- $this -> set_btns_click_handlers("kitchen_buttons_1");
- $this -> set_btns_click_handlers("kitchen_buttons_2");
- $this -> set_btns_click_handlers("first_hall_buttons1");
- $this -> set_btns_click_handlers("first_hall_buttons2");
-
-
-
-
- $this -> btn_on_online("plants_room_btns", [1]);
- $this -> set_btns_click_handlers("plants_room_btns");
-
- }
-
- public function register_actions_scripts(): void {
- $this -> add_action_script([
- "alias" => "master_room_lamp_switcher",
- "name" => "Осн. свет в спальне",
- "icon" => '',
- "description" => "Включить/выключить основной свет в спальне",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return $this -> lamp_switch("light_hub_1", 1);
- });
-
- $this -> add_action_script([
- "alias" => "hallway2_lamp_switcher",
- "name" => "Осн. свет в холе, эт2",
- "icon" => '',
- "description" => "Включить/выключить основной свет в холе на втором этаже",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return $this -> lamp_switch("light_hub_1", 2);
- });
-
- $this -> add_action_script([
- "alias" => "bathroom2_lamp_switcher",
- "name" => "Осн. свет в ванной 2",
- "icon" => '',
- "description" => "Включить/выключить основной свет в ванной комнате на верху",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return $this -> lamp_switch("light_hub_1", 3);
- });
-
- // ---
-
- $this -> add_action_script([
- "alias" => "hall1_light_switcher",
- "name" => "Свет в прихожей",
- "icon" => '',
- "description" => "Включить/выключить свет в прихожей",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return
- $this -> lamp_switch("fisrt_floor_big_relay", 3) and $this -> lamp_switch("fisrt_floor_big_relay", 4);
- });
-
- $this -> add_action_script([
- "alias" => "kitchen_light_switcher",
- "name" => "Полный свет на кухне",
- "icon" => '',
- "description" => "Включить/выключить весь имеющийся свет на кухне",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return
- $this -> lamp_switch("fisrt_floor_big_relay", 0) and $this -> lamp_switch("fisrt_floor_big_relay", 1);
- });
-
- $this -> add_action_script([
- "alias" => "hatch_open",
- "name" => "Открыть люк",
- "icon" => '',
- "description" => "Открыть люк на кухне",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return
- $this -> hatch_open("kitchen_hatch", 100);
- });
-
- $this -> add_action_script([
- "alias" => "hatch_close",
- "name" => "Закрыть люк",
- "icon" => '',
- "description" => "Закрыть люк на кухне",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return
- $this -> hatch_close("kitchen_hatch", 100);
- });
- }
-
- public function register_regular_scripts(): void {
- }
-
- // ACTIONS
-
- protected function lamp_switch(String $relay_alias, int $channel): Array {
- $relay_api = $this -> devices() -> by_alias($relay_alias) -> device_api();
-
- $result = false;
- if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
- $result = $relay_api -> toggle_channel($channel);
- $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $relay_alias);
- }
-
- return [
- "result" => $result
- ];
- }
-
- protected function hatch_do(String $hatch_alias, String $operation = "open", int $percent = 100): Array | bool {
- $hatch_api = $this -> devices() -> by_alias($hatch_alias) -> device_api();
-
- $result = false;
- if($hatch_api instanceof \SHServ\Tools\DeviceAPI\Hatch) {
- switch($operation) {
- case "open": $result = $hatch_api -> open($percent);
- break;
- case "close": $result = $hatch_api -> close($percent);
- break;
- }
- }
-
- return $result;
- }
-
- protected function hatch_open(String $hatch_alias, int $percent = 100) {
- return $this -> hatch_do($hatch_alias, "open", $percent);
- }
-
- protected function hatch_close(String $hatch_alias, int $percent = 100) {
- return $this -> hatch_do($hatch_alias, "close", $percent);
- }
-
-}
diff --git a/server/ControlScripts/Scopes/OfficeRoomScope.php b/server/ControlScripts/Scopes/OfficeRoomScope.php
deleted file mode 100644
index 8d6d36a..0000000
--- a/server/ControlScripts/Scopes/OfficeRoomScope.php
+++ /dev/null
@@ -1,71 +0,0 @@
- register_global_device_sync_map();
- }
-
- public function register_events_handlers(): void {
- $this -> btn_on_online("buttons_office_room");
- $this -> set_btns_click_handlers("buttons_office_room");
- }
-
- public function register_actions_scripts(): void {
- $this -> add_action_script([
- "alias" => "computer_table_lamp_switch",
- "name" => "Комп. лампа",
- "icon" => '',
- "description" => "Вкл/Выкл. настольную компьютерную лампу",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return $this -> lamp_switch("computer_table_lamp", 0);
- });
-
- $this -> add_action_script([
- "alias" => "craft_table_lamp_switch",
- "name" => "Крафт. лампа",
- "icon" => '',
- "description" => "Вкл/Выкл. настольную лампу на столе для крафта",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return $this -> lamp_switch("craft_table_lamp", 0);
- });
-
- $this -> add_action_script([
- "alias" => "main_lamps_switcher",
- "name" => "Осн. свет в кабинете",
- "icon" => '',
- "description" => "Включить/выключить основной свет в кабинете",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return $this -> lamp_switch("light_hub_1", 0);
- });
- }
-
- public function register_regular_scripts(): void {
- }
-
- // ACTIONS
-
- protected function lamp_switch(String $relay_alias, int $channel): Array {
- $btns_block_api = $this -> devices() -> by_alias("buttons_office_room") -> device_api();
- $relay_api = $this -> devices() -> by_alias($relay_alias) -> device_api();
-
- $result = false;
- if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
- $result = $relay_api -> toggle_channel($channel);
- $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $relay_alias);
- }
-
- return [
- "result" => $result
- ];
- }
-
-}
diff --git a/server/ControlScripts/Scopes/SpotlightsScope.php b/server/ControlScripts/Scopes/SpotlightsScope.php
deleted file mode 100644
index 269c19d..0000000
--- a/server/ControlScripts/Scopes/SpotlightsScope.php
+++ /dev/null
@@ -1,117 +0,0 @@
- register_global_device_sync_map();
- }
-
- public function register_events_handlers(): void {
- $this -> set_btns_click_handlers("buttons_backdoor");
- $this -> set_btns_click_handlers("master_door_btns");
- $this -> btn_on_online("buttons_backdoor", [3]);
- $this -> btn_on_online("master_door_btns", [2]);
- }
-
- public function register_actions_scripts(): void {
- $this -> add_action_script([
- "alias" => "spotlights_on",
- "name" => "All Spotlights On",
- "icon" => '',
- "description" => "Включить все прожекторы",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return $this -> all_spotlight_switch(true);
- });
-
- $this -> add_action_script([
- "alias" => "spotlights_off",
- "name" => "All Spotlights Off",
- "icon" => '',
- "description" => "Выключить все прожекторы",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return $this -> all_spotlight_switch(false);
- });
-
- $this -> add_action_script([
- "alias" => "front_spotlight_on",
- "name" => "ВКЛ фронтальный прожектор",
- "icon" => '',
- "description" => "Включить только фронтальный прожектор на главном входе",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return $this -> spotlight_switch("spotlight_main_front_1", true);
- });
-
- $this -> add_action_script([
- "alias" => "front_spotlight_off",
- "name" => "ВЫКЛ фронтальный прожектор",
- "icon" => '',
- "description" => "Выключить только фронтальный прожектор на главном входе",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- return $this -> spotlight_switch("spotlight_main_front_1", false);
- });
- }
-
- public function register_regular_scripts(): void {
- $this -> add_regular_script([
- "alias" => "spotlights_by_time",
- "name" => "Spotlights by Time",
- "description" => "Управление уличными прожекторами по времени",
- "author" => "Eugene Sukhodolskiy"
- ], function () {
- });
- }
-
- // ACTIONS
-
- protected function spotlight_switch(String $relay_alias, Bool $state = false) {
- $device_entries = $this -> helper() -> get_sync_entries_by_type($this -> sync_map(), "relay");
-
- $relay_api = $this -> devices() -> by_alias($relay_alias) -> device_api();
- $result = false;
- if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
- $result = $relay_api -> set_state($state);
- $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $relay_alias);
- }
-
- return [
- "result" => $result
- ];
- }
-
- protected function all_spotlight_switch(Bool $state = false): Array {
- $results = [];
- $device_entries = $this -> helper() -> get_sync_entries_by_type($this -> sync_map(), "relay");
-
- foreach($device_entries as $device_entry) {
- $relay_api = $this -> devices() -> by_alias($device_entry["alias"]) -> device_api();
- $result = false;
- $ch = $device_entry["channel"];
-
- if($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
- $status = $relay_api -> get_status();
-
- if(isset($status["channels"][$ch]["state"]) and $status["channels"][$ch]["state"] != ($state ? "on" : "off")) {
- $result = $relay_api -> set_state($state);
- }
- }
-
- $results[$device_entry["alias"]] = $result;
- $this -> helper() -> sync_relay_to_btns($this -> sync_map(), $device_entry["alias"]);
- }
-
-
- return [
- "devices" => $results
- ];
- }
-
-}
diff --git a/server/ControlScripts/Scopes/TestScriptsScope.php b/server/ControlScripts/Scopes/TestScriptsScope.php
deleted file mode 100644
index 1fa3994..0000000
--- a/server/ControlScripts/Scopes/TestScriptsScope.php
+++ /dev/null
@@ -1,33 +0,0 @@
- add_action_script([
- "alias" => "stand_relay_toggle",
- "icon" => '',
- "name" => "Toggle Stang Relay",
- "description" => "Управление тестовым стендом у меня на столе. Просто переключатель",
- "author" => "Eugene Sukhodolskiy"
- ], function($params) {
- $device = $this -> devices() -> by_alias("test_stand_relay");
- return [
- "device_response" => $device -> device_api() -> toggle_channel(),
- ];
- });
- }
-
- public function register_regular_scripts(): void {
- }
-
-}
\ No newline at end of file
diff --git a/server/ControlScripts/sync-map.json b/server/ControlScripts/sync-map.json
deleted file mode 100644
index 02e0879..0000000
--- a/server/ControlScripts/sync-map.json
+++ /dev/null
@@ -1,88 +0,0 @@
-[
- [
- {"type": "relay", "alias": "spotlight_main_back_1", "channel": 0},
- {"type": "button", "alias": "buttons_backdoor", "channel": 2},
- {"type": "button", "alias": "master_door_btns", "channel": 1},
- {"type": "button", "alias": "bed_btns_left", "channel": 0}
- ],
- [
- {"type": "relay", "alias": "spotlight_main_back_2", "channel": 0},
- {"type": "button", "alias": "buttons_backdoor", "channel": 1},
- {"type": "button", "alias": "master_door_btns", "channel": 0}
- ],
- [
- {"type": "relay", "alias": "spotlight_main_front_1", "channel": 0},
- {"type": "button", "alias": "buttons_backdoor", "channel": 0},
- {"type": "button", "alias": "master_door_btns", "channel": 3}
- ],
- [
- {"type": "relay", "alias": "light_hub_1", "channel": 0},
- {"type": "button", "alias": "buttons_office_room", "channel": 3}
- ],
- [
- {"type": "relay", "alias": "craft_table_lamp", "channel": 0},
- {"type": "button", "alias": "buttons_office_room", "channel": 2}
- ],
- [
- {"type": "relay", "alias": "computer_table_lamp", "channel": 0},
- {"type": "button", "alias": "buttons_office_room", "channel": 1}
- ],
- [
- {"type": "relay", "alias": "light_hub_1", "channel": 2},
- {"type": "button", "alias": "buttons_office_room", "channel": 0},
- {"type": "button", "alias": "master_room_btns", "channel": 1},
- {"type": "button", "alias": "btns_hall2_1", "channel": 0},
- {"type": "button", "alias": "hall_secondary", "channel": 0},
- {"type": "button", "alias": "bed_btns_right_1", "channel": 0}
- ],
- [
- {"type": "relay", "alias": "light_hub_1", "channel": 1},
- {"type": "button", "alias": "master_room_btns", "channel": 0},
- {"type": "button", "alias": "bed_btns_right_1", "channel": 1},
- {"type": "button", "alias": "bed_btns_left", "channel": 1}
- ],
- [
- {"type": "relay", "alias": "bathroom_2_light", "channel": 0},
- {"type": "button", "alias": "hall_secondary", "channel": 1}
- ],
- [
- {"type": "relay", "alias": "plants_room_light", "channel": 0},
- {"type": "button", "alias": "plants_room_btns", "channel": 3}
- ],
- [
- {"type": "relay", "alias": "italy_lamp_relay", "channel": 0},
- {"type": "button", "alias": "plants_room_btns", "channel": 2}
- ],
- [
- {"type": "relay", "alias": "floor_lamp_relay", "channel": 0},
- {"type": "button", "alias": "plants_room_btns", "channel": 0}
- ],
- [
- {"type": "relay", "alias": "server_room_light", "channel": 0},
- {"type": "button", "alias": "btns_hall2_1", "channel": 1}
- ],
- [
- {"type": "relay", "alias": "fisrt_floor_big_relay", "channel": 0},
- {"type": "button", "alias": "kitchen_buttons_1", "channel": 0},
- {"type": "button", "alias": "kitchen_buttons_2", "channel": 0}
- ],
- [
- {"type": "relay", "alias": "fisrt_floor_big_relay", "channel": 1},
- {"type": "button", "alias": "kitchen_buttons_1", "channel": 1},
- {"type": "button", "alias": "kitchen_buttons_2", "channel": 1}
- ],
- [
- {"type": "relay", "alias": "fisrt_floor_big_relay", "channel": 2},
- {"type": "button", "alias": "first_hall_buttons1", "channel": 0}
- ],
- [
- {"type": "relay", "alias": "fisrt_floor_big_relay", "channel": 3},
- {"type": "button", "alias": "first_hall_buttons1", "channel": 1},
- {"type": "button", "alias": "first_hall_buttons2", "channel": 0}
- ],
- [
- {"type": "relay", "alias": "fisrt_floor_big_relay", "channel": 4},
- {"type": "button", "alias": "first_hall_buttons1", "channel": 2},
- {"type": "button", "alias": "first_hall_buttons2", "channel": 1}
- ]
-]
\ No newline at end of file
diff --git a/server/SHServ/App.php b/server/SHServ/App.php
index a420ed8..a4d89a5 100644
--- a/server/SHServ/App.php
+++ b/server/SHServ/App.php
@@ -23,7 +23,6 @@
public $devtools;
public $control_scripts_instances = [];
- protected $required_control_scripts_instance;
public function __construct() {
parent::__construct();
@@ -145,16 +144,10 @@
public function control_scripts_init(): void {
\SHServ\Middleware\ControlScripts::flush_statics();
- $this -> required_control_scripts_instance = new \SHServ\RequiredControlScriptsScope();
+ $manifest_path = __DIR__ . "/../../automation/scopes-manifest.json";
+ $manifest = json_decode(file_get_contents($manifest_path), true);
- $scopes_dir = __DIR__ . "/../ControlScripts/Scopes/";
- $scripts_dir = scandir($scopes_dir);
- $scripts = array_filter($scripts_dir, function($item) use ($scopes_dir) {
- return !is_dir($scopes_dir . $item) and (pathinfo($item))["extension"] == "php";
- });
-
- foreach($scripts as $script_name) {
- $script_name = basename($script_name, ".php");
+ foreach($manifest["scopes"] as $script_name) {
$full_script_name = "\\ControlScripts\\Scopes\\{$script_name}";
$script = new $full_script_name();
diff --git a/server/SHServ/Controllers/CronController.php b/server/SHServ/Controllers/CronController.php
index 015b004..2fb8bf7 100644
--- a/server/SHServ/Controllers/CronController.php
+++ b/server/SHServ/Controllers/CronController.php
@@ -22,6 +22,21 @@
}
}
+ protected function run_script_cli(String $alias): int {
+ $output = [];
+ $returnCode = 0;
+ $consolePath = __DIR__ . "/../../console.php";
+ exec("php " . escapeshellarg($consolePath) . " run-regular-script " . escapeshellarg($alias) . " 2>&1", $output, $returnCode);
+ if($returnCode !== 0) {
+ \Fury\Kernel\Logging::ins() -> set(
+ "CronController@run_regular_cron_scripts",
+ "Regular script {$alias} exited with code {$returnCode}",
+ implode("\n", $output)
+ );
+ }
+ return $returnCode;
+ }
+
public function run_regular_cron_scripts() {
$this -> ensure_localhost_only();
$scripts_model = new Scripts();
@@ -32,16 +47,7 @@
continue;
}
- try {
- $script["script"]();
- } catch (\Exception $e) {
- \Fury\Kernel\Logging::ins() -> set(
- "CronController@run_regular_cron_scripts",
- "Regular script {$alias} failed",
- $e -> getMessage()
- );
- continue;
- }
+ $this -> run_script_cli($alias);
}
}
diff --git a/server/SHServ/Controllers/ScriptsRESTAPIController.php b/server/SHServ/Controllers/ScriptsRESTAPIController.php
index 9007db8..c9c9dbb 100644
--- a/server/SHServ/Controllers/ScriptsRESTAPIController.php
+++ b/server/SHServ/Controllers/ScriptsRESTAPIController.php
@@ -94,33 +94,6 @@
return $this -> utils() -> response_success(["source" => $file]);
}
- public function scope_update($name, $path, $file) {
- if(!strlen($file)) {
- return $this -> utils() -> response_error("empty_field", ["file"]);
- }
-
- $scripts_model = new Scripts();
- if(!$scripts_model -> scope_is_exists($name)) {
- return $this -> utils() -> response_error("scope_not_found");
- }
-
- $allowed_dir = realpath(__DIR__ . "/../../ControlScripts/Scopes/");
- $filepath = realpath("{$path}/{$name}") ?: realpath("{$path}/{$name}.php");
-
- if(!$filepath || strpos($filepath, $allowed_dir) !== 0) {
- return $this -> utils() -> response_error("invalid_path", ["path"]);
- }
-
- if(!file_exists($filepath)) {
- return $this -> utils() -> response_error("file_not_exists");
- }
-
- $result = file_put_contents($filepath, $file);
- return $result
- ? $this -> utils() -> response_success(["result" => true])
- : $this -> utils() -> response_error("undefined_error");
- }
-
public function scope_remove($name) {
return (new Scripts()) -> remove_scope($name)
? $this -> utils() -> response_success()
diff --git a/server/SHServ/EventsHandlers.php b/server/SHServ/EventsHandlers.php
index aa05749..e57332f 100644
--- a/server/SHServ/EventsHandlers.php
+++ b/server/SHServ/EventsHandlers.php
@@ -19,6 +19,14 @@
}
});
+ events() -> handler('app:online', function(Array $params) {
+ $device = $params["device"];
+ $data = $params["data"];
+ $device -> device_ip = $data["device_ip"];
+ $device -> connection_status = "active";
+ $device -> update();
+ });
+
if(FCONF["devmode"]) {
events() -> handler("module:Template.start_making", function(Array $params) {
app() -> devtools -> add_template_to_map(
@@ -60,4 +68,4 @@
});
}
}
-}
\ No newline at end of file
+}
diff --git a/server/SHServ/Middleware/ControlScripts.php b/server/SHServ/Middleware/ControlScripts.php
index 7b660ca..8ad0699 100644
--- a/server/SHServ/Middleware/ControlScripts.php
+++ b/server/SHServ/Middleware/ControlScripts.php
@@ -136,7 +136,7 @@
$start_time = microtime(true);
$result = self::$actions_scripts[$alias]["script"]($params);
-
+
$exec_time = microtime(true) - $start_time;
$exec_time = round($exec_time, 3);
@@ -146,6 +146,30 @@
];
}
+ public static function run_regular_script(String $alias): bool {
+ if(!isset(self::$regular_scripts[$alias])) {
+ return false;
+ }
+
+ $scripts_model = new Scripts();
+ if(!$scripts_model -> script_state("regular", $alias)) {
+ return false;
+ }
+
+ try {
+ self::$regular_scripts[$alias]["script"]();
+ } catch(\Exception $e) {
+ \Fury\Kernel\Logging::ins() -> set(
+ "ControlScripts::run_regular_script",
+ "Regular script {$alias} failed",
+ $e -> getMessage()
+ );
+ return false;
+ }
+
+ return true;
+ }
+
protected function get_source_code($func): String {
$ref_func = new \ReflectionFunction($func);
$file_name = $ref_func -> getFileName();
diff --git a/server/SHServ/RequiredControlScriptsScope.php b/server/SHServ/RequiredControlScriptsScope.php
deleted file mode 100644
index 2f124e8..0000000
--- a/server/SHServ/RequiredControlScriptsScope.php
+++ /dev/null
@@ -1,23 +0,0 @@
- add_event_handler("online", function(Device $device, Array $data) {
- $device -> device_ip = $data["device_ip"];
- $device -> connection_status = "active";
- $device -> update();
- });
- }
-
- public function register_regular_scripts(): void { }
-
- public function register_actions_scripts(): void { }
-
-}
\ No newline at end of file
diff --git a/server/SHServ/Routes/ScriptsRESTAPI_v1.php b/server/SHServ/Routes/ScriptsRESTAPI_v1.php
index 2866dc2..14e91b7 100644
--- a/server/SHServ/Routes/ScriptsRESTAPI_v1.php
+++ b/server/SHServ/Routes/ScriptsRESTAPI_v1.php
@@ -23,12 +23,6 @@
);
$this -> router -> post(
- [ "name", "path", "file" ],
- "{$this -> cn}\\ScriptsRESTAPIController@scope_update",
- '/api/v1/scripts/scopes/update'
- );
-
- $this -> router -> post(
[ "target_id", "place_in_area_id" ],
"{$this -> cn}\\ScriptsRESTAPIController@place_in_area",
"/api/v1/scripts/place-in-area"
diff --git a/server/composer.json b/server/composer.json
index 56a8e70..feea5cf 100644
--- a/server/composer.json
+++ b/server/composer.json
@@ -12,7 +12,7 @@
"classmap": [
"Fury/",
"SHServ/",
- "ControlScripts/"
+ "../automation/"
]
},
"autoload-dev": {
diff --git a/server/console.php b/server/console.php
index c8a9653..b45f38f 100644
--- a/server/console.php
+++ b/server/console.php
@@ -1,5 +1,6 @@
tb = app() -> thin_builder;
+ $this -> tb -> query("CREATE TABLE scripts (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ area_id INTEGER DEFAULT 0,
+ uniq_name TEXT,
+ type TEXT,
+ state TEXT,
+ create_at TEXT,
+ update_at TEXT
+ )");
+ ControlScripts::flush_statics();
+ }
+
+ protected function tearDown(): void {
+ $this -> tb -> query("DROP TABLE IF EXISTS scripts");
+ ControlScripts::flush_statics();
+ }
+
+ public function test_run_regular_script_returns_false_when_alias_missing(): void {
+ $this -> assertFalse(ControlScripts::run_regular_script('nonexistent'));
+ }
+
+ public function test_run_regular_script_returns_false_when_disabled(): void {
+ $ref = new \ReflectionClass(ControlScripts::class);
+ $prop = $ref -> getProperty('regular_scripts');
+ $prop -> setAccessible(true);
+ $prop -> setValue(null, [
+ 'disabled' => [
+ 'attributes' => ['alias' => 'disabled'],
+ 'code' => '',
+ 'script' => function() {}
+ ]
+ ]);
+
+ $this -> tb -> insert('scripts', [
+ 'uniq_name' => 'disabled',
+ 'type' => 'regular',
+ 'state' => 'disabled',
+ 'create_at' => date('Y-m-d H:i:s'),
+ ]);
+
+ $this -> assertFalse(ControlScripts::run_regular_script('disabled'));
+ }
+
+ public function test_run_regular_script_catches_exception(): void {
+ $ref = new \ReflectionClass(ControlScripts::class);
+ $prop = $ref -> getProperty('regular_scripts');
+ $prop -> setAccessible(true);
+ $prop -> setValue(null, [
+ 'fail' => [
+ 'attributes' => ['alias' => 'fail'],
+ 'code' => '',
+ 'script' => function() { throw new \Exception('boom'); }
+ ]
+ ]);
+
+ $this -> tb -> insert('scripts', [
+ 'uniq_name' => 'fail',
+ 'type' => 'regular',
+ 'state' => 'enabled',
+ 'create_at' => date('Y-m-d H:i:s'),
+ ]);
+
+ $this -> assertFalse(ControlScripts::run_regular_script('fail'));
+ }
+
+ public function test_run_regular_script_returns_true_on_success(): void {
+ $ref = new \ReflectionClass(ControlScripts::class);
+ $prop = $ref -> getProperty('regular_scripts');
+ $prop -> setAccessible(true);
+ $prop -> setValue(null, [
+ 'ok' => [
+ 'attributes' => ['alias' => 'ok'],
+ 'code' => '',
+ 'script' => function() { return true; }
+ ]
+ ]);
+
+ $this -> tb -> insert('scripts', [
+ 'uniq_name' => 'ok',
+ 'type' => 'regular',
+ 'state' => 'enabled',
+ 'create_at' => date('Y-m-d H:i:s'),
+ ]);
+
+ $this -> assertTrue(ControlScripts::run_regular_script('ok'));
+ }
+}
diff --git a/server/tests/CronControllerTest.php b/server/tests/CronControllerTest.php
index 73ed015..50ba1e3 100644
--- a/server/tests/CronControllerTest.php
+++ b/server/tests/CronControllerTest.php
@@ -4,6 +4,15 @@
use SHServ\Controllers\CronController;
use SHServ\Middleware\ControlScripts;
+class TestableCronController extends CronController {
+ public $cliCalls = [];
+ public $returnCodes = [];
+ protected function run_script_cli(String $alias): int {
+ $this -> cliCalls[] = $alias;
+ return $this -> returnCodes[$alias] ?? 0;
+ }
+}
+
class CronControllerTest extends TestCase {
protected $tb;
@@ -26,10 +35,7 @@
ControlScripts::flush_statics();
}
- public function test_regular_scripts_continue_after_failure(): void {
- $executed = [];
-
- // Inject test regular scripts directly into ControlScripts static storage
+ public function test_regular_scripts_are_dispatched_to_cli(): void {
$ref = new \ReflectionClass(ControlScripts::class);
$prop = $ref -> getProperty('regular_scripts');
$prop -> setAccessible(true);
@@ -38,22 +44,16 @@
'fail_script' => [
'attributes' => ['alias' => 'fail_script', 'name' => 'Fail'],
'code' => '',
- 'script' => function() use (&$executed) {
- $executed[] = 'fail';
- throw new \Exception('Intentional failure');
- }
+ 'script' => function() {}
],
'ok_script' => [
'attributes' => ['alias' => 'ok_script', 'name' => 'OK'],
'code' => '',
- 'script' => function() use (&$executed) {
- $executed[] = 'ok';
- }
+ 'script' => function() {}
]
];
$prop -> setValue(null, $scripts);
- // Enable both scripts in DB
$this -> tb -> insert('scripts', [
'uniq_name' => 'fail_script',
'type' => 'regular',
@@ -68,9 +68,38 @@
]);
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
- $controller = new CronController();
+ $controller = new TestableCronController();
+ $controller -> returnCodes = ['fail_script' => 1, 'ok_script' => 0];
$controller -> run_regular_cron_scripts();
- $this -> assertSame(['fail', 'ok'], $executed);
+ $this -> assertSame(['fail_script', 'ok_script'], $controller -> cliCalls);
+ }
+
+ public function test_disabled_regular_scripts_are_skipped(): void {
+ $ref = new \ReflectionClass(ControlScripts::class);
+ $prop = $ref -> getProperty('regular_scripts');
+ $prop -> setAccessible(true);
+
+ $scripts = [
+ 'disabled_script' => [
+ 'attributes' => ['alias' => 'disabled_script', 'name' => 'Disabled'],
+ 'code' => '',
+ 'script' => function() {}
+ ]
+ ];
+ $prop -> setValue(null, $scripts);
+
+ $this -> tb -> insert('scripts', [
+ 'uniq_name' => 'disabled_script',
+ 'type' => 'regular',
+ 'state' => 'disabled',
+ 'create_at' => date('Y-m-d H:i:s'),
+ ]);
+
+ $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
+ $controller = new TestableCronController();
+ $controller -> run_regular_cron_scripts();
+
+ $this -> assertSame([], $controller -> cliCalls);
}
}