Я уже несколько лет методично выбирал устройства для умного дома, работающие по протоколу Zigbee, чтобы не зависеть от облака вендора. Однако прошлой осенью в моей жизни появилась кошка. В силу ограниченности вариантов, пришлось обзавестись рядом устройств, работающих только по Wi‑Fi и только с приложением вендора.
Под катом расскажу, как я преодолел это недоразумение.

Интро
Зачем
Напрягало, что в домашней сети есть устройства, которые я фактически не контролирую (а в кормушке, например, есть микрофон).
Альтернативно можно пользоваться LocalTuya, но для его использования вам придётся зарегистриовать аккаунт на платформе разработчиков Tuya, и раз в пару месяцев продлевать бесплатный пробный период для доступа к ключам девайса. Так что отказом от облака это назвать сложно.

Что необходимо из оборудования
В минимальный комплект для анализа умных девайсов входят:
Мультиметр, он поможет прозвонить контакты и определить интерфейсы
Паяльник (nuff said)
UART адаптер. Подойдёт любой популярный на чипах FT232, CP2102, CH340. Главное чтобы была поддержка выбора рабочего напряжения 3.3V или 5V.
Щипцы чтобы не трогать элементы при пайке голыми руками
Припой
Несмываемый флюс
Оплётка чтобы лишний припой убрать при выпаивании элементов
Опционально ещё можно добавить антистатический браслет для того, чтобы заземлиться и ничего не убить статикой, а также паяльный фен — с ним выпаивать контроллеры гораздо удобнее.
Крайне советую перед началом пайки умных устройств потренироваться паять на чём-то ненужном. Хороший гайд по пайке есть например у Гайвера.

Кондиционер
Первым исследуемым устройством стал кондиционер Midea. Поставлялся он с вот таким наборчиком ранее мне незнакомого вендора Daichi. В комплекте “таблетка” с контроллером, двусторонний скотч с велкро для крепления под крышку внутреннего блока сплит-системы и набор проводов для подключения.

Начнём с поиска информации об этом чудо-девайсе. Главное пока гуглишь информацию не перепутать Daichi и какой-нибудь Daikin. Daikin также производит “умные” кондиционеры и даже продаёт подписку на них в развивающихся рынках. Платите за дни использование кондиционера — настоящий киберпанк!
Недовольные жители Арасаки правда уже написали альтернативную прошивку для контроллеров, чтобы управлять кондиционером локально — ESP32-Faikout.
Разобрав “таблетку” можем изучить её внутренний мир. Видим что плата называется Daichi DW23-B Ver. 05. Также видим что распаян контроллер TYWE3S на базе ESP8266.

Можем сразу загуглить этот чип и найти распиновку интерфейса UART:

Однако он нам не понадобится т.к. распаяный на плате порт USB на самом деле является UART портом о чём пишут на 4PDA. А загадочный переключатель с подписью UART переключает устройство между управлением кондиционером по UART и возможностью прошивки контроллера.

Переместив выключатель в обратную стрелочке сторону можем подключить контроллер к UART адаптеру и с помощью утилиты ESPTool создать резервную копию прошивки контроллера.
esptool.py --port /dev/ttyUSB0 read_flash 0 0 backup.bin

Взамен оригинальной прошивки я записал на контроллер ESPHome. Этот проект предоставляет удобный веб интерфейс для управления устройствами и обновления их конфигурации по Wi-Fi.

Для кондиционеров Midea достаточно добавить в конфигурационный файл ESPHome следующие строки:
climate: - platform: midea autoconf: True beeper: True name: AC bedroom
Полный конфиг контроллера выглядит так:
Полный конфиг контроллера
esphome: name: ac-bedroom friendly_name: AC-bedroom esp8266: board: d1_mini # Enable logging logger: # Enable Home Assistant API api: encryption: key: "********" ota: - platform: esphome password: "********" wifi: ssid: !secret wifi_ssid password: !secret wifi_password # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "AC-Bedroom Fallback Hotspot" password: "********" uart: - baud_rate: 9600 tx_pin: GPIO1 rx_pin: GPIO3 climate: - platform: midea autoconf: True beeper: True name: AC bedroom captive_portal:
Используя интеграцию ESPHome для HomeAssistant получаем в HA удобный интерфейс для управления кондиционером:

Кормушка
Первым кошачьим девайсом стала кормушка. Управлялась она с приложения Smart Life через интернет.

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

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

