
Попала мне в руки европейская версия шлюза zigbee Xiaomi (lumi.gateway.mieu01). Шлюз можно подключить к MiHome, но вот в сторонние системы автоматизации, как оказалось, это сделать не так просто. Поискав информацию на поверхности, все как один говорили, что его нельзя подключить ни в каком виде в Home Assistant. Но я люблю разбираться во всём самостоятельно, и вот уже к вечеру того же дня, я нашел информацию, что в шлюз можно подключиться по SSH, сбросив предварительно пароль root. А уже после этого подгрузить в шлюз модифицированные библиотеки и подключить его к Home Assistant. Конечно, этот способ не даёт вам весь набор возможностей, как это реализовано на шлюзе второй версии, но тем не менее, мы будем иметь:
- управление встроенной светодиодной подсветкой light.miio_gateway;
- управление звуком media_player.miio_gateway;
- датчик освещения sensor.miio_gateway_illuminance;
- сигнализацию и будильник alarm_control_panel.miio_gateway.
А также подключение внешних датчиков (binary_sensor): датчики движения, датчики открытия, датчики протечки, датчики дыма, датчики вибрации и, конечно, кнопки и (sensor): датчики температуры, датчики влажности и датчики давления.
Куда поставить и как подключить — Xiaomi Gateway 3 ?
Предупреждаю! Подгрузив в шлюз модифицированные библиотеки, вы утратите доступ к шлюзу через приложение MiHome! При желании всё можно откатить обратно, но действуете вы всегда на свой страх и риск.
Приступим. Нам потребуется Паяльник, провода, USB-UART, отвертка для винтов «Spanner», Putty и немного прямых рук. Согласно схеме припаиваем контакты.




Нам потребуется RX, TX и GND. Подключаете все три контакта к UART. Подключите UART к USB разъёму в вашем ПК. Находим в системе номер своего COM-порта. Выставляем скорость передачи 115200.
Подключаете шлюз в сеть. Нажмите Enter.
Если вы видите процесс загрузки HUSH shell, то я Вас поздравляю, у Вас всё получилось!
Если же вы не видите процесс загрузки, то, возможно, вы спутали RX и TX местами.
Сейчас вы в fac_test (тестовая консоль), которая запускается в самом конце процесса загрузки (in /etc/rc.local). Вы можете выйти из этого режима с помощью команды exit_factory. После выхода из консоли тестирования, вы получите приглашение для входа в систему, после чего нам нужно сбросить пароль от root.
Перезагрузите шлюз (например, отключите питание), в процессе загрузки нажмите 0, чтобы прервать загрузку. Введите команду printenv. Найдите в логе строчку, начинающуюся с «bootargs=. » и скопируйте все, что после текста bootargs=, в моём случае это было «console =. «.
Шлюз Xiaomi Aqara Hub M1S не подключается в MI Home — решение проблемы
Откройте блокнот. Введите текст: setenv bootargs ‘ (Не забудьте кавычку!) Вставьте скопированный текст. Пример в моём случае:
console=ttymxc0,115200 ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs cma=96M mtdparts=gpmi nand:3m(boot),7m(kernel), 1m(dtb),-(rootfs)
После вставленного текста, поставьте одиночный пробел, и ведите текст: single rw init=/bin/bash’ (и снова не забудьте про кавычку!). У вас должно получиться как-то так: setenv bootargs ‘console=. someparams single rw init=/bin/bash’.
Нажмите Enter. Если команда прошла, то в консоле не отразиться ни одного сообщения, будет лишь «=>». Если у Вас что-то пошло по-другому, то скорее всего, вы что-либо не правильно скопировали, или забыли про кавычки и пробелы!
Теперь все готово к сбросу пароля root. Прежде чем вводить команду boot, подготовьтесь к тому, что у вас будет около 5 секунд для смены пароля root. Вы должны установить пароль длиной не менее 8 символов с буквами и цифрами! Подготовьте пароль в блокноте и скопируйте его в буфер обмена. Введите команду boot.
Нажмите Enter. Теперь начнется процесс загрузки, в конце которого вы окажитесь в bash#. Теперь у вас есть 5 секунд. Введите команду passwd, нажмите Enter. Вставьте пароль из буфера обмена, нажмите Enter. Вставьте ещё раз пароль из буфера обмена, нажмите Enter.
В ответ получите «root password change».
Мои поздравления! У Вас всё получилось. Теперь перезагрузите шлюз. Выйдите из тестового режима с помощью команды exit_factory. Введите имя пользователя root и ваш пароль, который вы изменили.
Далее включаем SSH доступ. Вводим команду:
После генерации ключа, у вас появился доступ к шлюзу по SSH. Можете проверить. Но нам необходимо добавить SSH в автозагрузку и для этого мы вводим команду:
В тексте файла перед строчкой «/home/root/fac/fac_test», вписываем строку:
Выходим из nano Ctrl X, подтверждаем, что файл нужно сохранить Y, подтверждаем название файла Enter. Вводим команду «reboot», дожидаемся перезагрузки шлюза, если все прошло нормально, то мы попадаем в тестовый режим и SSH доступен. Если что-то пошло не так, то проверяем всё ли верно написали в файле «nano /etc/rc.local».


