Xiaomi Gateway 3: Перепрошивка и добавление в HA

2 февраля, 2021Изменена: 9 сентября, 2021 в 18:43

Не смотря на то, что практически все моменты касающиеся добавления этого шлюза в HA описаны на wiki компонента, в профильных телеграм-каналах регулярно возникают вопросы связанные с перепрошивкой и добавлением шлюза в HA.
Здесь я попробую собрать в кучку основную информацию по этому процессу.

Быстрый переход

Начать стоит с того, что здесь изложено исключительно мое видение вопроса и мой личный опыт, он может не совпадать с вашим мнением и вашими желаниями.

И помните, что ничего из изложенного ниже, было бы невозможно без энтузиастов — нашедших способ включения телнета на шлюзе, разработавших компонент для HA, собравших кастомные прошивки и написавших скрипты для их установки.
На все это нужно время и силы, если вы готовы их поддержать материально — сделайте это, всем будет приятно =)
Известные мне ссылки:
AlexxIT (автор компонента ХА): Coffee, YooMoney
Serrj_sv (обнаружил способ включения телнета и прочие очень полезные вещи): Coffee
icoderus (автор скрипта для прошивки шлюза под линукс и множества других вещей): Tinkoff

Так же огромная благодарность всем участникам канала @xiaomi_gw_v3_hack!

Внимание!

На текущий момент существует возможность включить telnet (и, соответственно, добавить шлюз в HA) на любой версии прошивки, полностью программно, без вскрытия шлюза.
О том как это сделать можно почитать здесь.

Общая информация

Шлюз Xiaomi Gateway 3 (lumi.gateway.mgl03), имеет на борту поддержку ZigBee 3, BLE, BT Mesh, WiFi, а так же HomeKit.
Основное «железо» шлюза представлено следующими чипами:

CPU + WiFi RTL8197FS
NAND Flash 128Mb
EFR32MG ZigBee 3
MHCB03P Bluetooth 5

Имеет 2 антенны-липучки для WiFi и разведенные на платах антенны для Bluetooth и ZigBee.
Существует возможность припаять внешние антенны для ZigBee и WiFi, а так же Ethernet разъем.

Бывает 2х версий — ZNDMWG03LM (для Китайского рынка) и ZNDMWG02LM (для Европейского).
Единственное отличие между ними в наличии у Китайца блока питания с китайской вилкой, у Европейца в комплекте блока питания нет.
С т.з. регионов Mi Home, дочерних ZigBee или BT устройств, а так же возможности установки прошивок — разницы нет.

Поддержка со стороны Home Assistant’а обеспечивается кастомным компонентом XiaomiGateway3 и зависит от версии прошивки устройства.

Прошивки

Список известных на текущий момент (версию можно узнать после добавления шлюза в Mi Home):

Можно добавить в HA не вскрывая шлюз
1.4.4_0003
1.4.5_0012
1.4.5_0016
1.4.6_0012 рекомендована AlexxIT
1.4.6_0030
1.4.6_0043
1.4.7_0040
1.4.7_0063
1.4.7_0065
1.4.7_0115
1.4.7_0160
1.5.0_0026 рекомендована AlexxIT
1.5.0_0027 — использовать не рекомендуется!
1.5.0_0102 — последняя доступная

Помимо официальных прошивок, устанавливаемых «с завода» и через Mi Home, есть и ряд модифицированных (кастомных) сборок созданных @Vtel.
В них присутствуют такие изменения, как включенный по умолчанию telnet, патч для BT позволяющий работать без интернета, патч для HomeKit’а позволяющий понижать версию прошивки и т.д.
Полный список изменений можно посмотреть на GitHub — для 1.4.6_012_mod20210309, 1.4.7_0160_mod20210309 или 1.5.0_0026_mod20210518.
Самый простой способ установить модифицированную прошивку описан здесь.

Важно!
На текущий момент для использования стоит рассматривать только две версии:
1.4.6_0012 (официальная или кастом) — Рекомендована автором компонента, т.к. вся разработка ведется под нее.
1.5.0_0026 (только кастом) — Рекомендована автором компонента, для тех кто любит посвежее. У нее есть некоторые ограничения — например, через настройки компонента нельзя отключить «пищалку».
В целом же, на текущий момент, компонент работает со всеми версиями прошивок при наличии открытого телнета без пароля.

— ~ —

Добавление в HA

