MQTT/en

Материал из Wiren Board
Версия от 15:02, 10 июня 2019; RomanKulibaba (обсуждение | вклад) (Новая страница: «=== The example of subscription ===»)

MQTT - is a message queue used in the Wiren Board software. Basic information about MQTT on Wikipedia.

Drivers responsible for the hardware capabilities of the controller (digital inputs, ADC, transistor outputs, ...) and functions of external connected devices (for example, relay modules connected via RS-485) record their status in the MQTT queue as special messages. The web interface reads these messages and displays the status of the devices.

If a button is pressed in the web interface, the web interface sends a message to the MQTT queue, the device driver receives it and sends a command to the device.

1 Examples of work via the MQTT queue

Getting the value from the temperature sensor and displaying it in the web interface

Sensor readings and its unique identifier on the Devices page of the web interface

Assume that a 1-Wire/en bus temperature sensor is connected to the Wiren Board. Let's see how the sensor data comes into the web interface via the message queue:

  1. The driver that is responsible for this hardware function (wb-homa-w1) polls the 1-Wire sensors connected to the controller.
  2. When a value is received, the driver queues a message that resembles the following:
    /devices/wb-w1/controls/28-0115a48fcfff 23.25
    It means that the 1-Wire device (ID 28-0115a48fcfff)registers a value of 23.25°C.
  3. The web interface that receives all messages from the queue (it is subscribed to all messages) receives this message and displays the sensor value to the page.

Pressing a button in the web interface and switching the relay on the external module

Web interface after pressing relay 1 on the relay module MRM2 CONNECTED via RS-485

Suppose that the relay module WB-MRM2 is connected to the controller via the RS-485 bus. The user presses the relay button in the web interface and switches it on. Let's see how the command from the web interface gets to the external module:

/devices/wb-mrm2_130/controls/Relay 1/on 1

It means that the device WB-MRM2 with the address 130 must transfer Relay 1 to the state of the logical unit - "on".

  1. The wb-mqtt-serial driver responsible for this hardware function receives this message (it is subscribed to all messages related to RS-485 devices) and sends a command to turn on the first relay via the RS-485 bus to the relay module.
  2. The WB-MRM2 relay module receives a command from the controller, switches the relay and sends back a notification ("Relay 1 is on").
  3. The wb-mqtt-serial driver receives this notification over RS-485 and sends the message to the queue:
    /devices/wb-mrm2_130/controls/Relay 1 1
    It means that the first relay on the WB-MRM2 device with address 130 is in the logical 1 state (is "on").

The principle of operation of a message queue

Drivers of internal functions, external devices, web interface, rules system work via the MQTT message queue

The MQTT message system is based on the following principle:

  • there is a hierarchical system of "topics" (like on the Internet forums)
  • clients (in the case of Wiren Board - device drivers and web interface) can write messages and read from these topics
  • to monitor the changes of the desired topic (for example, temperature on the sensor), the client can "subscribe" to it - then it will receive all messages in this topic.

For a full description of topics and subscriptions, see http://mosquitto.org/man/mqtt-7.html.http://mosquitto.org/man/mqtt-7.html.

Displaying devices in the queue structure

The logic of the organization of topics corresponding to different devices and their parameters in the Wiren Board follows certain rules - the so-called agreements (Wiren Board MQTT Conventions).

Полный список MQTT-топиков можно увидеть на странице Settings веб-интерфейса в разделе MQTT Channels (появилось в последних версиях прошивки).

The full list of MQTT topics can be seen on the Settings page of the web interface in the MQTT Channels section (supported in the latest firmware versions).

Message queue clients

  • internal hardware function drivers
  • external connected device drivers
  • web interface
  • rules engine
  • (if any) user's own programs

The structure of the message device status

Here is an example message from the 1-Wire temperature sensor driver from the example above:

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

The part before the space is the name of the topic, then the message itself.