В левой части экрана выбираем корневую директорию, создаём в ней папку «hacks», после чего копируем папку «miio_client» в папку «hacks». Выходим из Midnight Commander. Даём необходимые права, выполняя команду:
chmod ug+x /hacks/miio_client/miio_client
Теперь нам нужно добавить модифицированную библиотеку в автозапуск, но при этом нам нужно остановить исходную службу «miio_client».
Внимание! Удалять исходную службу нельзя, так как она участвует в подключении шлюза к сети Wi-Fi!

Всё прошло успешно? Поздравляю! Откладываем шлюз и его терминал и теперь переходим в Home Assistant. Скачиваем плагин из Git. Размещаем его любым доступным способом в директории /custom_components. Например, как описано в инструкции:
Переходим к конфигурации Home Assistant. Открываем configuration.yaml и вносим туда следующие строки:
miio_gateway: host: 192.168.1.13 # IP адрес Вашего шлюза port: 54321 # порт miio_client, по-умолчанию 54321
Перезагружаем HA. В устройствах находим новые устройства miio_gateway. Более подробно о конфигурации и подключении устройств к шлюзу вы можете почитать на странице плагина.

Надеюсь, что моя статья окажется кому-то полезной. На уникальность не претендую. Хорошего всем отпуска на карантине.
Источник: sprut.ai
kuznik
Итак, читать udp пакеты с информацией от сенсоров оказалось достаточно просто.
Попробуем теперь управлять шлюзом.
Напомню, что шлюз должен быть переключен в режим разработчика.
К слову, мониторить сообщения можно не только в node red, но и на linux хосте: sudo tcpdump -A udp port 9898
Помните пароль, который получили в приложении MiHome при вереводе шлюза в режим разработки? Теперь он нам пригодится! Чтобы шлюз принял команду на исполнение, надо зашифровать токен с помощью закрытого ключа (пароля от шлюза) и полученный открытый ключ использовать для подписи сообщения.

Вот как выглядит цепочка, которая генерирует ключ:
udp-test — тот же, что в этой статье. Что внутри ноды generate-key:

// подключаем библиотеку crypto
// напрямую её использовать в flow нельзя, можно почитать на stackoverflow.com об этом или в официальной документации.
// надо в каталоге с модулями node red (у меня это ~/.node-red/) внести изменения в settings.js,
var crypto = global.get(‘cryptoModule’);
// вектор, или стартовая переменная, которая выступает инициализацией для алгоритма шифрования при генерации псевдослучайных чисел
var iv = Buffer.from([0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58, 0x56, 0x2e]);
Источник: kuznik.livejournal.com
Xiaomi Gateway 2 можно и не паять

2020-05-24 в 14:16, admin , рубрики: diy умный дом xiaomi home assistant, умный дом