На плате видим контроллер WBR3, пару чёрных прямоугольных контроллеров и 4 площадки, очень похожие на площадки UART (помеченные как X14).

Определяем UART

Первым делом я решил посмотреть какие данные будут видны в UART. Для этого надо идентифицировать площадки. Тут может помочь гайд от проекта HardwareAllTheThings.
В кратком пересказе примерно так:
GND — прозванивается на землю
VCC — стабильные +3.3 или +5V со старта девайса
TX — много прыгает напряжение сразу после старта, затем уровень становится как у VCC, либо продолжает прыгать
RX — напряжение не прыгает, низкий уровень

Однако, подключившись и запитав устройство, мы получаем непонятный набор нечитаемых символов. Ситуация не меняется со сменой Baud rate.
Забегая вперёд скажу, что на этом этапе получалось видеть пакеты сообщений между контроллерами.
Tuya
Тут стоит сделать лирическое отступление и немножко рассказать про Tuya. Эти ребята продают производителям умных устройств свою облачную платформу, включающую в себя приложения для конечного пользователя “Tuya Smart” и “Smart Life” и панель управления облаком для производителей. Производители используют Wi-Fi контроллеры от Tuya (например WBR3) и готовую прошивку для них для подключения устройств к облаку.

В такой схеме, именуемой TuyaMCU, Wi-Fi контроллер подключается через вашу домашнюю сеть к облаку Tuya и регистрирует в нём устройство. Далее он опрашивает через UART другой контроллер — MCU, из которого получает данные с датчиков и ему же посылает команды, если вы в приложении нажали кнопку “Покормить кошку”. Вся логика работы устройства при этом реализована в MCU.
Таким образом Wi-Fi контроллер исполняет роль прокси между облаком Tuya и MCU, и даже если его насовсем выпаять то лоток продолжит самоочищаться, а кормушка продолжит давать корм по нажатию кнопки. Кормление по расписанию работать не будет т.к. при перезапуске в кормушке собьётся время.

Однако цель у меня была сохранить весь штатный функционал, поэтому я решил всё же перепрошить контроллер на что-то поддерживаемое HomeAssistant.
Перед перепрошивкой стоит вспомнить мою прошлую попытку подпаяться к UART. Это как раз был интерфейс между Wi-Fi контроллером и MCU. Если вы повторяете шаги за этой статьёй, то советую к тем пинам всё же подпаяться и с помощью TuyaMCUAnalyzer записать коммуникацию между контроллерами активно используя устройство через облако. Это очень упростит вам настройку устройства в дальнейшем.

Далее гуглим как вообще этот WBR3 прошивать и на что.

На сайте Tuya находим даташит, из которого выясняется, что пины, используемые для извлечения и замены прошивки находятся на нераспаяных пинах A_0 и A_15, из-за чего необходимо выпаять контроллер.

OpenBeken
Из-за того что WBR3 сделан на основе RTL8720CF, а не на основе чипов Espressif, ESPHome на него поставить не удастся. Можно конечно поменять контроллер на совместимый с ESPHome, но зачем?
Тем болле что на форуме elektroda.com сделали проект OpenBeken, представляющий альтернативу ESPHome/Tasmota для таких нишевых чипов как наш. Также они эксплицитно заявляют о поддержке TuyaMCU.
Список поддерживаемых платформ поистине внушителен.

Для простоты подключения к чипу нарисовал схему, тут указаны точки подключения TX и RX UART адаптера:

Как это выглядело у меня:

Для получения бекапа прошивки используем ltchiptool:
ltchiptool flash read realtek-abz2 backup.bin
Если у вас возникают ошибки на этом этапе, то кроме всего прочего проблема может быть в недостаточной мощности тока, выдаваемой UART адаптером. WBR3 могут быть очень прожорливы. Рекомендуется использовать внешний источник питания на 3.3V.
Записываем OpenBeken им же:
ltchiptool flash write OpenRTL87X0C_1.18.295.bin

