MQTT: различия между версиями
Admin (обсуждение | вклад) |
Admin (обсуждение | вклад) |
||
Строка 20: | Строка 20: | ||
#Веб-интерфейс, который получает все сообщения из очереди (он ''подписан'' на все сообщения), получает это сообщение и выводит значение датчика на страницу. | #Веб-интерфейс, который получает все сообщения из очереди (он ''подписан'' на все сообщения), получает это сообщение и выводит значение датчика на страницу. | ||
===Нажатие кнопки в веб-интерфейсе и переключение реле на внешнем модуле=== | ===Нажатие кнопки в веб-интерфейсе и переключение реле на внешнем модуле=== | ||
[[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]]. Пользователь в веб-интерфейсе нажимает кнопку включения реле. Проследим, как команда из веб-интерфейса попадает на внешний модуль: | ||
#После нажатия кнопки веб-интерфейс размещает в очереди сообщение следующего вида: <pre>/devices/wb-mrm2_130/controls/Relay 1/on 1</pre>Оно значит, что устройство WB-MRM2 с адресом ''130'' должно перевести Реле 1 в состояние логической единицы - "включено". | #После нажатия кнопки веб-интерфейс размещает в очереди сообщение следующего вида: <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 релейному модулю команду на включение первого реле. |
Версия 19:51, 18 февраля 2016
MQTT - очередь сообщений, использующаяся в ПО Wiren Board. Базовая информация по MQTT на Википедии.
Большая часть встроенных функций контроллера (АЦП, реле, транзисторный выход, watchdog) и функций внешних совместимых устройств (например, подключённых по RS-485 модулей реле) транслируются в очередь в виде сообщений. Сами они, в свою очередь, также реагируют на управляющие сообщения из очереди.
Программа (демон), отвечающая за рассылку сообщений от одних клиентов другим, называется брокером сообщений. В Wiren Board используется брокер сообщений Mosquitto.
Веб-интерфейс работает также через систему сообщений MQTT - нажатие кнопки в интерфейсе вызывает отправку сообщения в очередь (а именно брокеру сообщений); изменение показания датчика, поступившее в систему сообщений, тут же вызывает изменения транслируется в веб-интерфейс.
Пример: если на цифровой вход Wiren Board подан сигнал, драйвер wb-homa-gpio создаёт сообщение вида .......... - "на входе ... появился сигнал". Веб-интерфейс, который тоже подключён к системе сообщений, получает это сообщение и "зажигает" индикатор в веб-интерфейсе.
Примеры работы через очередь MQTT
Получение значения от датчика температуры и вывод его в веб-интерфейс
Предположим, что к Wiren Board подключён датчик температуры по шине 1-Wire. Проследим, как данные с него через очередь сообщений попадают в веб-интерфейс:
- Драйвер, отвечающий за данную аппаратную функцию (например, wb-homa-w1) опрашивает подключённые к контролеру датчики 1-Wire.
- При получении значения драйвер размещает в очереди сообщение следующего вида:
/devices/wb-w1/controls/28-0115a48fcfff 23.25
Оно значит, что на устройстве 1-Wire с идентификатором 28-0115a48fcfff получено значение 23.25°C. - Веб-интерфейс, который получает все сообщения из очереди (он подписан на все сообщения), получает это сообщение и выводит значение датчика на страницу.
Нажатие кнопки в веб-интерфейсе и переключение реле на внешнем модуле
![](/wiki/images/thumb/d/d2/Web-devices-serial.png/400px-Web-devices-serial.png)
Предположим, что к контроллеру по шине RS-485 подключён релейный модуль WB-MRM2. Пользователь в веб-интерфейсе нажимает кнопку включения реле. Проследим, как команда из веб-интерфейса попадает на внешний модуль:
- После нажатия кнопки веб-интерфейс размещает в очереди сообщение следующего вида:
/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 и публикует в очереди сообщение:
/devices/wb-mrm2_130/controls/Relay 1 1
Оно значит, что первое реле на устройстве WB-MRM2 с адресом 130 находится (уже переведено) в состоянии логической единицы ("включено").
Wiren Board использует набор соглашений по работе с MQTT. Эти соглашения описаны ниже. Полное каноническое описание соглашений Wiren Board смотрите в документе Wiren Board MQTT Conventions.
Архитектура ПО Wiren Board:
Специальные "драйверы" (отдельный для каждой функции контроллера и внешнего устройства) транслируют данные с устройства в очередь в виде сообщений специального формата. Сообщения из этой очереди получает веб-интерфейс и движок правил. Они же могут добавлять туда новые сообщения - например, "включить реле" после получения нажатия в интерфейсе или выполнения нужных условий в каком-нибудь правиле.
Принцип работы системы сообщений
MQTT построена по следующему принципу: есть иерархическая система "топиков" (прямо как на обычных форумах), куда клиенты могут писать сообщения, и откуда могут читать. Чтобы было удобно следить за изменениями нужного топика (например, температуры), на него можно "подписаться".
Пример сообщения
Вот пример сообщения от драйвера датчика 1-Wire (драйвер регулярно опрашивает датчик и отправляет в виде сообщений значения с него):
/devices/wb-w1/controls/28-000004a7d3f9 24.687000
Часть до пробела - название топика, после - само сообщение. Здесь:
- /devices - коренной топик для всех "устройств" - как встроенных модулей Wiren Board (реле, АЦП, ...), так и подключённых внешних,
- /wb-w1 - подтопик, который наполняется драйвером 1-Wire,
- /controls - подтопик, который есть у всех устройств - именно в него записываются все их параметры, которые меняются ("включено-выключено", значение датчика, ...),
- /28-000004a7d3f9 - непосредственно сам "контрол" - топик, куда записывается значение с датчика. Его название совпадает с адресом 1-Wire датчика (аппаратно закладывается в каждый датчик на заводе),
- 24.687000 - значение температуры. Это и есть содержание сообщения, отправленного драйвером 1-Wire в топик.
Пример подписки
Клиенты, которые хотят следить за значением температуры, "подписываются" на этот топик, и им приходят все новые сообщения - меняющиеся значения температуры. Один из таких клиентов - веб-интерфейс.
Подписаться на сообщения можно и из консоли Linux при помощи утилиты mosquitto_sub:
root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/controls/28-000004a7d3f9' -v /devices/wb-w1/controls/28-000004a7d3f9 20.312000 /devices/wb-w1/controls/28-000004a7d3f9 20.312000 /devices/wb-w1/controls/28-000004a7d3f9 20.375000
(описание утилиты смотрите [1]).
Подписаться можно не только на один топик, но и на группу по wildcard:
root@wirenboard:~# mosquitto_sub -t '/devices/wb-w1/#' -v /devices/wb-w1/meta/name 1-wire Thermometers /devices/wb-w1/controls/28-000004a7d3f9 23.312000 /devices/wb-w1/controls/28-000004a7d3f9/meta/type temperature /devices/wb-w1/controls/28-000004a7d3f9 23.312000 /devices/wb-w1/controls/28-000004a7d3f9 23.312000
, где # - означает любое количество топиков. Соответственно, вывелись не только значения с "контрола" устройства, но и топики с метаданными - название драйвера устройства и тип "контрола" - temperature.
Полное описание системы топиков и подписок: [2].
Пример сообщения от веб-интерфейса
Подпишемся на сообщения о состоянии встроенного реле Wiren Board:
root@wirenboard:~# mosquitto_sub -t '/devices/wb-gpio/controls/Relay_1/#' -v /devices/wb-gpio/controls/Relay_1/meta/type switch /devices/wb-gpio/controls/Relay_1/on 0 /devices/wb-gpio/controls/Relay_1 0
Тут стоит отметить, что MQTT сохраняет часть сообщений (а именно с флагом retained) вечно, поэтому после подписки вы получите даже те сообщения, которые были отправлен раньше, чем вы подписались.
Реле управляется драйвером wb-gpio (этот драйвер также управляет транзисторными выходами и всем, что в электрическом смысле управляется GPIO). У него есть соответствующий топик-"контрол" Relay_1. У него самого есть значение - 0 (реле выключено), и есть два подтопика. Один из них - служебный: в /meta/type записан тип "контрола". Здесь он switch - выключатель. Второй подтопик /on - интереснее: в него клиенты пишут то состояние, в которое они хотят установить реле. Заметим, что оно может не совпадать с тем состоянием, в котором реле находится, так как драйвер реле ведёт себя следующим образом: при получении сообщения в топик /devices/wb-gpio/controls/Relay_1/on он физически устанавливает его на реле, а лишь затем записывает новое значение реле в топик /devices/wb-gpio/controls/Relay_1.
Например, если мы сейчас нажмем на реле в веб-интерфейсе (переключим его состояние), то получим новые сообщения:
/devices/wb-gpio/controls/Relay_1/on 1 /devices/wb-gpio/controls/Relay_1 1
- веб-интерфейс сначала "даёт указание" включить реле, потом драйвер его включает и ставит актуальное состояние в "контрол".
Управление устройствами из командной строки
Как следует из написанного выше, для управления устройством (изменения значения канала), необходимо отправить сообщение в топик "/devices/<device-id>/controls/<control-id>/on" (обратите внимание на /on в конце). Это легко сделать с помощью консольной команды mosquitto_pub . Пример:
mosquitto_pub -t "/devices/wb-gpio/controls/Relay_1/on" -m "1"
команда включает реле 1 (канал "Relay_1" устройства "wb-gpio").
Отображение устройств в системе сообщений
Логика топиков, соответствующих разным устройствам и их параметрам, основывается на так называемых Conventions. Список актуальных типов здесь: [3]
Очистка сообщений MQTT
Ненужные retained-сообщения могут остаться в системе MQTT после удаления неиспользуемых драйверов или отключения каких-либо устройств. Это приводит к тому, что несуществующие больше устройства могут отображаться в разделе Devices веб-интерфейса.
Для удаления топиков можно воспользоваться командой mqtt-delete-retained.
Использование:
mqtt-delete-retained <маска mqtt>
например:
mqtt-delete-retained '/devices/noolite_tx_1234/#'
- удалит все топики, начинающиеся на '/devices/noolite_tx_1234/'
Использование данных внешними программами
Для многих языков программирования есть библиотеки MQTT. Примеры программ:
Система правил
Вы можете написать свои правила на языке Javascript. Подробнее смотрите [6]