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

11 556 байт добавлено ,  8 месяцев назад
м (Поправил немного типографику и пунктуацию.)
 
(не показаны 62 промежуточные версии 7 участников)
Строка 1: Строка 1:
{{DISPLAYTITLE: MQTT в контроллерах Wiren Board }}
== Описание ==
'''MQTT''' — протокол обмена данными, использующийся в [[Программное обеспечение Wiren Board|программном обеспечении Wiren Board]]. [http://en.wikipedia.org/wiki/MQTT Базовая информация по MQTT на Википедии].
'''MQTT''' — протокол обмена данными, использующийся в [[Программное обеспечение Wiren Board|программном обеспечении Wiren Board]]. [http://en.wikipedia.org/wiki/MQTT Базовая информация по MQTT на Википедии].


Строка 4: Строка 6:


Действия пользователя в веб-интерфейсе также публикуются по MQTT, где их получает драйвер и передает команду пользователя устройству.
Действия пользователя в веб-интерфейсе также публикуются по MQTT, где их получает драйвер и передает команду пользователя устройству.
== Примеры работы через MQTT ==  
 
Через MQTT работают: веб-интерфейс, движок правил и встроенные драйверы. Если вы разрабатываете собственное ПО в дополнение к предустановленному — мы рекомендуем использовать MQTT.
 
Структура топиков описана в [https://github.com/wirenboard/conventions/blob/main/README.md Wiren Board MQTT Conventions].
 
В контроллере используется MQTT брокер mosquitto, который по умолчанию разрешает соединения без пароля с любых хостов. Если вы хотите настроить авторизацию, [https://mosquitto.org/man/mosquitto-conf-5.html обратитесь к официальной документации].
 
== Примеры работы через MQTT ==
 
===Получение значения от датчика температуры и вывод его в веб-интерфейс===
===Получение значения от датчика температуры и вывод его в веб-интерфейс===
[[File:Web-devices-1-wire.png|400px|thumb|Показания датчика и его уникальный идентификатор на странице ''Devices'' веб-интерфейса]]
[[File:Web-devices-1-wire.png|400px|thumb|Показания датчика и его уникальный идентификатор на странице ''Devices'' веб-интерфейса]]


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


== Принцип работы MQTT ==  
== Принцип работы MQTT ==
[[File:MQTT.png | thumb | 600px | Через MQTT работают драйверы внутренних функций, внешних устройств, веб-интерфейс, система правил]]
[[File:DebianLinux.png | thumb | 600px | Через MQTT работают драйверы внутренних функций, внешних устройств, веб-интерфейс, система правил]]
Система сообщений MQTT построена по следующему принципу:
Система сообщений MQTT построена по следующему принципу:
*есть иерархическая система «топиков» (как на обычных форумах в интернете).
*есть иерархическая система «топиков» (как на обычных форумах в интернете).
Строка 30: Строка 40:
=== Отображение устройств в структуре сообщений ===  
=== Отображение устройств в структуре сообщений ===  


Логика организации топиков, соответствующих разным устройствам и их параметрам, в Wiren Board следует определённым правилам — так называемым соглашениям ([https://github.com/contactless/homeui/blob/master/conventions.md Wiren Board MQTT Conventions]).
Логика организации топиков, соответствующих разным устройствам и их параметрам, в Wiren Board следует определённым правилам — так называемым соглашениям ([https://github.com/wirenboard/conventions/blob/main/README.md Wiren Board MQTT Conventions]).


Полный список MQTT-топиков можно увидеть на странице ''Settings'' веб-интерфейса в разделе ''MQTT Channels'' (появилось в последних версиях [[Обновление прошивки|прошивки]]).
Полный список MQTT-топиков можно увидеть на странице ''Settings'' веб-интерфейса в разделе ''MQTT Channels'' (появилось в последних версиях [[Обновление прошивки|прошивки]]).
Строка 41: Строка 51:
*(если есть) собственные программы пользователя.
*(если есть) собственные программы пользователя.


=== Структура сообщения о состоянии устройства ===  
=== Структура сообщения о состоянии устройства ===
Вот пример сообщения от драйвера температурного датчика 1-Wire из примера выше:
Вот сообщение от драйвера температурного датчика 1-Wire из примера выше:
<pre>
<pre>
/devices/wb-w1/controls/28-0115a48fcfff 23.25
/devices/wb-w1/controls/28-0115a48fcfff 23.25
Строка 49: Строка 59:


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


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


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


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


Подписаться на сообщения можно и из консоли Linux при помощи утилиты '''mosquitto_sub''' (полное описание работы с MQTT из командной строки смотрите ниже):
Подписаться на сообщения можно и из консоли Linux при помощи утилиты <code>mosquitto_sub</code>:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/controls/28-0115a48fcfff' -v //получить сообщения из топика устройства 1-Wire с идентификатором 28-0115a48fcfff
~# 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
/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>
Полное описание работы с MQTT из командной строки смотрите ниже.


=== Структура сообщения — команды на изменение состояния ===  
=== Структура сообщения — команды на изменение состояния ===  
Строка 88: Строка 100:
Подпишемся на сообщения о состоянии первого реле подключённого по RS-485 релейного модуля WB-MRM2:
Подпишемся на сообщения о состоянии первого реле подключённого по 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
Строка 104: Строка 116:
- веб-интерфейс сначала «даёт указание» включить реле, потом драйвер его включает и записывает актуальное состояние в «канал» («контрол»).
- веб-интерфейс сначала «даёт указание» включить реле, потом драйвер его включает и записывает актуальное состояние в «канал» («контрол»).


==Работа с сообщениями MQTT==
==Локальная работа с сообщениями MQTT==
Программа (демон), отвечающая за рассылку сообщений от одних клиентов другим, называется брокером сообщений. В Wiren Board используется брокер сообщений [http://mosquitto.org/ Mosquitto]. Фактически, все драйверы и веб-интерфейс передают свои сообщения именно демону-брокеру Mosquitto.
Программа (демон), отвечающая за рассылку сообщений от одних клиентов другим, называется брокером сообщений. В Wiren Board используется брокер сообщений [http://mosquitto.org/ Mosquitto]. Фактически, все драйверы и веб-интерфейс передают свои сообщения именно демону-брокеру Mosquitto.
===Работа из командной строки===
===Работа из командной строки===
Строка 113: Строка 125:
Это делается с помощью консольной команды '''mosquitto_pub'''. Пример:
Это делается с помощью консольной команды '''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>
команда отправляет сообщение «1» (логическую единицу, «включить») в топик, соответствующий подключённому по RS-485 релейном модуле WM-MRM2 с адресом 130.
команда отправляет сообщение «1» (логическую единицу, «включить») в топик, соответствующий подключённому по RS-485 релейном модуле WM-MRM2 с адресом 130.
Строка 123: Строка 135:
Подписаться на сообщения можно и из консоли Linux при помощи утилиты '''mosquitto_sub''' (полное описание утилиты смотрите на [http://mosquitto.org/man/mosquitto_sub-1.html http://mosquitto.org/man/mosquitto_sub-1.html]):
Подписаться на сообщения можно и из консоли 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 //получить сообщения из топика устройства 1-Wire с идентификатором 28-0115a48fcfff
~# 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
/devices/wb-w1/controls/28-0115a48fcfff 22.75
Строка 132: Строка 144:
Подписаться можно не только на один топик, но и на группу топиков по метасиволу. В MQTT применяется два метасимвола: '''#''' и '''+'''. Метасимвол ''#''  означает любое количество уровней вложенных топиков. Выполним команду
Подписаться можно не только на один топик, но и на группу топиков по метасиволу. В 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
Строка 139: Строка 151:
</syntaxhighlight>
</syntaxhighlight>
В результате мы получили не только значения с «контрола» устройства, но и топики с метаданными — название драйвера устройства и тип «контрола» - ''temperature''.
В результате мы получили не только значения с «контрола» устройства, но и топики с метаданными — название драйвера устройства и тип «контрола» - ''temperature''.
Существует так же метасимвол ''+'', который обозначает один уровень, а не произвольное количество,как ''#'':
Существует так же метасимвол '''+''', который обозначает один уровень, а не произвольное количество,как '''#''':
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
mosquitto_sub -v -t "/config/widgets/+/name"  
mosquitto_sub -v -t "/config/widgets/+/name"  
Строка 145: Строка 157:
В этом случае мы получим имена всех виджетов.
В этом случае мы получим имена всех виджетов.


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


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


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


Для удаления топиков можно воспользоваться командой ''mqtt-delete-retained''. Пример использования:
Для удаления топиков можно воспользоваться командой <code>mqtt-delete-retained</code>.  
 
Например, удалим все топики, начинающиеся на <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>
удалит все топики, начинающиеся на '/devices/noolite_tx_1234/'


Для удаления топиков «по маске», можно циклично вызывать runShellCommand из правил. Таким образом, задача сводится к задаче работы со строками в js.
Для удаления топиков «по маске», можно циклично вызывать <code>runShellCommand</code> из правил. Таким образом, задача сводится к задаче работы со строками в js.
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
var deviceName = ['name1',.., 'nameN'];
var deviceName = ['name1',.., 'nameN'];
Строка 171: Строка 183:
=== Работа с MQTT из внешних программ ===
=== Работа с MQTT из внешних программ ===


Если вы разрабатываете собственное ПО для Wiren Board, взаимодействовать с его аппаратными ресурсами лучше всего через протокол MQTT — ваша программа передаёт сообщение по MQTT, драйвер управляет устройством, и вашей программе не нужно напрямую взаимодействовать с устройством на низком уровне.
Если вы разрабатываете собственное ПО для Wiren Board, взаимодействовать с его аппаратными ресурсами лучше всего через протокол MQTT — ваша программа передаёт сообщение по MQTT, драйвер управляет устройством и вашей программе не нужно напрямую взаимодействовать с устройством на низком уровне.
 
Для того, чтобы отправлять сообщения MQTT, для многих языков программирования есть библиотеки. Примеры:
* Python - [https://github.com/contactless/mqtt-tools]
* C - [http://mosquitto.org/man/libmosquitto-3.html]


Языки, для которых есть библиотеки для работы с MQTT, по ссылкам подробное описание:
* [[Python]]
* [[Cpp|C++]]
* [[Go]]
* [[Nodejs]]


=== Просмотр MQTT-каналов в web-интерфейсе ===
=== Просмотр MQTT-каналов в web-интерфейсе ===
MQTT-названия устройств, их элементов управления и последние значения можно найти в разделе Settings web-интерфейса:
MQTT-названия устройств, их элементов управления и последние значения можно найти в разделе '''Settings''' web-интерфейса:
[[Файл:Wb_settings.png|900px|thumb|center|Информация об MQTT-названиях устройств]]
[[Файл: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 брокер ===
Установить пароль на MQTT-брокер можно следующим образом.
#Добавьте нового пользователя в файл конфигурации, выполнив команду:
#:<syntaxhighlight lang="bash">
mosquitto_passwd -c /etc/mosquitto/passwd/default.conf username
</syntaxhighlight>
#:Вместо username можно указать произвольное имя пользователя.
#:После ввода команды появится запрос на ввод пароля, который нужно будет ввести два раза.
#Далее в файле <code>/etc/mosquitto/conf.d/10listeners.conf</code> установите параметр <code>allow_anonymous false</code> (по умолчанию true).
#:Изменить файл можно открыв его в текстовом редакторе, например, nano:
#:<syntaxhighlight lang="bash">
nano /etc/mosquitto/conf.d/10listeners.conf
</syntaxhighlight>
#В файле  <code>/etc/mosquitto/acl/default.conf</code> добавьте следующую запись:
#:<syntaxhighlight lang="bash">
user username
topic readwrite #
topic readwrite $SYS/#
</syntaxhighlight>
#:где, username — имя пользователя, заданное на первом шаге.
#:Открыть файл для редактирования:
#:<syntaxhighlight lang="bash">
nano  /etc/mosquitto/acl/default.conf
</syntaxhighlight>
#Перезапустите mosquitto командой:
#:<syntaxhighlight lang="bash">
systemctl restart mosquitto
</syntaxhighlight>
После выполнения этой инструкции анонимные подключения к брокеру станут недоступны. Поэтому нужно будет использовать установленный пароль в веб-интерфейсе контроллера, который по умолчанию использует анонимное подключение.
Для чтения топиков с компьютера на Linux в той же сети теперь нужно использовать команду:
<syntaxhighlight lang="bash">
mosquitto_sub -h 192.168.0.67 -p 1883 -v -t "/devices/power_status/controls/Vin" -i Test_Client -u username -P password
</syntaxhighlight>


=== Настройка MQTT моста (bridge) ===  
=== Настройка MQTT моста (bridge) ===  
[[File:CloudMQTT.png | thumb | 400px | Настройки брокера Cloud MQTT]]
[[File:CloudMQTT.png | thumb | 400px | Настройки брокера Cloud MQTT]]
MQTT мост (bridge) — это функция MQTT-брокера, позволяющая пересылать все или часть сообщений на другой MQTT-брокер, и получать сообщения с другого брокера обратно. На контроллере эта функция настраивается в конфигурационных файлах ''mosquitto''. Самый простой вариант конфигурации приведён ниже.
MQTT мост (bridge) — это функция MQTT-брокера, позволяющая пересылать все или часть сообщений на другой MQTT-брокер, и получать сообщения с другого брокера обратно.
 
Эту функцию удобно применять в следующей ситуации: хотя на самом контроллере уже есть MQTT-брокер, к нему часто неудобно подключаться, так как контроллер может не иметь белого IP-адреса, а иногда может быть выключен или не в сети. В таком случае удобно иметь отдельный брокер в облаке с фиксированным адресом, который будет всегда онлайн, и на который будут пересылаться сообщения с брокера контроллера.
 
На контроллере эта функция настраивается в конфигурационных файлах ''mosquitto''. Самый простой вариант конфигурации приведён ниже.


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


Строка 191: Строка 258:
# Зарегистрируйтесь на http://cloudmqtt.com/
# Зарегистрируйтесь на http://cloudmqtt.com/
# Зайдите в свой аккаунт на http://cloudmqtt.com/ и посмотрите настройки: сервер, порт, логин, пароль.
# Зайдите в свой аккаунт на http://cloudmqtt.com/ и посмотрите настройки: сервер, порт, логин, пароль.
# Зайдите на контроллер и добавьте в конец файла <code>/etc/mosquitto/mosquitto.conf</code> следующие строки:
# Зайдите на контроллер и добавьте в конец файла <code>/etc/mosquitto/conf.d/20bridges.conf</code> следующие строки:
#: <syntaxhighlight lang="bash">
#: <syntaxhighlight lang="bash">
connection cloudmqtt
connection cloudmqtt
Строка 204: Строка 271:
#: (последняя строка говорит, что нужно пересылать все сообщения (метасимвол '''#''', смотрите описание выше) в обе ('''both''') стороны (с брокера контроллера на облачный брокер и обратно)
#: (последняя строка говорит, что нужно пересылать все сообщения (метасимвол '''#''', смотрите описание выше) в обе ('''both''') стороны (с брокера контроллера на облачный брокер и обратно)
#: Более подробное описание всех опций смотрите на https://mosquitto.org/man/mosquitto-conf-5.html.
#: Более подробное описание всех опций смотрите на https://mosquitto.org/man/mosquitto-conf-5.html.
# Перезапустите mosquitto, выполнив в консоли
# Перезапустите <code>mosquitto</code>, выполнив в консоли:
#: <syntaxhighlight lang="bash">
systemctl restart mosquitto
</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/conf.d/20bridges.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_7/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">
#: <syntaxhighlight lang="bash">
service mosquitto restart
systemctl restart mosquitto
</syntaxhighlight>
#: Потребуется подождать некоторое время пока брокер <code>mosquitto</code> сможет организовать соединение. Подписавшись на контроллере к топику <code>/client/wb_7/bridge_status</code> можно увидеть статус соединения.
#:<syntaxhighlight lang="bash">
mosquitto_sub -v -t "/client/wb_7/bridge_status"
/client/wb_7/bridge_status 0
/client/wb_7/bridge_status 1
</syntaxhighlight>
</syntaxhighlight>


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


Список облачных брокеров, в том числе бесплатных: [https://github.com/mqtt/mqtt.github.io/wiki/public_brokers https://github.com/mqtt/mqtt.github.io/wiki/public_brokers]
Список облачных брокеров, в том числе бесплатных: [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>, с этого контроллера будем забирать топик.


'''Задача:''' настроить пересылку топика MQTT на другой контроллер.
На  ''SourceController'' есть <code>/client/temp1</code>, но его нужно видеть на ''DestinationController'' в <code>/devices/temp1</code>.
Есть два контроллера в одной сети, адреса:
;10.0.0.40
:На этот контроллер «забираем» топик. Обозначаем его как «40».
;10.0.0.70
:С этого контроллера, он источник. Назовем его «70».


На  '''70''' есть <code>/client/temp1</code>
Решается двумя способами, можно с ''SourceController'' публиковать на ''DestinationController'' или с ''DestinationController'' подписаться на топик ''SourceController'' и забирать изменения. От выбора стратегии зависит на каком контроллере будем проводить настройки.
Его нужно видеть на '''40''' в <code>/devices/temp1</code>


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


'''Решение:'''
'''Решение:''' На контроллере ''DestinationController'' добавьте в конфиг:
На контроллере «40» добавляем в конфиг:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
mcedit /etc/mosquitto/conf.d/bridge.conf
nano /etc/mosquitto/conf.d/20bridges.conf
</syntaxhighlight>
</syntaxhighlight>
Следующее
Строки:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
connection wb_40
connection wb_40
Строка 241: Строка 338:
restart_timeout 20
restart_timeout 20


topic /temp1/# in 2 /devices /client
topic /temp1/# in 1 /devices /client
 
</syntaxhighlight>
</syntaxhighlight>


Перезапускаем на нем же mosquitto:
Перезапустите <code>mosquitto</code> на ''DestinationController'':
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
systemctl restart mosquitto; systemctl status mosquitto
systemctl restart mosquitto; systemctl status mosquitto
</syntaxhighlight>
</syntaxhighlight>
'''ВАЖНО''' перед перезапуском желательно [[watchdog |остановить watchdog]]. В случае ошибки в конфигах брокер не запустится и watchdog вызовет перезапуск контроллера.
'''ВАЖНО:''' перед перезапуском желательно [[watchdog |остановить watchdog]]. В случае ошибки в конфигурационных файлах брокер не запустится и watchdog вызовет перезапуск контроллера.
 
Подробней о строчке:


<syntaxhighlight lang="bash">
Рассмотрим подробнее строчку <code>topic /temp1/# in 1 /devices /client</code>
topic /temp1/# in 2 /devices /client
</syntaxhighlight>
где:
где:
;/temp1/# это топик от «корня»
* <code>/temp1/#</code> это топик от «корня». На брокере-источнике /client/'''temp1'''.
:На брокере-источнике /client/'''temp1'''
* <code>in</code> — только забираем, изменения на контроллере не передадутся на сервер.
;in — только забираем, изменения на контроллере не передадутся на сервер
* <code>/devices</code> «корень» '''куда''' располагаем локально (на контроллере на котором '''настраиваем'''). На контроллере ''DestinationController'' это <code>/devices</code> и полный путь будет выгляджеть как '''/devices'''/temp1.
;/devices — »корень« '''куда''' располагаем локально
* <code>/client</code> — «корень» откуда забираем на удаленном. На контроллере ''SourceController'' это <code>/client</code> и полный путь будет выгляджеть как '''/client'''/temp1.
: На контроллере '''40''' это '''/devices''' и полный путь будет выгляджеть как '''/devices'''/temp1
;/client — «корень» откуда забираем на удаленном
: На контроллере '''70''' это '''/client''' и полный путь будет выгляджеть как '''/client'''/temp1


'''Проверка:'''
'''Проверка:'''
Дожидаемся статуса бриджа «1» в топике <code>/client/wb_40/bridge_status</code> на контроллере '''70'''.
Дожидаемся статуса бриджа «1» в топике <code>/client/wb_40/bridge_status</code> на контроллере ''SourceController''.
На нем же публикуем:
На нем же публикуем:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Строка 275: Строка 364:
</syntaxhighlight>
</syntaxhighlight>


подписавшись на контроллере '''40''' на целевой топик можно видеть:
Подписавшись на контроллере ''DestinationController'' на целевой топик можно видеть:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
mosquitto_sub -v -t /devices/temp1/#  
mosquitto_sub -v -t /devices/temp1/#  
Строка 305: Строка 394:
/devices/temp1/temp 25
/devices/temp1/temp 25
</syntaxhighlight>
</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/20bridges.conf</code>
#:<syntaxhighlight lang="bash">
nano /etc/mosquitto/conf.d/20bridges.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> можете указать уникальное имя контроллера, например, серийный номер.
wb_editors
890

правок