У меня дома 4 кондиционера. На одном из них уже стоял родной Wi-Fi-свисток Royal Clima OSK302 за 2500-2700 ₽. Когда я прикинул, во сколько обойдётся докупить ещё три таких — стало грустно. Плюс родной модуль умеет только облако через приложение NetHome Plus, без локального API, без HomeKit, без Home Assistant без костылей.

После пары вечеров копания выяснилось:

  • Внутри Royal Clima (серии Triumph) — обычная Midea OEM-платформа.
  • Кондиционер общается со штатным Wi-Fi модулем по UART 9600 8N1 через 4 контакта (5V / GND / TX / RX).
  • Этот же протокол давно отреверсен сообществом (dudanov/MideaUART, mac-zhou/midea-msmart и т.д.).
  • А значит — можно выкинуть «свисток» и поставить свой контроллер на ESP32 за 200-300 ₽, локально, без облака.

В итоге я собрал два варианта одного и того же модуля:

  • ESP32-C6 SuperMini + Matter (Wi-Fi) — нативно подключается в Apple Home, Google Home, Алису, Home Assistant.
  • ESP32-H2 SuperMini + Zigbee — заходит в Zigbee2MQTT той же сетью, где уже живут датчики и реле.

В обоих вариантах работает: вкл/выкл, режимы (Auto / Cool / Heat / Dry / Fan), задание температуры, скорость вентилятора, swing шторок (V/H), sleep, turbo, эконом, температура внутреннего и наружного блоков. Без облака, без приложения производителя, без IR-«пыхалок» в потолок.

В этой статье — полный путь от «у меня кондиционер Royal Clima» до «работает в Home Assistant локально». В двух вариантах: «для нормальных людей» (готовый бинарник, веб-флешер) и «для maker'ов» (сборка из исходников через ESP-IDF).


TL;DR — кому это подойдёт

Работает с любым кондиционером, у которого внутри Midea UART-протокол. Самый надёжный признак: штатный Wi-Fi модуль работает через приложение NetHome Plus, Midea Air или MSmartHome.

Точно совместимые бренды и линейки:

  • Royal Clima — серии Triumph, Triumph Gold, Triumph Inverter, Vela, Renaissance.
  • Pioneer — большинство моделей.
  • Comfee — дочерний бренд Midea, всё совместимо.
  • Inventor — большинство моделей (Греция).
  • Lessar — часть моделей.
  • Marsalle.
  • Senville, MrCool, Klimaire — часть моделей.
  • Cooper&Hunter — часть моделей.
  • Electrolux — европейские модели (часть).
  • Carrier, Toshiba — некоторые модели (Midea-Carrier joint venture).

Точно НЕ совместимые (там другие UART-протоколы):

  • Gree, Ballu (почти все), TCL (часть), Hisense с приложением ConnectLife — это Gree-протокол.
  • Haier — H-Link / U-Link.
  • Daikin — S21.
  • Mitsubishi — CN105.

Как точно проверить свой кондиционер за 30 секунд

  1. Посмотрите на штатный Wi-Fi модуль. Если на нём наклейка OSK102 / OSK103 / OSK104 / OSK105 / OSK302 / SK10x / SK11x / EU-SK10x — это Midea OEM, подойдёт.
  2. Посмотрите приложение из инструкции: NetHome Plus / Midea Air / MSmartHome — наш клиент.
  3. Посмотрите тип разъёма на корпусе внутреннего блока. USB-A гнездо (выглядит как обычный USB) — это Midea OEM с UART внутри.

Часть 1. Что покупать (BOM)

Минимум для одного кондиционера

Что Где брать Цена
ESP32-C6 SuperMini (для Matter) Ali / Озон ~250 ₽
ИЛИ ESP32-H2 SuperMini (для Zigbee) Ali / Озон ~300 ₽
BSS138 level-shifter 4-channel Ali / Озон ~70 ₽
Кабель USB → JST-XH 2.54 мм 4-pin Ali (~50 ₽) или из комплекта OSK 0-100 ₽
Провода МГТФ / DuPont у любого мейкера копейки

Итого: ~300-450 ₽ за модуль. Можно собрать аккуратно, обмотать термоусадкой, и спрятать прямо за родной USB-A разъём в корпусе кондера.