После прошивки запаиваем всё обратно, собираем устройство и включаем. Появится новая точка доступа, подключившись к которой можно будет в веб интерфейсе задать название и пароль Wi-Fi сети, к которой подключается устройство.
Далее необходимо задать конфигурацию OpenBeken. Нажимаем кнопку “Launch web app”, и переходим на вкладку Filesystem. Тут создаём файл “/autoexec.bat”. Каждому датчику и настраиваемому значению в MCU присвоен свой идентификатор dpID. Ему нужно задать тип данных. Также нужно активировать драйвер TuyaMCU для подключения функциональности общения с MCU и NTP для получения времени. Какой dpID за что отвечает вы уже знаете, если по совету выше прослушивали общение контроллера и MCU по UART с помощью TuyaMCUAnalyzer. Подробная документация и примеры по настройке есть в Wiki OpenBeken. Ниже приведу конфигурацию своей кормушки:
Содержимое autoexec.bat:
startDriver TuyaMCU # необходим для работы с TuyaMCU startDriver NTP # необходим для работы с NTP и получения времени для кормления по расписанию ntp_timeZoneOfs +3:00 # задаём временную зону waitFor NTPState 1 # ждём пока NTP получит данные setChannelType 4 TextField # состояние устройства linkTuyaMCUOutputToChannel 4 3 4 setChannelType 10 BatteryLevelPercent # состояние аккумуляторов, используемых при отключении электричества linkTuyaMCUOutputToChannel 10 int 10 setChannelType 3 Toggle # кнопка "покормить" linkTuyaMCUOutputToChannel 3 int 3 # tuyaMcu_defWiFiState 4 # многие устройства некорректно работают без этого параметра tuyaMcu_sendCurTime; # отправляет в MCU текущее время для работы кормления по расписанию
В самом OpenBeken интерфейс устройства абсолютно вырвиглазный:

Однако на стартовой странице OpenBeken мы можем задать адрес и учётные данные от MQTT сервера и через интеграцию c MQTT подключить его в HomeAssistant:

