MQTT: различия между версиями
Admin (обсуждение | вклад) |
Brainroot (обсуждение | вклад) |
||
(не показано 146 промежуточных версий 11 участников) | |||
Строка 1: | Строка 1: | ||
{{DISPLAYTITLE: MQTT в контроллерах Wiren Board }} | |||
== Описание == | |||
'''MQTT''' — протокол обмена данными, использующийся в [[Программное обеспечение Wiren Board|программном обеспечении Wiren Board]]. [http://en.wikipedia.org/wiki/MQTT Базовая информация по MQTT на Википедии]. | |||
'''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'' веб-интерфейса]] | |||
Wiren Board | К [[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'' находится (уже переведено) в состоянии логической единицы — «включено». | |||
== Принцип работы 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 === | |||
*драйверы внутренних аппаратных функций, | |||
*драйверы внешних подключённых устройств, | |||
*веб-интерфейс, | |||
*движок правил, | |||
*(если есть) собственные программы пользователя. | |||
=== | === Структура сообщения о состоянии устройства === | ||
Вот сообщение от драйвера температурного датчика 1-Wire из примера выше: | |||
<pre> | |||
/devices/wb-w1/controls/28-0115a48fcfff 23.25 | |||
</pre> | |||
Часть до пробела — название топика, после — само сообщение. | |||
Название топика состоит из вложенных друг в друга «подтопиков»: | |||
* <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- | /devices/wb-w1/controls/28-0115a48fcfff/meta/error r | ||
</pre> | </pre> | ||
Это означает, что не удалось получить температуру термометра с адресом ''28-0115a48fcfff''. | |||
[[Драйвер wb-mqtt-serial]] устанавливает признак '''r''', если не удалось запросить значение параметра устройства, признак '''w''' — не удалось передать значение устройству. | |||
[https://github.com/wirenboard/wb-homa-adc Драйвер wb-mqtt-adc] устанавливает признак '''r''', если не удалось получить значение соотвествующего канала АЦП. | |||
=== Пример подписки === | |||
Клиенты, которые хотят следить за значением температуры, «подписываются» на этот топик, и им приходят все новые сообщения — меняющиеся значения температуры. Один из таких клиентов — веб-интерфейс. | |||
Подписаться на сообщения можно и из консоли Linux при помощи утилиты <code>mosquitto_sub</code>: | |||
<syntaxhighlight lang="bash"> | |||
~# 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 | |||
</syntaxhighlight> | |||
Полное описание работы с MQTT из командной строки смотрите ниже. | |||
=== Структура сообщения — команды на изменение состояния === | |||
= | Подпишемся на сообщения о состоянии первого реле подключённого по RS-485 релейного модуля WB-MRM2: | ||
<syntaxhighlight lang="bash"> | |||
~# 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 | |||
</syntaxhighlight> | |||
Тут стоит отметить, что MQTT сохраняет часть сообщений (а именно те, которые при отправке были помечены флагом ''retained'') вечно, поэтому после подписки вы получите даже те сообщения, которые были отправлены раньше, чем вы подписались. | |||
Релейный модуль управляется драйвером [[Драйвер 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>. | |||
Например, если мы сейчас нажмём на кнопку реле в веб-интерфейсе (переключим его состояние), то получим новые сообщения: | |||
<pre> | <pre> | ||
/devices/wb-mrm2_130/controls/Relay 1/on 1 | |||
/devices/wb-mrm2_130/controls/Relay 1 1 | |||
/devices/wb- | |||
</pre> | </pre> | ||
( | - веб-интерфейс сначала «даёт указание» включить реле, потом драйвер его включает и записывает актуальное состояние в «канал» («контрол»). | ||
==Локальная работа с сообщениями MQTT== | |||
Программа (демон), отвечающая за рассылку сообщений от одних клиентов другим, называется брокером сообщений. В Wiren Board используется брокер сообщений [http://mosquitto.org/ Mosquitto]. Фактически, все драйверы и веб-интерфейс передают свои сообщения именно демону-брокеру Mosquitto. | |||
===Работа из командной строки=== | |||
==== Управление устройствами из командной строки ==== | |||
Для управления устройством (изменения значения канала), необходимо отправить сообщение в топик <code>/devices/<device-id>/controls/<control-id>/on</code> (обратите внимание на /on в конце). | |||
Это делается с помощью консольной команды '''mosquitto_pub'''. Пример: | |||
<syntaxhighlight lang="bash"> | |||
~# mosquitto_pub -t "/devices/wb-mrm2_130/controls/Relay 1/on" -m "1" | |||
</syntaxhighlight> | |||
команда отправляет сообщение «1» (логическую единицу, «включить») в топик, соответствующий подключённому по RS-485 релейном модуле WM-MRM2 с адресом 130. | |||
< | ==== Слежение за состоянием устройства / подписка на топик ==== | ||
Подписаться можно не только на один топик, но и на группу по | |||
< | Клиенты, которые хотят следить за значением температуры, «подписываются» на этот топик, и им приходят все новые сообщения - меняющиеся значения температуры. Один из таких клиентов - веб-интерфейс. | ||
Подписаться на сообщения можно и из консоли Linux при помощи утилиты '''mosquitto_sub''' (полное описание утилиты смотрите на [http://mosquitto.org/man/mosquitto_sub-1.html http://mosquitto.org/man/mosquitto_sub-1.html]): | |||
<syntaxhighlight lang="bash"> | |||
~# 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 | |||
</syntaxhighlight> | |||
===Метасимволы=== | |||
Подписаться можно не только на один топик, но и на группу топиков по метасиволу. В MQTT применяется два метасимвола: '''#''' и '''+'''. Метасимвол ''#'' означает любое количество уровней вложенных топиков. Выполним команду | |||
<syntaxhighlight lang="bash"> | |||
~# 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- | /devices/wb-w1/controls/28-0115a48fcfff 22.812 | ||
/devices/wb-w1/controls/28- | /devices/wb-w1/controls/28-0115a48fcfff/meta/type temperature | ||
/devices/wb-w1/controls/28- | /devices/wb-w1/controls/28-0115a48fcfff 22.75 | ||
/ | </syntaxhighlight> | ||
</ | В результате мы получили не только значения с «контрола» устройства, но и топики с метаданными — название драйвера устройства и тип «контрола» - ''temperature''. | ||
, | Существует так же метасимвол '''+''', который обозначает один уровень, а не произвольное количество,как '''#''': | ||
<syntaxhighlight lang="bash"> | |||
mosquitto_sub -v -t "/config/widgets/+/name" | |||
</syntaxhighlight> | |||
В этом случае мы получим имена всех виджетов. | |||
[http://mosquitto.org/man/mqtt-7.html Полное описание системы топиков и подписок]. | |||
=== Очистка очереди сообщений === | |||
Ненужные retained-сообщения могут остаться в системе MQTT после удаления неиспользуемых драйверов или отключения каких-либо устройств. | |||
Это приводит к тому, что несуществующие больше устройства могут отображаться в разделе ''Devices'' веб-интерфейса. | |||
Для удаления топиков можно воспользоваться командой <code>mqtt-delete-retained</code>. | |||
Например, удалим все топики, начинающиеся на <code>/devices/noolite_tx_1234/</code> | |||
<syntaxhighlight lang="bash"> | |||
~# mqtt-delete-retained '/devices/noolite_tx_1234/#' | |||
</syntaxhighlight> | |||
Для удаления топиков «по маске», можно циклично вызывать <code>runShellCommand</code> из правил. Таким образом, задача сводится к задаче работы со строками в js. | |||
<syntaxhighlight lang="bash"> | |||
var deviceName = ['name1',.., 'nameN']; | |||
var controlName = 'Temperature'; | |||
for (var i = 0; i<deviceName.length; i++) { | |||
runShellCommand ('mqtt-delete-retained /devices/'+ deviceName[i] + '/controls/controlName/#'); | |||
} | |||
</syntaxhighlight> | |||
=== Работа с MQTT из внешних программ === | |||
Если вы разрабатываете собственное ПО для Wiren Board, взаимодействовать с его аппаратными ресурсами лучше всего через протокол MQTT — ваша программа передаёт сообщение по MQTT, драйвер управляет устройством и вашей программе не нужно напрямую взаимодействовать с устройством на низком уровне. | |||
Языки, для которых есть библиотеки для работы с MQTT, по ссылкам подробное описание: | |||
* [[Python]] | |||
* [[Cpp|C++]] | |||
* [[Go]] | |||
* [[Nodejs]] | |||
=== Просмотр MQTT-каналов в web-интерфейсе === | |||
MQTT-названия устройств, их элементов управления и последние значения можно найти в разделе '''Settings''' web-интерфейса: | |||
[[Файл: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) === | |||
[[File:CloudMQTT.png | thumb | 400px | Настройки брокера Cloud MQTT]] | |||
MQTT мост (bridge) — это функция MQTT-брокера, позволяющая пересылать все или часть сообщений на другой MQTT-брокер, и получать сообщения с другого брокера обратно. | |||
Эту функцию удобно применять в следующей ситуации: хотя на самом контроллере уже есть MQTT-брокер, к нему часто неудобно подключаться, так как контроллер может не иметь белого IP-адреса, а иногда может быть выключен или не в сети. В таком случае удобно иметь отдельный брокер в облаке с фиксированным адресом, который будет всегда онлайн, и на который будут пересылаться сообщения с брокера контроллера. | |||
На контроллере эта функция настраивается в конфигурационных файлах ''mosquitto''. Самый простой вариант конфигурации приведён ниже. | |||
==== Настройка моста с MQTT брокером Cloudmqtt ==== | |||
'''Задача:''' настроить пересылку всех сообщений MQTT на популярный дешёвый облачный MQTT брокер http://cloudmqtt.com/ и обратно. | |||
'''Решение:''' | |||
# Зарегистрируйтесь на http://cloudmqtt.com/ | |||
# Зайдите в свой аккаунт на http://cloudmqtt.com/ и посмотрите настройки: сервер, порт, логин, пароль. | |||
# Зайдите на контроллер и добавьте в конец файла <code>/etc/mosquitto/conf.d/20bridges.conf</code> следующие строки: | |||
#: <syntaxhighlight lang="bash"> | |||
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 | |||
</syntaxhighlight> | |||
#: (последняя строка говорит, что нужно пересылать все сообщения (метасимвол '''#''', смотрите описание выше) в обе ('''both''') стороны (с брокера контроллера на облачный брокер и обратно) | |||
#: Более подробное описание всех опций смотрите на https://mosquitto.org/man/mosquitto-conf-5.html. | |||
# Перезапустите <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"> | |||
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> | |||
==== Другие облачные брокеры ==== | |||
Список облачных брокеров, в том числе бесплатных: [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"> | ||
nano /etc/mosquitto/conf.d/20bridges.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 1 /devices /client | ||
</syntaxhighlight> | |||
< | Перезапустите <code>mosquitto</code> на ''DestinationController'': | ||
< | <syntaxhighlight lang="bash"> | ||
systemctl restart mosquitto; systemctl status mosquitto | |||
</ | </syntaxhighlight> | ||
'''ВАЖНО:''' перед перезапуском желательно [[watchdog |остановить watchdog]]. В случае ошибки в конфигурационных файлах брокер не запустится и watchdog вызовет перезапуск контроллера. | |||
< | Рассмотрим подробнее строчку <code>topic /temp1/# in 1 /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/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> можете указать уникальное имя контроллера, например, серийный номер. | ||
</ |
Текущая версия на 09:42, 16 августа 2023
Описание
MQTT — протокол обмена данными, использующийся в программном обеспечении Wiren Board. Базовая информация по MQTT на Википедии.
Драйверы, которые отвечают за аппаратную часть контроллера (цифровые и транзисторные входы, АЦП и т.п.) и функции внешних подключенных устройств публикуют их состояние по MQTT в виде сообщений. Веб-интерфейс читает эти сообщения и на их основе отображает состояние устройств.
Действия пользователя в веб-интерфейсе также публикуются по MQTT, где их получает драйвер и передает команду пользователя устройству.
Через MQTT работают: веб-интерфейс, движок правил и встроенные драйверы. Если вы разрабатываете собственное ПО в дополнение к предустановленному — мы рекомендуем использовать MQTT.
Структура топиков описана в Wiren Board MQTT Conventions.
В контроллере используется MQTT брокер mosquitto, который по умолчанию разрешает соединения без пароля с любых хостов. Если вы хотите настроить авторизацию, обратитесь к официальной документации.
Примеры работы через MQTT
Получение значения от датчика температуры и вывод его в веб-интерфейс
К Wiren Board подключён датчик температуры по шине 1-Wire. Проследим, как данные с него через MQTT попадают в веб-интерфейс:
- Драйвер wb-mqtt-w1, отвечающий за данную аппаратную функцию, опрашивает подключенные к контролеру датчики 1-Wire.
- При получении значения драйвер публикует MQTT сообщение вида:
/devices/wb-w1/controls/28-0115a48fcfff 23.25
Оно значит, что от устройства 1-Wire с идентификатором 28-0115a48fcfff получено значение 23.25 °C. - Веб-интерфейс, который подписан на все сообщения из MQTT, получает это сообщение и выводит значение датчика на страницу.
Нажатие кнопки в веб-интерфейсе и переключение реле на внешнем модуле
![](/wiki/images/thumb/d/d2/Web-devices-serial.png/400px-Web-devices-serial.png)
К контроллеру по шине RS-485 подключён релейный модуль WB-MRM2. Пользователь в веб-интерфейсе нажимает кнопку включения реле. Проследим, как команда из веб-интерфейса попадает на внешний модуль:
- После нажатия кнопки веб-интерфейс публикует по MQTT сообщение вида:
/devices/wb-mrm2_130/controls/Relay 1/on 1
Оно значит, что устройство WB-MRM2 с адресом 130 должно перевести Реле 1 в состояние логической единицы — «включено». - Драйвер wb-mqtt-serial, отвечающий за данную аппаратную функцию, получает это сообщение (он подписан на все сообщения, относящиеся к подключённым по RS-485 устройствам) и посылает по шине RS-485 релейному модулю команду на включение первого реле.
- Релейный модуль WB-MRM2 получает команду от контроллера, переключает реле и посылает обратно уведомление «Реле 1 включено».
- Драйвер wb-mqtt-serial получает это уведомление по RS-485 и публикует по MQTT сообщение:
/devices/wb-mrm2_130/controls/Relay 1 1
Оно значит, что первое реле на устройстве WB-MRM2 с адресом 130 находится (уже переведено) в состоянии логической единицы — «включено».
Принцип работы 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 с внешнего устройства
Установленный на контроллер брокер 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 брокер
Установить пароль на MQTT-брокер можно следующим образом.
- Добавьте нового пользователя в файл конфигурации, выполнив команду:
mosquitto_passwd -c /etc/mosquitto/passwd/default.conf username
- Вместо username можно указать произвольное имя пользователя.
- После ввода команды появится запрос на ввод пароля, который нужно будет ввести два раза.
- Далее в файле
/etc/mosquitto/conf.d/10listeners.conf
установите параметрallow_anonymous false
(по умолчанию true).- Изменить файл можно открыв его в текстовом редакторе, например, nano:
nano /etc/mosquitto/conf.d/10listeners.conf
- В файле
/etc/mosquitto/acl/default.conf
добавьте следующую запись:user username topic readwrite # topic readwrite $SYS/#
- где, username — имя пользователя, заданное на первом шаге.
- Открыть файл для редактирования:
nano /etc/mosquitto/acl/default.conf
- Перезапустите mosquitto командой:
systemctl restart mosquitto
После выполнения этой инструкции анонимные подключения к брокеру станут недоступны. Поэтому нужно будет использовать установленный пароль в веб-интерфейсе контроллера, который по умолчанию использует анонимное подключение.
Для чтения топиков с компьютера на Linux в той же сети теперь нужно использовать команду:
mosquitto_sub -h 192.168.0.67 -p 1883 -v -t "/devices/power_status/controls/Vin" -i Test_Client -u username -P password
Настройка MQTT моста (bridge)
MQTT мост (bridge) — это функция MQTT-брокера, позволяющая пересылать все или часть сообщений на другой MQTT-брокер, и получать сообщения с другого брокера обратно.
Эту функцию удобно применять в следующей ситуации: хотя на самом контроллере уже есть MQTT-брокер, к нему часто неудобно подключаться, так как контроллер может не иметь белого IP-адреса, а иногда может быть выключен или не в сети. В таком случае удобно иметь отдельный брокер в облаке с фиксированным адресом, который будет всегда онлайн, и на который будут пересылаться сообщения с брокера контроллера.
На контроллере эта функция настраивается в конфигурационных файлах mosquitto. Самый простой вариант конфигурации приведён ниже.
Настройка моста с MQTT брокером Cloudmqtt
Задача: настроить пересылку всех сообщений MQTT на популярный дешёвый облачный MQTT брокер http://cloudmqtt.com/ и обратно.
Решение:
- Зарегистрируйтесь на http://cloudmqtt.com/
- Зайдите в свой аккаунт на http://cloudmqtt.com/ и посмотрите настройки: сервер, порт, логин, пароль.
- Зайдите на контроллер и добавьте в конец файла
/etc/mosquitto/conf.d/20bridges.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.
- Перезапустите
mosquitto
, выполнив в консоли:systemctl restart mosquitto
Настройка моста с MQTT брокером Clusterfly
Задача: настроить пересылку всех сообщений MQTT на бесплатный облачный MQTT брокер https://clusterfly.ru/ и обратно.
Решение:
- Зарегистрируйтесь на https://clusterfly.ru/
- Зайдите в свой аккаунт на https://clusterfly.ru/ и выберите «Профиль» посмотрите настройки: сервер, порт, логин и сгенерируйте пароль. Для пересылки используйте сервер
srv1.clusterfly.ru
. - Зайдите на контроллер и добавьте в конец файла
/etc/mosquitto/conf.d/20bridges.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_7/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
.
- Перезапустите
mosquitto
, выполнив в консоли:systemctl restart mosquitto
- Потребуется подождать некоторое время пока брокер
mosquitto
сможет организовать соединение. Подписавшись на контроллере к топику/client/wb_7/bridge_status
можно увидеть статус соединения. mosquitto_sub -v -t "/client/wb_7/bridge_status" /client/wb_7/bridge_status 0 /client/wb_7/bridge_status 1
Другие облачные брокеры
Список облачных брокеров, в том числе бесплатных: https://github.com/mqtt/mqtt.github.io/wiki/public_brokers
Задача: настроить пересылку топика MQTT на другой контроллер. Есть два контроллера в одной сети:
- DestinationController с адресом
10.0.0.40
, на этот контроллер получать топик. - SourceController с адресом
10.0.0.70
, с этого контроллера будем забирать топик.
На SourceController есть /client/temp1
, но его нужно видеть на DestinationController в /devices/temp1
.
Решается двумя способами, можно с SourceController публиковать на DestinationController или с DestinationController подписаться на топик SourceController и забирать изменения. От выбора стратегии зависит на каком контроллере будем проводить настройки.
Мы будем настраивать DestinationController.
Решение: На контроллере DestinationController добавьте в конфиг:
nano /etc/mosquitto/conf.d/20bridges.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 1 /devices /client
Перезапустите mosquitto
на DestinationController:
systemctl restart mosquitto; systemctl status mosquitto
ВАЖНО: перед перезапуском желательно остановить watchdog. В случае ошибки в конфигурационных файлах брокер не запустится и watchdog вызовет перезапуск контроллера.
Рассмотрим подробнее строчку topic /temp1/# in 1 /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-адрес. Если контроллеров несколько, вы можете разделить данные от них на брокере, для этого в настройках моста укажите для каждого контроллера отдельный корневой топик.
Установка брокера
- Установите
mosquitto
:sudo apt update && sudo apt install mosquitto mosquitto-clients -y
- Отключите возможность анонимного входа, для этого:
- Откройте файл конфигурации в редакторе
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
- Создайте пароль для пользователя, в примере использован пользователь
test
с паролемwbpassword
:sudo mosquitto_passwd -c /etc/mosquitto/mosquitto.pwd test
- Введите пароль дважды и запомните его, он вам пригодится ниже.
- Перезапустите
mosquitto
и проверьте его состояние:sudo systemctl restart mosquitto && sudo systemctl status mosquitto
- Подключитесь к брокеру для проверки, в примере адрес брокера
127.0.0.1
:mosquitto_sub -v -h 127.0.0.1 -u test -P wbpassword -t "/#"
- Запустите в другой консоли команду ниже и убедитесь, что топик меняется:
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
Брокер установлен и доступен с контроллера. Для подключения нужно ввести логин и пароль.
Настройка моста на контроллере
Создайте конфигурацию моста, для этого:
- Откройте файл
/etc/mosquitto/conf.d/20bridges.conf
nano /etc/mosquitto/conf.d/20bridges.conf
- Вставьте в конец файла строки, где
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
можете указать уникальное имя контроллера, например, серийный номер.