Files
lighthub/documentation/core/core_concepts.md
T
andry f496e30600 Add configuration examples for various devices and functionalities
- 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.
2026-10-15 19:11:34 +03:00

18 KiB
Raw Blame History

Основные принципы 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, примеры конфигураций.