Также был написан простенький скрипт для кормления по нажатию кнопки изменением состояния dpID 3:
sequence: - device_id: 7154562b9a74904a0c1e9a0a4d11ccab #кормушка domain: text entity_id: 9b44f0b33e5989d3417e9a14ec95ec70 #dpID 3 type: set_value value: "0" - device_id: 7154562b9a74904a0c1e9a0a4d11ccab #кормушка domain: text entity_id: 9b44f0b33e5989d3417e9a14ec95ec70 #dpID 3 type: set_value value: "1" - delay: hours: 0 minutes: 0 seconds: 3 milliseconds: 0 - device_id: 7154562b9a74904a0c1e9a0a4d11ccab #кормушка domain: text entity_id: 9b44f0b33e5989d3417e9a14ec95ec70 #dpID 3 type: set_value value: "0" alias: Feed cat description: ""
Внимательный читатель может заметить, что тут нет настройки расписания кормушки, а ведь это важная функция! Проблема только в том, что она представляет из себя большую структуру, с которой не умеет работать OpenBeken. Увидеть расписание в dpID=3 можно выполнив команду tuyaMcu_sendQueryState в терминале OpenBeken во вкладке Logs.
Результат выполнения команды tuyaMcu_sendQueryState:
Info:CMD:[WebApp Cmd 'tuyaMcu_sendQueryState' Result] OK Info:TuyaMCU:Received: 55 AA 03 07 00 1D 01 00 00 19 7F 09 00 01 00 2B 0D 00 01 00 7F 0F 00 01 00 2B 11 00 01 00 7F 15 00 01 00 63 Info:TuyaMCU:ProcessIncoming[v=3]: cmd 7 (State) len 36 Info:TuyaMCU:ParseState: id 1 type 0-raw len 25 Info:TuyaMCU:Received: 55 AA 03 07 00 08 0A 02 00 04 00 00 00 3F 60 Info:TuyaMCU:ProcessIncoming[v=3]: cmd 7 (State) len 15 Info:TuyaMCU:ParseState: id 10 type 2-val len 4 Info:TuyaMCU:ParseState: int32 63 Info:GEN:No change in channel 10 (still set to 63) - ignoring Info:TuyaMCU:Received: 55 AA 03 07 00 05 04 04 00 01 00 17 Info:TuyaMCU:ProcessIncoming[v=3]: cmd 7 (State) len 12 Info:TuyaMCU:ParseState: id 4 type 4-enum len 1 Info:TuyaMCU:ParseState: byte 0 Info:GEN:No change in channel 4 (still set to 0) - ignoring Info:TuyaMCU:Received: 55 AA 03 34 00 01 04 3B
Интересующий нас пакет: 55 AA 03 07 00 1D 01 00 00 19 7F 09 00 01 00 2B 0D 00 01 00 7F 0F 00 01 00 2B 11 00 01 00 7F 15 00 01 00 63
Разберём его:
55 AA: Константный заголовок03: Версия протокола07: Тип комманды (0x07=report_status).00 1D: Длинна блока данных
Далее идут несколько значений расписания:
7F 09 00 01 012B 0D 00 01 007F 0F 00 01 002B 11 00 01 007F 15 00 01 00
И 63: Контрольная сумма.
Разберём формат:
7F: Битовое поле дней недели. 7F —01111111, каждый день09: Часы00: Минуты01: Количество порций01: Активно или нет правило
На основе этого можно навайбкодить шаблон для генерации такого пакета в HomeAssistant:
Шаблон для HA
template: - sensor: - name: "Cat Feeder Outbound Payload" state: >- {%- set header = "55aa0006001d01000019" -%} {# Macro to split the time picker string and build a 5-byte slot #} {%- macro build_slot(prefix, time_id, port_id, en_id) -%} {%- set sun = 1 if states('input_boolean.' ~ prefix ~ '_sun') == 'on' else 0 -%} {%- set mon = 2 if states('input_boolean.' ~ prefix ~ '_mon') == 'on' else 0 -%} {%- set tue = 4 if states('input_boolean.' ~ prefix ~ '_tue') == 'on' else 0 -%} {%- set wed = 8 if states('input_boolean.' ~ prefix ~ '_wed') == 'on' else 0 -%} {%- set thu = 16 if states('input_boolean.' ~ prefix ~ '_thu') == 'on' else 0 -%} {%- set fri = 32 if states('input_boolean.' ~ prefix ~ '_fri') == 'on' else 0 -%} {%- set sat = 64 if states('input_boolean.' ~ prefix ~ '_sat') == 'on' else 0 -%} {%- set days_mask = sun + mon + tue + wed + thu + fri + sat -%} {%- set time_val = states(time_id) -%} {%- set h = time_val.split(':')[0]|int(0) if ':' in time_val else 0 -%} {%- set m = time_val.split(':')[1]|int(0) if ':' in time_val else 0 -%} {%- set p = states(port_id)|int(1) -%} {%- set e = 1 if states(en_id) == 'on' else 0 -%} {{- "%02x"|format(days_mask) ~ "%02x"|format(h) ~ "%02x"|format(m) ~ "%02x"|format(p) ~ "%02x"|format(e) -}} {%- endmacro -%} {# Compile all 5 slots seamlessly #} {%- set s1 = build_slot('feeder_s1', 'input_datetime.feeder_s1_time', 'input_number.feeder_s1_portions', 'input_boolean.feeder_s1_enabled') -%} {%- set s2 = build_slot('feeder_s2', 'input_datetime.feeder_s2_time', 'input_number.feeder_s2_portions', 'input_boolean.feeder_s2_enabled') -%} {%- set s3 = build_slot('feeder_s3', 'input_datetime.feeder_s3_time', 'input_number.feeder_s3_portions', 'input_boolean.feeder_s3_enabled') -%} {%- set s4 = build_slot('feeder_s4', 'input_datetime.feeder_s4_time', 'input_number.feeder_s4_portions', 'input_boolean.feeder_s4_enabled') -%} {%- set s5 = build_slot('feeder_s5', 'input_datetime.feeder_s5_time', 'input_number.feeder_s5_portions', 'input_boolean.feeder_s5_enabled') -%} {%- set full_packet_no_checksum = (header ~ s1 ~ s2 ~ s3 ~ s4 ~ s5)|trim -%} {# Dynamic Checksum Processor (Modulo 256) #} {%- set ns = namespace(total=0) -%} {%- for i in range(0, full_packet_no_checksum|length, 2) -%} {%- set ns.total = ns.total + ("0x" ~ full_packet_no_checksum[i:i+2])|int(0, 16) -%} {%- endfor -%} {%- set checksum = "%02x"|format(ns.total % 256) -%} {{ (full_packet_no_checksum ~ checksum)|trim }}
И скриптом с помощью MQTT отправлять в OpenBeken сырой пакет в MCU:
alias: Cat Feeder - Send Calendar Configuration description: "" triggers: - entity_id: sensor.cat_feeder_outbound_payload trigger: state conditions: [] actions: - delay: "00:00:02" - data: topic: cmnd/catfeeder-s/uartSendHex payload: "{{ states('sensor.cat_feeder_outbound_payload') }}" action: mqtt.publish
Также можно навайбкодить вот такой конфигуратор календаря:

Исходный код конфигуратора:
UI календаря
type: vertical-stack cards: - type: markdown content: "## ? Cat Feeder Schedule Configuration" - type: entities title: Slot 1 Settings show_header_toggle: false entities: - entity: input_boolean.feeder_s1_enabled name: Enable Feeding icon: mdi:power - type: conditional conditions: - condition: state entity: input_boolean.feeder_s1_enabled state: "on" card: type: vertical-stack cards: - type: entities entities: - entity: input_datetime.feeder_s1_time name: Feeding Time - entity: input_number.feeder_s1_portions name: Portions - type: grid columns: 7 square: false cards: - type: tile entity: input_boolean.feeder_s1_mon name: M icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s1_tue name: T icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s1_wed name: W icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s1_thu name: T icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s1_fri name: F icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s1_sat name: S icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s1_sun name: S icon_tap_action: action: toggle - type: entities title: Slot 2 Settings show_header_toggle: false entities: - entity: input_boolean.feeder_s2_enabled name: Enable Feeding icon: mdi:power - type: conditional conditions: - condition: state entity: input_boolean.feeder_s2_enabled state: "on" card: type: vertical-stack cards: - type: entities entities: - entity: input_datetime.feeder_s2_time name: Feeding Time - entity: input_number.feeder_s2_portions name: Portions - type: grid columns: 7 square: false cards: - type: tile entity: input_boolean.feeder_s2_mon name: M icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s2_tue name: T icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s2_wed name: W icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s2_thu name: T icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s2_fri name: F icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s2_sat name: S icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s2_sun name: S icon_tap_action: action: toggle - type: entities title: Slot 3 Settings show_header_toggle: false entities: - entity: input_boolean.feeder_s3_enabled name: Enable Feeding icon: mdi:power - type: conditional conditions: - condition: state entity: input_boolean.feeder_s3_enabled state: "on" card: type: vertical-stack cards: - type: entities entities: - entity: input_datetime.feeder_s3_time name: Feeding Time - entity: input_number.feeder_s3_portions name: Portions - type: grid columns: 7 square: false cards: - type: tile entity: input_boolean.feeder_s3_mon name: M icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s3_tue name: T icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s3_wed name: W icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s3_thu name: T icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s3_fri name: F icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s3_sat name: S icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s3_sun name: S icon_tap_action: action: toggle - type: entities title: Slot 4 Settings show_header_toggle: false entities: - entity: input_boolean.feeder_s4_enabled name: Enable Feeding icon: mdi:power - type: conditional conditions: - condition: state entity: input_boolean.feeder_s4_enabled state: "on" card: type: vertical-stack cards: - type: entities entities: - entity: input_datetime.feeder_s4_time name: Feeding Time - entity: input_number.feeder_s4_portions name: Portions - type: grid columns: 7 square: false cards: - type: tile entity: input_boolean.feeder_s4_mon name: M icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s4_tue name: T icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s4_wed name: W icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s4_thu name: T icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s4_fri name: F icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s4_sat name: S icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s4_sun name: S icon_tap_action: action: toggle - type: entities title: Slot 5 Settings show_header_toggle: false entities: - entity: input_boolean.feeder_s5_enabled name: Enable Feeding icon: mdi:power - type: conditional conditions: - condition: state entity: input_boolean.feeder_s5_enabled state: "on" card: type: vertical-stack cards: - type: entities entities: - entity: input_datetime.feeder_s5_time name: Feeding Time - entity: input_number.feeder_s5_portions name: Portions - type: grid columns: 7 square: false cards: - type: tile entity: input_boolean.feeder_s5_mon name: M icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s5_tue name: T icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s5_wed name: W icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s5_thu name: T icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s5_fri name: F icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s5_sat name: S icon_tap_action: action: toggle - type: tile entity: input_boolean.feeder_s5_sun name: S icon_tap_action: action: toggle
Таким образом кормушка со всем её функционалом добавлена в HomeAssistant.
Лоток
Вторым устройство с маркетплейсов был автоматический лоток.

Кошка сначала очень удивлялась происходящему, но очень быстро привыкла.

Разборка
Разбирается он в принципе несложно, также по ходу процесса делаем фотографии. Внутри видим плату с кучей проводов и таким же как у кормушки контроллером WBR3. Тут он располагается в углу платы. Оценив количество проводов, я принял решение дальше их не разбирать, а просто снять плату и выпаять её, подложив силиконовый коврик.

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

Контроллеру лотка не хватило питания от того же UART адаптера, поэтому я подключил его чуть более напрямую и немного поперебирал имеющиеся UART адаптеры. С одним из них у меня всё же мощности хватило и изобретать дополнительный источник питания не пришлось.

Настройка OpenBeken
От “умных” функций лотка мне интересен только мониторинг веса кошки, чтобы можно было в случае разких изменений заметить, что что-то не так или адаптировать кормление при смене корма. Просто посмотрев на отдаваемые командой tuyaMcu_sendQueryState можно заметить что на вес кошки похоже только значение с dpID 6.
Результат выполнения комманды tuyaMcu_sendQueryState:
Вывод комманды
Info:TuyaMCU:ProcessIncoming[v=3]: cmd 7 (State) len 120 Info:TuyaMCU:ParseState: id 105 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 1 Info:GEN:No change in channel 4 (still set to 1) - ignoring Info:TuyaMCU:ParseState: id 6 type 2-val len 4 Info:TuyaMCU:ParseState: int32 3530 Info:GEN:No change in channel 6 (still set to 1500) - ignoring Info:TuyaMCU:ParseState: id 101 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 0 Info:GEN:No change in channel 2 (still set to 0) - ignoring Info:TuyaMCU:ParseState: id 17 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 0 Info:GEN:No change in channel 1 (still set to 0) - ignoring Info:TuyaMCU:ParseState: id 102 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 0 Info:GEN:No change in channel 3 (still set to 0) - ignoring Info:TuyaMCU:ParseState: id 117 type 2-val len 4 Info:TuyaMCU:ParseState: int32 3 Info:GEN:No change in channel 12 (still set to 3) - ignoring Info:TuyaMCU:ParseState: id 118 type 2-val len 4 Info:TuyaMCU:ParseState: int32 15 Info:GEN:No change in channel 13 (still set to 15) - ignoring Info:TuyaMCU:ParseState: id 119 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 0 Info:GEN:No change in channel 8 (still set to 0) - ignoring Info:TuyaMCU:ParseState: id 114 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 0 Info:GEN:No change in channel 7 (still set to 0) - ignoring Info:TuyaMCU:ParseState: id 122 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 0 Info:GEN:No change in channel 9 (still set to 0) - ignoring Info:TuyaMCU:ParseState: id 108 type 0-raw len 1 Info:TuyaMCU:ParseState: byte 1 Info:GEN:No change in channel 19 (still set to 1) - ignoring Info:TuyaMCU:ParseState: id 109 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 1 Info:GEN:No change in channel 5 (still set to 1) - ignoring Info:TuyaMCU:ParseState: id 22 type 5-bitmap len 1 Info:TuyaMCU:ParseState: byte 0 Info:GEN:No change in channel 18 (still set to 0) - ignoring Info:TuyaMCU:ParseState: id 111 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 1 Info:GEN:No change in channel 6 (still set to 1) - ignoring Info:TuyaMCU:ParseState: id 124 type 2-val len 4 Info:TuyaMCU:ParseState: int32 0 Info:GEN:No change in channel 14 (still set to 0) - ignoring Info:TuyaMCU:ParseState: id 125 type 2-val len 4 Info:TuyaMCU:ParseState: int32 3 Info:GEN:No change in channel 15 (still set to 3) - ignoring Info:TuyaMCU:ParseState: id 126 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 1 Info:GEN:No change in channel 10 (still set to 1) - ignoring Info:TuyaMCU:ParseState: id 127 type 2-val len 4 Info:TuyaMCU:ParseState: int32 1500 Info:GEN:No change in channel 16 (still set to 1500) - ignoring Info:TuyaMCU:ParseState: id 128 type 2-val len 4 Info:TuyaMCU:ParseState: int32 0 Info:GEN:No change in channel 17 (still set to 0) - ignoring Info:TuyaMCU:ParseState: id 130 type 1-bool len 1 Info:TuyaMCU:ParseState: byte 0 Info:GEN:No change in channel 11 (still set to 0) - ignoring
Содержимое autoexec.bat:
// Start the TuyaMCU driver startDriver TuyaMCU tuyaMcu_defWiFiState 4 // --- Active Weight Sensor --- linkTuyaMCUOutputToChannel 6 val 0 0.001 setChannelLabel 0 "dpID 6 Cat Weight"
Итог
В HomeAssistant на дашборд добавлены:
Кнопка кормления кошки
Состояние батареи кормушки
Вес
Когда в последний раз кошка ела
Настройка расписания кормления

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

Sosnin
03.09.2026 02:46Кстати с ZigBee тоже всё неоднозначно. Есть куча устройств которые вполне дружелюбно работают с TuyaSmart, но никак не заводятся в Zigbee HA ... например "Регулятор температуры пола" - просто "непонятное устройство без сенсоров и переключателей"; есть 3 термометра достаточно умных, купленных одновременно партией. 2 - "почти норм" (время от НА не получает), 3-ий - как "непонятное устройство без сенсоров"
4-Gang выключатель ZigBee пришлось снять... 0,фаза, 4 канала - всё подключено, все работает.. но в другой комнате люстра моргает в момент сработки. С таким же WiFi - моргания нет.
aptk
03.09.2026 02:46"Непонятное устройство без сенсоров и переключателей" решается с помощью zha quirk'ов. С высокой вероятностью под ваше устройство они уже написаны кем-то. Если нет - можно поискать конвертер для z2m, их энтузиасты еще быстрее пишут. На основе конвертера под z2m достаточно легко пишется квирк, самостоятельно или с ллм. А вот если ни того ни другого нет - предстоит увлекательный процесс выяснения того, для чего используется каждый из кастомных zigbee эндпоинтов.

TraX325
03.09.2026 02:46Тоже косо поглядываю на имеющиеся у меня кошачьи смарт вещи, но настолько радикально влезать точно не готов. Была мысль просто сделать свой сервер, почти как пиратские сервера вова создавали - реверс инжинирнуть запросы да и натравить девайсы днсами на собственный инстанс, а если надоест этим заниматься то переключить обратно. Да, нужно на чём-то его крутить, сильно больше мороки с софтом, все возможные интеграции придётся впиливать самому, но зато не придётся давать мне в руки паяльник :)

