MQTT является, пожалуй, самым общим и распространенным протоколом в IoT
Работа контроллера LightHub полностью управляется при помощи данного протокола.
Прочитать про MQTT, а также, ознакомиться с основными принципами протокола и понятиями, которые используются далее, можно [[https://www.lazyhome.ru/index.php/featurerequest/15-overview/32-mqtt|тут]]
Именно MQTT является протоколом для интеграции контроллера в системы Умного Дома под управлением таких открытых систем автоматизации как [[интеграция_с_homeassistant|HomeAsistant]], [[openhab|OpenHab]], IOBroker, NodeRed и прочих. (по ссылками приведены примеры конфигураций систем Умного дома)
Теперь о том, как MQTT применяется в данном контроллере:
В общем виде, формат топика выглядит следующим образом:
root/id-устройства_или_bcst_или_out/имя_item-a/[subitem/]suffix
* **root**: это значение имеет смысл, если один брокер обслуживает много абсолютно независимых систем или пользователей. По умолчанию - myhome
* **id-устройства** - индивидуальное Имя контроллера, задаваемое в его конфигурации (к одному брокеру может быть подключен только один контроллер с конкретным именем. Если подключается второй с тем же именем - первый отключается).
* **bcst** - групповое (широковещательное) имя контроллера. Может быть одинаковое у многих контроллеров, подключенных к одному брокеру. Используя это имя, можно выдавать команду сразу на группу контроллеров (при этом, конечно, требуется чтобы item (устройство или группа устройств), которому адресована данная команда был настроем с одним именем на всех устройствах
* **item** - устройство или группа устройств, обслуживаемое данным контроллером. Настраивается в разделе items конфигурации
* **subitem** - значение, интерпретируемое драйвером устройства. Опционально
Для адресной светодиодной ленты: 10-20 будет значить, что команду надо применить к пикселям в интервале 10-20.
Также, если в качестве subitem указать значения из набора ON,OFF,HALT,AUTO,HEAT,COOL,DRY,FAN_ONLY то команда будет применена только к устройствам, находящимся в указанном состоянии. Очень удобно для управления группой устройств. Например, через топик //myhome/in/floor/AUTO/set// можно дать команду всем теплым полам в группе floor всех контроллеров. Команду выполнят только полы, находящимся в режиме AUTO. Теплые полы в режиме OFF или HEAT эту команду проигнорируют. Очень удобно, чтобы автоматически регулировать температуру в зависимости от времени суток/тарифов электроэнергии. В режиме Авто пол на автопилоте, но его можно или насильственно включить или выключить через тот же интерфейс Home Assistant.
* **suffix** - параметр определяет какое именно свойство объекта меняется. Может быть одним из стандартного набора **cmd,set** или значением, специфичным для конкретного устройства. Например, для кондиционера или термостата **mode,lock,swing,queit,fan** для цветного освещения: **hue,sat,hsv,rgb**. Подробнее - см ниже.
Имеются три типа топиков - командные, статусные и служебные
По командным - объекты контроллера получают инструкции извне, интерпретируют их, выполняют и изменившийся статус направляют в статусные топики.
Программы удаленного доступа используют статусные топики для отображения актуального текущего состояния устройств в своем интерфейсе, вне зависимости от того, как инициировано изменение, контроллер направит информацию об этом изменении в статусные топики. Данная информация публикуется контроллером с ключом PERSISTENT. Это позволяет любой программе управления, подключившись к брокеру и подписавшись на статусные топики, сразу получить от брокера и отобразить весь актуальный статус устройств. Брокер сам вышлет вновь подключившейся программе последний актуальный статус.
Также, в статусные топики направляется информация если состояние объекта контроллера изменилось в связи с локальными процессами (например, объект переключен при помощи локальных входов)
Служебные топики используются для нужд, напрямую не связанных с управлением устройствами. Предназначены для удаленного управления контроллером, для информационных сообщений от контроллера относительно настроенных топиков, времени работы, свободной памяти
===== Пример настройки MQTT в JSON конфигурации: =====
"mqtt":["LHexample03","test.mosquitto.org",1883,"user","password"],
"topics":{"root":"myhome","bcst":"in","out":"s_out"}
Настройка mqtt задает (в порядке следования):
* Имя контроллера (к одному брокеру может быть подключен только один контроллер с конкретным именем. Если подключается второй с тем же именем - первый отключается). В данном примере, используется имя **LHexample03**
* IP или доменное имя брокера
* Порт (по умолчанию, 1883)
* Имя пользователя и пароль (по умолчанию, отсутствуют)
===== MQTT топики =====
Настройка topics в примере выше, позволяет определить как формируются MQTT топики у данного контроллера
В данном примере:
**Командные топики (широковещательные):**
* myhome/in/<имя item>
* myhome/in/<имя item>/set
* myhome/in/<имя item>/cmd
**Командные топики (индивидуальные):**
* myhome/LHexample03/<имя item>
* myhome/LHexample03/<имя item>/set
* myhome/LHexample03/<имя item>/cmd
* myhome/LHexample03/<имя item>/<иной специфичный для устройства суффикс>
**Статусные топики:**
* myhome/s_out/<имя item>
* myhome/s_out/<имя item>/set
* myhome/s_out/<имя item>/cmd
(Именно это соответствует настройкам по-умолчанию, если вообще не указан раздел topics в конфигурации)
Зачем два типа командных топиков:
Через индивидуальный, можно управлять каждым контроллером домена в отдельности. Через общий широковещательный - выдавать команды сразу всем контроллерам, с одинаковым параметром //bcst//, если они подключены к одному брокеру и имеют одинаковый //root//
В старой версии контроллера, имя топика завершалось именем item для управления
В данный //совмещенный// топик можно отправлять как команды ON OFF HALT REST и прочие (см. ниже), так и установки канала (яркость, температура и пр.)
Отличительная особенность - запись в такой совмещенный топик ненулевого значения включает канал, запись нулевого - выключает канал;
Топики данного типа используются для интеграции с системой OpenHab
**Внимание, начиная с версии ПО 3.0.0 появилось различие:**
Топики с суффиксом /set и /hsv оперируют значениями 0..255 для настройки яркости/уровня PWM, одновременно с этим, в топиках без суффикса сохранена старая нотация 0..100 для совместимости с OpenHAB
===== Суффиксы =====
В последних версиях введено понятие "суффикс" (или окончание). Это значение, которое может находиться в конце топика и определяет то свойство канала, к которому надо применить параметр, полученный в Payload
В первую очередь, остановимся на суффиксах /set и /cmd
Использование их позволяет полностью разнести логику подачи команд каналу и логику установки параметров канала
Например, если канал диммера выключен, запись в топик с окончанием /set значения 60 не включит его, а задаст значение яркости 60 (из 255). Если следом отправить ON в топик с окончанием /cmd, диммер включится на заранее установленное значение (из 255) яркости. Данные топики крайне полезны для интеграции LightHub системами HomeAssistant, HomeBridge.
Кроме окончаний /cmd и /set возможны окончания, специфичные для того или иного типа устройства:
например, окончания
Кондиционер:
* /fan (значения HIGH, MEDIUM, LOW)
* /mode
* /lock (ON,OFF)
* /swing (ON,OFF)
* /quiet (ON,OFF)
Цветное освещение:
* /hue - цвет. Шкала 0-365
* /sat - насыщенность цвета. 0 - белый, 100 - максимально насыщенный
* /hsv - цвет в нотации hue,saturation,volume (три параметра через запятую). Также, этот формат принимается по-умолчанию при записи в иные топики
* /rgb - Цвет в нотации RGB или RGBW. (3 или 4 цифры, разделенные запятыми). В отличии от HSV нотации, формат не позволяет менять яркость канала путем передачи значения 0.255 в топик с окончанием /set. Но, как и в случае HSV, цвет сохраняется в MQTT брокере на случай перезапуска, работают команды ON, OFF, XON, XOFF, HALT, REST
===== Служебные топики =====
LightHub (во многом) руководствуется конвенцией [[https://homieiot.github.io/|homie]] для формирования структуры топиков MQTT. (Пока еще не полная поддержка, но основные моменты соблюдены)
В частности, контроллер использует топик $state, чтобы отражать текущее состояние ("ready" или "disconnected"), а в топик $stats, раз в 30 секунд передает uptime и размер доступной памяти
В командный топик $command (например, myhome/controllerName/$command можно записывать CLI команды, и они будут выполняться таким же образом, как и в случае получения через последовательный порт (см. [[cli_интерфейс]])
===== Важные для понимания моменты =====
При старте контроллер сам подписывается на свои статусные топики на период 5 секунд. Таким образом, он получает от MQTT брокера последнее состояние всех своих обьектов (items) и восстанавливает их значения на момент до старта
Принимая в качестве команд расширенный набор команд, контроллер интерпретирует их и в статусный топик передает уже интерпретированные значения.
Например, контроллер получил команду "ON" для RGB канала. Он восстанавливает из памяти последнее значения цвета, насыщенности и яркости (HSV) и в статусный топик передает уже эти значения
===== Команды и инструкции, которые могут быть переданы в Payload =====
=== Базовый набор команд (совместим с OpenHab):===
* ON - Включить канал. Если сохранились предыдущие значения (яркость, температура и пр) то эти значения будут восстановлены. (Исключение - если яркость была менее 30% то будет установлена яркость 30%). Если предыдущие значения не найдены, будут заданы значения по-умолчанию: Для света - белый, яркостью 100%, для термостата - 20 градусов цельсия
* OFF - Выключить канал
* - Задает яркость для света (с сохранением цвета), Температуру для термостата, уровень для PWM
* ,, - Color notation in Hue,Saturation,Volume
* , - Color notation in Hue,Saturation. Яркость остается неизменной. Сделано для простой интеграции с HomeAssistant, в котором разнесены установки яркости и цвета
=== Расширенный набор команд (также, данные команды работают для групп каналов):===
* HALT - выключить канал(группу)
* REST - включить канал(группу), канал будет включен только если он был успешно выключен перед этим командой HALT (крайне удобно для Master выключателей. Контроллер умеет включать только то, что было выключено при уходе)
* XON - включить канал (группу) (если это не запрещено командой DISABLE). Также см. [[работа_с_mqtt#команды_включаемые_на_время]]
* XOFF - выключить (но только при условии что канал был включен командой XON) - идеально для временного включения освещения по детектору движения
* TOGGLE: Переключать из состояния ON в OFF. Если применяется для группы - то принимается что если хоть один канал, входящий в группу включен - она активна и при получении TOGGLE произойдет выключение того, что включено. Последующая команда TOGGLE включит все каналы, входящие в группу.
* #AABBCC: Color notation in RGB - Home Remote app color picker compatible
* %-N : Уменьшить значение (яркость, уровень и пр) канала на N пунктов
* %+N : Увеличить значение (яркость, уровень и пр) канала на N пунктов
==== Команды, применимые для кондиционера и термостата:====
* AUTO
* HEAT
* COOL
* FAN_ONLY
* DRY
* HIGH
* MED
* LOW
Соответственно, данное значение может быть записано в командный топик термостата или кондиционера hbath1. Например: в "myhome/in/h_bath1/cmd"
Температура - в топик "myhome/in/hbath1/set"
Соответственно, термостат или кондиционер hbath1 свое состояние будет отражать в следующих статусных топиках:
* Режим работы: "myhome/s_out/hbath1/cmd"
* Установленная температура: "myhome/s_out/hbath1/set"
* Текущая температура: "myhome/s_out/tbath1"
==== Прочие команды: ====
* ENABLE для PID регулятора - разрешить авторегулирование, для всех каналов - разрешить команду XON
* DISABLE для PID регулятора - запретить авторегулирование, для всех каналов - запретить команду XON. Использование данной пары команд очень удобно для разрешения - запрещения сценариев временного включения канала. Например временного включения света по датчику движения.
* FREEZE - заблокировать канал, после этого он игнорирует поступающие команды
* UNFREEZE - разблокировать канал
Последние 4 команды передаются на статусный топик MQTT с суффиксом /ctrl вместо /cmd как для прочих команд. При рестарте контроллера, эти значения, также, считываются из статусных топиков и восстанавливаются. Это позволяет запоминать комбинации состояний канала в брокере. Например, канал может быть одновременно заблокирован и включен
* INCREASE N - увеличить значение канала на N (аналог %N)
* DECREASE N - уменьшить значение канала на N (аналог %-N)
==== Команды с задержкой ====
Команды "ON","OFF","REST","TOGGLE","HALT","XON","XOFF","INCREASE","DECREASE","ENABLE","DISABLE","UNFREEZE","FREEZE","AUTO","FAN_ONLY" могут быть выполнены с задержкой после получения, если вместо командный топик с суффиксом /cmd их направить в топик с суффиксом /del и в Payload после названия команды, через пробел, указать величину задержки в миллисекундах
==== Команды, включаемые на время ====
Если после команды указать целое положительное число, то команда будет выполнена, но спустя указанное время, будет выполнена обратная команда
Взаимно - Обратные Команды
* "ON","OFF",
* "TOGGLE","TOGGLE"
* "REST","HALT",
* "XON","XOFF",
* "INCREASE","DECREASE",
* "ENABLE","DISABLE",
* "UNFREEZE","FREEZE"
==== Команды, с криптографической подписью ====
В том случае, если надо гарантировать, что, даже получив доступ к локальной сети, MQTT брокеру или HTTP API, потенциальный злоумышленник не сможет выполнить критичную команду (например, открытие ворот), можно использовать механизм цифровой подписи команды.
подробное описание тут [[криптоподпись_команды]]