Что лежит в коробке OSK302 (если у вас уже есть родной модуль)

Если родной свисток уже куплен — там в комплекте уже есть USB→JST-XH удлинитель, который можно переиспользовать. Просто отрежьте USB-A конец, провода зачистите — вот и весь кабель.


Часть 2. Схема подключения

Распиновка USB-A разъёма Midea (на корпусе AC)

Это не USB! Это UART 9600 8N1 в стандартной USB-A обвязке. Распиновка по 4 контактам:

Распиновка USB-A разъёма Midea Подпись курсивом под картинкой — необязательно

Pin 1 → +5V    (питание)
Pin 2 → UART_RX_5V0  (вход кондера — наш TX)
Pin 3 → UART_TX_5V0  (выход кондера — наш RX, 5В!)
Pin 4 → GND

Полная схема

       Кондиционер                  BSS138                  ESP32-C6 SuperMini

       USB-A 4 pin                  4-канальный
       ┌─────────────┐              level shifter           ┌──────────────┐
       │ pin 1 (+5V) ├──┬───────────┤ HV          LV ├─┬────┤ 5V (или 3V3) │
       │             │  │           │                 │ │    │              │
       │             │  └─────────────────────────────┼─┤    │ 3V3 ────────┘
       │             │              │                 │ │    │              │
       │ pin 4 (GND) ├──────────────┤ GND        GND ├─┤────┤ GND          │
       │             │              │                 │ │    │              │
       │ pin 3 (TX,  │              │ HV1        LV1 ├─────┤ GPIO 7 (RX1) │
       │   5В)       ├──────────────┤                 │ │    │              │
       │             │              │                 │ │    │              │
       │ pin 2 (RX)  ├──────────────┤ HV2        LV2 ├─────┤ GPIO 6 (TX1) │
       │             │              │                 │ │    │              │
       └─────────────┘              └─────────────────┘ │    └──────────────┘
                                                       │
                                          (HV3/HV4 и LV3/LV4 не используются)

Важные нюансы:

  1. На HV-стороне level shifter'а опорное напряжение — 5V с кондера. На LV-стороне — 3.3V с пина 3V3 ESP32-C6 (это вывод внутреннего LDO, можно использовать как опору).
  2. Общая земля обязательна — без GND между AC и ESP UART не заработает, даже если всё остальное правильно.
  3. Питать ESP можно либо от 5V кондера (он спокойно тянет 200 мА), либо от USB-C для отладки. Кондер при отключённом ESP всё равно подаёт 5V на разъём.

Тест без level shifter (на свой страх)

Если очень хочется попробовать «прямо сейчас», и нет BSS138 — поставьте один резистор 4.7 кΩ в разрыв TX кондера → GPIO 7 ESP. Это защитит входной пин ESP от 5В (ток через ESD-диод ограничится до безопасных 340 µA). Линию ESP→AC можно подключать напрямую — кондер прочитает 3.3В как «1». Минус: форма сигнала будет хуже из-за RC, постоянно так оставлять не стоит.


Часть 3. Быстрый путь (для пользователя HA)

Если не хотите возиться с ESP-IDF, компилятором и Linux/WSL — есть готовый прошитый бинарник, который льётся одним кликом через браузер.

Шаг 1 — флеш через Web Flasher или esptool

Готовые бинарники лежат в репозитории в папке release/:

  • release/matter-esp32c6/ — для Matter-варианта (ESP32-C6 SuperMini)
  • release/zigbee-esp32h2/ — для Zigbee-варианта (ESP32-H2 SuperMini)

В каждой папке: bootloader.bin, partition-table.bin, основной .bin приложения, и файл flash_args с готовыми адресами для прошивки.

Способ А — Web Flasher (без установки чего-либо)

  1. Откройте ESPHome Web Flasher в Chrome или Edge (Firefox/Safari не поддерживают Web Serial).
  2. Подключите ESP в USB-C к компьютеру.
  3. Нажмите «Connect», выберите COM-порт (если порт не появился — поставьте драйвер CH340/CP2102 в зависимости от вашей платы).
  4. Загрузите три файла из release-папки (bootloader / partition-table / основной .bin) на соответствующие адреса (см. ниже).

Способ Б — esptool.py из командной строки

Для Matter (ESP32-C6):

