MQTT в Home Assistant: retained, QoS, LWT и настройка broker без ошибок
MQTT · Home Assistant · Mosquitto · локальная автоматика

MQTT в Home Assistant: broker, topics, retained, QoS и почему устройства иногда «залипают»

MQTT часто используют для связи Home Assistant, Wiren Board, Node-RED, ESPHome и самодельных устройств. Но проблемы обычно начинаются не на уровне «подключилось или нет», а позже: старое retained-состояние возвращается после перезапуска, availability показывает неверный online, несколько устройств публикуют в одну тему, а высокий QoS применяют там, где он не нужен.

MQTT brokertopicsretainedQoS 0/1/2LWTavailability
Коротко: для большинства домашних систем достаточно одного локального broker, понятной структуры topics, QoS 0 или 1 и аккуратного использования retained. LWT/availability нужен для корректного offline-состояния, а retained не следует включать «на всякий случай» на команды и временные события.

Что такое MQTT простыми словами

MQTT — лёгкий publish/subscribe протокол обмена сообщениями. Устройства не обязаны соединяться напрямую друг с другом. Они подключаются к broker и либо публикуют сообщения в topics, либо подписываются на них.

Датчикpublish
→
MQTT brokerраспределяет сообщения
→
Home Assistantsubscribe

Например, счётчик публикует текущую мощность в topic house/power/total, а Home Assistant подписывается на него. При этом тот же topic одновременно может читать Node-RED, Grafana-bridge или другой контроллер.

MQTT не является беспроводным протоколом. Он может работать поверх Ethernet, Wi-Fi, VPN и других IP-сетей. Это прикладной протокол обмена сообщениями.

Зачем нужен MQTT broker

Broker — центральная точка MQTT-обмена. Он принимает сообщения от publishers и доставляет их всем подходящим subscribers.

В домашней автоматизации broker часто выполняет несколько задач:

  • связывает Home Assistant и внешние контроллеры;
  • передаёт телеметрию датчиков и счётчиков;
  • доставляет команды исполнительным устройствам;
  • хранит retained messages;
  • отслеживает соединения клиентов;
  • реализует ACL и аутентификацию.

Один из самых распространённых broker — Eclipse Mosquitto. В Home Assistant OS его часто разворачивают как add-on, но broker может работать и на отдельном Linux-сервере, NAS или другом постоянно включённом устройстве.

Для надёжной архитектуры broker лучше считать отдельным инфраструктурным сервисом. Если от него зависят отопление, датчики или аварийные уведомления, нужно резервировать его питание и сохранять конфигурацию.

Topics: как MQTT понимает, кому отправлять данные

Topic — строковый путь, по которому публикуется сообщение. Обычно структуру строят иерархически через символ /.

house/kitchen/temperature
house/kitchen/humidity
house/boiler/status
house/power/total
house/gate/state

Подписчик может слушать конкретный topic или использовать wildcard.

ПодпискаЧто она получит
house/kitchen/temperatureТолько температуру кухни
house/kitchen/+Все значения одним уровнем ниже kitchen
house/#Все topics внутри ветки house
Не используйте одну topic для разных физических устройств или разных типов данных. Это одна из причин труднообъяснимых состояний и конфликтов.

Что такое retained message и почему оно может «оживлять» старое состояние

Если publisher отправляет сообщение с флагом RETAIN, broker сохраняет последнее retained-сообщение для этой topic. Когда новый subscriber подпишется позже, broker сразу отправит ему сохранённое значение.

Устройствоpublish: ON + retain
→
Brokerсохраняет ON
→
Home Assistantподключается позже
→
Получает ONсразу после subscribe

Это полезно для текущего состояния, но опасно для команд и кратковременных событий.

Где retained обычно полезен

  • последнее известное состояние устройства;
  • статическая конфигурация;
  • MQTT Discovery messages;
  • некоторые availability/status topics при правильной логике.

Где retained часто вреден

  • команда «открыть ворота»;
  • импульс «перезагрузить»;
  • одноразовое событие кнопки;
  • триггер сценария.
Классическая ошибка: команда gate/open была опубликована с retain. После переподключения новый subscriber может получить старую команду снова. Для command topics retain обычно должен быть выключен, если протокол устройства явно не требует обратного.

Как удалить retained message

По MQTT 5 retained-сообщение удаляется публикацией сообщения с нулевой длиной payload в ту же topic с установленным RETAIN.