The name of the topic consists of nested "subtopics":

  • /devices - root topic for all "devices" - as built-in functions of Wiren Board (digital, ADC, ...) and connected external (e.g. relay modules)
  • /wb-w1 - subtopics, which is filled with 1-Wire driver
  • /controls - podtopit all devices in it are recorded all of their parameters are changed ("on / off", the value of the sensor ...)
  • /28-0115a48fcfff - directly the "channel" ("control)" - topic, where the value is recorded from the sensor. Its name is the same as the address of the 1-Wire sensor on the bus.

Message content:

  • 23.25 - temperature value

If you want to write a device driver yourself, and you want it to appear on the Devices tab and be able to use it in rules, you need to follow the same topic structure.

The example of subscription

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

Подписаться на сообщения можно и из консоли 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

Структура сообщения - команды на изменение состояния

Подпишемся на сообщения о состоянии первого реле подключённого по RS-485 релейного модуля WB-MRM2:

root@wirenboard:~# mosquitto_sub -t "/devices/wb-mrm2_130/controls/Relay 1/#" -v
/devices/wb-mrm2_130/controls/Relay 1/meta/type switch
/devices/wb-mrm2_130/controls/Relay 1/meta/order 1
/devices/wb-mrm2_130/controls/Relay 1 0

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

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

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

/devices/wb-mrm2_130/controls/Relay 1/on 1
/devices/wb-mrm2_130/controls/Relay 1 1

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

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

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

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

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

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

root@wirenboard:~# mosquitto_pub -t "/devices/wb-mrm2_130/controls/Relay 1/on" -m "1"

команда отправляет сообщение "1" (логическую единицу, "включить") в топик, соответствующий подключённому по RS-485 релейном модуле WM-MRM2 с адресом 130.

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

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

Подписаться на сообщения можно и из консоли 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

Метасимволы

Подписаться можно не только на один топик, но и на группу топиков по метасиволу. В MQTT применяется два метасимвола: # и +. Метасимвол # означает любое количество уровней вложенных топиков. Выполним команду

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. Существует так же метасимвол +, который обозначает один уровень, а не произвольное количество,как #:

mosquitto_sub -v -t "/config/widgets/+/name"

В этом случае мы получим имена всех виджетов.


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

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

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

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

root@wirenboard:~# mqtt-delete-retained '/devices/noolite_tx_1234/#'

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

Для удаления топиков "по маске", можно циклично вызывать runShellCommand из правил. Таким образом, задача сводится к задаче работы со строками в js.

var deviceName = ['name1',.., 'nameN'];
var controlName = 'Temperature';

for (var i = 0; i<deviceName.length; i++) {
  runShellCommand ('mqtt-delete-retained /devices/'+ deviceName[i]  + '/controls/controlName/#'); 
}

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

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

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


Просмотр MQTT-каналов в web-интерфейсе

MQTT-названия устройств, их элементов управления и последние значения можно найти в разделе Settings web-интерфейса:

Информация об MQTT-названиях устройств

Настройка MQTT моста (bridge)

Настройки брокера Cloud MQTT

MQTT мост (bridge) - это функция MQTT-брокера, позволяющая пересылать все или часть сообщений на другой MQTT-брокер, и получать сообщения с другого брокера обратно. На контроллере эта функция настраивается в конфигурационных файлах mosquitto. Самый простой вариант конфигурации приведён ниже.

Задача: настроить пересылку всех сообщений MQTT на популярный бесплатный облачный MQTT брокер http://cloudmqtt.com/ и обратно.

Решение:

  1. Зарегистрируйтесь на http://cloudmqtt.com/
  2. Зайдите в свой аккаунт на http://cloudmqtt.com/ и посмотрите настройки: сервер, порт, логин, пароль.
  3. Зайдите на контроллер и добавьте в конец файла /etc/mosquitto/mosquitto.conf следующие строки:
    connection cloudmqtt
    address m21.cloudmqtt.com:10858
    remote_username fs_user_kp
    remote_password 5dn_pass_pm
    clientid pavel_test
    try_private false
    start_type automatic
    topic # both
    
    (последняя строка говорит, что нужно пересылать все сообщения (метасимвол #, смотрите описание выше) в обе (both) стороны (с брокера контроллера на облачный брокер и обратно)
    Более подробное описание всех опций смотрите на https://mosquitto.org/man/mosquitto-conf-5.html.
  4. Перезапустите mosquitto, выполнив в консоли
    service mosquitto restart