esptool.py --chip esp32c6 --port COM9 --baud 460800 write_flash \
    --flash_mode dio --flash_freq 80m --flash_size 4MB \
    0x0      bootloader.bin \
    0x8000   partition-table.bin \
    0x10000  ac_matter.bin

Для Zigbee (ESP32-H2):

esptool.py --chip esp32h2 --port COM9 --baud 460800 write_flash \
    --flash_mode dio --flash_freq 48m --flash_size 2MB \
    0x0      bootloader.bin \
    0x8000   partition-table.bin \
    0xf000   ota_data_initial.bin \
    0x20000  zb_midea_ac.bin

После прошивки откройте idf.py monitor или любой serial-терминал (115200 бод). Должна появиться строка Matter AC started или Zigbee AC started соответственно.

Шаг 2 — подключение к кондиционеру

Спаяйте по схеме выше (модуль BSS138 + 4 провода). Включите кондер в розетку (он подаёт 5V на разъём, даже когда выключен пультом).

Шаг 3 — добавление в Home Assistant

  1. В HA: Settings → Devices & Services → Add Integration → Matter.
  2. На устройстве — длинное нажатие GPIO 9 (BOOT-кнопка) на 5 секунд — это сбрасывает фабрику и открывает окно комиссионинга на 5 минут.
  3. В мониторе (или в логе) появится QR-код / pairing code — введите в HA или отсканируйте телефоном.
  4. Через 30-60 секунд устройство появится в HA.

Шаг 4 — переименование entity

После сопряжения вы увидите такие сущности в HA:

  • climate.ac_thermostat — основной термостат
  • fan.ac_fan — карточка вентилятора
  • sensor.ac_indoor_temperature, sensor.ac_outdoor_temperature — температуры
  • light.ac_swing_v, light.ac_swing_h, light.ac_eco, light.ac_turbo, light.ac_sleep, light.ac_display — переключатели (HA опознаёт OnOff-light как лампочку, в UI работает как toggle)

Переименуйте в Settings → Devices → ваш AC → Entities — клик по карандашику, новое имя и иконка mdi:fan / mdi:lightbulb-off и т.д.

Шаг 5 — пример Lovelace-карточки

type: vertical-stack
title: Кондиционер в спальне
cards:
  - type: thermostat
    entity: climate.bedroom_ac
  - type: entities
    entities:
      - entity: fan.bedroom_ac
      - entity: light.bedroom_ac_swing_v
        name: Шторки вертикально
      - entity: light.bedroom_ac_swing_h
        name: Шторки горизонтально
      - entity: light.bedroom_ac_eco
        name: Эко
      - entity: light.bedroom_ac_turbo
        name: Турбо
      - entity: light.bedroom_ac_sleep
        name: Sleep
      - entity: light.bedroom_ac_display
        name: Дисплей
      - entity: sensor.bedroom_ac_indoor_temperature
        name: Температура в комнате
      - entity: sensor.bedroom_ac_outdoor_temperature
        name: Температура на улице

