MQTT: различия между версиями

Материал из Wiren Board
Строка 125: Строка 125:
root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/#' -v
root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/#' -v
/devices/wb-w1/meta/name 1-wire Thermometers
/devices/wb-w1/meta/name 1-wire Thermometers
/devices/wb-w1/controls/28-000004a7d3f9 23.312000
/devices/wb-w1/controls/28-0115a48fcfff 22.812
/devices/wb-w1/controls/28-000004a7d3f9/meta/type temperature
/devices/wb-w1/controls/28-0115a48fcfff/meta/type temperature
/devices/wb-w1/controls/28-000004a7d3f9 23.312000
/devices/wb-w1/controls/28-0115a48fcfff 22.75
/devices/wb-w1/controls/28-000004a7d3f9 23.312000
</syntaxhighlight>
</syntaxhighlight>
, где ''#'' - означает любое количество вложенных топиков. Соответственно, вывелись не только значения с "контрола" устройства, но и топики с метаданными - название драйвера устройства и тип "контрола" - ''temperature''.
, где ''#'' - означает любое количество вложенных топиков. Соответственно, вывелись не только значения с "контрола" устройства, но и топики с метаданными - название драйвера устройства и тип "контрола" - ''temperature''.

Версия 20:59, 18 февраля 2016

MQTT - очередь сообщений, использующаяся в программном обеспечении Wiren Board. Базовая информация по MQTT на Википедии.

Драйверы, отвечающие за аппаратные возможности контроллера (цифровые входы, АЦП, транзисторный выходы, ...) и функции внешних подключённых устройств (например, подключённых по RS-485 модулей реле) записывают их состояние в очередь MQTT в виде специальных сообщений. Веб-интерфейс читает эти сообщения и на их основе отображает состояние устройств.

Если же происходит нажатие кнопки в веб-интерфейсе, уже веб-интерфейс отправляет сообщение в очередь MQTT, драйвер устройства его получает и отдаёт команду устройству.

Примеры работы через очередь MQTT

Получение значения от датчика температуры и вывод его в веб-интерфейс

Показания датчика и его уникальный идентификатор на странице Devices веб-интерфейса

Предположим, что к Wiren Board подключён датчик температуры по шине 1-Wire. Проследим, как данные с него через очередь сообщений попадают в веб-интерфейс:

  1. Драйвер, отвечающий за данную аппаратную функцию (например, wb-homa-w1) опрашивает подключённые к контролеру датчики 1-Wire.
  2. При получении значения драйвер размещает в очереди сообщение следующего вида:
    /devices/wb-w1/controls/28-0115a48fcfff 23.25
    Оно значит, что на устройстве 1-Wire с идентификатором 28-0115a48fcfff получено значение 23.25°C.
  3. Веб-интерфейс, который получает все сообщения из очереди (он подписан на все сообщения), получает это сообщение и выводит значение датчика на страницу.

Нажатие кнопки в веб-интерфейсе и переключение реле на внешнем модуле

Веб-интерфейс после нажатия кнопки включения Реле 1 на подключённом по RS-485 релейном модуле WB-MRM2

Предположим, что к контроллеру по шине RS-485 подключён релейный модуль WB-MRM2. Пользователь в веб-интерфейсе нажимает кнопку включения реле. Проследим, как команда из веб-интерфейса попадает на внешний модуль:

  1. После нажатия кнопки веб-интерфейс размещает в очереди сообщение следующего вида:
    /devices/wb-mrm2_130/controls/Relay 1/on 1
    Оно значит, что устройство WB-MRM2 с адресом 130 должно перевести Реле 1 в состояние логической единицы - "включено".
  2. Драйвер wb-mqtt-serial, отвечающий за данную аппаратную функцию, получает это сообщение (он подписан на все сообщения, относящиеся к подключённым по RS-485 устройствам) и посылает по шине RS-485 релейному модулю команду на включение первого реле.
  3. Релейный модуль WB-MRM2 получает команду от контроллера, переключает реле и посылает обратно уведомление ("Реле 1 включено").
  4. Драйвер wb-mqtt-serial получает это уведомление по RS-485 и публикует в очереди сообщение:
    /devices/wb-mrm2_130/controls/Relay 1 1
    Оно значит, что первое реле на устройстве WB-MRM2 с адресом 130 находится (уже переведено) в состоянии логической единицы ("включено").

