Что такое MQTT

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

Я написал этот текст специально для людей кто никогда раньше не сталкивались с MQTT.

История возникновения MQTT

MQTT — это такой специальный протокол по которому умеют общаться программы и устройства. Есть русский язык и люди которые умеют разговаривать на этом языке могут понять друг друга. Точно так же есть "язык" MQTT — программы и устройства которые умеют разговаривать на этом языке могут общаться друг с другом.

MQTT был создан в 1999 году. Была задача — в пустыне установлено много нефтедобывающих вышек. Со всех этих вышек нужно получать кучу разных технических параметров (давление, температура, скорость потока, ...) и передавать все эти данные в единый центр.

Для передачи данных использовалась спутниковые телефоны, которые и сейчас очень дорогие, а 20 лет назад были очень-очень дорогие. Поэтому технология передачи должна была быть как можно более экономной — передавать как можно меньше данных.

Протокол MQTT смог успешно решить эта задачу и стал применяться и в других отраслях. Постепенно компьютеры и микропроцессоры становились все дешевле и это привело к тому что стала появляться куча разных устройств в которые добавили "ума" (для этого придумали красивый термин IoT — Internet of Things — Интернет Вещей). Умный чайник, умный обогреватель — эти устройства могут отправлять данные про себя (какая сейчас температура, сколько устройство работает), а так же удаленно получать команды на управление.

Есть множество устройств разных производителей — как им общаться друг с другом и с серверами умного дома? Можно взять и придумать новый язык (протокол) и многие производители так и делают. Но есть протокол MQTT которые отлично подходит для общения разных устройств и программ. Некоторые производители используют MQTT в своих устройствах. MQTT популярен в мире бесплатных и открытых программ (Open Source).

Программа MQTT Explorer

Если вы работаете с MQTT, то вам нужно обязательно скачать и поставить программу MQTT Explorer.

http://mqtt-explorer.com/

Программа бесплатная. Программа работает на Windows, на macOS и на Linux.

С помощью этой программы можно подключиться к MQTT серверу и увидеть все то что там происходит.

MQTT брокер

MQTT — это протокол который работает по модели клиент-сервер.

Центральная часть — это MQTT сервер. Обычно сервер MQTT называют MQTT брокер.

Есть очень популярная программа Mosquitto — если запустить эту программу, то у вас появится работающий MQTT сервер.

Далеко не всегда нужно самому запускать MQTT сервер. Многие системы сами поднимают MQTT сервер с которыми работают.

Клиенты

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

Чтобы клиент мог подключиться к MQTT серверу нужно указать:

Топики и отправка сообщений

Итак, есть MQTT брокер — центр системы. Есть клиенты которые подключаются к этому центру.

Давайте разберем задачу. Есть датчик температуры и есть система умного дома. Как с помощью MQTT датчик может передать температуру в систему умного дома?

Датчик температуры подключается к серверу MQTT. Раз в 5 минут датчик производит замер температуры и отправляет результат замера в сервер MQTT. Например, температура 23.8 °C

Для того чтобы отправить температуру в MQTT датчик должен знать две вещи. Во-первых, саму температуру, она есть — 23.8. А во-вторых датчик должен указать адрес топика в который будет отправлено это значение. Что же такое топик? Чуть-чуть отойдем в сторону. Представим что нужно сохранить число 23.8 на компьютер. Можно сохранить в файл. Для этого нужно знать полный путь к файлу. Например, c:\temperature\sensor.txt — в этом файл мы можем записать число 23.8

Топик очень похож на файл — это расположение какого-то кусочка информации в MQTT сервере. Датчик температуру может отправить сообщение 23.8 в топик temperature/sensor — теперь MQTT сервер знает про это число.

Половину задачи решели — датчик температуру отправил значение температуру в MQTT сервер.

Как же система умного дома узнает о том что датчик прислал новую температуру? При подключении к серверу MQTT система умного дома говорит — я хочу получить все данные которые приходят в топик temperature/sensor MQTT сервер запоминает это желание клиента и как только в топик temperature/sensor приходит какое-то значение сервер пересылает это сообщение всем клиентам кто выразил желание получать сообщение из этого топика (это называется кто "подписался" на эти топики")

Символ решетка

Клиент при подключении к MQTT серверу может указать список топиков которые он хочет "слушать" (т.е. получать все сообщения которые поступают в эти топики)

При подписке можно указать символ решетка. Например, если клиент говорит что он хочет подписать на temperature/# то этот клиент получит все сообщения которые будут отправлены вот в такие топики:

Так же клиент может подписать на топик # — это ознчает что он будет получать вообще все сообщения которые прилетают в MQTT сервер.

Retain Флаг

MQTT сервер — это всего лишь посредник между разными клиентами. Клиент отправил сообщение в MQTT сервер, сервер переслал это сообщение всем клиентам, которым интересно это сообщение и сервер тут же забыл про это сообщение. Новые клиенты которые подключаются к MQTT серверу уже не получат это сообщение.

Пример. Есть датчик температуры и есть система умного дома. Штатный режим работы. Система умного дома подключилась к MQTT серверу и слушает все сообщения. Датчик температуры подключился к MQTT серверу и каждые 5 минут отправляет данные про температуру. Все работает прекрасно — датчик отправл температуру, MQTT сервер переслал эту температуру в систему умного дома и умный дом отобразил эту температуру в интерфейсе.

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

Решение такой ситуации — это флаг retain. При отправке сообщения клиент может сказать что это сообщение нужно отправить с флагом retain, т.е. сервер должен сохранить сообщение. В этом случае сервер получит сообщение, переправит его всем клиентам, но не забывает про это сообщение, а оставляет его у себя и будет отправлять это же сообщением всем новым клиентам которые подключились к MQTT серверу.

Last will

Одна из интересных фишек протокола MQTT — это штука под названием Last will — завещание. Еще используют аббревиатуру "LWT" — Last Will and Testament.

Стандартная работа — клиент подключается к MQTT серверу и все время остается подключенным к серверу (сервер "видит" момент подключения и может понять когда клиент отключился).

Задача. Есть клиент — компьютер — он должен быть всегда подключен к MQTT серверу. Если этот компьютер не подключен к MQTT серверу — это авария, что-то случилось либо с этим компьютером, либо с каналом связи. Как об этой аварии могут узнать другие клиенты?

Решение следующее: клиент при подключении говорит серверу: "слушай, когда я отключусь, ты, пожалуйста, вот в этот топик положи вот такое сообщение". Сервер принимает такое "завещание" от клиента и когда этот клиент отключается, MQTT сервер выполняет "последнюю волю" клиента.

Например, клиент может попросить сервер отправить сообщение "offline" в топик "computers/my-desktop/status". И когда этот клиент отвалится MQTT сервер отправит сообщение "offline" в нужный топик. Клиент подключился, сказал MQTT серверу что при отключении нужно отправить в топик значение "offline" и тут же отправляет в этот же топик значение "online". Тогда все другие клиенты которым интересен статус этого клиента могут следить за этим топиком — если там "online" значит с компьютером все нормально, если "offline", то есть проблема.

Иван Бессарабов
ivan@bessarabov.ru

26 октября 2020

Кстати, у меня есть телеграм канал про Home Assistant: https://t.me/bessarabov_ha