Благодаря автору интеграции, добавление шлюза максимально простой процесс. Все сводится к установке компонента (руками в папку custom_components или через HACS) и перезагрузке HA.
После этого в веб-интерфесе нужно добавить последовательно две интеграции «Xiaomi Gateway 3»:
Первая — для аккаунта Mi Cloud («Add Mi Cloud Account»).
Это нужно для того, что бы компонент мог сам получить miio-токен для шлюза и с его помощью включить на нем telnet.
Вторая — непосредственно для шлюза (выбрать нужный из выпадающего списка).

Первая:

Вторая:

При добавлении второй интеграции (шлюза) важно правильно указать команду, которая откроет на нем telnet (строка «Команда для открытия Telnet»), без этого шлюз в HA работать не будет.
Если на шлюзе прошивка до 1.4.6_0030 включительно, можно ничего не менять и оставить значение по умолчанию.
Во всех остальных случаях необходимо заменить команду на следующую:

{"method":"set_ip_info","params":{"ssid":"\"\"","pswd":"123123 ; passwd -d admin ; echo enable > /sys/class/tty/tty/enable; telnetd"}}

До 1.4.6_0030 (включительно):

После 1.4.6_0030:

После успешного добавления шлюза, не забудьте заблокировать обновление прошивки через Mi Home.
Без этого всегда есть шанс того, что шлюз обновит прошивку на новую, неподдерживаемую версию (автоматически или вы случайно согласитесь на обновление в приложении), в результате вы потеряете к нему доступ и потребуется вскрытие.

— ~ —

Прошивка через UART

Основная и самая подробная инструкция находится здесь (на английском языке).
У меня нет цели ее заменить, первоисточник всегда лучше =) я лишь хочу осветить основные моменты на великом и могучем, возможно это кому-то упростит жизнь.

Для начала шлюз необходимо открыть. На эту тему много инструкций, видео и фото, в т.ч. на wiki компонента.
Свой опыт я описал здесь.

После этого нужно подключить провода к диагностическим площадкам на плате шлюза.
Здесь есть разные варианты, как с пайкой, так и без.
Расположение и назначение контактов на плате (как основных, так и резервных) есть в оригинальной инструкции.
Для прошивки нужно использовать 3 контакта: Rx (прием), Tx (передача), Gnd (земля).

! Внимание!
Крайне осторожно отнеситесь к выбору USB-TTL (UART) адаптера, он должен работать в режиме 3.3V, т.е. напряжение между контактами Tx и Gnd адаптера должно равняться ~3.3 Вольта.
Точно подойдут адаптеры с возможностью выбора рабочего напряжения перемычкой:

Если есть сомнения, лучше взять мультиметр и замерить напряжение перед подключением к шлюзу.

Вместо USB адаптера можно использовать Rspberry Pi, ESP* и прочие платы, имеющие на борту UART интерфейс c 3v3 логикой (напряжением 3.3V).
Т.к. у меня подобного железа нет, по вопросам их использования лучше всего обратиться к документации или на профильные ресурсы.

Подключите шлюз к USB адаптеру. При подключении обратите внимание на схему:

Rx адаптера — Tx шлюза
Tx адаптера — Rx шлюза
Gnd адаптера — Gnd шлюза

! Одна из самых распространенных ошибок — подключение Rx- Rx и Tx-Tx. Так делать НЕ нужно!

При наличии возможности, хорошей идеей будет проверить соединения «прозвонив» каждую линию тестером, от «ноги» адаптера до контактной площадки на плате шлюза.

Скачайте необходимые для прошивки файлы:
Bootloader (начните с 115200, при желании можно попробовать самый быстрый или медленный)
Выбор скорости зависит как от качества соединения шлюз-адаптер, так и от самого адаптера и его драйверов.
Firmware (1.4.6_0012_mod20210309 или 1.4.7_0160_mod20210309)
На мой взгляд нет ни малейшего смысла использовать оригинальные, поэтому ссылки даны на «кастом».

! Убедитесь что размер скачанных файлов соответствует размещенным на GitHub!
(bootloader ~100Kb, firmware ~13Mb)

Можно приступать к прошивке.

Для ОС Windows (автор метода @serrj-sv):

  • Скачайте и установите ПО TeraTerm (например, версия 4.105)
  • Скачайте mgl03_uart_recovery.ttl (скрипт, автоматизирующий процесс прошивки для TeraTerm)
  • Запустите TeraTerm и выберите Serial и Port, к которому подключен USB-TTL адаптер
  • В меню Control нажмите Macro и выберите скачанный ранее файл mgl03_uart_recovery.ttl
  • Следуйте инструкциям во всплывающих окнах
  • После окончания процесса и полной загрузки шлюза нажмите 10 раз подряд на кнопку на его корпусе.
    Это сбросит все настройки шлюза к заводским (factory reset).