Принцип работы очереди сообщений

Через очередь сообщений MQTT работают драйверы внутренних функций, внешних устройств, веб-интерфейс, система правил

Система сообщений MQTT построена по следующему принципу:

  • есть иерархическая система "топиков" (как на обычных форумах в интернете)
  • в эти топики клиенты (в случае Wiren Board это драйверы устройств и веб-интерфейс) могут писать сообщения и читать оттуда
  • чтобы следить за изменениями нужного топика (например, температуры на датчике), клиент может на него "подписаться" - тогда он получит все сообщения в данном топике.

Полное описание системы топиков и подписок http://mosquitto.org/man/mqtt-7.html.

Отображение устройств в структуре сообщений

Логика топиков, соответствующих разным устройствам и их параметрам, в Wiren Board основывается на так называемых Conventions - https://github.com/contactless/homeui/blob/contactless/conventions.md

Клиенты очереди сообщений

  • драйверы внутренних аппаратных функций
  • драйверы внешних подключённых устройств
  • веб-интерфейс
  • движок правил
  • (если есть) собственные программы пользователя

Пример сообщения

Вот пример сообщения от драйвера температурного датчика 1-Wire из примера выше:

/devices/wb-w1/controls/28-0115a48fcfff 23.25

Часть до пробела - название топика, после - само сообщение.

