Вероятно, вы слышали о том, что сухость воздуха — одна из частых причин появления статического электричества. Вот и я решил обзавестись увлажнителем, когда заметил, что кошка бьется током почти при каждом прикосновении. И нет, ее зовут не Электро или Шторм Спирит. Знакомьтесь, Амидала (в честь персонажа вселенной «Звездных войн»).

Время шло, потребности в комфортном использовании техники росли, а вот ее функциональность и стабильность оставляли желать лучшего. После очередного сбоя серверов Xiaomi в октябре прошлого года в голове окончательно закралась мысль: почему дом — мой, а серверы — чужие? Так я познакомился с Home Assistant, MQTT, zigbee2mqtt и селфхостингом, о чем расскажу под катом!

Любите детективы? Пройдите квест «В поисках пропавших ссылок»! Регистрируйтесь на сайте и попробуйте себя в роли сыщика: найдите на страницах Selectel спрятанные ссылки и первыми дойдите до финала. Выиграйте эксклюзивный мерч и промокод на сервисы Selectel.


Мой дом — мои серверы


Если zigbee-устройства без проблем работают локально благодаря zigbee2mqtt (Z2M), то с увлажнителем возникли сложности. Казалось бы, у Xiaomi есть проприетарный протокол miIO для управления устройствами в локальной сети. Значит ли это, что можно обойтись без чужих серверов?

Home Assistant — это платформа с открытым исходным кодом для управления умным домом, создания сценариев автоматизации и т. д. Она позволяет интегрировать устройства разных производителей с разными типами подключения и не быть привязанным к одной экосисте.

Home Assistant (далее — HA) действительно умеет работать с протоколом miIO, но есть несколько нюансов.

  1. Для управления нужен токен. Чтобы его получить, следует зарегистрировать устройство в приложении. Нам же не нужны посредники, правда?
  2. Даже если получить токен и добавить увлажнитель в HA, то… все заработает. Победа? Увы, но работать все будет только пока есть интернет. Хоть мы и управляем устройством локально, выгоды от этого немного, ведь без облаков мы получим тыкву через несколько минут.


Есть решение


А вдруг нашлись умельцы, разобрались, написали прошивку и выложили в открытый доступ? После недолгих поисков я нашел нужный репозиторий, кодом которого мы сегодня и воспользуемся.

Альтернативный сценарий — использование ESPHome и написание несложных yaml-файлов. Вероятно, я займусь этим в будущем, когда влажность дома перестанет проседать ниже 50%.

Подготовка


На самом деле, указанный выше репозиторий подходит только для устройств, выпущенных в первые годы производства. После того, как производитель решил поменять протокол, по которому плата общалась с железом, появилось несколько форков (подробнее можете почитать в issue от декабря 2022 года).

Я буду использовать форк другого форка, так как именно эта версия заработала c HA без написания лишних yaml-файлов для подписки на mqtt-топики. К слову, имя автора наталкивает на мысли о его происхождении. Быть может, он читает эту статью?

Итак, нам понадобятся:

  • 3.3v USB TTL UART — адаптер для прошивки впаянной в плату микросхемы ESP8266;
  • несколько проводов разных цветов радуги;
  • паяльник, отвертка;
  • прямые руки (хотя я обошелся и без них).

Автор лишь делится своим опытом и не несет ответственности за манипуляции с техникой. Стоит помнить, что гарантия производителя может перестать действовать после внесения некоторых изменений. Однако представленная реализация достаточно проста и не предполагает особых вторжений в аппаратную часть.

Железо


Снимаем нижнюю крышку увлажнителя Xiaomi Deerma Air Humidifier 5L (ZNJSQ01DEM):


Нас интересует серая платка у стенки корпуса, к которой идет шлейф из белых проводов. Достаем и видим, что она действительно работает на популярной ESP8266:


Цепляем GND, VCC 3.3v (это важно!), TX и RX к программатору (RX в TX и наоборот). GPIO 0 тянем к земле (GND), он нужен для загрузки микроконтроллера в режим загрузки по UART.

Адаптер для прошивки впаянной в плату микросхемы.

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


Со стороны железа у нас все готово, перейдем к софту.

Софт