! Если при перепрошивке вы меняли ее версию (например 1.4.6 -> 1.4.7), вам стоит так же обновить и прошивку модуля Bluetooth.

Для ОС Linux (автор метода @CODeRUS):

  • Убедитесь что у вас установлены утилиты expect, stty и sx (из пакета lrzsz)
  • Скачайте mgl03_uart_recovery.expect (скрипт, автоматизирующий процесс прошивки)
  • Поместите все 3 файла (bootloader, firmware, mgl03_uart_recovery.expect) в одну папку.
    Избегайте использования пробелов и русских имен.
    Не меняйте имена скачанных файлов.
# ls /tmp/mi_gw
mgl03_1.4.6_0012_mod20201223.uart
mgl03_uart_recovery.expect
rtkboot_115200.bin
  • Убедитесь что у вашего пользователя есть права на доступ к устройству USB-TTL (чаще всего /dev/ttyUSB*)
    Добавьте себя в группу dialout.
# sudo usermod -a -G dialout your_username

Далее все операции необходимо проводить в папке с .expect скриптом.

  • Сделайте mgl03_uart_recovery.expect исполняемым
# chmod +x mgl03_uart_recovery.expect
  • Запустите скрипт на исполнение и следуйте инструкциям на экране:
# ./mgl03_uart_recovery.expect 
Xiaomi Gateway 3 flashing script
Requires:
  sx (package lrzsz)
  stty (package coreutils)


Connect Gateway to UART, disconnect it from power

Available bootloaders:
[0] rtkboot_115200.bin
Choose bootloader (0): 0
Using bootloader from: rtkboot_115200.bin
Selected bootloader speed: 115200

Available firmwares:
[0] mgl03_1.4.6_0012_mod20201223.uart
Choose firmware (0): 0
Using firmware from: mgl03_1.4.6_0012_mod20201223.uart


kernel size: 20ec04
rootfs size: 9e7002
rootfs offset: a0c0ec3a

Enter serial device name (/dev/ttyUSB0):

Определить каким устройством ttyUSB* является нужный вам адаптер можно например так:

# ls -l /dev/serial/by-id/
total 0
lrwxrwxrwx 1 root root 13 фев  2 14:27 usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 -> ../../ttyUSB0
# dmesg | grep tty
[    0.144962] printk: console [tty0] enabled
[   16.567573] systemd[1]: Created slice system-getty.slice.
[68395.861798] usb 1-1.3.4.2: cp210x converter now attached to ttyUSB0
[68395.885219] cp210x ttyUSB0: cp210x converter now disconnected from ttyUSB0
[69533.892928] usb 1-1.3.4.2: cp210x converter now attached to ttyUSB0
  • После окончания процесса и полной загрузки шлюза нажмите 10 раз подряд на кнопку на его корпусе.
    Это сбросит все настройки шлюза к заводским (factory reset).

! Если при перепрошивке вы меняли ее версию (например 1.4.6 -> 1.4.7), вам стоит так же обновить и прошивку модуля Bluetooth.

— ~ —

Прошивка через Telnet

Если вы счастливый обладатель шлюза с открытым телнетом (без разницы, стоковая прошивка или кастомная), у вас есть возможность менять прошивку шлюза без проводов, подключившись к шлюзу по telnet.
Для помощи в этом процессе есть прекрасная инструкция от автора кастомных прошивок — @zvldz. Прочтите ее.

В составе этой инструкции есть скрипт, который полностью автоматизирует процесс смены прошивки на одну из кастомных как вверх по версии, так и вниз. Плюс — обновляет прошивку модуля Bluetooth.
Вкратце, процесс можно описать следующими шагами:

  • Подключитесь по протоколу telnet к шлюзу
    Логин: admin, пароля нет.
    Для Win можно использовать Putty, TeraTerm, встроенный в ОС telnet.
  • Скопировать, вставить и запустить на шлюзе следующие команды:
    (можно навести курсор на строку ниже и нажать в правом верхнем углу «Copy»)
wget -O /tmp/curl "http://master.dl.sourceforge.net/project/mgl03/bin/curl?viasf=1" && chmod +x /tmp/curl
export PATH="$PATH:/tmp"
curl -s -k -L -o /tmp/update.sh \
https://raw.githubusercontent.com/zvldz/mgl03_fw/main/firmware/mgl03_update.sh && sh /tmp/update.sh
  • После успешного запуска скрипта следуйте инструкциям на экране:
# curl -s -k -L -o /tmp/update.sh \
> https://gist.github.com/zvldz/b40b4873e3c4c1a64ac536e8ce5dbdad/raw/mgl03_update.sh && sh /tmp/update.sh
* Getting firmware list

For recommended firmware, see https://github.com/AlexxIT/XiaomiGateway3/wiki
Available firmware:
[1] mgl03_1.4.6_0012_mod20210308.zip
[2] mgl03_1.4.7_0115_mod20210308.zip
[3] mgl03_1.4.7_0160_mod20210308.zip
Please choose firmware: 4
...
  • После завершения процесса шлюз будет автоматически перезагружен, следите за сообщениями на экране.

При понижении версии прошивки (например с 1.4.7_* на 1.4.6_*) возможно потребуется выполнить сброс настроек шлюза к заводским (factory reset) — нажать 10 раз подряд кнопку на корпусе.
! Учтите, что это действие cбросит все настройки шлюза, удалит все биндинги устройств ZigBee (все устройства потребуется подключать снова), а так же потребует перенастройки интеграции в ХА (сменится токен miio).

— ~ —

Разное

Сброс настроек

  • Зажать кнопку на корпусе шлюза на 10 секунд — сброс только сетевых настроек (WiFi, привязка к Mi Home).
    1.4.6_* — /usr/app/bin/network_reset.sh, 1.4.7_* — /bin/network_reset.sh
  • 10 раз подряд коротко нажать на кнопку — полный сброс всех настроек (factory reset).
    1.4.6_* — /usr/app/bin/factory_reset.sh, 1.4.7_* — /bin/factory_reset.sh

Обновление firmware модуля Bluetooth

При смене прошивки шлюза обычным способом (через приложение Mi Home) в файле содержатся обновления в т.ч. и для чипов Bluetooth и ZigBee. Если же вы перепошивали шлюз через UART, все firmware чипов у вас остаются неизменными, такими, как они вышли с завода.
Но, благодаря энтузиастам разобравшим официальные прошивки на кусочки, у нас есть возможность обновить модуль Bluetooth вручную.

Для обновления Bluetooth стека вам потребуется ZIP-файл соответствующий вашей версии прошивки:

Скачайте и распакуйте архив. Из архива вам нужен файл full_ble_<fw_version>.gbl.
Файл нужно скопировать на шлюз, например с помощью FTP.
Включить FTP на шлюзе с кастомной прошивкой можно либо подключившись к нему по telnet выполнить:

/data/busybox tcpsvd -vE 0.0.0.0 21 /data/busybox ftpd -w &

Либо, с помощью компонента HA (интеграция шлюз — HA должна быть уже настроена).
Для этого в Панели разработчика перейти на закладку Службы (developer-tools/service).
Выбрать службу remote.send_command и объект вашего шлюза (вида remote.0x588e81fffedca899_pair),
в поле «Данные служб в формате YAML …» добавить строку command: ftp, нажать «вызвать службу«.