Название топика состоит из вложенных друг в друга "подтопиков":

  • /devices - коренной топик для всех "устройств" - как встроенных функций Wiren Board (цифровые, АЦП, ...), так и подключённых внешних (например, модулей реле)
  • /wb-w1 - подтопик, который наполняется драйвером 1-Wire
  • /controls - подтопик, который есть у всех устройств - именно в него записываются все их параметры, которые меняются ("включено-выключено", значение датчика, ...)
  • /28-0115a48fcfff - непосредственно сам "канал" ("контрол)" - топик, куда записывается значение с датчика. Его название совпадает с адресом 1-Wire датчика на шине.

Содержание сообщения:

  • 23.25 - значение температуры

Пример подписки

Клиенты, которые хотят следить за значением температуры, "подписываются" на этот топик, и им приходят все новые сообщения - меняющиеся значения температуры. Один из таких клиентов - веб-интерфейс.

Подписаться на сообщения можно и из консоли Linux при помощи утилиты mosquitto_sub (полное описание работы с очередью из командной строки смотрите ниже):

root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/controls/28-0115a48fcfff' -v //получить сообщения из топика устройства 1-Wire с идентификатором 28-0115a48fcfff
/devices/wb-w1/controls/28-0115a48fcfff 22.75 //в этой строке и ниже - вывод утилиты, полученные сообщения
/devices/wb-w1/controls/28-0115a48fcfff 22.75
/devices/wb-w1/controls/28-0115a48fcfff 22.75

Пример сообщения от веб-интерфейса

Подпишемся на сообщения о состоянии встроенного реле Wiren Board:

root@wirenboard:~# mosquitto_sub -t '/devices/wb-gpio/controls/Relay_1/#' -v
/devices/wb-gpio/controls/Relay_1/meta/type switch
/devices/wb-gpio/controls/Relay_1/on 0
/devices/wb-gpio/controls/Relay_1 0

Тут стоит отметить, что MQTT сохраняет часть сообщений (а именно с флагом retained) вечно, поэтому после подписки вы получите даже те сообщения, которые были отправлен раньше, чем вы подписались.

Реле управляется драйвером wb-gpio (этот драйвер также управляет транзисторными выходами и всем, что в электрическом смысле управляется GPIO). У него есть соответствующий топик-"контрол" Relay_1. У него самого есть значение - 0 (реле выключено), и есть два подтопика. Один из них - служебный: в /meta/type записан тип "контрола". Здесь он switch - выключатель. Второй подтопик /on - интереснее: в него клиенты пишут то состояние, в которое они хотят установить реле. Заметим, что оно может не совпадать с тем состоянием, в котором реле находится, так как драйвер реле ведёт себя следующим образом: при получении сообщения в топик /devices/wb-gpio/controls/Relay_1/on он физически устанавливает его на реле, а лишь затем записывает новое значение реле в топик /devices/wb-gpio/controls/Relay_1.

Например, если мы сейчас нажмем на реле в веб-интерфейсе (переключим его состояние), то получим новые сообщения:

/devices/wb-gpio/controls/Relay_1/on 1
/devices/wb-gpio/controls/Relay_1 1

- веб-интерфейс сначала "даёт указание" включить реле, потом драйвер его включает и ставит актуальное состояние в "контрол".

Работа с очередью сообщений

Программа (демон), отвечающая за рассылку сообщений от одних клиентов другим, называется брокером сообщений. В Wiren Board используется брокер сообщений Mosquitto. Фактически, все драйверы и веб-интерфейс передают свои сообщения именно демону-брокеру Mosquitto.

Работа из командной строки

Управление устройствами из командной строки

Для управления устройством (изменения значения канала), необходимо отправить сообщение в топик "/devices/<device-id>/controls/<control-id>/on" (обратите внимание на /on в конце). Это делается с помощью консольной команды mosquitto_pub. Пример:

mosquitto_pub -t "/devices/wb-gpio/controls/Relay_1/on" -m "1"

команда включает реле 1 (канал "Relay_1" устройства "wb-gpio").

Слежение за состоянием устройства / подписка на топик

Клиенты, которые хотят следить за значением температуры, "подписываются" на этот топик, и им приходят все новые сообщения - меняющиеся значения температуры. Один из таких клиентов - веб-интерфейс.

Подписаться на сообщения можно и из консоли Linux при помощи утилиты mosquitto_sub (полное описание утилиты смотрите на http://mosquitto.org/man/mosquitto_sub-1.html):

root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/controls/28-0115a48fcfff' -v //получить сообщения из топика устройства 1-Wire с идентификатором 28-0115a48fcfff
/devices/wb-w1/controls/28-0115a48fcfff 22.75 //в этой строке и ниже - вывод утилиты, полученные сообщения
/devices/wb-w1/controls/28-0115a48fcfff 22.75
/devices/wb-w1/controls/28-0115a48fcfff 22.75

Подписаться можно не только на один топик, но и на группу по wildcard:

root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/#' -v
/devices/wb-w1/meta/name 1-wire Thermometers
/devices/wb-w1/controls/28-0115a48fcfff 22.812
/devices/wb-w1/controls/28-0115a48fcfff/meta/type temperature
/devices/wb-w1/controls/28-0115a48fcfff 22.75

, где # - означает любое количество вложенных топиков. Соответственно, вывелись не только значения с "контрола" устройства, но и топики с метаданными - название драйвера устройства и тип "контрола" - temperature.

Полное описание системы топиков и подписок http://mosquitto.org/man/mqtt-7.html.

Очистка очереди сообщений

Ненужные retained-сообщения могут остаться в системе MQTT после удаления неиспользуемых драйверов или отключения каких-либо устройств. Это приводит к тому, что несуществующие больше устройства могут отображаться в разделе Devices веб-интерфейса.

Для удаления топиков можно воспользоваться командой mqtt-delete-retained. Пример использования:

mqtt-delete-retained '/devices/noolite_tx_1234/#' 

- удалит все топики, начинающиеся на '/devices/noolite_tx_1234/'

Работа с очередью из внешних программ

Если вы разрабатываете собственное ПО для Wiren Board, взаимодействовать с его аппаратными ресурсами лучше всего через очередь сообщений - ваша программа передаёт сообщение в очередь, драйвер управляет устройством, и вашей программе не нужно напрямую взаимодействовать с устройством на низком уровне.

Для того, чтобы отправлять сообщения MQTT, для многих языков программирования есть библиотеки. Примеры: