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

Материал из Wiren Board
(Новая страница: «'''Solution:''' # Register on http://cloudmqtt.com/ # Go to your account on http://cloudmqtt.com/ to view settings: server, port, username, password. # Go to the…»)
(Обновление для соответствия новой версии исходной страницы.)
Строка 1: Строка 1:
<languages/>
== Описание ==
'''MQTT''' - is a message queue used in the [[Программное обеспечение Wiren Board/en|Wiren Board software]]. [http://en.wikipedia.org/wiki/MQTT Basic information about MQTT on Wikipedia].
'''MQTT''' — протокол обмена данными, использующийся в [[Программное обеспечение Wiren Board|программном обеспечении Wiren Board]]. [http://en.wikipedia.org/wiki/MQTT Базовая информация по MQTT на Википедии].


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.
Драйверы, которые отвечают за аппаратную часть контроллера (цифровые и транзисторные входы, АЦП и т.п.) и функции внешних подключенных устройств публикуют их состояние по MQTT в виде сообщений. Веб-интерфейс читает эти сообщения и на их основе отображает состояние устройств.


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.
Действия пользователя в веб-интерфейсе также публикуются по MQTT, где их получает драйвер и передает команду пользователя устройству.


== 1 Examples of work via the MQTT queue ==
Через MQTT работают: веб-интерфейс, движок правил и встроенные драйверы. Если вы разрабатываете собственное ПО в дополнение к предустановленному — мы рекомендуем использовать MQTT.
===Getting the value from the temperature sensor and displaying it in the web interface===
[[File:Web-devices-1-wire.png|400px|thumb|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:
#The driver that is responsible for this hardware function  ([https://github.com/contactless/wb-homa-drivers/tree/master/wb-homa-w1 wb-homa-w1]) polls the 1-Wire sensors connected to the controller.
#When a value is received, the driver queues a message that resembles the following: <pre>/devices/wb-w1/controls/28-0115a48fcfff 23.25</pre>It means that the 1-Wire  device (ID 28-0115a48fcfff)registers a value of 23.25°C.
#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===
[[File:Web-devices-serial.png|400px|thumb|Web interface after pressing relay 1 on the relay module [[WB-MRM2/en| MRM2]] CONNECTED via RS-485]]
Suppose that the relay module WB-MRM2 is connected to the controller via the [[RS-485/en| 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:
#After clicking the button, the web interface places the following message in the queue:<pre>/devices/wb-mrm2_130/controls/Relay 1/on 1</pre>It means that the device WB-MRM2 with the address ''130'' must transfer Relay 1 to the state of the logical 1 - "on".
#[[Драйвер wb-mqtt-serial/en|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.
#The WB-MRM2 relay module receives a command from the controller, switches the relay and sends back a notification ("Relay 1 is on").
#The wb-mqtt-serial driver receives this notification over RS-485 and sends the message to the queue:<pre>/devices/wb-mrm2_130/controls/Relay 1 1</pre>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 ==
== Примеры работы через MQTT ==
[[File:MQTT.png | thumb | 600px | 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:
[[File:Web-devices-1-wire.png|400px|thumb|Показания датчика и его уникальный идентификатор на странице ''Devices'' веб-интерфейса]]
*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 http://mosquitto.org/man/mqtt-7.html].


=== Displaying devices in the queue structure===
К [[Wiren Board]] подключён датчик температуры по шине [[1-Wire]]. Проследим, как данные с него через MQTT попадают в веб-интерфейс:
#Драйвер [https://github.com/wirenboard/wb-mqtt-w1 wb-mqtt-w1], отвечающий за данную аппаратную функцию, опрашивает подключенные к контролеру датчики 1-Wire.
#При получении значения драйвер публикует MQTT сообщение вида: <pre>/devices/wb-w1/controls/28-0115a48fcfff 23.25</pre>Оно значит, что от устройства 1-Wire с идентификатором ''28-0115a48fcfff'' получено значение 23.25 °C.
#Веб-интерфейс, который подписан на все сообщения из MQTT, получает это сообщение и выводит значение датчика на страницу.
===Нажатие кнопки в веб-интерфейсе и переключение реле на внешнем модуле===
[[File:Web-devices-serial.png|400px|thumb|Веб-интерфейс после нажатия кнопки включения Реле 1 на подключённом по RS-485 релейном модуле [[WB-MRM2]]]]
К контроллеру по шине [[RS-485]] подключён релейный модуль [[WB-MRM2]]. Пользователь в веб-интерфейсе нажимает кнопку включения реле. Проследим, как команда из веб-интерфейса попадает на внешний модуль:
#После нажатия кнопки веб-интерфейс публикует по MQTT сообщение вида: <pre>/devices/wb-mrm2_130/controls/Relay 1/on 1</pre>Оно значит, что устройство WB-MRM2 с адресом ''130'' должно перевести ''Реле 1'' в состояние логической единицы — «включено».
#[[Драйвер wb-mqtt-serial]], отвечающий за данную аппаратную функцию, получает это сообщение (он ''подписан'' на все сообщения, относящиеся к подключённым по RS-485 устройствам) и посылает по шине RS-485 релейному модулю команду на включение первого реле.
#Релейный модуль WB-MRM2 получает команду от контроллера, переключает реле и посылает обратно уведомление «Реле 1 включено».
#Драйвер wb-mqtt-serial получает это уведомление по RS-485 и публикует по MQTT сообщение:<pre>/devices/wb-mrm2_130/controls/Relay 1 1</pre>Оно значит, что первое реле на устройстве WB-MRM2 с адресом ''130'' находится (уже переведено) в состоянии логической единицы — «включено».


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 ([https://github.com/contactless/homeui/blob/master/conventions.md Wiren Board MQTT Conventions]).
== Принцип работы MQTT ==
[[File:DebianLinux.png | thumb | 600px | Через MQTT работают драйверы внутренних функций, внешних устройств, веб-интерфейс, система правил]]
Система сообщений MQTT построена по следующему принципу:
*есть иерархическая система «топиков» (как на обычных форумах в интернете).
*в эти топики клиенты (в случае Wiren Board это драйверы устройств и веб-интерфейс) могут писать сообщения и читать оттуда.
*чтобы следить за изменениями нужного топика (например, температуры на датчике), клиент может на него «подписаться» — тогда он получит все сообщения в этом топике.
[http://mosquitto.org/man/mqtt-7.html Читать полное описание системы топиков и подписок].
 
=== Отображение устройств в структуре сообщений ===
 
Логика организации топиков, соответствующих разным устройствам и их параметрам, в Wiren Board следует определённым правилам — так называемым соглашениям ([https://github.com/wirenboard/conventions/blob/main/README.md Wiren Board MQTT Conventions]).


Полный список MQTT-топиков можно увидеть на странице ''Settings'' веб-интерфейса в разделе ''MQTT Channels'' (появилось в последних версиях [[Обновление прошивки|прошивки]]).
Полный список 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 [[Обновление прошивки/en|latest]] firmware versions).
=== Клиенты MQTT ===
*драйверы внутренних аппаратных функций,
*драйверы внешних подключённых устройств,
*веб-интерфейс,
*движок правил,
*(если есть) собственные программы пользователя.


===Message queue clients===
=== Структура сообщения о состоянии устройства ===
*internal hardware function drivers
Вот сообщение от драйвера температурного датчика 1-Wire из примера выше:
*external connected device drivers
<pre>
*web interface
/devices/wb-w1/controls/28-0115a48fcfff 23.25
*rules engine
</pre>
*(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:
* <code>/devices</code> — коренной топик для всех «устройств» — как встроенных функций Wiren Board (цифровые, АЦП, ...), так и подключённых внешних (например, модулей реле).
* <code>/wb-w1</code> — подтопик, который наполняется драйвером 1-Wire.
* <code>/controls</code> — подтопик, который есть у всех устройств — именно в него записываются все их параметры, которые меняются («включено-выключено», значение датчика, ...).
* <code>/28-0115a48fcfff</code> — непосредственно сам «канал» («контрол») — топик, куда записывается значение с датчика. Его название совпадает с адресом 1-Wire датчика на шине.
Содержание сообщения:
* <code>23.25</code> — значение температуры
 
Если вы хотите самостоятельно написать драйвер устройства, и хотите, что оно отображалось на вкладке '''Devices''' и его можно было использовать в правилах, вам необходимо придерживаться такой же структуры топиков.
 
=== Структура сообщения об ошибке опроса устройства ===
Каждый «канал» («контрол») имеет «подтопик» <code>/meta/error</code>, в котором содержится информация о наличии ошибок взаимодействия с устройством. Ошибки получения данных (чтения) обозначаются символом '''r''', ошибки записи — '''w'''.
 
Пример ошибки получения данных:
<pre>
<pre>
/devices/wb-w1/controls/28-0115a48fcfff 23.25
/devices/wb-w1/controls/28-0115a48fcfff/meta/error r
</pre>
</pre>
The part before the space is the name of the topic, then the message itself.


The name of the topic consists of nested "subtopics":
Это означает, что не удалось получить температуру термометра с адресом ''28-0115a48fcfff''.
*''/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
[[Драйвер wb-mqtt-serial]] устанавливает признак '''r''', если не удалось запросить значение параметра устройства, признак '''w''' — не удалось передать значение устройству.


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.
[https://github.com/wirenboard/wb-homa-adc Драйвер wb-mqtt-adc] устанавливает признак '''r''', если не удалось получить значение соотвествующего канала АЦП.


=== The example of subscription ===
=== Пример подписки ===  


Clients which need to monitor the temperature value, "subscribe" to this topic, and they receive new messages - changing temperature values. One such client is the web interface.
Клиенты, которые хотят следить за значением температуры, «подписываются» на этот топик, и им приходят все новые сообщения — меняющиеся значения температуры. Один из таких клиентов — веб-интерфейс.


You can also subscribe to messages from the Linux console using the '''mosquitto_sub''' utility (see below for a complete description of Queuing from the command line):
Подписаться на сообщения можно и из консоли Linux при помощи утилиты <code>mosquitto_sub</code>:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/controls/28-0115a48fcfff' -v // receive messages from a topic of the 1-Wire device with ID: 28-0115a48fcfff
~# mosquitto_sub -t '/devices/wb-w1/controls/28-0115a48fcfff' -v //получить сообщения из топика устройства 1-Wire с идентификатором 28-0115a48fcfff
/devices/wb-w1/controls/28-0115a48fcfff 22.75 //in this line and below is the output of the utility received messages
/devices/wb-w1/controls/28-0115a48fcfff 22.75 //в этой строке и ниже - вывод утилиты, полученные сообщения
/devices/wb-w1/controls/28-0115a48fcfff 22.75
/devices/wb-w1/controls/28-0115a48fcfff 22.75
/devices/wb-w1/controls/28-0115a48fcfff 22.75
/devices/wb-w1/controls/28-0115a48fcfff 22.75
</syntaxhighlight>
</syntaxhighlight>


=== Message structure commands to change the state of the devices ===
Полное описание работы с MQTT из командной строки смотрите ниже.


Let's subscribe to the status messages of the first relay connected via RS-485 of the WB-MRM2 relay module:
=== Структура сообщения — команды на изменение состояния ===
 
Подпишемся на сообщения о состоянии первого реле подключённого по RS-485 релейного модуля WB-MRM2:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
root@wirenboard:~# mosquitto_sub -t "/devices/wb-mrm2_130/controls/Relay 1/#" -v
~# 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/type switch
/devices/wb-mrm2_130/controls/Relay 1/meta/order 1
/devices/wb-mrm2_130/controls/Relay 1/meta/order 1
/devices/wb-mrm2_130/controls/Relay 1 0
/devices/wb-mrm2_130/controls/Relay 1 0
</syntaxhighlight>
</syntaxhighlight>
Note that MQTT keeps part of the messages (namely those that were marked with the flag retained when sending) forever, so after subscribing you will receive even those messages that were sent before you subscribed.
Тут стоит отметить, что MQTT сохраняет часть сообщений (а именно те, которые при отправке были помечены флагом ''retained'') вечно, поэтому после подписки вы получите даже те сообщения, которые были отправлены раньше, чем вы подписались.


The relay module is controlled by the wb-mqtt-serial driver driver, which has a corresponding topic-"channel"("control") Relay 1. It has a value - 0 (relay off), and there are two subtopics. One of them is service: the type of "control" is written  in the folder /meta/type. Here it is a switch - circuit-breaker. The second subtopic ''/on'' is more interesting: here clients write the state in which they want to set the relay. Note that it may not coincide for some time (spent on the switching process) with the state in which the relay is located. The driver behaves as follows: when receiving a message in the topic ''/devices/wb-mrm2_130/controls/Relay 1/on'', it physically turns on the relay module, and only then writes the new state of the relay to the topic ''/devices/wb-mrm2_130/controls/Relay.''
Релейный модуль управляется драйвером [[Драйвер wb-mqtt-serial]]. У него есть соответствующий топик-«канал» («контрол») ''Relay 1''. У него самого есть значение — ''0'' (реле выключено), и есть два подтопика. Один из них — служебный: в <code>/meta/type</code> записан тип «контрола». Здесь он ''switch'' — выключатель. Второй подтопик ''/on'' — интереснее: в него клиенты пишут то состояние, в которое они хотят установить реле. Заметим, что оно может не совпадать некоторое время (затрачиваемое на процесс переключения) с тем состоянием, в котором реле находится. Драйвер при этом ведёт себя следующим образом: при получении сообщения в топик <code>/devices/wb-mrm2_130/controls/Relay 1/on</code> он физически включает реле на релейном модуле, а лишь затем записывает новое состояние реле в топик <code>/devices/wb-mrm2_130/controls/Relay</code>.


For example, if we now click on the relay button in the web interface (switch its state), we will receive new messages:
Например, если мы сейчас нажмём на кнопку реле в веб-интерфейсе (переключим его состояние), то получим новые сообщения:
<pre>
<pre>
/devices/wb-mrm2_130/controls/Relay 1/on 1
/devices/wb-mrm2_130/controls/Relay 1/on 1
/devices/wb-mrm2_130/controls/Relay 1 1
/devices/wb-mrm2_130/controls/Relay 1 1
</pre>
</pre>
- the web interface first "instructs" to turn on the relay, then the driver turns it on and records the current state in the "channel"("control").
- веб-интерфейс сначала «даёт указание» включить реле, потом драйвер его включает и записывает актуальное состояние в «канал» («контрол»).
 
==Working with message queue==
The program (daemon) responsible for sending messages from one client to another is called a message broker. Wiren Board uses  [http://mosquitto.org/ Mosquitto] message broker. In fact, all drivers and the web interface transmit their messages to this daemon broker
===Working via the command line===


==== Managing devices from the command line====
==Локальная работа с сообщениями MQTT==
Программа (демон), отвечающая за рассылку сообщений от одних клиентов другим, называется брокером сообщений. В Wiren Board используется брокер сообщений [http://mosquitto.org/ Mosquitto]. Фактически, все драйверы и веб-интерфейс передают свои сообщения именно демону-брокеру Mosquitto.
===Работа из командной строки===


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


To control the device (change the channel value), you need to send a message to the topic 
Для управления устройством (изменения значения канала), необходимо отправить сообщение в топик <code>/devices/<device-id>/controls/<control-id>/on</code> (обратите внимание на /on в конце).
"/devices/<device-id>/controls/<control-id>/on" This is done using the '''mosquitto_pub''' console command. Example:
Это делается с помощью консольной команды '''mosquitto_pub'''. Пример:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
root@wirenboard:~# mosquitto_pub -t "/devices/wb-mrm2_130/controls/Relay 1/on" -m "1"
~# mosquitto_pub -t "/devices/wb-mrm2_130/controls/Relay 1/on" -m "1"
</syntaxhighlight>
</syntaxhighlight>
the command sends the message "1" (logical unit, "turn on") to the topic corresponding to the connected via RS-485 relay module WM-MRM2 with the address '''130'''.
команда отправляет сообщение «1» (логическую единицу, «включить») в топик, соответствующий подключённому по RS-485 релейном модуле WM-MRM2 с адресом 130.


==== Tracking the status of the device / subscribe to topic ====
==== Слежение за состоянием устройства / подписка на топик ====  


Customers who want to monitor the temperature value, "subscribe" to this topic, and they receive new messages - changing temperature values. One such client is the web interface.
Клиенты, которые хотят следить за значением температуры, «подписываются» на этот топик, и им приходят все новые сообщения - меняющиеся значения температуры. Один из таких клиентов - веб-интерфейс.


You can also subscribe to messages from the Linux console using the mosquitto_sub utility (for a full description of the utility, see [http://mosquitto.org/man/mosquitto_sub-1.html The article]):
Подписаться на сообщения можно и из консоли Linux при помощи утилиты '''mosquitto_sub''' (полное описание утилиты смотрите на [http://mosquitto.org/man/mosquitto_sub-1.html http://mosquitto.org/man/mosquitto_sub-1.html]):
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/controls/28-0115a48fcfff' -v //receive messages from a topic of the  1-Wire device with ID: 28-0115a48fcfff
~# mosquitto_sub -t '/devices/wb-w1/controls/28-0115a48fcfff' -v //получить сообщения из топика устройства 1-Wire с идентификатором 28-0115a48fcfff
/devices/wb-w1/controls/28-0115a48fcfff 22.75 //in this line and below is the output of the utility received messages
/devices/wb-w1/controls/28-0115a48fcfff 22.75 //в этой строке и ниже — вывод утилиты, полученные сообщения
/devices/wb-w1/controls/28-0115a48fcfff 22.75
/devices/wb-w1/controls/28-0115a48fcfff 22.75
/devices/wb-w1/controls/28-0115a48fcfff 22.75
/devices/wb-w1/controls/28-0115a48fcfff 22.75
</syntaxhighlight>
</syntaxhighlight>
===Metacharacters===
===Метасимволы===  


You can subscribe not just for one topic, but for a group of topics by metasymbol. In MQTT we use two special characters: '''#''' and '''+'''. The special character '''#''' means any number of levels of nested topics. Execute the command
Подписаться можно не только на один топик, но и на группу топиков по метасиволу. В MQTT применяется два метасимвола: '''#''' и '''+'''. Метасимвол ''#'' означает любое количество уровней вложенных топиков. Выполним команду
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/#' -v
~# 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-0115a48fcfff 22.812
/devices/wb-w1/controls/28-0115a48fcfff 22.812
Строка 129: Строка 144:
/devices/wb-w1/controls/28-0115a48fcfff 22.75
/devices/wb-w1/controls/28-0115a48fcfff 22.75
</syntaxhighlight>
</syntaxhighlight>
As a result, we got not only the values from the ''control'' device, but also topics with metadata - the name of the device driver and the type of "control" - temperature. There is also a metacharacter '''+''', which denotes one level, not an arbitrary number,as '''#''':
В результате мы получили не только значения с «контрола» устройства, но и топики с метаданными — название драйвера устройства и тип «контрола» - ''temperature''.
Существует так же метасимвол '''+''', который обозначает один уровень, а не произвольное количество,как '''#''':
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
mosquitto_sub -v -t "/config/widgets/+/name"  
mosquitto_sub -v -t "/config/widgets/+/name"  
</syntaxhighlight>
</syntaxhighlight>
In this case we will get the names of all widgets.
В этом случае мы получим имена всех виджетов.


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


Full description of topics and subscriptions:[http://mosquitto.org/man/mqtt-7.html http://mosquitto.org/man/mqtt-7.html].
=== Очистка очереди сообщений ===


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


Unnecessary retained messages may remain in the MQTT system after unused drivers are removed or any devices are disconnected. This causes nonexistent devices to appear in the ''Devices'' section of the web interface.
Для удаления топиков можно воспользоваться командой <code>mqtt-delete-retained</code>.  


To delete topics, you can use the command ''mqtt-delete-retained''. Example of use:
Например, удалим все топики, начинающиеся на <code>/devices/noolite_tx_1234/</code>
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
root@wirenboard:~# mqtt-delete-retained '/devices/noolite_tx_1234/#'  
~# mqtt-delete-retained '/devices/noolite_tx_1234/#'  
</syntaxhighlight>
</syntaxhighlight>
- removes all topics starting with '/devices/noolite_tx_1234/'


To remove the topics by the "mask", it is possible to call runShellCommand of the rules cyclically. Thus, the task is reduced to the task of working with strings in js.
Для удаления топиков «по маске», можно циклично вызывать <code>runShellCommand</code> из правил. Таким образом, задача сводится к задаче работы со строками в js.
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
var deviceName = ['name1',.., 'nameN'];
var deviceName = ['name1',.., 'nameN'];
Строка 158: Строка 175:
</syntaxhighlight>
</syntaxhighlight>


=== Working with queue from external programs ===
=== Работа с MQTT из внешних программ ===


If you are developing your own SOFTWARE for the Wiren Board, it is best to communicate with its hardware resources through a message queue - your program sends a message to the queue, the driver controls the device, and your program does not need to communicate directly with the device at a low level.
Если вы разрабатываете собственное ПО для Wiren Board, взаимодействовать с его аппаратными ресурсами лучше всего через протокол MQTT — ваша программа передаёт сообщение по MQTT, драйвер управляет устройством и вашей программе не нужно напрямую взаимодействовать с устройством на низком уровне.


In order to send MQTT messages, there are libraries for many programming languages. Examples:
Для того, чтобы отправлять сообщения MQTT, для многих языков программирования есть библиотеки:
* Python - [https://github.com/contactless/mqtt-tools]
* Python - [https://github.com/contactless/mqtt-tools]
* C - [http://mosquitto.org/man/libmosquitto-3.html]
* C - [http://mosquitto.org/man/libmosquitto-3.html]




=== Viewing MQTT channels in the web interface ===
=== Просмотр MQTT-каналов в web-интерфейсе ===
MQTT-names of devices, their controls and the latest values can be found in the Settings section of the web interface:
MQTT-названия устройств, их элементов управления и последние значения можно найти в разделе '''Settings''' web-интерфейса:
[[Файл:Wb_settings.png|900px|thumb|center|Information about MQTT-the names of the devices]]
[[Файл:Wb_settings.png|900px|thumb|center|Информация об MQTT-названиях устройств]]
 
==Работа с сообщениями MQTT с внешнего устройства==
 
Установленный на контроллер брокер mosquitto по умолчанию принимает подключения внешних клиентов по порту 1883 без пароля.
 
Например, если контроллер имеет адрес 192.168.0.67, его топики можно прочитать с другого компьютера с Linux, находящегося в той же сети:
<syntaxhighlight lang="bash">
mosquitto_sub -h 192.168.0.67 -p 1883 -v -t "/devices/power_status/controls/Vin" -i Test_Client
</syntaxhighlight>
 
Альтернативный вариант — использовать [[MQTT Explorer]].
 
=== Настройка MQTT моста (bridge) ===
[[File:CloudMQTT.png | thumb | 400px | Настройки брокера Cloud MQTT]]
MQTT мост (bridge) — это функция MQTT-брокера, позволяющая пересылать все или часть сообщений на другой MQTT-брокер, и получать сообщения с другого брокера обратно.


=== Setting up the MQTT bridge ===
Эту функцию удобно применять в следующей ситуации: хотя на самом контроллере уже есть MQTT-брокер, к нему часто неудобно подключаться, так как контроллер может не иметь белого IP-адреса, а иногда может быть выключен или не в сети. В таком случае удобно иметь отдельный брокер в облаке с фиксированным адресом, который будет всегда онлайн, и на который будут пересылаться сообщения с брокера контроллера.
[[File:CloudMQTT.png | thumb | 400px | Settings of the MQTT Cloud broker]]
MQTT bridge is a feature of the MQTT broker that allows you to forward all or part of messages to another MQTT broker and receive messages from another broker back. On the controller, this feature is configured in the mosquitto configuration files. The simplest configuration option is shown below.


'''Task''': set up forwarding of all MQTT messages to the popular free cloud MQTT broker http://cloudmqtt.com/ and back.
На контроллере эта функция настраивается в конфигурационных файлах ''mosquitto''. Самый простой вариант конфигурации приведён ниже.


'''Solution:'''
==== Настройка моста с MQTT брокером Cloudmqtt ====
# Register on http://cloudmqtt.com/
'''Задача:''' настроить пересылку всех сообщений MQTT на популярный дешёвый облачный MQTT брокер http://cloudmqtt.com/ и обратно.
# Go to your account on http://cloudmqtt.com/ to view settings: server, port, username, password.
 
# Go to the controller and add the following lines to the end of the  ''/etc/mosquitto/mosquitto.conf'' file :
'''Решение:'''
# Зарегистрируйтесь на http://cloudmqtt.com/
# Зайдите в свой аккаунт на http://cloudmqtt.com/ и посмотрите настройки: сервер, порт, логин, пароль.
# Зайдите на контроллер и добавьте в конец файла <code>/etc/mosquitto/mosquitto.conf</code> следующие строки:
#: <syntaxhighlight lang="bash">
#: <syntaxhighlight lang="bash">
connection cloudmqtt
connection cloudmqtt
Строка 191: Строка 224:
topic # both
topic # both
</syntaxhighlight>
</syntaxhighlight>
#:(the last line says that you want to forward all messages ('''#''' metasymbol, see description above) in either ('''both''') side (broker cloud controller to the broker and back)
#: (последняя строка говорит, что нужно пересылать все сообщения (метасимвол '''#''', смотрите описание выше) в обе ('''both''') стороны (с брокера контроллера на облачный брокер и обратно)
#:For a more detailed description of all options, see  https://mosquitto.org/man/mosquitto-conf-5.html.
#: Более подробное описание всех опций смотрите на https://mosquitto.org/man/mosquitto-conf-5.html.
# Restart mosquitto by running the following in console
# Перезапустите <code>mosquitto</code>, выполнив в консоли:
#: <syntaxhighlight lang="bash">
#: <syntaxhighlight lang="bash">
service mosquitto restart
service mosquitto restart
</syntaxhighlight>
</syntaxhighlight>
[[File:Clusterfly3.png | thumb | 400px | Настройки брокера CLUSTERFLY]]
==== Настройка моста с MQTT брокером Clusterfly ====
'''Задача:''' настроить пересылку всех сообщений MQTT на бесплатный облачный MQTT брокер https://clusterfly.ru/ и обратно.
'''Решение:'''
# Зарегистрируйтесь на https://clusterfly.ru/
# Зайдите в свой аккаунт на https://clusterfly.ru/ и выберите "Профиль" посмотрите настройки: сервер, порт, логин и сгенерируйте пароль. Для пересылки используйте сервер <code>srv1.clusterfly.ru</code>.
# Зайдите на контроллер и добавьте в конец файла <code>/etc/mosquitto/mosquitto.conf</code> следующие строки:
#: <syntaxhighlight lang="bash">
connection clusterfly
address srv1.clusterfly.ru:9124
remote_username user_xxxxxx
remote_password pass_xxxxxx
try_private false
notifications true
notification_topic /client/wb_6/bridge_status
start_type automatic
topic /# both 0 "" user_xxxxxx
bridge_insecure true
cleansession false
</syntaxhighlight>
#:строка <code>'topic /#  both 0 "" user_xxxxxx'</code> говорит, что нужно пересылать все сообщения (метасимвол '''#''', смотрите описание выше) в обе ('''both''') стороны (с брокера контроллера на облачный брокер и обратно) c префиксом ('''user_xxxxxx'''). Пример обращения к топику: <code>user_xxxxxx/devices/wb-mr6c_200/controls/K2</code>.
# Перезапустите <code>mosquitto</code>, выполнив в консоли:
#: <syntaxhighlight lang="bash">
service mosquitto restart
</syntaxhighlight>
#: Потребуется подождать некоторое время пока брокер <code>mosquitto</code> сможет организовать соединение. Подписавшись на контроллере к топику <code>/client/wb_6/bridge_status</code> можно увидеть статус соединения.
#:<syntaxhighlight lang="bash">
mosquitto_sub -v -t "/client/wb_6/bridge_status"
/client/wb_6/bridge_status 0
/client/wb_6/bridge_status 1
</syntaxhighlight>
==== Другие облачные брокеры ====
Список облачных брокеров, в том числе бесплатных: [https://github.com/mqtt/mqtt.github.io/wiki/public_brokers https://github.com/mqtt/mqtt.github.io/wiki/public_brokers]
'''Задача:''' настроить пересылку топика MQTT на другой контроллер.
Есть два контроллера в одной сети:
# ''DestinationController'' с адресом <code>10.0.0.40</code>, на этот контроллер получать топик.
# ''SourceController'' с адресом <code>10.0.0.70</code>, с этого контроллера будем забирать топик.
На  ''SourceController'' есть <code>/client/temp1</code>, но его нужно видеть на ''DestinationController'' в <code>/devices/temp1</code>.
Решается двумя способами, можно с ''SourceController'' публиковать на ''DestinationController'' или с ''DestinationController'' подписаться на топик ''SourceController'' и забирать изменения. От выбора стратегии зависит на каком контроллере будем проводить настройки.
Мы будем настраивать ''DestinationController''.
'''Решение:''' На контроллере ''DestinationController'' добавьте в конфиг:
<syntaxhighlight lang="bash">
mcedit /etc/mosquitto/conf.d/bridge.conf
</syntaxhighlight>
Строки:
<syntaxhighlight lang="bash">
connection wb_40
address 10.0.0.70
notifications true
notification_topic /client/wb_40/bridge_status
keepalive_interval 20
restart_timeout 20
topic /temp1/# in 2 /devices /client
</syntaxhighlight>
Перезапустите <code>mosquitto</code> на ''DestinationController'':
<syntaxhighlight lang="bash">
systemctl restart mosquitto; systemctl status mosquitto
</syntaxhighlight>
'''ВАЖНО:''' перед перезапуском желательно [[watchdog |остановить watchdog]]. В случае ошибки в конфигурационных файлах брокер не запустится и watchdog вызовет перезапуск контроллера.
Рассмотрим подробнее строчку <code>topic /temp1/# in 2 /devices /client</code>
где:
* <code>/temp1/#</code> это топик от «корня». На брокере-источнике /client/'''temp1'''.
* <code>in</code> — только забираем, изменения на контроллере не передадутся на сервер.
* <code>/devices</code> — «корень» '''куда''' располагаем локально (на контроллере на котором '''настраиваем'''). На контроллере ''DestinationController'' это <code>/devices</code> и полный путь будет выгляджеть как '''/devices'''/temp1.
* <code>/client</code> — «корень» откуда забираем на удаленном. На контроллере ''SourceController'' это <code>/client</code> и полный путь будет выгляджеть как '''/client'''/temp1.
'''Проверка:'''
Дожидаемся статуса бриджа «1» в топике <code>/client/wb_40/bridge_status</code> на контроллере ''SourceController''.
На нем же публикуем:
<syntaxhighlight lang="bash">
for i in {1..25}
do
mosquitto_pub  -t "/client/temp1/temp" -m "$i" -r
done
</syntaxhighlight>
Подписавшись на контроллере ''DestinationController'' на целевой топик можно видеть:
<syntaxhighlight lang="bash">
mosquitto_sub -v -t /devices/temp1/#
/devices/temp1/temp
/devices/temp1/temp 1
/devices/temp1/temp 2
/devices/temp1/temp 3
/devices/temp1/temp 4
/devices/temp1/temp 5
/devices/temp1/temp 6
/devices/temp1/temp 7
/devices/temp1/temp 8
/devices/temp1/temp 9
/devices/temp1/temp 10
/devices/temp1/temp 11
/devices/temp1/temp 12
/devices/temp1/temp 13
/devices/temp1/temp 14
/devices/temp1/temp 15
/devices/temp1/temp 16
/devices/temp1/temp 17
/devices/temp1/temp 18
/devices/temp1/temp 19
/devices/temp1/temp 20
/devices/temp1/temp 21
/devices/temp1/temp 22
/devices/temp1/temp 23
/devices/temp1/temp 24
/devices/temp1/temp 25
</syntaxhighlight>
== Создание своего брокера MQTT ==
Вы можете создать отдельный брокер на компьютере или на VDS-сервере в интернете и собирать на нем данные с контроллеров.
Инициировать соединение будет контроллер, поэтому контроллеру не нужен «белый» IP-адрес. Если контроллеров несколько, вы можете разделить данные от них на брокере, для этого в настройках моста укажите для каждого контроллера отдельный корневой топик.
=== Установка брокера ===
#Установите <code>mosquitto</code>:
#:<syntaxhighlight lang="bash">
sudo apt update && sudo apt install mosquitto mosquitto-clients -y
</syntaxhighlight>
#Отключите возможность анонимного входа, для этого:
#*Откройте файл конфигурации в редакторе
#:<syntaxhighlight lang="bash">
sudo nano /etc/mosquitto/mosquitto.conf
</syntaxhighlight>
#*Добавьте в конец файла строки:
#:<syntaxhighlight lang="bash">
#Turn on port listening
listener 1883
#Disable anonomous login:
allow_anonymous false
#Password file:
password_file /etc/mosquitto/mosquitto.pwd
</syntaxhighlight>
#Создайте пароль для пользователя, в примере использован пользователь <code>test</code> с паролем <code>wbpassword</code>:
#:<syntaxhighlight lang="bash">
sudo mosquitto_passwd -c /etc/mosquitto/mosquitto.pwd test
</syntaxhighlight>
#Введите пароль дважды и запомните его, он вам пригодится ниже.
#Перезапустите <code>mosquitto</code> и проверьте его состояние:
#:<syntaxhighlight lang="bash">
sudo systemctl restart mosquitto && sudo systemctl status mosquitto
</syntaxhighlight>
#Подключитесь к брокеру для проверки, в примере адрес брокера <code>127.0.0.1</code>:
#:<syntaxhighlight lang="bash">
mosquitto_sub -v -h 127.0.0.1 -u test -P wbpassword -t "/#"
</syntaxhighlight>
#Запустите в другой консоли команду ниже и убедитесь, что топик меняется:
#:<syntaxhighlight lang="bash">
for i in {1..25}; do mosquitto_pub -h 127.0.0.1 -u test -P wbpassword -t "/client/temp1/temp" -m "$i" -r; done
</syntaxhighlight>
Брокер установлен и доступен с контроллера. Для подключения нужно ввести логин и пароль.
=== Настройка моста на контроллере ===
Создайте файл конфигурации моста, для этого:
# Создайте файл <code>/etc/mosquitto/conf.d/bridge1.conf</code>
#:<syntaxhighlight lang="bash">
nano /etc/mosquitto/conf.d/bridge1.conf
</syntaxhighlight>
# Вставьте в него строки, где <code>10.0.0.105</code> — адрес брокера:
#:<syntaxhighlight lang="bash">
connection bridge1
#address of server
address 10.0.0.105
notifications true
notification_topic /clientnotification/bridge1_status
remote_username test
remote_password wbpassword
topic /temp1/# both 2 /devices /controller
</syntaxhighlight>
Содержимое топика <code>/devices/temp1/#</code> контроллера будет отображаться на брокере в <code>/controller</code>. Вместо <code>/controller</code> можете указать уникальное имя контроллера, например, серийный номер.

Версия 18:02, 2 мая 2022

Описание

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

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

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

Через MQTT работают: веб-интерфейс, движок правил и встроенные драйверы. Если вы разрабатываете собственное ПО в дополнение к предустановленному — мы рекомендуем использовать MQTT.

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

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

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

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

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

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

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

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

  1. После нажатия кнопки веб-интерфейс публикует по MQTT сообщение вида:
    /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 и публикует по MQTT сообщение:
    /devices/wb-mrm2_130/controls/Relay 1 1
    Оно значит, что первое реле на устройстве WB-MRM2 с адресом 130 находится (уже переведено) в состоянии логической единицы — «включено».

Принцип работы MQTT

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

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

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

Читать полное описание системы топиков и подписок.

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

Логика организации топиков, соответствующих разным устройствам и их параметрам, в Wiren Board следует определённым правилам — так называемым соглашениям (Wiren Board MQTT Conventions).

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

Клиенты MQTT

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

Структура сообщения о состоянии устройства

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

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

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

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

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

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

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

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

Структура сообщения об ошибке опроса устройства

Каждый «канал» («контрол») имеет «подтопик» /meta/error, в котором содержится информация о наличии ошибок взаимодействия с устройством. Ошибки получения данных (чтения) обозначаются символом r, ошибки записи — w.

Пример ошибки получения данных:

/devices/wb-w1/controls/28-0115a48fcfff/meta/error r

Это означает, что не удалось получить температуру термометра с адресом 28-0115a48fcfff.

Драйвер wb-mqtt-serial устанавливает признак r, если не удалось запросить значение параметра устройства, признак w — не удалось передать значение устройству.

Драйвер wb-mqtt-adc устанавливает признак r, если не удалось получить значение соотвествующего канала АЦП.

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

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

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

~# 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 из командной строки смотрите ниже.

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

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

~# 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

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

Локальная работа с сообщениями MQTT

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

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

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

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

~# 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):

~# 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 применяется два метасимвола: # и +. Метасимвол # означает любое количество уровней вложенных топиков. Выполним команду

~# 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"

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

Полное описание системы топиков и подписок.

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

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

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

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

~# mqtt-delete-retained '/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/#'); 
}

Работа с MQTT из внешних программ

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

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


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

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

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

Работа с сообщениями MQTT с внешнего устройства

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

Например, если контроллер имеет адрес 192.168.0.67, его топики можно прочитать с другого компьютера с Linux, находящегося в той же сети:

mosquitto_sub -h 192.168.0.67 -p 1883 -v -t "/devices/power_status/controls/Vin" -i Test_Client

Альтернативный вариант — использовать MQTT Explorer.

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

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

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

Эту функцию удобно применять в следующей ситуации: хотя на самом контроллере уже есть MQTT-брокер, к нему часто неудобно подключаться, так как контроллер может не иметь белого IP-адреса, а иногда может быть выключен или не в сети. В таком случае удобно иметь отдельный брокер в облаке с фиксированным адресом, который будет всегда онлайн, и на который будут пересылаться сообщения с брокера контроллера.

На контроллере эта функция настраивается в конфигурационных файлах mosquitto. Самый простой вариант конфигурации приведён ниже.

Настройка моста с MQTT брокером Cloudmqtt

Задача: настроить пересылку всех сообщений 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
    
Настройки брокера CLUSTERFLY

Настройка моста с MQTT брокером Clusterfly

Задача: настроить пересылку всех сообщений MQTT на бесплатный облачный MQTT брокер https://clusterfly.ru/ и обратно.

Решение:

  1. Зарегистрируйтесь на https://clusterfly.ru/
  2. Зайдите в свой аккаунт на https://clusterfly.ru/ и выберите "Профиль" посмотрите настройки: сервер, порт, логин и сгенерируйте пароль. Для пересылки используйте сервер srv1.clusterfly.ru.
  3. Зайдите на контроллер и добавьте в конец файла /etc/mosquitto/mosquitto.conf следующие строки:
    connection clusterfly
    address srv1.clusterfly.ru:9124
    remote_username user_xxxxxx
    remote_password pass_xxxxxx
    try_private false
    notifications true
    notification_topic /client/wb_6/bridge_status
    start_type automatic
    topic /# both 0 "" user_xxxxxx
    bridge_insecure true
    cleansession false
    
    строка 'topic /# both 0 "" user_xxxxxx' говорит, что нужно пересылать все сообщения (метасимвол #, смотрите описание выше) в обе (both) стороны (с брокера контроллера на облачный брокер и обратно) c префиксом (user_xxxxxx). Пример обращения к топику: user_xxxxxx/devices/wb-mr6c_200/controls/K2.
  4. Перезапустите mosquitto, выполнив в консоли:
    service mosquitto restart
    
    Потребуется подождать некоторое время пока брокер mosquitto сможет организовать соединение. Подписавшись на контроллере к топику /client/wb_6/bridge_status можно увидеть статус соединения.
    mosquitto_sub -v -t "/client/wb_6/bridge_status" 
    /client/wb_6/bridge_status 0
    /client/wb_6/bridge_status 1
    

Другие облачные брокеры

Список облачных брокеров, в том числе бесплатных: https://github.com/mqtt/mqtt.github.io/wiki/public_brokers

Задача: настроить пересылку топика MQTT на другой контроллер. Есть два контроллера в одной сети:

  1. DestinationController с адресом 10.0.0.40, на этот контроллер получать топик.
  2. SourceController с адресом 10.0.0.70, с этого контроллера будем забирать топик.

На SourceController есть /client/temp1, но его нужно видеть на DestinationController в /devices/temp1.

Решается двумя способами, можно с SourceController публиковать на DestinationController или с DestinationController подписаться на топик SourceController и забирать изменения. От выбора стратегии зависит на каком контроллере будем проводить настройки.

Мы будем настраивать DestinationController.

Решение: На контроллере DestinationController добавьте в конфиг:

mcedit /etc/mosquitto/conf.d/bridge.conf

Строки:

connection wb_40
address 10.0.0.70
notifications true
notification_topic /client/wb_40/bridge_status
keepalive_interval 20
restart_timeout 20

topic /temp1/# in 2 /devices /client

Перезапустите mosquitto на DestinationController:

systemctl restart mosquitto; systemctl status mosquitto

ВАЖНО: перед перезапуском желательно остановить watchdog. В случае ошибки в конфигурационных файлах брокер не запустится и watchdog вызовет перезапуск контроллера.

Рассмотрим подробнее строчку topic /temp1/# in 2 /devices /client где:

  • /temp1/# это топик от «корня». На брокере-источнике /client/temp1.
  • in — только забираем, изменения на контроллере не передадутся на сервер.
  • /devices — «корень» куда располагаем локально (на контроллере на котором настраиваем). На контроллере DestinationController это /devices и полный путь будет выгляджеть как /devices/temp1.
  • /client — «корень» откуда забираем на удаленном. На контроллере SourceController это /client и полный путь будет выгляджеть как /client/temp1.

Проверка: Дожидаемся статуса бриджа «1» в топике /client/wb_40/bridge_status на контроллере SourceController. На нем же публикуем:

for i in {1..25}
do
mosquitto_pub  -t "/client/temp1/temp" -m "$i" -r
done

Подписавшись на контроллере DestinationController на целевой топик можно видеть:

mosquitto_sub -v -t /devices/temp1/# 
/devices/temp1/temp
/devices/temp1/temp 1
/devices/temp1/temp 2
/devices/temp1/temp 3
/devices/temp1/temp 4
/devices/temp1/temp 5
/devices/temp1/temp 6
/devices/temp1/temp 7
/devices/temp1/temp 8
/devices/temp1/temp 9
/devices/temp1/temp 10
/devices/temp1/temp 11
/devices/temp1/temp 12
/devices/temp1/temp 13
/devices/temp1/temp 14
/devices/temp1/temp 15
/devices/temp1/temp 16
/devices/temp1/temp 17
/devices/temp1/temp 18
/devices/temp1/temp 19
/devices/temp1/temp 20
/devices/temp1/temp 21
/devices/temp1/temp 22
/devices/temp1/temp 23
/devices/temp1/temp 24
/devices/temp1/temp 25

Создание своего брокера MQTT

Вы можете создать отдельный брокер на компьютере или на VDS-сервере в интернете и собирать на нем данные с контроллеров.

Инициировать соединение будет контроллер, поэтому контроллеру не нужен «белый» IP-адрес. Если контроллеров несколько, вы можете разделить данные от них на брокере, для этого в настройках моста укажите для каждого контроллера отдельный корневой топик.

Установка брокера

  1. Установите mosquitto:
    sudo apt update && sudo apt install mosquitto mosquitto-clients -y
    
  2. Отключите возможность анонимного входа, для этого:
    • Откройте файл конфигурации в редакторе
    sudo nano /etc/mosquitto/mosquitto.conf
    
    • Добавьте в конец файла строки:
    #Turn on port listening
    listener 1883
    #Disable anonomous login:
    allow_anonymous false
    #Password file:
    password_file /etc/mosquitto/mosquitto.pwd
    
  3. Создайте пароль для пользователя, в примере использован пользователь test с паролем wbpassword:
    sudo mosquitto_passwd -c /etc/mosquitto/mosquitto.pwd test
    
  4. Введите пароль дважды и запомните его, он вам пригодится ниже.
  5. Перезапустите mosquitto и проверьте его состояние:
    sudo systemctl restart mosquitto && sudo systemctl status mosquitto
    
  6. Подключитесь к брокеру для проверки, в примере адрес брокера 127.0.0.1:
    mosquitto_sub -v -h 127.0.0.1 -u test -P wbpassword -t "/#"
    
  7. Запустите в другой консоли команду ниже и убедитесь, что топик меняется:
    for i in {1..25}; do mosquitto_pub -h 127.0.0.1 -u test -P wbpassword -t "/client/temp1/temp" -m "$i" -r; done
    

Брокер установлен и доступен с контроллера. Для подключения нужно ввести логин и пароль.

Настройка моста на контроллере

Создайте файл конфигурации моста, для этого:

  1. Создайте файл /etc/mosquitto/conf.d/bridge1.conf
    nano /etc/mosquitto/conf.d/bridge1.conf
    
  2. Вставьте в него строки, где 10.0.0.105 — адрес брокера:
    connection bridge1
    #address of server
    address 10.0.0.105
    notifications true
    notification_topic /clientnotification/bridge1_status
    remote_username test
    remote_password wbpassword
    
    topic /temp1/# both 2 /devices /controller
    

Содержимое топика /devices/temp1/# контроллера будет отображаться на брокере в /controller. Вместо /controller можете указать уникальное имя контроллера, например, серийный номер.