- Introduced multivent ventilation configuration for managing multiple zones. - Added PID heating batteries configuration for temperature control. - Created relay GPIO switch configuration for controlling relays. - Implemented RGBW LED strip configuration for lighting control. - Added Modbus CO2 sensor configuration for environmental monitoring. - Introduced Sonoff S26 humidity controller example for humidity management. - Created sprinkler irrigation configuration for garden management. - Added thermostat on/off relay configuration for heating and cooling control. - Implemented ventilation fan monitoring configuration for performance tracking. - Added core concepts documentation for LightHub, detailing items, commands, and execution objects.
18 KiB
Основные принципы LightHub
Этот раздел объясняет базовые сущности, на которых построен контроллер: item (канал), itemCmd (унифицированная команда) и execObj (унифицированный объект действия). Понимание этих трёх вещей делает предсказуемым всё остальное: конфигурацию, MQTT-топики, поведение модулей и расширение системы новыми типами устройств.
Раздел адресован инженерам-интеграторам и разработчикам модулей.
1. Item — виртуальный канал
Item — это канал: единая абстракция для всего, чем LightHub управляет или что измеряет. Лампа за DMX, реле на GPIO, термостат, датчик 1-Wire, Modbus-устройство, кондиционер Haier, группа светильников, система полива — всё это items.
1.1 Как item описан в конфигурации
Каждый item — запись в глобальном объекте items JSON-конфигурации.
Имя записи — имя канала (оно же база MQTT-топика), значение — массив:
"items": {
"lamp_living": [0, 5],
"pump": [6, 23],
"heating": [13, [[500, 100, 10800], {"item": "rheat/set"}], 21]
}
Позиции массива фиксированы (см. item.h, I_TYPE…I_TIMESTAMP):
| Индекс | Поле | Содержимое |
|---|---|---|
| 0 | I_TYPE |
Тип канала CH_* (0–23) — выбирает драйвер |
| 1 | I_ARG |
Аргумент драйвера: пин, адрес или массив параметров |
| 2 | I_VAL |
Последнее значение (уставка) — сохраняется, переживает перезагрузку |
| 3 | I_CMD |
Последняя команда + служебные флаги |
| 4 | I_EXT |
Расширение драйвера |
| 5 | I_TIMESTAMP |
Отложенная команда (время срабатывания) |
В конфигурации обычно задают только [тип, аргумент]; остальные поля
контроллер создаёт и ведёт сам.
Опционально, можно задать третий параметр масива - значение, которое будет изначально записано в уставку канала при включении (при восстановлении состояния из топика MQTT оно будет перезаписано, если в топике сохранено предыдущее значение)
Также, можно определить четвертый параметр массива - команду, с которой будет инициализирован канал (по умолчанию OFF, но можно задать иное значение (в виде цифры). Также, будет перезаписано при восстановлении, если в топике сохранено предыдущее значение)
Специальная возможность: к значению этого параметра можно добавить специальное побитовое значение, которое инициализирует канал сразу с одним или несколькими специальными флагами, например, в заблокированном состоянии (см команда FREEZE), в котором команды и/или значения будут игнорироваться вплоть до команды UNFREEZE, или "Запрещенном" (команда DISABLE) состоянии, выход из которых возможен по команде ENABLE
Полный перечень флагов:
#define FLAG_DISABLED 0x100UL // 256 в десятичном виде
#define FLAG_LOCKED_CMD 0x200UL // 512 в десятичном виде
#define FLAG_LOCKED_SET 0x400UL // 1024 в десятичном виде
#define FLAG_FREEZED 0x600UL // 1536 - игнорируем и команду и значение
1.2 Тип канала выбирает драйвер, общее — наследуется
Тип канала (CH_RELAY, CH_PID, CH_MBUS, …) определяет драйвер —
модуль, который знает, как говорить с конкретной природой устройства.
Но все драйверы наследуются от общего базового класса (abstractOut),
поэтому у всех каналов есть одинаковый набор базовых свойств, работающих
одинаково для каналов разной природы:
-
Команды
ON / OFF / TOGGLE / HALT / REST / XON / XOFF / FREEZE / UNFREEZE / ENABLE / DISABLE— включая сквозные флаги:HALTгасит канал с возможностью обратного включения поREST;XON/XOFF— моментные включения;FREEZEблокирует изменения. -
Значения
/set— числовая уставка (яркость, температура, положение задвижки, скважность),/val— измеренное вовне значение полезное каналу. -
Отложенные команды —
ON 5000выполнится через 5 секунд (если направлено в суффикс /del) либо немедленно выполненная команда ON с отложенной через 5 сек противоположной командой (тут- OFF) если отправлено в суффикс /cmd -
Статусы — контроллер публикует состояние канала в MQTT и рассылает по CAN по единой схеме.
-
Группы — item типа
CH_GROUPпросто перечисляет имена других items; команда группе рекурсивно выполняется на всех членах. Группы могут вкладываться друг в друга и пересекаться. -
Персистентность — значение и команда канала хранятся в MQTT брокере и восстанавливаются после перезагрузки.
Именно поэтому, научившись управлять диммером, вы уже умеете управлять реле, термостатом и Modbus-устройством: интерфейс один, разница — только в аргументах драйвера.
1.3 Item с суффиксом: item/subitem/suffix
Канал адресуется строкой имя_канала/суффикс, где суффикс указывает,
какое свойство канала затрагивается (cmd, set, val, fan, mode,
hue, …). Ряд драйверов (MULTIVENT, HUMIDIFIER, SPRINKLER, MBUS) делит
один item на подканалы по имени: vents/zal3/set, hum/bedr1/cmd.
Имена подканалов — это ключи объекта-аргумента канала.
Полный список суффиксов — в справочнике суффиксов.
2. itemCmd — унифицированная команда
Всё, что приходит в канал, кодируется одной структурой — itemCmd.
Неважно, откуда пришло сообщение (MQTT, CAN, кнопка на входе, HTTP API,
другой item) и куда оно идёт: сначала оно разбирается в itemCmd, и уже
в этом виде передаётся каналу. Это «единая валюта» управляющего ядра.
2.1 Что внутри
itemCmd упаковывает в два 32-битных слова три вещи:
- Код команды (
CMD_*):ON,OFF,TOGGLE,HALT,REST,XON,XOFF,HEAT,COOL,AUTO,FAN_ONLY,DRY,HEAT_COOL,HIGH/MEDIUM/LOW,ENABLE/DISABLE,FREEZE/UNFREEZE,RGB,HSV,RESET— текстовые имена, массив кодов 1–0x19. - Тип значения + само значение (
ST_*): целое 0–255 (проценты), float (температура и пр), «десятые» целочисленное представление вещественного числа без потери точности (12.3 кодируется как 123), цвета HSV/RGB/RGBW и пр. - Суффикс (
S_*): какому свойству канала адресовано —cmd,set,val,fan,mode,hue,sat,temp,rawи т.д.
Команда и значение могут присутствовать одновременно: HEAT в /cmd
кондиционера — это команда; 22.5 в /set — значение с суффиксом set.
Одна и та же структура используется и в обратную сторону — статусы
каналов сериализуются из itemCmd в текст MQTT.
Такая плотная побитная упаковка позволяет уместить унифицированную команду/уставку/измерянное значение или статус канала всего в 64 бита - размер CAN сообщения, что делает возможным надежную коммуникацию между каналами в физически разных контроллерах по шине CAN,
2.2 Как это выглядит снаружи
По MQTT сообщение — это просто payload в топике канала с суффиксом:
house/lh1/pump/cmd ← ON (команда)
house/lh1/pump/set ← 128 (значение)
house/lh1/ac/cmd ← HEAT (команда)
house/lh1/ac/set ← 22.5 (значение, float)
house/lh1/rgb/HSV ← 240,100,200 (цвет)
house/lh1/lamp/cmd ← ON 5000 (отложенная команда, 5 сек)
Внутри конфигурации (EXEC-объекты, входы) команды задаются строками
"icmd": "TOGGLE", "icmd": "%+4" (инкремент текущего значения на 4) —
они разбираются тем же парсером в itemCmd.
2.3 Преобразования
Универсальность itemCmd позволяет ядру преобразовывать формулы между
форматами без знания о природе устройства:
-
map— линейное масштабирование значения и/или подстановка текстовых команд в числа регистра (для Modbus):"map": {"val": [400, 2000, 0, 100], "cmd": [["HEAT", 4], ["COOL", 2]]}. -
Проценты — 0–100 в топике без суффикса и 0–255 внутри.
3. execObj — унифицированный объект действия
execObj (EXEC-объект) — это маленький JSON-объект, описывающий
«что сделать». Он используется во многих модулях — везде, где нужно
описать реакцию: маршрутизация параметров Modbus-шаблона, каскады
MULTIVENT (cas), выходы PID-регулятора, обработчики кнопок и входов,
onFault спринклера, onextcmd центральной установки.
Исполнением занимается единая функция executeCommand (utils.cpp):
один и тот же формат работает и в конфиге, и во время исполнения.
3.1 Ключи execObj
{
"item": "имя_item[/subitem][/suffix]",
"emit": "MQTT-топик",
"can": [адрес_контроллера, номер_item, "суффикс", subitem],
"icmd": "команда/значение для item",
"ecmd": "payload для emit",
"map": { ...преобразование значения... }
}
| Ключ | Назначение |
|---|---|
item |
Вызвать локальный канал: строка имя/суффикс (например pump/cmd, ac/set). Если icmd не задан — передаётся само значение, с которым исполнен execObj |
emit |
Опубликовать в MQTT. Топик поддерживает подстановки ${ключ} из секции topics и ${sfx} — текущий суффикс |
can |
Отправить команду на другой контроллер LightHub по CAN-шине: [id_контроллера, id_item, суффикс], четвёртый элемент — номер подканала. На приёме адресуется в item целевого контроллера |
icmd |
Текст команды для item (ON, TOGGLE, %+4, число) |
ecmd |
Текст payload для emit; без него публикуется значение |
map |
Преобразование значения перед доставкой (см. преобразования map) |
Входы (секция in) дополнительно понимают пары icmd/irev, ecmd/
erev — чередующиеся команды для повторных срабатываний (например,
одна кнопка увеличивает яркость, повторное нажатие уменьшает).
3.2 Примеры
Значение регистратора Modbus → в PID и в MQTT:
"co2": {
"emit": "house/snsr/co2living/val",
"item": "co2living_pid/val",
"@S": null
}
Команда кнопки → включить локальный насос и отправить по CAN на контроллер 15, item 431:
"click": { "item": "pump/cmd", "icmd": "TOGGLE" },
"dclick": { "can": [15, 431, "cmd"], "icmd": "TOGGLE" }
Выход PID → уставка реле и каскад уставки на панель:
"tliving": [13,
[500, 100, 10800, 50, 200, 200, 30],
[
{ "item": "rliving/set" },
{ "item": "p_living/settemp" }
], 22]
execObj может быть массивом объектов — выполнятся все по очереди
(как в примере выше: два адресата одного значения). Строка вместо
объекта — тоже execObj (легаси-форма): она трактуется как emit.
3.3 Служебные пометки @S / @V
В объектах маршрутизации параметров Modbus (и аналогичных) используются служебные ключи-пометки:
"@S": 0— не публиковать статус повторно, если значение не изменилось;"@S": null— публикация при каждом опросе (для датчиков);"@V"— запоминание последнего отправленного значения (защита от «эха»: значение, записанное нами самими, не обрабатывается как изменение от устройства).
4. Как всё сходится
MQTT / CAN / кнопка / HTTP
│ (текст: "ON", "22.5", "HEAT")
▼
┌─────────┐
│ itemCmd │ унифицированная команда/значение
└────┬────┘
│ адресация: item/subitem/suffix
▼
┌───────────────────┐
│ Item (канал) │ общие свойства: команды, значения,
│ + драйвер CH_* │ статусы, группы, персистентность
└─────────┬─────────┘
│ (реакция модуля)
▼
┌─────────┐
│ execObj │ куда доставить результат: item / emit / can
└─────────┘
- Вход любой природы превращается в
itemCmd. itemCmdадресуется в item (канал) по имени и суффиксу.- Драйвер канала выполняет команду и/или вычисляет результат.
- Результат уходит наружу через
execObj: в другой item, в MQTT или на другой контроллер по CAN.
Смежные разделы: справочник суффиксов, типы каналов, техническая таблица типов, работа с MQTT, примеры конфигураций.