diff --git a/database_dump/smart-home-server_table_devices.sql b/database_dump/smart-home-server_table_devices.sql index 192efde..80dbbcc 100644 --- a/database_dump/smart-home-server_table_devices.sql +++ b/database_dump/smart-home-server_table_devices.sql @@ -37,7 +37,7 @@ `device_ip` varchar(50) NOT NULL, `device_mac` varchar(100) NOT NULL, `device_hard_id` varchar(100) NOT NULL, - `firmware_version` varchar(10) NOT NULL, + `firmware_version` varchar(32) NOT NULL, `connection_state` varchar(50) NOT NULL COMMENT 'active | lost', `state` varchar(16) NOT NULL DEFAULT 'active' COMMENT 'active | removed | freezed', `description` text NOT NULL, diff --git a/docs/devices/button.md b/docs/devices/button.md index e69de29..81fce89 100644 --- a/docs/devices/button.md +++ b/docs/devices/button.md @@ -0,0 +1,60 @@ +## Девайс с набором физически кнопок без фиксации состояни. +**Примечание.** Устройство имеет индикацию состояния кнопок. +Состояние кнопок хранится на сервере. +Индикаторы и кнопки - развязаны, индикаторы могут принимать любое значение из доступных. +Хоть кнопки и программируемые, в первую очередь организация общения устройства с сервером предполагает режим переключателя. + +### Доступные значения индикаторов + - `setup` (global) - Белое мигание раз в секунду. Это значение нельзя установить намеренно, подразумевает, что устройство не подключено к серверу. + - `nowifi` (global) - Синие мегание раз в секунду. Это значение нельзя установить намеренно. Это значит, что устройство не подключено к вайфай и разраёт свою точку доступа. + - `enabled` (channel) - Зелёное, постоянное свечение. Может использоваться для обратной связи включения какого-то устроства. + - `disabled` (channel) - Белое, постоянное свечение. Может использоваться для обратной связи выключения какого-то устроства. + - `mute` (channel) - Отключеная индикация, значит, что нажатие на кнопку не приведёт к какому либо действию. Например если кнопка была отключена или её нужно заглушить на время разработки. + - `waiting` (channel) - Жёлтое, постоянное свечение. Это значение нельзя установить намеренно. Это значение устройство устанавливает на время ожидания ответа от сервера, **по таймауту 10 секунд устройство признает попытку обращения к серверу неудачной** + - `warning` (channel) - Оранжевое мигание раз в пол секунды. Это значение подразумевает неудачное выполнение предыдущей операции. Может использоваться для обратной связи. + - `error` (channel) - Красное мигание раз в секунду. Может использоваться для обратной связи. Например чтоб обозначить какую-то ошибку. + + +--- + +### `GET /status` + +#### Пример запроса состояния индикаторов +Состояние индикаторов + +```json +{ + "status": "ok", + "indicators": "nowifi", + "channels": [ + { + "id": 0, + "indicator": "enabled" + }, + { + "id": 1, + "indicator": "disabled", + }, + { + "id": 2, + "indicator": "mute", + } + ] +} + +``` + +### `POST /action` + +#### Пример запроса на изменения состояния индикаторов + +```json +{ + "action": "set_channel_state", + "params": { + "channel": 0, + "state": "enabled" + } +} + +``` \ No newline at end of file diff --git a/docs/server-spec.md b/docs/server-spec.md index e177a5f..e18884f 100644 --- a/docs/server-spec.md +++ b/docs/server-spec.md @@ -16,7 +16,6 @@ ```json { - "device_type": "relay", // Тип устройства (relay, sensor, button и т.п.) "device_id": "ecf0a1b5c9d74f9a8e294c1f67b0a8b9", // Уникальный идентификатор устройства "event_name": "button_press", // Название события (button_press, state_change, sensor_data и т.д.) "data": { // Объект с данными события, структура зависит от event_name и device_type diff --git a/server/ControlScripts/TestScript.php b/server/ControlScripts/TestScript.php new file mode 100644 index 0000000..860f5f0 --- /dev/null +++ b/server/ControlScripts/TestScript.php @@ -0,0 +1,15 @@ + handler("app:button.click", function(Array $params) { + var_dump($params); + }); + } + + public function register_regular_scripts() { + + } +} \ No newline at end of file diff --git a/server/Fury/Modules/Router/RouterImplementation.php b/server/Fury/Modules/Router/RouterImplementation.php index e86cbe2..5f124fe 100644 --- a/server/Fury/Modules/Router/RouterImplementation.php +++ b/server/Fury/Modules/Router/RouterImplementation.php @@ -70,6 +70,7 @@ $route_vars = explode('&', $route_vars); $flag = true; + if(isset($route_uri) and $route_uri != $this -> uri){ $flag = false; } diff --git a/server/SHServ/App.php b/server/SHServ/App.php index 7395017..6ec0925 100644 --- a/server/SHServ/App.php +++ b/server/SHServ/App.php @@ -22,6 +22,8 @@ public $factory; public $devtools; + public $control_scripts = []; + public function __construct(){ parent::__construct(); @@ -37,6 +39,9 @@ \Fury\Modules\Template\Template::set_driver(new \Fury\Drivers\TemplateDriver()); + $this -> control_scripts_init(); + $this -> router_json_to_post_emulate(); + $this -> devtools = new DevTools(); $this -> router = new Router(); $this -> routes = new Routes($this -> router); @@ -55,6 +60,32 @@ return $root; } + protected function router_json_to_post_emulate() { + $content_type = $_SERVER['CONTENT_TYPE'] ?? ''; + + if (stripos($content_type, 'application/json') === false) { + return; + } + + $raw_body = file_get_contents('php://input'); + $json_data = json_decode($raw_body, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + return; + } + + foreach($json_data as $param_name => $param_val) { + $_POST[$param_name] = $param_val; + } + } + + public function control_scripts_init() { + $script = new \ControlScripts\TestScript(); + $this -> control_scripts["TestScript"] = $script; + + $script -> register_events_handlers(); + $script -> register_regular_scripts(); + } } new App(); \ No newline at end of file diff --git a/server/SHServ/Controllers/DevTestController.php b/server/SHServ/Controllers/DevTestController.php index 6d5b683..afa17c2 100644 --- a/server/SHServ/Controllers/DevTestController.php +++ b/server/SHServ/Controllers/DevTestController.php @@ -17,5 +17,8 @@ var_dump($device_scanner -> filter_by_status($devices, "setup")); } + public function ping($action, $value) { + var_dump([$action, $value, "aaa"]); + } } \ No newline at end of file diff --git a/server/SHServ/Controllers/EventsController.php b/server/SHServ/Controllers/EventsController.php new file mode 100644 index 0000000..17b18c6 --- /dev/null +++ b/server/SHServ/Controllers/EventsController.php @@ -0,0 +1,39 @@ + get_by_device_hard_id($device_id); + + if(!$device) { + return $this -> utils() -> response_error("unknown_device", ["device_id"]); + } + + if(!$device -> auth() -> is_active()) { + return $this -> utils() -> response_error("error_of_device_auth"); + } + + $result = events() -> app_call( + "{$device -> device_type}.{$event_name}", + [ + "device" => $device, + "data" => $data + ] + ); + + return $this -> utils() -> response_success([ + "result" => $result + ]); + } +} \ No newline at end of file diff --git a/server/SHServ/Entities/Area.php b/server/SHServ/Entities/Area.php index bb84247..0cfde84 100644 --- a/server/SHServ/Entities/Area.php +++ b/server/SHServ/Entities/Area.php @@ -39,7 +39,7 @@ return $area; } - public function place_in_space(int $area_id): Array | bool { + public function place_in_area(int $area_id): Array | bool { $this -> parent_id = $area_id; return $this -> update(); } diff --git a/server/SHServ/Entities/Device.php b/server/SHServ/Entities/Device.php index 3aa8d75..fd55313 100644 --- a/server/SHServ/Entities/Device.php +++ b/server/SHServ/Entities/Device.php @@ -82,7 +82,7 @@ return $this -> auth() -> update(); } - public function place_in_space(int $area_id): bool { + public function place_in_area(int $area_id): bool { $this -> area_id = $area_id; return $this -> update() ? true : false; } diff --git a/server/SHServ/Entities/DeviceAuth.php b/server/SHServ/Entities/DeviceAuth.php index 78ee7fe..708b0e7 100644 --- a/server/SHServ/Entities/DeviceAuth.php +++ b/server/SHServ/Entities/DeviceAuth.php @@ -24,4 +24,8 @@ $this -> state = "killed"; return $this -> update(); } + + public function is_active() { + return $this -> state == "active"; + } } \ No newline at end of file diff --git a/server/SHServ/Implements/ControlScriptsInterface.php b/server/SHServ/Implements/ControlScriptsInterface.php new file mode 100644 index 0000000..0740ff3 --- /dev/null +++ b/server/SHServ/Implements/ControlScriptsInterface.php @@ -0,0 +1,21 @@ + filter_by_status($devices, $status); } + + public function get_by_device_hard_id(String $device_hard_id): Device | null { + $results = app() -> thin_builder -> select( + Device::$table_name, + Device::get_fields(), + [ + [ "device_hard_id", "=", $device_hard_id ], + "AND", + [ "state", "=", "active" ] + ] + ); + + if(!$results) { + return null; + } + + return new Device($results[0]["id"], $results[0]); + } } \ No newline at end of file diff --git a/server/SHServ/Routes.php b/server/SHServ/Routes.php index 8fe166b..da603cf 100644 --- a/server/SHServ/Routes.php +++ b/server/SHServ/Routes.php @@ -64,7 +64,7 @@ $devices_model = new \SHServ\Models\Devices(); echo "
";
- var_dump($devices_model -> connect_new_device("192.168.68.7", "test_device", "Test device"));
+ var_dump($devices_model -> connect_new_device("192.168.68.3", "test_device_btn", "Test device"));
});
$this -> router -> uri("/dev/test/model/devices/unregistered_devices.html", function($args){
@@ -97,6 +97,12 @@
"{$this -> cn}\\AuthController@signup",
"/auth/signup"
);
+
+ $this -> router -> post(
+ [ "event_name", "device_id", "data"],
+ "{$this -> cn}\\EventsController@new_event",
+ "/events/new"
+ );
}
/**
diff --git a/server/SHServ/Tools/DeviceAPI/Button.php b/server/SHServ/Tools/DeviceAPI/Button.php
new file mode 100644
index 0000000..6e20151
--- /dev/null
+++ b/server/SHServ/Tools/DeviceAPI/Button.php
@@ -0,0 +1,50 @@
+ get_status();
+
+ if($status_response["status"] != "ok") {
+ return [];
+ }
+
+ return [
+ "indicators" => $status_response["indicators"] ?? null,
+ "channels" => $status_response["channels"] ?? []
+ ];
+ }
+
+ public function get_indicator_state(int $channel_id = 0): String | null {
+ $indicators = $this -> get_indicators();
+
+ foreach($indicators["channels"] as $channel) {
+ if($channel["id"] == $channel_id) {
+ return $channel["indicator"];
+ }
+ }
+
+ return null;
+ }
+
+ public function set_channel_state(String $state_mode, int $channel_id): Array | null {
+ $modes = [
+ "enabled",
+ "disabled",
+ "mute",
+ "waiting",
+ "warning",
+ "error"
+ ];
+
+ if(!in_array($state_mode, $modes)) {
+ $state_mode = "error";
+ }
+
+ return $this -> post_action("set_channel_state", [
+ "state" => $state_mode,
+ "channel" => $channel_id
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/server/SHServ/Tools/DeviceAPI/TestActions/Base_test.php b/server/SHServ/Tools/DeviceAPI/TestActions/Base_test.php
index f0b3191..771f1b2 100644
--- a/server/SHServ/Tools/DeviceAPI/TestActions/Base_test.php
+++ b/server/SHServ/Tools/DeviceAPI/TestActions/Base_test.php
@@ -47,7 +47,7 @@
}
public function device_api_base__reset() {
- $device_base_api = new Base("192.168.68.7", "mytoken123");
+ $device_base_api = new Base("192.168.68.3", "38b545dcb18ddbca");
$result = $device_base_api -> reset();
echo "";
diff --git a/server/SHServ/text-msgs.php b/server/SHServ/text-msgs.php
index 8e28078..cae295a 100644
--- a/server/SHServ/text-msgs.php
+++ b/server/SHServ/text-msgs.php
@@ -40,6 +40,10 @@
"np_fail_of_department_number" => "Укажите номер отделения или поштомата",
"np_fail_of_selected_city" => "Выберите населённый пункт",
+ // SHServ Errs
+ "unknown_device" => "",
+ "error_of_device_auth" => "",
+
// Other
"accept_removing" => "Подтвердите удаление",
"remove" => "Удалить",