-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Добавлены функции зональной уборки (**zoned_clean**), движения к точке (**goto_target**) и смены мощности/режима работы (**custom_mode**) для пылесосов. * Добавлена справка по метрикам для шлюза Mijia. * Добавлена справка по метрикам для шлюза Aqara AC. * Добавлена справка по метрикам для IR-шайбы. * Обновлен readme.md
- Loading branch information
1 parent
316ce17
commit 63b210f
Showing
7 changed files
with
349 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,52 @@ | ||
# majordomo-xiaomimiio | ||
Xiaomi Smart Home miIO-devices integration | ||
# Xiaomi miIO | ||
|
||
Модуль предназначен для интеграции **MajorDoMo** с Wi-Fi устройствами из экосистемы **Xiaomi Mihome**, взаимодействующих по протоколу **miIO**. | ||
|
||
**miIO** - проприетарный сетевой протокол Xiaomi с шифрованием, по которому взаимодействуют wifi-устройства из экосистемы Xiaomi и приложение Mihome на смартфоне. В качестве транспорта используется UDP и порт 54321. Содержимое пакетов шифруется. Ключи шифрования формируются на основе уникальных токенов. Для контроля корректности принимаемых пакетов используется контрольная сумма на основе алгоритма MD5. | ||
|
||
Использование этого протокола позволяет управлять теми устройствами, которые не имеют открытого API (режима разработчика). Например, пылесосы, лампы, светильники, увлажнители и очистители воздуха, розетки и многие другие. Также позволяет расширить имеющиеся возможности открытого API у xiaomi-шлюза, в частности переводить его в режим сопряжения, привязывать и отвязывать zigbee-устройства, управлять радио и др. | ||
|
||
В основе модуля лежит библиотека **[php-miio](https://github.com/skysilver-lab/php-miio)**. | ||
|
||
Обсуждение модуля на **[Форуме](https://majordomo.smartliving.ru/forum/viewtopic.php?f=5&t=4863)**. | ||
|
||
Модуль в **[Connect](https://connect.smartliving.ru/tasks/51.html)**. | ||
|
||
![miio](https://kb.smartliving.ru/wp-content/uploads/2018/07/module_miio.gif) | ||
|
||
### Поддерживаемые устройства | ||
> По состоянию на июль 2018 года. | ||
1. Шлюз ZigBee ***Mi Smart Home Gateway 2*** | ||
2. Шлюз ZigBee ***Aqara AC Companion Gateway*** | ||
3. Розетка ***Mi Smart Socket Plug 2*** | ||
4. Розетка ***Mi Smart Socket Plug with USB*** | ||
5. Розетка ***Mi Smart Socket Plug with 2 USB*** | ||
6. Пылесос ***Mi Vacuum Cleaner*** | ||
7. Пылесос ***Mi Roborock S50/S51*** | ||
8. Настольная лампа ***Philips EyeCare Smart Desk Lamp 2*** | ||
9. Лампочка белая Е27 ***Philips Light Bulb*** | ||
10. Лампочка белая Е27 ***Yeelight White Bulb*** | ||
11. Лампочка цветная Е27 ***Yeelight Color Bulb*** | ||
12. Лампочки ***Philips Rui Chi Candle Light Bulb | ||
13. Настольная лампа ***Mi LED Desk Lamp*** | ||
14. Потолочный светильник ***Yeelight Ceiling Light*** | ||
15. Потолочный светильник ***Philips EyeCare Smart Ceiling Lamp*** | ||
16. Светодиодная лента ***Yeelight LED Lightstrip*** | ||
17. Удлинитель (6 розеток) ***Mi Smart Power Strip 6 Plugs*** | ||
18. Увлажнитель воздуха ***Mi Air Humidifier*** | ||
19. Увлажнитель воздуха ***Mi Air Humidifier 2*** | ||
20. Очиститель воздуха ***Mi Air Purifier 2S*** | ||
21. IR-контроллер ***Mi IR Remote 360*** | ||
22. WiFi-колонка ***Mi Internet Speaker*** | ||
23. Ночник ***Yeelight Bedside Lamp*** | ||
24. Светильник (спот) ***Philips Zhirui Downlight*** | ||
|
||
![devices](https://connect.smartliving.ru/cms/data_images/152_image.png) | ||
### Документация по модулю | ||
* [Общие сведения](https://kb.smartliving.ru/xiaomimiio_help/) | ||
* [Установка, обновление, удаление модуля](https://kb.smartliving.ru/xiaomimiio-ustanovka-obnovlenie/) | ||
* [Интерфейс модуля](https://kb.smartliving.ru/xiaomimiio-gui/) | ||
* [Настройка модуля](https://kb.smartliving.ru/xiaomimiio-settings/) | ||
* [Протокол miIO](https://kb.smartliving.ru/xiaomimiio-protocol/) | ||
* [Токены устройств](https://kb.smartliving.ru/xiaomimiio-tokens/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
/* | ||
* @author <[email protected]> | ||
* @copyright 2017-2018 Agaphonov Dmitri aka skysilver <[email protected]> (c) | ||
* @version 1.8.5b | ||
* @version 1.9b | ||
*/ | ||
|
||
if ($this->owner->name == 'panel') { | ||
|
@@ -46,21 +46,24 @@ | |
$rec['NEXT_UPDATE'] = date('Y-m-d H:i:s'); | ||
} | ||
|
||
$commands = array('online', 'command', 'message'); | ||
if (($rec['DEVICE_TYPE'] == 'lumi.gateway.v3') || ($rec['DEVICE_TYPE'] == 'lumi.acpartner.v3')) { | ||
$commands[] = 'add_program'; | ||
$commands[] = 'del_program'; | ||
} | ||
if ($rec['DEVICE_TYPE'] == 'chuangmi.ir.v2' || $rec['DEVICE_TYPE'] == 'lumi.acpartner.v3') { | ||
$commands[] = 'ir_play'; | ||
} | ||
if ($rec['DEVICE_TYPE'] == 'xiaomi.wifispeaker.v1') { | ||
$commands[] = 'vol_up'; | ||
$commands[] = 'vol_down'; | ||
} | ||
if ($rec['DEVICE_TYPE'] == 'lumi.acpartner.v3') { | ||
// Базовые метрики устройств | ||
$commands = array('online', 'command', 'message'); | ||
|
||
// Специфичные метрики для некоторых устройств | ||
if (($rec['DEVICE_TYPE'] == 'lumi.gateway.v3') || ($rec['DEVICE_TYPE'] == 'lumi.acpartner.v3')) { | ||
$commands[] = 'add_program'; | ||
$commands[] = 'del_program'; | ||
} else if ($rec['DEVICE_TYPE'] == 'chuangmi.ir.v2' || $rec['DEVICE_TYPE'] == 'lumi.acpartner.v3') { | ||
$commands[] = 'ir_play'; | ||
} else if ($rec['DEVICE_TYPE'] == 'xiaomi.wifispeaker.v1') { | ||
$commands[] = 'vol_up'; | ||
$commands[] = 'vol_down'; | ||
} else if ($rec['DEVICE_TYPE'] == 'lumi.acpartner.v3') { | ||
$commands[] = 'power'; | ||
$commands[] = 'load_power'; | ||
} else if ($rec['DEVICE_TYPE'] == 'rockrobo.vacuum.v1' || $rec['DEVICE_TYPE'] == 'roborock.vacuum.s5') { | ||
$commands[] = 'goto_target'; | ||
$commands[] = 'zoned_clean'; | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
* @package project | ||
* @author <[email protected]> | ||
* @copyright 2017-2018 Agaphonov Dmitri aka skysilver <[email protected]> (c) | ||
* @version 1.8b | ||
* @version 1.9b | ||
*/ | ||
|
||
define ('MIIO_YEELIGHT_WHITE_BULB_PROPS', 'power,bright,flow_params,flowing'); | ||
|
@@ -33,24 +33,26 @@ | |
define ('MIIO_MIWIFISPEAKER_V1_PROPS', 'umi,volume,rel_time'); | ||
|
||
define ('MIIO_MIVACUUM_1_STATE_CODES', serialize (array('0' => 'Unknown', | ||
'1' => 'Initiating', | ||
'2' => 'Sleeping', | ||
'3' => 'Waiting', | ||
'4' => 'Remote control active', | ||
'5' => 'Cleaning', | ||
'6' => 'Back to home', | ||
'7' => 'Manual mode', | ||
'8' => 'Charging', | ||
'9' => 'Charging Error', | ||
'10' => 'Pause', | ||
'11' => 'Spot Cleaning', | ||
'12' => 'In Error', | ||
'13' => 'Shutting down', | ||
'14' => 'Updating', | ||
'15' => 'Docking', | ||
'16' => 'Going to target', | ||
'17' => 'Zoned cleaning', | ||
'100' => 'Full'))); | ||
'1' => 'Initiating', | ||
'2' => 'Sleeping', | ||
'3' => 'Waiting', | ||
'4' => 'Remote control active', | ||
'5' => 'Cleaning', | ||
'6' => 'Back to home', | ||
'7' => 'Manual mode', | ||
'8' => 'Charging', | ||
'9' => 'Charging Error', | ||
'10' => 'Pause', | ||
'11' => 'Spot Cleaning', | ||
'12' => 'In Error', | ||
'13' => 'Shutting down', | ||
'14' => 'Updating', | ||
'15' => 'Docking', | ||
'16' => 'Going to target', | ||
'17' => 'Zoned cleaning', | ||
'100' => 'Full', | ||
'101' => 'Wet cleaning', | ||
'105' => 'Turbo'))); | ||
|
||
define ('MIIO_MIVACUUM_1_ERROR_CODES', serialize (array('0' => 'No error', | ||
'1' => 'Laser distance sensor error', | ||
|
@@ -358,7 +360,7 @@ function discover($ip = '') { | |
continue; | ||
} | ||
|
||
//TO-DO: новые сравниваются по sid и devcode, но если устройство было добавлено вручную, то эти параметры будут отсутствовать, | ||
//TODO: новые сравниваются по sid и devcode, но если устройство было добавлено вручную, то эти параметры будут отсутствовать, | ||
//соотвественно устройство добавится как новое, а не перезапишет (обновит) добавленно вручную. | ||
$dev_rec = SQLSelectOne("SELECT * FROM miio_devices WHERE DEVICE_TYPE_CODE='$device_type_code' AND SERIAL='$device_serial'"); | ||
|
||
|
@@ -406,31 +408,32 @@ function discover($ip = '') { | |
} | ||
} | ||
|
||
$dev_rec['ID'] = SQLInsert('miio_devices', $dev_rec); | ||
$dev_rec['ID'] = SQLInsert('miio_devices', $dev_rec); | ||
|
||
// Базовые метрики устройств | ||
$this->processCommand($dev_rec['ID'], 'online', 1); | ||
$this->processCommand($dev_rec['ID'], 'command', ''); | ||
$this->processCommand($dev_rec['ID'], 'message', ''); | ||
|
||
// Специфичные метрики для некоторых устройств | ||
if ($dev_rec['DEVICE_TYPE'] != '') { | ||
$this->requestStatus($dev_rec['ID']); | ||
if (($dev_rec['DEVICE_TYPE'] == 'lumi.gateway.v3') || ($dev_rec['DEVICE_TYPE'] == 'lumi.acpartner.v3')) { | ||
$this->processCommand($dev_rec['ID'], 'add_program', ''); | ||
$this->processCommand($dev_rec['ID'], 'del_program', ''); | ||
} | ||
if ($dev_rec['DEVICE_TYPE'] == 'chuangmi.ir.v2' || $dev_rec['DEVICE_TYPE'] == 'lumi.acpartner.v3') { | ||
$this->processCommand($dev_rec['ID'], 'ir_play', ''); | ||
} | ||
if ($dev_rec['DEVICE_TYPE'] == 'xiaomi.wifispeaker.v1') { | ||
$this->processCommand($dev_rec['ID'], 'vol_up', ''); | ||
$this->processCommand($dev_rec['ID'], 'vol_down', ''); | ||
} | ||
if ($dev_rec['DEVICE_TYPE'] == 'lumi.acpartner.v3') { | ||
$this->requestStatus($dev_rec['ID']); | ||
if (($dev_rec['DEVICE_TYPE'] == 'lumi.gateway.v3') || ($dev_rec['DEVICE_TYPE'] == 'lumi.acpartner.v3')) { | ||
$this->processCommand($dev_rec['ID'], 'add_program', ''); | ||
$this->processCommand($dev_rec['ID'], 'del_program', ''); | ||
} else if ($dev_rec['DEVICE_TYPE'] == 'chuangmi.ir.v2' || $dev_rec['DEVICE_TYPE'] == 'lumi.acpartner.v3') { | ||
$this->processCommand($dev_rec['ID'], 'ir_play', ''); | ||
} else if ($dev_rec['DEVICE_TYPE'] == 'xiaomi.wifispeaker.v1') { | ||
$this->processCommand($dev_rec['ID'], 'vol_up', ''); | ||
$this->processCommand($dev_rec['ID'], 'vol_down', ''); | ||
} else if ($dev_rec['DEVICE_TYPE'] == 'lumi.acpartner.v3') { | ||
$this->processCommand($dev_rec['ID'], 'power', ''); | ||
$this->processCommand($dev_rec['ID'], 'load_power', ''); | ||
} else if ($dev_rec['DEVICE_TYPE'] == 'rockrobo.vacuum.v1' || $dev_rec['DEVICE_TYPE'] == 'roborock.vacuum.s5') { | ||
$this->processCommand($dev_rec['ID'], 'goto_target', ''); | ||
$this->processCommand($dev_rec['ID'], 'zoned_clean', ''); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
@@ -520,10 +523,12 @@ function requestStatus($device_id) { | |
} | ||
$this->addToQueue($device_id, 'get_prop', '[' . implode(',', $props) . ']'); | ||
} else if (($device_rec['DEVICE_TYPE'] == 'rockrobo.vacuum.v1') || ($device_rec['DEVICE_TYPE'] == 'roborock.vacuum.s5')) { | ||
// | ||
$this->addToQueue($device_id, 'get_status'); | ||
sleep(1); | ||
$this->addToQueue($device_id, 'get_consumable'); | ||
// | ||
$this->addToQueue($device_id, 'get_status'); | ||
sleep(1); | ||
$this->addToQueue($device_id, 'get_consumable'); | ||
sleep(1); | ||
$this->addToQueue($device_id, 'get_custom_mode'); | ||
} elseif ($device_rec['DEVICE_TYPE'] == 'chuangmi.plug.m1') { | ||
// | ||
$props = explode(',', MIIO_CHUANGMI_PLUG_M1_PROPS); | ||
|
@@ -813,7 +818,7 @@ function propertySetHandle($object, $property, $value) { | |
// Например, miIO.info, toggle, app_start и др. | ||
$this->addToQueue($properties[$i]['DEVICE_ID'], $value, '[]'); | ||
} | ||
//TO-DO: после отправки команды желательно обновить сведения об устройстве, | ||
//TODO: после отправки команды желательно обновить сведения об устройстве, | ||
//но при этом перезапишется поле message (удалится результат выполнения команды), | ||
//что может быть неприемлемо. | ||
//$this->requestStatus($properties[$i]['DEVICE_ID']); | ||
|
@@ -993,7 +998,20 @@ function propertySetHandle($object, $property, $value) { | |
$this->addToQueue($properties[$i]['DEVICE_ID'], 'set_mode', '["' . $value . '"]'); | ||
} | ||
} | ||
} elseif ($properties[$i]['TITLE'] == 'flow') { | ||
} elseif ($properties[$i]['TITLE'] == 'custom_mode') { | ||
// Изменение режима работы (мощности) пылесоса (от 1 до 100%, 101 - влажная уборка, 105 - турбо) | ||
$this->addToQueue($properties[$i]['DEVICE_ID'], 'set_custom_mode', '[' . $value . ']'); | ||
} elseif ($properties[$i]['TITLE'] == 'zoned_clean') { | ||
// Уборка указанных зон (параметры - либо одна зона [[zone1]], либо список зон [[zone1],[zone2]]) | ||
// [x1 Integer, y1 Integer, x2 Integer, y2 Integer, times Integer] | ||
// {"id":8338,"method":"app_zoned_clean","params":[[26234,26042,27284,26642,5]]} | ||
// {"id":8338,"method":"app_zoned_clean","params":[[26234,26042,27284,26642,1],[26232,25304,27282,25804,2],[26246,24189,27296,25139,3]]} | ||
$this->addToQueue($properties[$i]['DEVICE_ID'], 'app_zoned_clean', '[' . $value . ']'); | ||
} elseif ($properties[$i]['TITLE'] == 'goto_target') { | ||
// Движение в заданную точку (параметры [x Integer, y Integer]) | ||
// {"id": 25736111,"method": "app_goto_target","params": [24200,20200]} | ||
$this->addToQueue($properties[$i]['DEVICE_ID'], 'app_goto_target', '[' . $value . ']'); | ||
} elseif ($properties[$i]['TITLE'] == 'flow') { | ||
// | ||
if ($value != '') { | ||
$this->addToQueue($properties[$i]['DEVICE_ID'], 'start_cf', "[$value]"); | ||
|
@@ -1242,7 +1260,10 @@ function processMessage($message, $command, $device_id) { | |
if (array_key_exists($value, $error_codes)) $res_commands[] = array('command' => 'error_text', 'value' => $error_codes[$value]); | ||
} | ||
} | ||
} | ||
} else if ($command == 'get_custom_mode' && is_array($data['result'])) { | ||
//get_custom_mode {"result":[60],"id":1535013272} | ||
$res_commands[] = array('command' => 'custom_mode', 'value' => $data['result'][0]); | ||
} | ||
} elseif ($device['DEVICE_TYPE'] == 'chuangmi.plug.m1' && $command == 'get_prop' && is_array($data['result'])) { | ||
$props = explode(',', MIIO_CHUANGMI_PLUG_M1_PROPS); | ||
$i = 0; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.