From e80ceda98d3a3a7789d12524d6c2769cc93f3337 Mon Sep 17 00:00:00 2001 From: skysilver Date: Fri, 15 Dec 2017 23:20:47 +0300 Subject: [PATCH] v.0.8-beta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Добавлена регулировка цветовой температуры (в кельвинах от 1700к до 6500к) для Yeelight. * Добавлена регулировка цвета RGB (в формате hex) для Yeelight. * Добавлена базовая поддержка Yeelight LED Lightstrip: - получение текущего статуса; - включение/выключение; - регулировка яркости; - регулировка цветовой температуры; - регулировка цвета RGB. * Добавлена базовая поддержка Yeelight Ceiling Light, Mi LED Desk Lamp, Philips EyeCare Smart Ceiling Lamp: - получение текущего статуса; - включение/выключение; - регулировка яркости; - регулировка цветовой температуры. * Добавлена поддержка Mi Smart Power Strip 6 Plugs: - получение текущего статуса (в т.ч. температура, потребляемая мощность и сила тока); - включение/выключение; - включение/выключение светодиода wifi. * В интерфейс модуля добавлена кнопка для тестирования API-команд. * В перечень устройств внесен Mi IR Remote 360. * В About добавлена ссылка на тему на форуме. --- modules/xiaomimiio/miio_devices_edit.inc.php | 11 +- .../xiaomimiio/miio_devices_search.inc.php | 2 +- modules/xiaomimiio/xiaomimiio.class.php | 157 +++++++++++++++++- scripts/cycle_xiaomimiio.php | 2 +- templates/xiaomimiio/action_admin.html | 4 +- .../xiaomimiio/img/small/chuangmi.ir.v2.png | Bin 0 -> 10789 bytes .../img/small/philips.light.ceiling.png | Bin 0 -> 5002 bytes .../img/small/yeelink.light.ceiling1.png | Bin 0 -> 4514 bytes .../img/small/yeelink.light.lamp1.png | Bin 0 -> 3961 bytes .../img/small/yeelink.light.strip1.png | Bin 0 -> 10292 bytes .../img/small/zimi.powerstrip.v2.png | Bin 0 -> 1942 bytes .../xiaomimiio/miio_devices_edit_default.html | 10 +- .../xiaomimiio/miio_devices_search_admin.html | 74 ++++++++- 13 files changed, 244 insertions(+), 16 deletions(-) create mode 100644 templates/xiaomimiio/img/small/chuangmi.ir.v2.png create mode 100644 templates/xiaomimiio/img/small/philips.light.ceiling.png create mode 100644 templates/xiaomimiio/img/small/yeelink.light.ceiling1.png create mode 100644 templates/xiaomimiio/img/small/yeelink.light.lamp1.png create mode 100644 templates/xiaomimiio/img/small/yeelink.light.strip1.png create mode 100644 templates/xiaomimiio/img/small/zimi.powerstrip.v2.png diff --git a/modules/xiaomimiio/miio_devices_edit.inc.php b/modules/xiaomimiio/miio_devices_edit.inc.php index 6230aeb..ab1a8e2 100644 --- a/modules/xiaomimiio/miio_devices_edit.inc.php +++ b/modules/xiaomimiio/miio_devices_edit.inc.php @@ -2,7 +2,7 @@ /* * @author * @copyright 2017 Agaphonov Dmitri aka skysilver (c) -* @version 0.7b +* @version 0.8b */ if ($this->owner->name == 'panel') { @@ -147,9 +147,12 @@ if ($properties[$i]['TITLE'] == 'cct') { $properties[$i]['SDEVICE_TYPE'] = 'dimmer'; } - //if ($properties[$i]['TITLE'] == 'rgb') { - //$properties[$i]['SDEVICE_TYPE'] = 'rgb'; - //} + if ($properties[$i]['TITLE'] == 'ct') { + $properties[$i]['SDEVICE_TYPE'] = 'dimmer'; + } + if ($properties[$i]['TITLE'] == 'rgb') { + $properties[$i]['SDEVICE_TYPE'] = 'rgb'; + } if ($properties[$i]['TITLE'] == 'temperature') { $properties[$i]['SDEVICE_TYPE'] = 'sensor_temp'; } diff --git a/modules/xiaomimiio/miio_devices_search.inc.php b/modules/xiaomimiio/miio_devices_search.inc.php index 2a6f58b..105c264 100644 --- a/modules/xiaomimiio/miio_devices_search.inc.php +++ b/modules/xiaomimiio/miio_devices_search.inc.php @@ -2,7 +2,7 @@ /* * @author * @copyright 2017 Agaphonov Dmitri aka skysilver (c) -* @version 0.7b +* @version 0.8b */ global $session; diff --git a/modules/xiaomimiio/xiaomimiio.class.php b/modules/xiaomimiio/xiaomimiio.class.php index a18039d..5d03573 100644 --- a/modules/xiaomimiio/xiaomimiio.class.php +++ b/modules/xiaomimiio/xiaomimiio.class.php @@ -4,16 +4,21 @@ * @package project * @author * @copyright 2017 Agaphonov Dmitri aka skysilver (c) -* @version 0.7b +* @version 0.8b */ define ('MIIO_YEELIGHT_WHITE_BULB_PROPS', 'power,bright'); define ('MIIO_YEELIGHT_COLOR_BULB_PROPS', 'power,bright,ct,rgb,hue,sat,color_mode'); +define ('MIIO_YEELIGHT_STRIP_PROPS', 'power,bright,ct,rgb,color_mode'); +define ('MIIO_YEELIGHT_CEILING_LIGHT_PROPS', 'power,bright,ct'); +define ('MIIO_YEELIGHT_LAMP_LIGHT_PROPS', 'power,bright,ct'); define ('MIIO_PHILIPS_LIGHT_BULB_PROPS', 'power,bright,cct,snm,dv'); +define ('MIIO_PHILIPS_LIGHT_CEILING_PROPS', 'power,bright,cct'); define ('MIIO_PHILIPS_EYECARE_LAMP_2_PROPS', 'power,bright,notifystatus,ambstatus,ambvalue,eyecare,scene_num,bls,dvalue'); define ('MIIO_CHUANGMI_PLUG_M1_PROPS', 'power,temperature'); +define ('MIIO_ZIMI_POWERSTRIP_2_PROPS', 'power,temperature,current,power_consume_rate,wifi_led,mode'); define ('MIIO_MIVACUUM_1_STATE_CODES', serialize (array('0' => 'Unknown', '1' => 'Initiating', @@ -406,7 +411,7 @@ function requestInfo($device_id) { /** * requestStatus * - * ... + * Запрос статусов устройств * * @access public */ @@ -468,6 +473,46 @@ function requestStatus($device_id) { $this->addToQueue($device_id, 'get_zigbee_channel', '[]'); } $this->addToQueue($device_id, 'get_channels', '{"start":0}'); + } elseif ($device_rec['DEVICE_TYPE'] == 'philips.light.ceiling') { + // + $props = explode(',', MIIO_PHILIPS_LIGHT_CEILING_PROPS); + $total = count($props); + for ($i = 0; $i < $total; $i++) { + $props[$i] = '"' . $props[$i] . '"'; + } + $this->addToQueue($device_id, 'get_prop', '['.implode(',',$props).']'); + } elseif ($device_rec['DEVICE_TYPE'] == 'yeelink.light.ceiling1') { + // + $props = explode(',', MIIO_YEELIGHT_CEILING_LIGHT_PROPS); + $total = count($props); + for ($i = 0; $i < $total; $i++) { + $props[$i] = '"' . $props[$i] . '"'; + } + $this->addToQueue($device_id, 'get_prop', '[' . implode(',', $props) . ']'); + } elseif ($device_rec['DEVICE_TYPE'] == 'yeelink.light.lamp1') { + // + $props = explode(',', MIIO_YEELIGHT_LAMP_LIGHT_PROPS); + $total = count($props); + for ($i = 0; $i < $total; $i++) { + $props[$i] = '"' . $props[$i] . '"'; + } + $this->addToQueue($device_id, 'get_prop', '[' . implode(',', $props) . ']'); + } elseif ($device_rec['DEVICE_TYPE'] == 'yeelink.light.strip1') { + // + $props = explode(',', MIIO_YEELIGHT_STRIP_PROPS); + $total = count($props); + for ($i = 0; $i < $total; $i++) { + $props[$i] = '"' . $props[$i] . '"'; + } + $this->addToQueue($device_id, 'get_prop', '[' . implode(',', $props) . ']'); + } elseif ($device_rec['DEVICE_TYPE'] == 'zimi.powerstrip.v2') { + // + $props = explode(',', MIIO_ZIMI_POWERSTRIP_2_PROPS); + $total = count($props); + for ($i = 0; $i < $total; $i++) { + $props[$i] = '"' . $props[$i] . '"'; + } + $this->addToQueue($device_id, 'get_prop', '[' . implode(',', $props) . ']'); } } @@ -519,6 +564,35 @@ function usual(&$out) { else $info = $dev->data; } else $info = 'Что-то пошло не так...'; + echo $info; + exit; + } else if ($op == 'test_api_cmd') { + + $dip = $_GET['dip']; + $dtoken = $_GET['dtoken']; + $cmd = $_GET['dcmd']; + $opt = $_GET['dopt']; + + header("HTTP/1.0: 200 OK\n"); + header('Content-Type: text/html; charset=utf-8'); + + if (!class_exists('miIO', false)) { + include_once(DIR_MODULES . 'xiaomimiio/lib/miio.class.php'); + } + $this->getConfig(); + + if ($miio_module->config['API_IP']) $bind_ip = $miio_module->config['API_IP']; + else $bind_ip = '0.0.0.0'; + if ($miio_module->config['API_LOG_MIIO']) $miio_debug = true; + else $miio_debug = false; + + $dev = new miIO($dip, $bind_ip, $dtoken, $miio_debug); + + if ($dev->msgSendRcv($cmd, $opt, time())) { + if ($dev->data == '') $info = 'Результат выполнения команды не получен. Вероятно, указан неверный токен.'; + else $info = $dev->data; + } else $info = 'Что-то пошло не так...'; + echo $info; exit; } @@ -602,7 +676,7 @@ function propertySetHandle($object, $property, $value) { //что может быть неприемлемо. //$this->requestStatus($properties[$i]['DEVICE_ID']); } elseif ($properties[$i]['TITLE'] == 'power') { - // Команда на включение и выключени + // Команда на включение и выключение if ($value) { $this->addToQueue($properties[$i]['DEVICE_ID'], 'set_power', '["on"]'); } else { @@ -620,6 +694,27 @@ function propertySetHandle($object, $property, $value) { if ($value < 1) $value = 1; if ($value > 100) $value = 100; $this->addToQueue($properties[$i]['DEVICE_ID'], 'set_cct', "[$value]"); + } elseif ($properties[$i]['TITLE'] == 'ct') { + // Команда на изменение цветовой температуры (в кельвинах от 1700 до 6500) + $value = (int)$value; + if ($value < 1700) $value = 1700; + if ($value > 6500) $value = 6500; + $this->addToQueue($properties[$i]['DEVICE_ID'], 'set_ct_abx', '[' . $value . ',"sudden",200]'); + } elseif ($properties[$i]['TITLE'] == 'rgb') { + // Команда на изменение цвета RGB (от 0 до 16777215) + // RGB = (R*65536)+(G*256)+B, где R, G и B десятичные значения от 0 до 255. + $value = preg_replace('/^#/', '', $value); + $val = hexdec($value); + if ($val != 0 && $val < 16777216) { + $this->addToQueue($properties[$i]['DEVICE_ID'], 'set_rgb', '[' . $val . ',"smooth",100]'); + } + } elseif ($properties[$i]['TITLE'] == 'wifi_led') { + // Команда на включение и выключение индикатора wifi + if ($value) { + $this->addToQueue($properties[$i]['DEVICE_ID'], 'set_wifi_led', '["on"]'); + } else { + $this->addToQueue($properties[$i]['DEVICE_ID'], 'set_wifi_led', '["off"]'); + } } if($properties[$i]['DEVICE_TYPE'] == 'lumi.gateway.v3') { @@ -702,7 +797,7 @@ function processCommand($device_id, $command, $value, $params = 0) { /** * processMessage * - * ... + * Обработка ответов от устройств * * @access private */ @@ -805,6 +900,9 @@ function processMessage($message, $command, $device_id) { $i = 0; foreach($props as $key) { $value = $data['result'][$i]; + if ($key == 'rgb') { + $value = str_pad(dechex($value), 6, '0', STR_PAD_LEFT); + } $res_commands[] = array('command' => $key, 'value' => $value); $i++; } @@ -828,13 +926,62 @@ function processMessage($message, $command, $device_id) { $res_commands[] = array('command' => $key, 'value' => $value); $i++; } + } elseif ($device['DEVICE_TYPE'] == 'philips.light.ceiling' && $command == 'get_prop' && is_array($data['result'])) { + $props = explode(',', MIIO_PHILIPS_LIGHT_CEILING_PROPS); + $i = 0; + foreach($props as $key) { + $value = $data['result'][$i]; + $res_commands[] = array('command' => $key, 'value' => $value); + $i++; + } + } elseif ($device['DEVICE_TYPE'] == 'yeelink.light.ceiling1' && $command == 'get_prop' && is_array($data['result'])) { + $props = explode(',', MIIO_YEELIGHT_CEILING_LIGHT_PROPS); + $i = 0; + foreach($props as $key) { + $value = $data['result'][$i]; + $res_commands[] = array('command' => $key, 'value' => $value); + $i++; + } + } elseif ($device['DEVICE_TYPE'] == 'yeelink.light.lamp1' && $command == 'get_prop' && is_array($data['result'])) { + $props = explode(',', MIIO_YEELIGHT_LAMP_LIGHT_PROPS); + $i = 0; + foreach($props as $key) { + $value = $data['result'][$i]; + $res_commands[] = array('command' => $key, 'value' => $value); + $i++; + } + } elseif ($device['DEVICE_TYPE'] == 'yeelink.light.strip1' && $command == 'get_prop' && is_array($data['result'])) { + $props = explode(',', MIIO_YEELIGHT_STRIP_PROPS); + $i = 0; + foreach($props as $key) { + $value = $data['result'][$i]; + if ($key == 'rgb') { + $value = str_pad(dechex($value), 6, '0', STR_PAD_LEFT); + } + $res_commands[] = array('command' => $key, 'value' => $value); + $i++; + } + } elseif ($device['DEVICE_TYPE'] == 'zimi.powerstrip.v2' && $command == 'get_prop' && is_array($data['result'])) { + $props = explode(',', MIIO_ZIMI_POWERSTRIP_2_PROPS); + $i = 0; + foreach($props as $key) { + $value = $data['result'][$i]; + if ($key == 'current' || $key == 'power_consume_rate') { + if ($value == '' || $value == 'null' || $value == null) $value = '0.00'; + } + if ($key == 'mode') { + if ($value == 'null' || $value == null) $value = ''; + } + $res_commands[] = array('command' => $key, 'value' => $value); + $i++; + } } } foreach ($res_commands as $c) { $cmd = $c['command']; $val = $c['value']; - if ($cmd == 'power') { + if ($cmd == 'power' || $cmd == 'wifi_led') { if ($val == 'on') $val = 1; else if ($val == 'off') $val = 0; } diff --git a/scripts/cycle_xiaomimiio.php b/scripts/cycle_xiaomimiio.php index 173164f..ef2bd5c 100644 --- a/scripts/cycle_xiaomimiio.php +++ b/scripts/cycle_xiaomimiio.php @@ -3,7 +3,7 @@ * Xiaomi miIO Cycle * @author * @copyright 2017 Agaphonov Dmitri aka skysilver (c) -* @version 0.7b +* @version 0.8b */ chdir(dirname(__FILE__) . '/../'); diff --git a/templates/xiaomimiio/action_admin.html b/templates/xiaomimiio/action_admin.html index 80e2201..356f495 100644 --- a/templates/xiaomimiio/action_admin.html +++ b/templates/xiaomimiio/action_admin.html @@ -20,11 +20,11 @@ diff --git a/templates/xiaomimiio/miio_devices_search_admin.html b/templates/xiaomimiio/miio_devices_search_admin.html index 0dddce4..f0e742b 100644 --- a/templates/xiaomimiio/miio_devices_search_admin.html +++ b/templates/xiaomimiio/miio_devices_search_admin.html @@ -41,6 +41,40 @@ + +
@@ -58,6 +92,41 @@ } }); } + function getIPToken(ip,token){ + $("#api_dev_ip").html(ip); + $("#api_dev_token").html(token); + $("#api_dev_log").html(''); + Data = new Date(); + Hour = Data.getHours(); + Minutes = Data.getMinutes(); + Seconds = Data.getSeconds(); + $('#api_dev_log').append(Hour+":"+Minutes+":"+Seconds+' IP = '+ip+'
'); + $('#api_dev_log').append(Hour+":"+Minutes+":"+Seconds+' Token = '+token+'
'); + } + function sendAPIcmd(){ + ip = $("#api_dev_ip").html(); + token = $("#api_dev_token").html(); + cmd = $("#api_dev_cmd").val(); + opt = $("#api_dev_opt").val(); + var url="/ajax/xiaomimiio.html?op=test_api_cmd&dip="+ip+"&dtoken="+token+"&dcmd="+cmd+"&dopt="+opt; + + Data = new Date(); + Hour = Data.getHours(); + Minutes = Data.getMinutes(); + Seconds = Data.getSeconds(); + + $('#api_dev_log').append(Hour+":"+Minutes+":"+Seconds+' command = '+cmd+'
'); + $('#api_dev_log').append(Hour+":"+Minutes+":"+Seconds+' properties = '+opt+'
'); + $('#api_dev_log').append(Hour+":"+Minutes+":"+Seconds+' '+url+'
'); + + $.ajax({ + url: url, + cache: false, + success: function(html){ + $('#api_dev_log').append(Hour+":"+Minutes+":"+Seconds+' '+html); + } + }); + } @@ -80,7 +149,10 @@ [#if TOKEN!="" && ONLINE==1#] - + + + + [#endif#] [#else#]