LampGraph
03.09.2026 02:46Прошел полный путь от самодельных датчиков температуры на ардуино, дальше wi-fi, zigbee, обрабатывал все домашний сервер на линуксе (где-то между была малина), разный софт: Majordomo, HA и в итоге остановился на Wirenboard и nodered для логики установленном на нем же. Решил для себя:
Умный дом должен быть умным - это когда не участвуешь в его делах. Он сам поддерживает температуру, сам кормит кота и собаку, поливает огород и прочее. Единственное чем сейчас управляем - это включаем и выключаем свет в тех комнатах где работа по датчикам присутствия не применима. И то через Алису (Алиса только для взаимодействия, вся логика работает локально и не зависит от интернета).
Ну и коммуникация по проводам, везде где это возможно (если устройству нужна розетка - значит и витуху можно проложить).
На днях с каким то приятным чувством обнаружил что настроенный год назад климат-контроль в погребе (принудительная вентиляция, если на улице холоднее чем требуемая температура в погребе и закрытие заслонки если на улице теплее) работает. А я думал показания с датчиков температуры на дашборде не меняются потому что он отвалился и осенью надо будет чинить. Оказалось просто там все в порядке. температура стабилизировалась и за лето поднялась всего на несколько градусов, да так плавно что было не заметно.
Теперь вот пишу софт который по изображению с камеры будет распознавать номер моей машины и открывать ворота. Локально, без облаков.

mitzury
03.09.2026 02:46Идея хорошая но, складывается ощущение что проще купить устройство (например туже кормушку), разобрать, выкинуть всю электронику кроме перифеии и поставить свою ардуино (или аналог) и подключить к ней всю периферию. Или же сделать самому с нуля весь умный дом…
noidol
Добрый день! Скажите, по Вашему мнению, HomeAssistant является ПО для "увлеченных? Насколько он дружелюбен к пользователям, которые не особо дружат с паяльником)? С чего стоит начинать освоение автономного "умного дома", без привязки к облакам?
Etern0x
Тут уже намекнули - ZigBee.