Часть 4. Сборка из исходников (для maker'а)

Если хочется собрать самому, что-то подправить или сделать форк под свою модель.

Требования

  • ESP-IDF v5.4.1+ (инструкция установки)
  • esp-matter SDK (склонировать с GitHub espressif/esp-matter)
  • Git, Python 3.11+
  • Windows / Linux / macOS — всё работает

Сборка

git clone https://github.com/pirsasha/esp32-midea-ac.git
cd esp32-midea-ac

# поднимаем окружение
. /path/to/esp-idf/export.sh           # Linux/macOS
C:\esp-idf\export.bat                  # Windows
set ESP_MATTER_PATH=C:\esp-matter      # путь к esp-matter

# собираем
idf.py set-target esp32c6
idf.py build
idf.py -p COM9 flash monitor           # COM9 = ваш порт

После прошивки в monitor увидите:

I (xxxx) matter_ac: Matter AC started. UART1: TX=GPIO6 RX=GPIO7 @9600 8N1
I (xxxx) chip[SVR]: SetupQRCode: [MT:Y.K9042C00KA0648G00]

QR-код этим Setup'ом сканируете в HA / Apple Home / Google Home / Алисе.

Структура проекта

royal-matter-firmware/
├── CMakeLists.txt
├── partitions_matter.csv      # партиции с esp_secure_cert
├── sdkconfig.defaults
└── main/
    ├── CMakeLists.txt
    ├── main.cpp               # Matter endpoints + маппинги
    ├── midea.cpp              # UART-драйвер протокола Midea
    └── midea.h

Что менять под другой бренд

Если ваш кондер — не Royal Clima, а, скажем, Pioneer или Inventor, базовый функционал заработает «из коробки» — кадры Midea одинаковые. Что может потребовать правок:

  • Формула температуры в midea.cppparse_status(): сейчас (raw - 50) / 2. На некоторых прошивках бывает иначе.
  • Display toggle (build_display_toggle_frame): байты могут различаться от модели к модели. Если стандартные не сработали, можно снять рабочие байты сниффером (см. ниже).
  • Set state body — если какие-то функции (например, sleep / turbo) не реагируют, нужно подкорректировать байт [8] в build_set_frame().

Если что-то не работает — sniffer

Самый надёжный способ узнать «как правильно» — записать, что делает родной OSK302 в той же ситуации. Для этого есть готовый инструмент:

reneklootwijk/midea-uartsniffer — ESP-прошивка, которая садится «в разрыв» между OEM-модулем и кондером и пишет в лог все кадры в обе стороны. Жмёте кнопку на пульте → видите ровно тот байтовый поток, который надо воспроизвести.


Часть 5. Zigbee-вариант (ESP32-H2)

Если в доме уже Zigbee2MQTT — и Matter заводить не хочется — параллельно сделан вариант на ESP32-H2 SuperMini. Внутри тот же midea.cpp UART-драйвер, но вместо Matter — Zigbee cluster library (ZCL) на базе ESP Zigbee SDK.

Размер прошивки получается заметно меньше: ~530 КБ против ~1.65 МБ у Matter-варианта (Zigbee не тащит TLS / Wi-Fi / TCP/IP стек).

Схема подключения — та же

Распиновка идентична Matter-варианту: 5V → 5V, GND → GND, TX кондера → GPIO 7 ESP (через level shifter), RX кондера → GPIO 6 ESP. Тот же BSS138, тот же кабель. Единственное отличие — у ESP32-H2 нет Wi-Fi, только Zigbee (802.15.4), плюс BLE для отладки.

Прошивка

Берёте release/zigbee-esp32h2/ и шьёте через esptool (команда выше) либо Web Flasher. Стартовая прошивка сразу открывает permit join — устройство готово к включению в Zigbee2MQTT-сеть.

Что увидите в Zigbee2MQTT

Устройство опознаётся как: - Vendor: Custom - Model: ZB-MIDEA-AC - Description: Zigbee air conditioner Royal Clima/Midea on ESP32-H2

И сразу экспонирует через Z2M:

Параметр Тип Значения
climate (occupied_heating_setpoint) numeric 16..30 °C, шаг 0.5
local_temperature numeric (read) температура в комнате
system_mode enum off / auto / cool / heat / dry / fan_only
fan_mode enum auto / low / medium / high / quiet
swing_mode enum off / horizontal / vertical / both
preset enum none / sleep / turbo
display binary ON / OFF (дисплей и звуковой сигнал)
outdoor_temperature numeric (read) температура наружного блока, °C
firmware_version numeric (read) версия прошивки

Под капотом — кастомные атрибуты на стандартном genAnalogInput кластере (0xF000..0xF009) плюс зеркало основных параметров в hvacThermostat для совместимости со старыми контроллерами.

Настройка Zigbee2MQTT

Просто включите паринг в Z2M, перезагрузите ESP — устройство появится. Но чтобы Z2M понимал все наши атрибуты, нужно подключить external converter — JS-файл, который лежит в репе: release/zigbee-esp32h2/esp-ac.js.

  1. Положите esp-ac.js в папку data/external_converters/ вашего Zigbee2MQTT.
  2. В configuration.yaml Zigbee2MQTT добавьте:
external_converters:
  - esp-ac.js
  1. Перезапустите Z2M.
  2. Спарьте устройство (permit_join: true в Z2M, потом перезагрузка ESP — она автоматически просит сети).
  3. В Z2M-вебе появится новое устройство с полным набором контролов.

В Home Assistant оно подтянется через интеграцию MQTT → Zigbee2MQTT автоматически, как climate.<имя> плюс несколько вспомогательных entity.

Пример карточки в HA для Zigbee-варианта

type: vertical-stack
title: Кондиционер (Zigbee)
cards:
  - type: thermostat
    entity: climate.zb_midea_ac
  - type: entities
    entities:
      - entity: select.zb_midea_ac_fan_mode
        name: Скорость вентилятора
      - entity: select.zb_midea_ac_swing_mode
        name: Шторки
      - entity: select.zb_midea_ac_preset
        name: Пресет (sleep/turbo)
      - entity: switch.zb_midea_ac_display
        name: Дисплей
      - entity: sensor.zb_midea_ac_outdoor_temperature
        name: Температура на улице

Сравнение Matter vs Zigbee варианта

Что Matter (ESP32-C6) Zigbee (ESP32-H2)
Размер прошивки ~1.65 МБ ~530 КБ
Сеть Wi-Fi 2.4 ГГц Zigbee 3.0 (802.15.4)
Что нужно дома Matter Controller (HA + Matter Server / Apple Home / Алиса) Zigbee-координатор (Sonoff, ConBee и т.п.) + Zigbee2MQTT
Шаринг между экосистемами Один QR в Apple/Google/Алиса/HA Только через Z2M
Энергопотребление ~80-150 мА (Wi-Fi) ~20-40 мА (Zigbee)
Цена платы ~250 ₽ ~300 ₽

Часть 6. FAQ и траблшутинг

«В мониторе нет строк midea: status: ...»

Кондер не отвечает. Проверьте по порядку:

  1. 5V приходит на пин 5V ESP — мультиметром между 5V и GND.
  2. Общая земля — реально соединена между AC и ESP.
  3. TX/RX не перепутаны — поменяйте местами средние два провода и перезагрузите ESP. Поломок от этого нет.
  4. Кондер включён в розетку. Даже выключенный с пульта, он подаёт 5V на разъём и должен отвечать на запросы статуса.
  5. Level shifter — проверьте, что HV запитан 5V, LV — 3.3V, GND общая.

«В мониторе вижу bad checksum»

Помехи / плохой контакт / без делителя или level shifter. Перепроверьте пайку, попробуйте на коротких проводах.

«Matter не паирится в HA»

  • В HA должен стоять Matter Server (addon Matter Server или Home Assistant OS с поддержкой Matter).
  • Должен быть Wi-Fi 2.4 ГГц — ESP32-C6 на 5 GHz сети не подключится.
  • Откройте idf.py monitor и найдите строки BLE advertising started и Pairing code: XXX. Окно открыто 5 минут после загрузки.
  • Если не успели — зажмите GPIO 9 на 5 секунд, окно откроется снова.

«Display / Eco / Turbo не реагируют на кнопку»

Конкретные байты этих команд могут различаться от модели к модели. В коде используются стандартные значения из dudanov/MideaUART. Если не работает — снимайте сниффером, какие байты шлёт OSK302, и подставляйте в build_set_frame или build_display_toggle_frame.

«Можно ли совместить с родным OSK модулем?»

Нет. Их одновременно нельзя — кондер общается только с одним мастером. Либо OSK + NetHome Plus, либо наш ESP + Matter/Zigbee. Зато можно в любой момент откатиться — просто отключить ESP и вставить OSK обратно.


Итог

Вместо 4 родных модулей за ~10 000 ₽, NetHome Plus с облачной задержкой и зависимостью от чужих серверов — получился свой локальный Matter/Zigbee-модуль за ~300 ₽ на каждый кондер, с полным управлением из Home Assistant.

Главное приятное: устройство больше не зависит от облака и приложения производителя. Работает локально, не отваливается при проблемах с интернетом, видно всем умным домам через Matter и Zigbee.

Исходники, готовый бинарник, прошивка для Zigbee, конвертер для Z2M, схема — всё на GitHub: github.com/pirsasha/esp32-midea-ac.

Если статья зайдёт — будут ещё разборы по протоколу Midea, как добавить поддержку Haier / Gree / Daikin и как сделать универсальный модуль с автоопределением. Звёздочка на GitHub, issue с фидбеком, PR с поддержкой вашей модели кондера — всё это очень приветствуется.


Ссылки