В предыдущих сериях я:
- Накупил устройств от Xiaomi для умного дома и посредством паяльника заставил их работать в увлекательнной манере без родных серверов через home assistant habr.com/ru/post/496856
- Завернул web interface от home assistant в electron habr.com/ru/post/497880 с поддержкой нотификаций, менюшек, точбара итд (код тут github.com/bskaplou/home-assistant-electron)
Но по мере появления всё новых устройств стало вскрываться странное…
Например, что поддержки Aqara Wireless Relay 2ch (LLKZMK11LM) в интеграции xiaomi_aqara нет, а на открытие Issues в GitHub владельцы кода отвечали, что поддержать это реле невозможно без обновления прошивки устройства. «Что-то тут не так» — подумал я и пошел разбираться по коду, как так вышло. И так увлекся, что запилил интеграцию сначала для работы с реле через xiaomi_miio github.com/rytilahti/python-miio/pull/696, а затем реализовал поддержку кубика и кнопки Xiaomi для этой интеграции github.com/rytilahti/python-miio/pull/703, а теперь расскажу зачем и как.
Developer API
Когда-то давно Xiaomi выпуская шлюз (lumi.gateway.v3) укомплектовали его developer api и даже документацией к нему. Developer API это та штука что общается по UDP на портах 4321 и 9898. Такой ход очень понравился сообществу и оно ответило пачкой репозиториев, интегрирующих устройство во всё что можно. Работа с этим developer api легла в основу home assistant интеграции xiaomi_aqara github.com/home-assistant/core/tree/dev/homeassistant/components/xiaomi_aqara и всё было замечательно пока…
Пока Xiaomi не переклинило и они не стали забивать на поддержку developer api, в нем перестали появляться идентификаторы новых устройств. Искомое реле есть в списке устройств подключённых по zigbee к gateway, но там реле фигурирует с пустым идентификатором модели, без которого невозможно что-либо сделать. Затем, уже совсем недавно, Xiaomi выкатили обновление прошивки gateway после установки которой невозможно было включить developer api без паяльника, (если он не был включен до обновления) habr.com/ru/post/487768.
Оказавшись в самом центре этой Санта-Барбары, я всплакнул и пошел заказывать немецкий ZigBee донгл ConBee2 на амазоне, чтобы работать с zigbee устройствами без gateway. Но пока немцы в условиях апокалипсиса готовили к отправке мой заказ, я утомленный ожиданием стал копать глубже…
Более родной протокол MIIO
Miio — это более новый протокол работы с устройствами Xiaomi, подключаемыми к сети по wi-fi. Родное приложение Mi Home общается по этому протоколу и с wi-fi розетками, и с IR Remote, и пылесосами, и со всеми остальными и даже с моим xiaomi gateway v2. Это тоже UDP протокол, но на этот раз задействован порт не порт 4321, а порт 54321 (прекрасный метод выбора портов я считаю). «Опаньки» — подумал я: «Значит оно еще и другой протокол знает, а не попробовать ли подключить реле по этому новому протоколу?».
Протокол miio шифрует все сообщения токеном, но, к счастью, методы извлечения токена и шифрования/дешифрования уже были вскрыты и работа с ними реализована в нескольких библиотеках (https://github.com/rytilahti/python-miio/, github.com/aholstenson/miio). Я не первый, кто занялся интеграцией нового устройства по протоколу miio, поэтому путь был известен и я ему последовал.
- Добываем security token устройств извлекая их из логов github.com/Maxmudjon/com.xiaomi-miio/blob/master/docs/obtain_token.md или из модифицированного приложения www.kapiba.ru/2017/11/mi-home.html
- Снимаем трафик между мобильным приложением и устройством
- Расшифровываем UDP пакеты с security token полученным в начале
- Учим код создавать аналогичные пакеты
Я снял трафик прямо со своего wi-fi роутера, к счастью для него есть кастомная прошивка asuswrt-merlin, в которую можно с помощью Entware поставить tcpdump. Утилита github.com/aholstenson/miio/blob/master/cli/commands/protocol/json-dump.js прекрасна, но дампы от tcpdump она не понимает, зато понимает json-dump генерируемый Wireshark. Для перегона бинарного дампа из tcpdump в json я использовал утилиту tshark. После этого увидел какими командами приложение mi home управляет реле я породил PR с добавлением поддержки реле github.com/rytilahti/python-miio/pull/696.
Заказ на ConBee2 я отменил, ибо программным методом и быстрее и веселее…
Зачем нам кузнец?
И вот значит я, с шашкой наголо, оказываюсь в ситуации, когда всё, вроде работает, но теперь в home assistant мой Xiamo Gateway 2 представлен двумя сущностями одна по протоколу developer api (интеграция xiaomi_aqara) и еще одна по проколу miio (интеграция xiaomi_miio github.com/home-assistant/core/tree/dev/homeassistant/components/xiaomi_miio). А еще я не люблю паять, хотелось и себе и людям жизнь упростить. Нужно было реализовать недостающую часть устройств в xiaomi_miio.
По большей части, после созидания программной обвязки это механическая работа:
- включил tcpdump
- создал в приложении Mi Home автоматизацию включающую действие которое я хочу отслеживать
- инициировал это автоматизацию
- расшифровал дамп
- копипаста из расшифровки в код
- посылаем команды с консоли
- доработка напильником до блеска
Но руки чешутся, а приключения зовут…
Ненастоящее miio устройство
Вскрытие показало, что в протоколе miio нет механизма колбеков. Сенсоры можно и раз в 20 секунд pullить, а вот для корректной работы кнопок и кубиков опрашивать устройство по 10 раз в секунду показалось плохой идеей. В этом парадоксе я увидел интересную деятельность, а механическим кодированием отснифанных пакетов заниматься не очень хотелось.
Исследование еще одной библиотеки работающий с протоколом miio github.com/aholstenson/miio/blob/master/lib/devices/gateway/developer-api.js удивило меня до глубины души. Авторы собрали комбайн который общается с устройством по протоколу miio, но для перехвата событий с кубиков и кнопок использует developer-api. Такой подход меня основательно напряг, приводит он к тому, что часть функционала начинает работать сразу, а для части таки надо паять устройство…
Снова вооружившись tcpdump и, доработав дешифратор функцией расшифровки от всех устройств за один запуск, стал слушать всё что летает по сети на UDP порт 54321. И вижу довольно интересную картину. Когда я создаю автоматизацию типа “Если повернули zigbee кубик, включить wi-fi розетку” из приложения в gateway по протоколу miio засылается json внутри поля data которого json закодированный в строку; “DSL” — подумал Штирлиц, их почему-то из покон веков все так пакуют… Детали тут github.com/rytilahti/python-miio/issues/699.
Просмотр содержимого этой строки показал, что реакция на действие не передается куда-то в облака, прямо в этой json программке фигурировал ip адрес и токен шифрования wi-fi розетки (этот абзац противоречит абзацу из первой серии, там я был не прав ;( гейт сам общается с дружественными устройствами — без помощи облаков). Да и сам скрипт напоминает автоматизацию из home assistant, есть параметры триггера, есть ip куда заслать реакцию. То есть никакого протокола pub/sub найти в дампах не удалось.
Зато родилась идея как всё-таки отловить все нужные события с кнопок и кубиков:
1. Эмулируем miio устройство в приложении, отвечаем на PINGи приложения и запросы от gateway
2. Пишем генератор скриптов для gateway для генерации по одному на пару ~ (устройство, событие)
3. Засылаем скрипты так чтобы при наступлении события в эмулятор приходил miio запрос
Пару дней заняло это всё реализовать и привести в божеский вид.
На текущий момент библиотека python-miio умеет работать и с реле и с кубиком и с кнопкой github.com/rytilahti/python-miio/pull/703
Остается примотать этот апдейт к home assistant и можно будет работать с Xiaomi gateway 2 без пайки и developer api.
Если кто готов потестировать на своих устройствах и/или добавить поддержку новых — присоединяйтесь 🙂
Еще в продаже есть славный Xiaomi 1C пылесос вот такой gigant-store.ru/goods/robot-pylesos-xiaomi-mijia-sweeping-robot-1c-ch и недоделка github.com/rytilahti/python-miio/tree/dreame_miot_mc1808 по его интеграции в home assistant. Думаю взяться… Надо оно?
Источник: www.pvsm.ru