QoS 0, QoS 1 и QoS 2: какой выбрать

QoSГарантия доставкиПрактический сценарий
0At most onceЧастая телеметрия, где потеря одного значения некритична
1At least onceСостояния и команды, где важнее доставка, чем возможный дубль
2Exactly once на уровне протоколаРедкие специальные случаи; выше накладные расходы

QoS 0

Сообщение отправляется без подтверждения доставки. Это самый лёгкий режим. Для температуры, мощности или RSSI, публикуемых каждые несколько секунд, потеря одного пакета обычно незаметна.

QoS 1

Broker/клиент подтверждает доставку. Сообщение может быть доставлено повторно, поэтому обработчик должен по возможности быть идемпотентным.

QoS 2

Использует более сложный четырёхшаговый обмен для исключения повторной доставки на уровне MQTT. В домашней автоматизации QoS 2 нужен редко.

Практическое правило: QoS 0 для частой телеметрии, QoS 1 для значимых состояний и команд. QoS 2 не нужно включать просто потому, что цифра больше.

LWT: как Home Assistant понимает, что устройство действительно offline

Last Will and Testament — сообщение, которое клиент заранее передаёт broker при подключении. Если соединение оборвётся некорректно, broker публикует Will Message за клиента.

Устройство onlineподключено к broker
→
Связь пропалабез нормального DISCONNECT
→
Brokerпубликует LWT: offline

Обычно используют отдельную availability topic:

device/boiler/availability = online
device/boiler/availability = offline

При штатном подключении устройство публикует online, а Will Message заранее настроено как offline.

LWT показывает потерю MQTT-соединения, а не обязательно физическую неисправность оборудования. Устройство может продолжать локально работать, но потерять сеть или broker.

Как MQTT интегрируется с Home Assistant

В Home Assistant есть официальная MQTT integration. После подключения к broker она может создавать MQTT sensors, switches, lights, binary sensors, climate entities и другие типы объектов.

У сущности обычно есть отдельные topics:

state_topic: house/pump/state
command_topic: house/pump/set
availability_topic: house/pump/availability

Такое разделение важно: state topic сообщает фактическое состояние, command topic принимает желаемое действие, availability topic показывает доступность.

Не используйте command topic как единственный источник фактического состояния. Команда «ON» ещё не доказывает, что реле действительно включилось.

MQTT Discovery: автоматическое создание сущностей

Home Assistant умеет автоматически создавать MQTT entities по специальным discovery topics. Устройство публикует конфигурацию, а Home Assistant создаёт сущность без ручного YAML.

homeassistant/sensor/boiler_temp/config

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

Discovery config обычно публикуют retained, чтобы Home Assistant получил конфигурацию даже если подключился к broker позже.

ESPHome: Native API или MQTT

ESPHome поддерживает оба подхода. Для обычного проекта Home Assistant чаще проще Native API: он обеспечивает прямую интеграцию, автоматическое появление сущностей и не требует отдельного broker.

СценарийЧто логичнее
ESPHome используется только с Home AssistantNative API
Одни данные нужны нескольким системамMQTT
Есть уже развитая MQTT-инфраструктураMQTT
Нужно минимизировать число сервисовNative API
Устройство должно жить независимо от HAЛокальная ESPHome automation + при необходимости MQTT

MQTT не делает ESPHome автоматически надёжнее. Он добавляет ещё один компонент — broker, который тоже должен работать и быть доступен.

Как строить topics, чтобы система не превратилась в хаос

Для домашней системы удобно придерживаться стабильной структуры:

house/{zone}/{device}/{parameter}

house/kitchen/climate/temperature
house/boiler/controller/state
house/power/meter1/voltage_l1
house/gate/controller/availability

Полезные правила:

  • не включать IP-адрес в topic, если он может измениться;
  • использовать стабильный device ID;
  • отделять state от command;
  • отделять availability от обычного состояния;
  • не смешивать единицы измерения внутри одной topic;
  • не менять структуру topics без необходимости на работающем объекте;
  • документировать topics для инженерных устройств.
Чем дольше должна жить автоматизация, тем важнее стабильные идентификаторы. Красивый dashboard можно переделать за вечер, а изменение сотен MQTT topics ломает интеграции сразу в нескольких системах.

