В последнее время мне пришлось долго и муторно разбираться с протоколом MQTT (Mosquitto) и с тем, как его можно использовать с домашней автоматизацией. Поэтому пришлось разбираться с тем, как оно работает и зачем нужны все эти настройки.
Немного теории
Итак, простым языком протокол MQTT используется для общения между умными устройствами, путем пересылки сообщений о своем состоянии. Для этого используется WiFi сеть и некое центральное устройство под названием Брокер (Broker). В его задачу входит слушать сеть, получать и передавать полученные сообщения и хранить их "пока смерть не разлучит нас" если это запрошено.
Основные термины и понятия используемые в данном протоколе:
- Message
- Publish
- Subscribe
- Topic
- QoS
- Retain
Разберем каждый термин по отдельности
Message
Сообщения (message) содержат в себе информацию, которую один участник сети на базе протокола MQTT хочет передать другим. Взаимодействие между участниками сети осуществляется через Брокера. То есть, если мне, как устройству, нужно передать сообщение о том что я что-то сделал или сообщить о том, как у меня дела, я передаю сообщение брокеру публикуя во всеуслышание что "я что-то сделал" или "как у меня дела".
Publish
Это процесс передачи сообщения брокеру.
То есть простым языком, я подошел к брокеру и сказал "мама я покакал". Брокер гипотетически должен услышать это сообщение и записать его к себе в блокнотик. Почему гипотетически? Потому что есть особенности протокола, которые мы разберем чуть ниже. Пока берем за данность, что я сказал что-то брокеру используя механизм Publish и он это услышал и записал.
Subscribe
Так как всеми сообщениями от всех устройств владеет исключительно брокер, то нам жеж нужно как то получить эти сообщения. Для этого мы подписываемся на рассылку от брокера для получения проходящих через него сообщений. Чтобы читать какие-то конкретные сообщения, нам необходимо определить на какую тему мы хотим получать эти сообщения, и для этого как раз используется механизм Topic
Topic
Это как раз таки Тема, по поводу которой мы хотим получать или как ни странно отправлять сообщения.
То есть формат общения между участниками выглядит примерно так.
Я как участник хочу сказать всем "мама я покакала"
для этого я создаю топик любого содержания, например: мое_тело/задница/
и сообщаю в этот топик сообщение "мама я покакала"
Брокер получит это сообщение, и передаст всем, кто подписался на тему (топик) мое_тело/задница/
То есть это такая вот упрощенная система смс рассылок с определенными темами.
Формат топика может быть разным и абсолютно любым. В принципе мы можем создать любой топик, и в него передавать сообщения любого содержания. Главное чтобы получатель был подписан на этот топик и знал что делать с информацией полученной из сообщений.
Что касается особенностей топиков, то их не так чтобы много.
Во первых они чувствительны к регистру. То есть топик "мое_тело/задница" и топик "Мое_Тело/Задница" это два разных топика.
Во вторых, топики не создаются не сервере администратором. Они создаются публикаторами и подписчиками которые на них подписаны. Брокер только занимается передачей сообщений и служебной информации.
Зачем нужны разделители в виде "/" ?
Они позволяют выстраивать иерархию. Ну например:
У нас есть в гостиной и в спальне по два выключателя и один в гараже. Для этого мы формируем на выключателях в топики в виде:
В гостиной:
home/livingroom/switch1
home/livingroom/switch2
home/livingroom/switch1
home/livingroom/switch2
В спальне:
home/bedroom/switch1
home/bedroom/switch2
В гараже:
garage/switch1
Зачем это нужно ?
Затем, что есть служебные топики, которые позволяют подписаться на группы топиков или сообщений.
Например если мы хотим читать вообще все сообщения мы подписываемся на топик #
Если мы хотим видеть то, что происходит в доме, то мы подписываемся на топик home/# и будем получать сообщения в топиках:
home/livingroom/switch1
home/livingroom/switch2
home/bedroom/switch1
home/bedroom/switch2
Но не будем видеть то что происходит в топике:
garage/switch1
Если мы хотим видеть то, что происходит в гостиной, мы подписываемся на топик home/livingroom/# и будем получать сообщения только из топиков
home/livingroom/switch1
home/livingroom/switch2
Также в подписках можно использовать символ +Он позволяет например узнать, что происходит со всеми выключателями под номером 1 во всех комнатах дома. Для этого мы подписываемся на топик home/+/switch1, и мы будем получать сообщения в топиках home/livingroom/switch1 и home/bedroom/switch1
В общем я думаю понятно что и как происходит с этими топиками.
Служебные сообщения
В качестве служебных сообщений используются в основном два типа сообщений
Birth Message - которое сообщает миру что "я родился и живой"
и
Last Will and Testament (LWT) которое сообщает что после этого сообщения считать меня мертвым.
Ну плюс еще используется Keep Alive сообщения, которые сообщают брокеру что "я все еще живой" и стандартно посылаются каждые 60 секунд. Если брокер не получил это сообщение от клиента, то он принудительно пингует его чтобы выяснить живой ли тот, и если выясняется что он неживой, то брокер публикует за клиента LWT сообщение, чтобы все узнали что тот скончался.
Соответственно получение брокером Birth Message от устройства, переводит устройство в понимании брокера в режим ONLINE, а после того как брокер получает от устройства LWT сообщение или когда сам принимает решения что тот скончался проверив устройство на доступность, то переводит статус устройства в режим OFFLINE.
QoS
QoS в принципе расшифровывается как Quality Of Service, то есть качество предоставляемой услуги. В разрезе MQTT оно имеет три значения 0,1 и 2
Если по простому, то эти варианты означают по факту определение того, надо ли нам как публикующему свое сообщение устройству, быть уверенным что оно получено.
QoS=0 означает что мы один раз публикуем сообщение "мама я покакала" и нам пофиг услышали нас или нет
QoS=1 означает что мы будем публиковать сообщение "мама я покакала" до посинения, до тех пор пока нам не скажут что нас услышали и можно заткнуться уже.
QoS=2 означает что мы один раз сказали "мама я покакала", получили от мамы подтверждение того что она нас услышала, сообщили маме что мы узнали о том что мама нас улышала, а мама подтвердила, что она поняла что мы узнали о том что она услышала :))))))
Я думаю первая буква М в протоколе, имеет отсылку в адрес Майкрософта, который по стопицот раз переспрашивает "действительно ли вы уверены что хотите закрыть это приложения?" :)))))))
Вот в общем то и все.
Retain
Этот параметр имеет всего два значения вкл и выкл. Означает он очень простой механизм.Если у нас режим выключен, то когда я сообщаю всему миру "мама я покакала", то его слышат все кто подписан сейчас на топик в который я это сообщил. Но вновь подключившийся подписчик на наш веселый топик "мое_тело/задница" не узнает о том что все уже случилось и так и умрет в неведении наверное.Если же мы включаем режим Retain, то брокер берет на себя обязательство, после того как мы сообщили миру об акте дефекации, сообщать каждому вновь подписавшемуся на этот топик сей удивительный и жизненно необходимый факт.
Вот в общем то и вся теория.
О практическом применении данного протокола, поговорим в следующей статье, где мы будем разбирать брокера на базе Home Assistant (конкретнее Hass.io) установленный на Raspberry Pi 3 с установленным плагином Mosquitto MQTT broker из официального репозитория Hass.io
Великолепный материал, лайк однозначно + отправляется в избранное =)
Статья прямо в тему, как раз начал изучать MQTT для использования в УД, а в статье всё разложено по полочкам, за что огромное спасибо!
Буду ждать следующую статью о практическом применении.
Почему стоит использовать Mosquitto вместо, а не встроенный в Home Assistant mqtt-брокер?
ващета он и имелся в виду :))) mosquitto это развернутое название протокола
Виталий, не знал что Mosquitto расширенный MQTT, для меня он был просто одним брокером для MQTT. Спасибо, теперь буду знать.
А что Mosquitto добавляет к стандарту MQTT?
И ждём продолжения как использовать MQTT в Home Assistant ;)
Отличная статья! Спасибо что разложили все по полочкам и заставили улыбнуться!
друзья, подскажите как побороть москитто в следующем моменте. Как только я рву линк или перезагружаю сервер где крутится хоум ассистент и москитто, после восстановления соединения у меня реле щелкает светом, чаще та, которая была активной последней. То есть инвертируется. При этом в хоум ассистант состояние этого реле остается старое, и программно его уже не перещелкнуть.
QoS и Retain какие на него стоят ?
QoS =2 Retain=false в настройках обоих реле
добавлю, что состояние в хоум ассистант со временем исправляется.
по идее надо смотреть логи брокера при старте... ведь по идее он берет откуда то состояние retain устройств при запуске.... надо смотреть короче.... возможно топики виноваты, а возможно и у реле сносит башню, особенно если включен autodiscovery у HA
сейчас поправил конфиг чтоб полные логи писались, похоже реле восстанавливает состояние так. попробую узнать в тех поддержке какого фига