Сперва ставим Arduino IDE любым удобным способом. Подойдет как привычная первая версия, так и обновленная вторая. Следом необходимо добавить поддержку ESP8266. Открываем IDE, переходим в меню File Preferences, вставляем ссылку arduino.esp8266.com/stable/package_esp8266com_index.json в поле Additional Boards Manager URLs и нажимаем OK. С подробным описанием процесса вы можете ознакомиться в инструкции.


После этого можем скачать необходимые пакеты в Tools Board Board Manager:


Наконец, выбираем нашего красавца Generic ESP8266 Module в том же меню.

На данном этапе мы можем «послушать» UART. Подключаем программатор к ПК (GPIO 0 нужно отцепить от земли), выбираем его в Tools Port, открываем консоль Serial Monitor в правом верхнем углу.

Если все получилось, мы должны увидеть сообщения о событиях (снятие крышки, включение увлажнителя и т. д.):

properties_changed 2 1 true
properties_changed 2 1 false
properties_changed 7 1 false

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

Скачиваем необходимые пакеты в Sketch Include Library Manage Libraries:

  • ArduinoOTA 1.1.0 — для получения обновлений по воздуху,
  • ArduinoJSON 7.0.3,
  • PubSubClient 2.8.0 — MQTT клиент,
  • WiFiManager 2.0.17 (если вы используете код из оригинального репозитория — 0.16.0),
  • Uptime Library 1.0.0 (если используете форк от yobushka).

Клонируем нужный репозиторий и открываем в IDE. Теперь мы готовы прошивать.

git clone https://github.com/yobushka/esp8266-deerma-humidifier
cd esp8266-deerma-humidifier/src/esp8266-deerma-humidifier
arduino esp8266-deerma-humidifier.ino

Пробуем собрать проект, нажав на галочку в левом верхнем углу. Ждем некоторое время, и, если все прошло успешно, получаем информацию о скомпилированной прошивке:

. Variables and constants in RAM (global, static), used 50420 / 80192 bytes (62%)
║   SEGMENT  BYTES    DESCRIPTION
╠══ DATA     1648     initialized variables
╠══ RODATA   11100    constants       
╚══ BSS      37672    zeroed variables
. Instruction RAM (IRAM_ATTR, ICACHE_RAM_ATTR), used 62440 / 65536 bytes (95%)
║   SEGMENT  BYTES    DESCRIPTION
╠══ ICACHE   32768    reserved space for flash instruction cache
╚══ IRAM     29672    code in IRAM    
. Code in flash (default, ICACHE_FLASH_ATTR), used 385796 / 1048576 bytes (36%)
║   SEGMENT  BYTES    DESCRIPTION
╚══ IROM     385796   code in flash  

По-хорошему, конечно же, стоит сделать дамп существующей прошивки, иначе пути обратно не будет (подробнее можете узнать из официальной документации esp8266). Ну а я нажимаю Upload, не забыв подцепить упомянутый GPIO 0 к земле. Так прошивка заливается на контроллер, после чего он перезагружается:

esptool.py v3.0
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: b4:60:ed:4a:93:52
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 2MB
Flash params set to 0x0330
Compressed 432368 bytes to 304004...
Writing at 0x00000000... (5 %)
Writing at 0x00004000... (10 %)
Writing at 0x00008000... (15 %)
Writing at 0x0000c000... (21 %)
Writing at 0x00010000... (26 %)
Writing at 0x00014000... (31 %)
Writing at 0x00018000... (36 %)
Writing at 0x0001c000... (42 %)
Writing at 0x00020000... (47 %)
Writing at 0x00024000... (52 %)
Writing at 0x00028000... (57 %)
Writing at 0x0002c000... (63 %)
Writing at 0x00030000... (68 %)
Writing at 0x00034000... (73 %)
Writing at 0x00038000... (78 %)
Writing at 0x0003c000... (84 %)
Writing at 0x00040000... (89 %)
Writing at 0x00044000... (94 %)
Writing at 0x00048000... (100 %)
Wrote 432368 bytes (304004 compressed) at 0x00000000 in 26.5 seconds (effective 130.4 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...

Отсоединяем GPIO от земли и перезагружаем увлажнитель.

Настройка


Через какое-то время после перезагрузки у вас должна появиться открытая Wi-Fi сеть «SETUPME». Подключаемся к ней и переходим к настройке:


Обязательно вводим Hostname и Location, они нужны для формирования сообщений в MQTT-брокер. Выбираем нашу домашнюю сеть, вводим пароль и нажимаем Submit. Увлажнитель подключается к нашей точке, получает ip-адрес, а мы переходим по нему в браузере.

Далее нужно подключить увлажнитель к MQTT-брокеру (предполагается, что он есть). Я использую Mosquitto, де-факто стандарт в IoT. При желании этот брокер можно поставить даже на роутер, однако в HA для этого уже есть соответствующий аддон.


Сохраняем настройки и ждем подключения. HA сам нашел увлажнитель и добавил его:


Заключение


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

Решение работает уже несколько месяцев, никаких проблем замечено не было. И теперь почти все, что происходит в моем доме, остается в моем доме. В дальнейшем я бы хотел вызволить из внешних облаков еще несколько устройств.

Например, робота-пылесоса при помощи программы Valetudo. Возможно, вы сталкивались с ней или подобными реализациями? Поделитесь опытом в комментариях, будет интересно узнать.

Комментарии (37)


  1. HardWrMan
    03.04.2024 09:13
    +6

    Например, робота-пылесоса при помощи программы Valetudo. Возможно, вы сталкивались с ней или подобными реализациями? Поделитесь опытом в комментариях, будет интересно узнать.

    Когда мой поломал себе ногу (ирония судьбы: в редуктор одного колеса попала твёрдая пыль) и я его открыл, то увидел, что помимо основной материнской платы с мозгами там висит ESP:

    Быть может вызволить его тоже будет сильно проще, чем кажется. Ведь я могу повесить самописец на интерфейс между ESP и материнкой и записать весь обмен в процессе работы и потом тупо заменить ESP (или её прошивку) на что-то своё, родное. Я же правильно всё понял?


    1. uneeny Автор
      03.04.2024 09:13
      +2

      Интересно. Вероятно, ESP32 в данном пылесосе используется как wifi/bluetooth модуль (Я похожий используют как BLE-proxy для своего умного дома), а сами мозги обычно на linux работают. Насколько я понимаю, часто этот самый linux рутируют и делают с системой что хотят :)

      Посмотрите в сторону Valetudo, быть может ваш робот есть в списке поддерживаемых?


      1. HardWrMan
        03.04.2024 09:13

        Очень интересно, спасибо.

        Посмотрите в сторону Valetudo, быть может ваш робот есть в списке поддерживаемых?

        Быстрый просмотр показал, что нету его в списке.


      1. FelixTheMagnificent
        03.04.2024 09:13

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

        Те же, что на линуксе - имеют SLAM/VSLAM на борту, Player в качестве интерфейса к железной части, и WiFi-модуль там более "железный", подключенный к CPU через SDIO.

        Маленький хинт: если на пылесосе есть лидар или камера - 100% там есть линукс, если же нет - 99% что его там нету.

        А иметь линукс и иметь геморрой с ESP32 - это надо очень сильно накуриться :)


    1. gudvinr
      03.04.2024 09:13

      Вполне возможно, что ESP работает как модем, через UART и AT команды. Тогда у вас будет просто дамп шифрованного https трафика


      1. HardWrMan
        03.04.2024 09:13

        Не исключено.


  1. SpiderEkb
    03.04.2024 09:13

    Т.е. для каждого устройства это придется делать отдельно? И искать соотв. прошивку?

    А теперь представьте - у меня в доме только термостатов 15 штук. Которые работают через облако. А есть еще девайсы типа робота-пылесоса и еще чего-то там.

    Это мне под каждый тип устройства придется искать подходящее (и не факт что оно вообще есть в природе), потом каждое устройство ломать и перепрошивать (с риском что "что-то пойдет не так и оно окирпичится").

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

    При всем этом теряется одно из преимуществ облачного решения - будучи вне дома я могу с телефона управлять любым девайсом через приложение. Тут придется какое-то дополнительное решение искать.


    1. Cregennan
      03.04.2024 09:13

      HA можно точно так-же заставить из домашней сети в интернет торчать, если есть белый IP вообще здорово) В крайнем случае можно подключаться в сеть по VPN-подобным схемам


      1. SpiderEkb
        03.04.2024 09:13
        +2

        Да.

        Но все-таки мне кажется что более перспективно не прошивка каждого девайса, а "заворот" пакетов в сторону локального НА на роутере.

        Тем более, что есть роутеры со встроенной поддержкой MQTT в режимах publisher/subscriber/bridge.


        1. Xius
          03.04.2024 09:13
          +1

          Но все-таки мне кажется что более перспективно не прошивка каждого девайса, а "заворот" пакетов в сторону локального НА на роутере.

          Имхо, всё-таки более перспективно изначально выбирать выбирать девайсы, которые не привязывают пользователя к проприетарным облакам


          1. Rsa97
            03.04.2024 09:13
            +1

            Увы, не всегда это возможно. Выбрать выключатели, реле, датчики, приводы - это без проблем. Zigbee или BLE устройств хватает. Для устройств с пультами можно найти USB/LAN-IR или USB/LAN-RF433 пульты. А вот вентиляторы, увлажнители, пылесосы, автокормушки обычно либо через облако, либо вообще без дистанционного управления.


            1. eternalwayfarer
              03.04.2024 09:13

              Для некоторых устройств без дистанционного управления можно рассмотреть такой девайс, как fingerbot. Есть версии с Zigbee и BLE, но минус, конечно - никакой обратной связи, просто управляемые нажатия.


              1. Rsa97
                03.04.2024 09:13

                Фингербот - это одна кнопка. Ставить три фингербота чтобы управлять одним вентилятором (питание, скорость, качание) - это уже перебор. А на автокормушке вообще ни одной кнопки (кроме инициализации) может не быть.


            1. V1RuS
              03.04.2024 09:13

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


      1. gudvinr
        03.04.2024 09:13

        Светить HA наружу (и вообще любые части домашней сети) - это наоборот не здорово

        Если нужно снаружи иметь доступ, то только VPN до дома, иначе это путь к тому, чтобы стать счастливым членом ботнета


    1. HardWrMan
      03.04.2024 09:13
      +2

      При всем этом теряется одно из преимуществ облачного решения - будучи вне дома я могу с телефона управлять любым девайсом через приложение. Тут придется какое-то дополнительное решение искать.

      Тут поправочка: через приложение производителя. А если у тебя девайсы разных фирм то и в зоопарке таких приложух, живущих в смартфоне, будет соответствующее количество.

      А так разве HA не позволяет собой управлять удалённо, за пределами домашней сети?


      1. SpiderEkb
        03.04.2024 09:13

        Позволяет. Но ведь опять через чужое облако, нет?


        1. Rsa97
          03.04.2024 09:13
          +1

          Нет. У HA стандартный web-сервер на nginx, который можно как открыть в браузере, так и подключиться через родное приложение.


        1. alferiusgmailcom
          03.04.2024 09:13

          Или чужой vpn


          1. HardWrMan
            03.04.2024 09:13

            VPN и свой можно организовать. При этом наличие белого IP просто упрощает этот процесс. Кстати, я бы в текущее время не советовал открыто светить 80/443 наружу на белом IP. Я у себя их закрыл, оставил только VPN (и тут не суть важно какой: OpenVPN или тупой PPTP, главное чтобы шифрование на своих парах ключей было) и стучу ко всем внутренним ресурсам через него. Потому что очень много всякого подозрительного стало всплывать в логах последние 2 года.


        1. eternalwayfarer
          03.04.2024 09:13
          +3

          Если у вас HA на домашнем сервере, то при наличии белого IP будет доступ без участия чужих облаков. Да и без белого IP со схемами через VPN вы будете зависеть от одного провайдера, которого в случае чего поменять проще, чем устройства производителя, чьи облака вдруг перестали корректно работать.


        1. HardWrMan
          03.04.2024 09:13

          Зато весь твой зоопарк разношёрстных питомцев через одно.


    1. uneeny Автор
      03.04.2024 09:13
      +2

      Да, действительно, это нужно делать для каждого устройства, а если устройств много, то идея с перехватом трафика кажется разумной. Мало того, насколько я понимаю, ПО Valetudo для пылесосов работает именно так. Тут уже дело личного предпочтения - мне хотелось не заковать устройство и обманывать, а сделать его действительно свободным :)

      Насчет удаленного доступа. Как и писали, тут два правильных пути: Либо подключить сервер к своему vpn и использовать через него, либо брать у своего провайдера постоянный белый ip. Я выбрал именно второй вариант. Купил домен, прокинул порты, получил сертификаты...


      1. FelixTheMagnificent
        03.04.2024 09:13

        Valetudo - "клон" китайского облака, если быть точнее. Оно реализует базовые удаленные команды управления девайсом + сервер карт для софта пылесоса, и торчит "наружу" через весьма приятный веб-интерфейс + mqtt.


    1. DeKaNszn
      03.04.2024 09:13

      Иногда достаточно просто завернуть устройство локально, например так


  1. Rsa97
    03.04.2024 09:13
    +1

    ведь без облаков мы получим тыкву через несколько минут.

    Не проверял, но вроде после получения ключа облако не нужно. Интеграция xiaomi_airpurifier цепляется локально. По крайней мере, IP-адрес увлажнителя в настройках указывается из внутренней сети. Только этот адрес желательно зафиксировать в DHCP, чтобы не пришлось менять при перезагрузке роутера.


    1. uneeny Автор
      03.04.2024 09:13
      +1

      Именно это я и делал, да. Настроил в приложении, получил токен, но увлажнитель перестает отвечать через какое-то время если ограничить внешний трафик на роутере :(


  1. Pyku_He_oTTyda
    03.04.2024 09:13
    +6

    Фото с котом это читерство чистой воды :)


    1. teakettle
      03.04.2024 09:13
      +1

      В тексте указано, что это не кот, а кошка. Так что не считается :)


      1. Pyku_He_oTTyda
        03.04.2024 09:13

        Это обобщено, например как "человек", уточнения мужчина или женщина.


    1. HardWrMan
      03.04.2024 09:13

      Ну речь же за увлажнение! А испарение воды суть её очищение от примесей.


  1. VasVovec
    03.04.2024 09:13
    +1

    Спасибо, @uneeny, прочитал с интересом. Только не понял, каким образом на фото, где провода от адаптера к нужным пятачкам на плате подключены, они там держатся?


  1. Ra3wum
    03.04.2024 09:13
    +2

    Была похожая история с умной колонкой от них же. Вскрытие показало, что там CPU mt7621 на архитектуре MIPS с Linux. Поставил туда чистое ядро + проигрыватель с плейлистом интересующих онлайн радиостанций. В итоге имеем тот функционал, что изначально от устройства требовался без дополнительных облаков и прочего. Кстати, в данной умной колонке был ещё и микрофон, хотя в характеристиках его не значилось.


  1. zzzzzzzzzzzz
    03.04.2024 09:13

    А какой вообще смысл в подключении обычного бытового увлажнителя к каким-либо сетям?

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

    Извините, если демотивирую, но уж если оптимизировать, то начинать с самого начала.


    1. Rsa97
      03.04.2024 09:13
      +2

      У фаната умного дома нет цели, у него есть только путь.
      Ежели уж можно отвязать увлажнитель от облака, то почему бы это не сделать?


    1. HardWrMan
      03.04.2024 09:13

      Тогда уж подключать увлажнитель к водопроводу через систему клапанов и автоматизировать подлив воды по мере необходимости.


  1. RomZa77
    03.04.2024 09:13
    +1

    Интересно было почитать. Поностальгировал. Но брать готовое и просто прошить это же не спортивно, но допустимо. Я три года назад сам "парсил" как основная плата именно этого увлажнителя по Serial общается с ESP. Все запротоколировал, запрос - ответ все сообщения как они общаются и в итоге снес к чертям родную прошивку и написал свой код. Тут прашивали вверху зачем: ну первое это какая то стойкая неприязнь к облакам, особенно к китайским сформировалась за годы использования всяких полу-умных вещей. Второе более простая интеграция в свой умный дом без облаков, MQTT и далее что угодно. Треть: как раз контроль наличия воды и автоматическое включение клапана для заливки воды из магистрали от обратного осмоса. Эта модель чем интересна так это тем что у нее бак не закрытого типа, так что просто сверху/сбоку трубка для заливки воды и все, прощай беганье по два раза в сутки с кувшинами.