Как защитить MQTT broker

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

  • не разрешайте anonymous access без явной необходимости;
  • используйте отдельные учётные записи для разных сервисов;
  • ограничивайте ACL по topics;
  • не публикуйте порт broker напрямую в интернет;
  • для удалённых площадок используйте VPN или защищённый канал;
  • применяйте TLS там, где трафик выходит за пределы доверенного сегмента;
  • не храните пароль broker открытым в публичных конфигурациях;
  • обновляйте Mosquitto и клиентские библиотеки.
Если пользователь MQTT имеет право публиковать в #, компрометация одной учётной записи может дать возможность отправлять команды множеству устройств. ACL должен соответствовать реальной роли клиента.

Как диагностировать MQTT, если Home Assistant показывает странное состояние

  1. 1

    Подписаться на нужную ветку

    Посмотреть реальные сообщения через MQTT Explorer или mosquitto_sub.

  2. 2

    Проверить retained

    Если значение появляется мгновенно после subscribe, выяснить, не retained ли оно.

  3. 3

    Проверить state и command topics

    Убедиться, что они не перепутаны.

  4. 4

    Проверить availability

    Посмотреть, кто публикует online/offline и есть ли LWT.

  5. 5

    Проверить client ID

    Два клиента с одинаковым Client Identifier могут выбивать друг друга из broker.

  6. 6

    Проверить ACL

    Клиент может подключаться, но не иметь права читать или публиковать нужную topic.

  7. 7

    Проверить QoS и reconnect

    Особенно если сообщения дублируются после потери связи.

mosquitto_sub -h 192.168.1.10 \
  -u ha_debug \
  -P 'PASSWORD' \
  -v \
  -t 'house/#'

Типичные ошибки MQTT в умном доме

Retain на командах

Старая команда может неожиданно прийти новому subscriber после подключения.

Один topic для state и command

Становится непонятно, где желаемое состояние, а где реальное.

QoS 2 везде

Усложняет обмен без реальной пользы для большинства домашних датчиков.

Нет LWT

Home Assistant продолжает считать устройство online после аварийного обрыва связи.

Одинаковый Client ID

Клиенты периодически отключают друг друга от broker.

Wildcard ACL

Одному устройству выдаются права на весь broker, хотя ему нужны 2–3 topics.

Broker без UPS

Кратковременное отключение питания рушит сразу все MQTT-зависимые интеграции.

Topics без документации

Через год непонятно, кто публикует значение и что сломается после переименования.

Частые вопросы

Нужен ли MQTT для Home Assistant?

Нет. Home Assistant имеет множество прямых интеграций. MQTT нужен только для устройств и систем, которые используют его или когда он удобен как общий транспорт между несколькими платформами.

Что такое retained message?

Последнее сообщение, которое broker сохраняет для topic и сразу отдаёт новым подписчикам. Полезно для состояния и discovery, но опасно для одноразовых команд.

Какой QoS использовать в умном доме?

Чаще всего QoS 0 для частой телеметрии и QoS 1 для важных состояний/команд. QoS 2 нужен редко.

Что такое LWT?

Last Will and Testament — заранее заданное сообщение, которое broker публикует, если клиент неожиданно теряет соединение. Обычно используется для offline availability.

Почему устройство в Home Assistant online, хотя оно выключено?

Частые причины: нет корректного LWT, availability topic не настроена или старое retained online осталось на broker.

Почему после перезапуска приходит старое значение?

Скорее всего, это retained message. Broker хранит его независимо от текущей MQTT-сессии и отправляет новому subscriber после подписки.

MQTT безопасен?

Может быть безопасным при нормальной аутентификации, ACL, TLS/VPN и отсутствии прямой публикации broker в интернет. Сам по себе протокол не компенсирует плохую сетевую конфигурацию.

Вывод

MQTT хорошо подходит для локальной автоматизации, когда нужно связать несколько независимых систем через простой publish/subscribe механизм. Но надёжность определяется не самим фактом использования Mosquitto, а дисциплиной topics, retained, QoS и availability.

Для большинства домашних проектов достаточно QoS 0/1, отдельных state и command topics, LWT для offline-состояния и минимального количества retained messages. Broker должен быть защищён, резервироваться по питанию и иметь понятные ACL.

Если MQTT используется только потому, что «так принято», а устройство уже имеет хорошую прямую интеграцию Home Assistant, дополнительный broker может быть лишним. Но для Wiren Board, Node-RED, внешних контроллеров и многосистемной архитектуры MQTT остаётся одним из самых полезных локальных интерфейсов.