После этого можно подключатся к шлюзу по FTP (ftp://ip_address), например с помощью Total Commander или FileZilla.

Скопируйте файл full_ble_<fw_version>.gbl в директорию /tmp, подключитесь к шлюзу по telnet, и выполните в зависимости от версии вашей прошивки.

Для 1.4.6_0012:

run_ble_dfu.sh /dev/ttyS1 /tmp/full_ble_1.4.6_0012.gbl 123 1

Для 1.4.7_0115:

run_ble_dfu.sh /dev/ttyS1 /tmp/full_ble_1.4.7_0115.gbl 125 1

Для 1.4.7_0160:

run_ble_dfu.sh /dev/ttyS1 /tmp/full_ble_1.4.7_0160.gbl 130 1

Следите за выводом на экран, пример успешного выполнения:

# run_ble_dfu.sh /dev/ttyS1 /tmp/full_ble_1.4.7_0115.gbl 125 1
uart-dfu /dev/ttyS1 /tmp/full_ble_1.4.7_0115.gbl 1 OTA_STATE:0
do app!!
start update ble firmware!!
killall: start_ot.sh: no process killed
killall: ncp_daemon: no process killed
sh: write error: Device or resource busy
Bytes to send:322092
Syncing..DFU OK
Bootloader version: 17301508 (0x1080004)
DFU packet size:322092
99%
finish
ncp target version:125
--200--->app ota_state:0
----->ble app updated

После завершения процесса перезагрузите шлюз.

Проверить текущую версию прошивки Bluetooth можно в файле /data/ble_info:

# cat /data/ble_info 
ncp_host_version=134
ncp_target_version=125
bootloader_version=101
ota=0

Значение параметра ncp_target_version соответствует версии прошивки (123 для шлюза 1.4.6_* и 125 для 1.4.7_*).

Включение Telnet с помощью miIO

23.02.2021 в Telegram канале Xiaomi Gateway v3 Hack был опубликован полностью программный способ включения telnet на любой версии прошивки шлюза.
Оригинал инструкции на английском можно найти здесь.
Включить telnet можно следующими способами:

1. Воспользоваться компонентом XiaomiGateway3 HA от AlexxIT.
Потребуется токен miIO (с ним поможет сам компонент, если предварительно добавить интеграцию для Mi Cloud’а (Add Mi Cloud Account)) и специальная команда:

{"method":"set_ip_info","params":{"ssid":"\"\"","pswd":"123123 ; passwd -d admin ; echo enable > /sys/class/tty/tty/enable; telnetd"}}

Ее необходимо скопировать и вставить в поле «Команда для открытия Telnet» при добавлении шлюза:

2. С помощью miIO (без HA).
Для этого метода вам также потребуется токен, получить его можно многими способами, самый простой — воспользоваться модифицированным приложением Mi Home для Android (в приложении долгое нажатие на шлюз — переименовать (rename) — в открывшемся диалоге можно скопировать токен (Token)).
Помимо этого нужен php и реализация протокола miIO на php.

Команда для включения telnet (замените <ip> и <token> на ip-адрес и токен вашего шлюза):

php miio-cli.php --ip <ip> --token <token> --sendcmd '{"id":123,"method":"set_ip_info","params":{"ssid":"\"\"","pswd":"123123 ; passwd -d admin ; echo enable > /sys/class/tty/tty/enable; telnetd"}}'

! Если с первого раза не получилось, при следующих попытках обязательно поменяйте ID запроса — '{"id":123, ...
Например, увеличивая значение на единицу (124, 125 и т.д.)

Пример выполнения на Linux:

$ git clone https://github.com/skysilver-lab/php-miio
Cloning into 'php-miio'...
remote: Enumerating objects: 186, done.
remote: Total 186 (delta 0), reused 0 (delta 0), pack-reused 186
Receiving objects: 100% (186/186), 804.56 KiB | 2.12 MiB/s, done.
Resolving deltas: 100% (96/96), done.
$ php php-miio/miio-cli.php --ip 172.16.16.241 \
  --token 524d69366d5365484255495537735371 \
  --sendcmd '{"id":123,"method":"set_ip_info","params":{"ssid":"\"\"","pswd":"123123 ; passwd -d admin ; echo enable > /sys/class/tty/tty/enable; telnetd"}}'
Устройство 172.16.16.241 доступно и ответило:
{"code":0,"result":["ok"],"id":123}

На старых версиях прошивок (до 1.4.6_0030 включительно) существует возможность включить telnet с использованием другой miIO команды.
Данный способ был найден Serrj и опубликован на форуме HA.

php miio-cli.php  --ip <ip> --token <token> --sendcmd '{"id":0,"method":"enable_telnet_service", "params":[]}'

Пример использования на Linux:

$ git clone https://github.com/skysilver-lab/php-miio
Cloning into 'php-miio'...
remote: Enumerating objects: 186, done.
remote: Total 186 (delta 0), reused 0 (delta 0), pack-reused 186
Receiving objects: 100% (186/186), 804.56 KiB | 2.12 MiB/s, done.
Resolving deltas: 100% (96/96), done.
$ php php-miio/miio-cli.php --ip 172.16.16.241 \
  --token 524d69366d5365484255495537735371 \
  --sendcmd '{"id":0,"method":"enable_telnet_service", "params":[]}'
Устройство 172.16.16.241 доступно и ответило:
{"code":0,"result":["ok"],"id":0}

Модификации шлюза

Внешние антенны

  • Установка 3х внешних антенн (WiFi и ZigBee), автор @icoderus. Фото из группы xiaomi_gw_v3_hack.
    WiFi антенны заменяют собой штатные, на плате есть разъемы типа UFL (?), а для ZigBee есть возможность ее припаять.

Ethernet

  • Ethernet порт (RJ-45), авторы Alexandr, @serrj_ua, @icoderus, @lmahmutov. Фото из группы xiaomi_gw_v3_hack.
    Информацию о расположении контактов для пайки порта на плате можно найти на этом фото.