Files
lighthub/documentation/core/modules_real_config.md
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

26 KiB
Raw Permalink Blame History

LightHub: Модули управления и конфигурация

Описание реальных параметров модулей, загружаемых кодом. Основано исключительно на анализе исходных файлов C++.


Типы модулей (numbers в JSON)

Type Модуль Класс Описание
0 DMX out_dmx DMX512 управление освещением
3 PWM out_pwm Широтно-импульсная модуляция
4 Modbus Dimmer out_Modbus AC-диммер через Modbus RTU (legacy)
6 Реле out_relay Управление электромагнитным реле
10 AC out_AC Управление кондиционером (Haier, UART)
11 SPI LED out_SPILed Адресуемые светодиоды WS2812/APA102
12 Мотор out_Motor Управление моторами с обратной связью
13 PID out_pid PID-регулятор
14 Modbus out_Modbus Modbus устройства (general)
15 UART Bridge out_UARTbridge UART-мост между портами
16 RELAYX out_relay Медленный PWM через реле
18 Multivent out_Multivent Многозональная вентиляция
19 Лифт out_Elevator Управление лифтом (UART)
20 Счётчик out_counter Счётчик импульсов
21 Увлажнитель out_humidifier Форсуночное увлажнение
22 Меркурий out_Mercury Счётчик электроэнергии Меркурий
23 Полив out_sprinkler Система полива

1. out_counter — Счётчик

Конфигурация (Type 20)

"pumpctr": [20, [0.02, 1.2]],   // режим 2: автоинкремент (моторчасы)
"gasctr":   [20, 0]             // режим 1: внешние импульсы (газ)

Два режима работы

Режим 1 — внешние импульсы ([20], [20, вес] или [20, 0]): канал держит показание, вход контроллера добавляет к нему вес импульса командой %X в /set:

"waterctr": [20, 0],
...
"in": {
  "41": { "item": "waterctr/set", "scmd": "%0.01", "rcmd": "" }
}

Режим 2 — автоинкремент старт-стоп ([20, [импульс, период_сек]]): команды ON/OFF стартуют/останавливают таймер, каждые период секунд добавляется импульс. Типичное применение — наработка оборудования; старт/стоп привязывается через execObj (например, motorExecObj увлажнителя вызывает {"item": "pumpctr"} с ON/OFF при включении/выключении насоса).

Параметры массива (режим 2)

Индекс Тип Описание Пример
[0] float Импульс — приращение за период 0.02 (1 «минута» моторчасов)
[1] float Период накопления (сек) 1.2 сек

Логика работы (по коду, out_counter.cpp)

  1. ON-подобная команда (ON, HEAT, COOL, AUTO, FAN, DRY, HEATCOOL) или ненулевое /set запускают таймер (I_EXT = метка времени); OFF или /set 0 останавливают
  2. По истечении периода к значению канала (I_VAL, хранится в «десятых») добавляется импульс × 100
  3. Обновлённое значение публикуется в MQTT (/set)

Пример (реальная конфигурация, контроллер air)

{
  "items": {
    "hum": [21, [
      [22, 29, 61, 200, 600, 11, 20, 50],
      { "bedr3": { "N": 1, "pin": 30 } },
      { "item": "pumpctr" }
    ]],
    "pumpctr": [20, [0.02, 1.2]],
    "waterctr": [20, 0],
    "gasctr": [20, 0]
  },
  "in": {
    "41": { "item": "waterctr/set", "scmd": "%0.01", "rcmd": "" },
    "39": { "item": "gasctr/set", "scmd": "%0.1", "rcmd": "" }
  }
}

2. out_relay — Электромагнитное реле (Type 6)

Конфигурация

"pump": [6, [pin, period_сек]]

Параметры

Индекс Тип Описание Диапазон
[0] int GPIO пин (отрицательное = инвертировать) 0-54
[1] float Период цикла (сек), для RELAYX (16) любой > 0

Логика

  • HIGH (или LOW если инвертировано) = ON
  • LOW (или HIGH если инвертировано) = OFF
  • Если pin < 0, используется инверсия логики

Примеры

"relay_normal": [6, 33],
"relay_inverted": [6, -33],
"relay_with_period": [16, [32, 5]]

3. out_Motor — Управление моторами (Type 12)

Конфигурация

"roller_blind": [12, [pinUp, pinDown, pinFeedback, feedbackOpen, feedbackClosed, maxOnTime]]

Параметры

Индекс Тип Описание Диапазон Значение по умолч.
[0] int GPIO пин UP (отрицательное = инвертировать) 0-54 32
[1] int GPIO пин DOWN 0-54 33
[2] int GPIO пин обратной связи (аналоговый) 0-54 0
[3] int Значение обратной связи (открыто) 0-1024 0
[4] int Значение обратной связи (закрыто) 0-1024 1024
[5] int Максимальное время движения (мс) > 0 10000

Логика работы

  1. Модуль сравнивает targetPos (из команды 0-255) с curPos (из обратной связи)
  2. Если разница > POS_ERR (10):
    • Если targetPos < curPos → движение вниз (pinDown)
    • Если targetPos > curPos → движение вверх (pinUp)
  3. При достижении targetPos или maxOnTime мотор останавливается
  4. Защита от перегрузки: одновременно работают макс. MOTOR_QUOTE моторов (обычно 2)

Примеры

"blind_motor": [12, [32, 33, 36, 0, 1023, 120000]],
"gate_motor": [12, [-10, -11, 12, 100, 900, 60000]]

Управление

Команда: CMD_ON → движение вверх до конца
Команда: CMD_OFF → движение вниз до конца
Значение 0-255 → позиция (0=полностью открыто, 255=полностью закрыто)

4. out_PID — PID-регулятор (Type 13)

Конфигурация

"heater": [13, [
  [Kp, Ki, Kd, dT, alarmTO, alarmVal, outMin, outMax],
  {output_execObj},
  {cascade_execObj}
], setpoint]

Параметры массива [0]

Индекс Тип Описание Обязательный
[0] float Kp (пропорциональный) ✓
[1] float Ki (интегральный) ✓
[2] float Kd (дифференциальный) ✓
[3] float dT (период сэмплирования, сек) опционально (5 по умолч.)
[4] int Timeout будильника (сек) опционально
[5] float Порог будильника опционально
[6] float Минимум выхода опционально
[7] float Максимум выхода опционально

Логика

  • Kp < 0 → режим REVERSE (для охлаждения)
  • Kp > 0 → режим DIRECT (для нагрева)
  • Выход ограничивается [outMin, outMax]
  • dT = период опроса в секундах

Примеры

"room_temperature": [
  13,
  [
    [1.0, 0.05, 0.02, 5.0],
    {"item": "heater"},
    null
  ],
  21.5
]

5. out_PWM — ШИМ управление (Type 3)

Конфигурация

"led_brightness": [3, [pin0, pin1, ...]]

Параметры

Индекс Тип Описание
[0] int GPIO пин (1 канал) или массив пин

Число пин задаёт тип: 3 → RGB, 4 → RGBW, 5 → RGBWW. Частота PWM настраивается в коде, не в конфиге.

Примеры

"pwm_led": [3, 5],
"pwm_fan": [3, 6],
"pwm_rgbw": [3, [11, 12, 13, 14]]

6. out_relay (Type 6) — детально

Загружаемые параметры (getConfig)

pin = item->getArg(0);           // основной параметр
if (pin < 0) {
  pin = -pin;
  inverted = true;               // инвертировать логику
}
period = item->getFloatArg(1) * 1000.0;  // период из конфига в СЕКундах → мс
if (!period) period = 5000UL;    // по умолчанию 5 сек

Вывод: модуль загружает ровно 2 параметра; тот же драйвер используется для RELAYX (Type 16), где период определяет цикл ШИМ


7. out_counter (Type 20) — детально

Загружаемые параметры (Poll)

uint32_t impulse = item->getFloatArg(0) * TENS_BASE;  // [0] массива аргументов
uint32_t period = item->getFloatArg(1) * 1000.0;       // [1] в мс

Оба параметра читаются только в режиме автоинкремента ([20, [импульс, период]]); при скалярном аргументе автоинкремент отключён (period = 0) и канал работает как накопитель внешних импульсов (%X в /set).

Логика (out_counter.cpp):

  1. Пока таймер не запущен (getExt() = 0), Poll ничего не делает
  2. Команда ON (или HEAT/COOL/AUTO/FAN/DRY/HEATCOOL), а также ненулевое /set, записывают в I_EXT метку времени старта; OFF или /set 0 обнуляют её
  3. По истечении period к значению (I_VAL, в «десятых») добавляется impulse, метка времени сдвигается на период
  4. Публикуется обновлённое значение (FLAG_PARAMETERS)

8. out_Motor (Type 12) — детально

Загружаемые параметры (getConfig)

pinUp = item->getArg(0);                  // [0]
pinDown = item->getArg(1);                // [1]
pinFeedback = item->getArg(2);            // [2]
feedbackOpen = item->getArg(3);           // [3]
feedbackClosed = item->getArg(4);         // [4]
maxOnTime = item->getArg(5);              // [5], по умолчанию 10000 мс

Обработка отрицательных значений

if (pinUp < 0) {
  pinUp = -pinUp;
  inverted = true;
}
if (pinDown < 0) {
  pinDown = -pinDown;
  inverted = true;
}

9. out_PID (Type 13) — детально

Загружаемые параметры (getConfig)

aJsonObject * kPIDObj = aJson.getArrayItem(item->itemArg, 0);
// Обрабатывает случаи от 1 до 8 элементов:
// [Kp]
// [Kp, Ki]
// [Kp, Ki, Kd]
// [Kp, Ki, Kd, dT]
// [Kp, Ki, Kd, dT, alarmTO]
// [Kp, Ki, Kd, dT, alarmTO, alarmVal]
// [Kp, Ki, Kd, dT, alarmTO, alarmVal, outMin]
// [Kp, Ki, Kd, dT, alarmTO, alarmVal, outMin, outMax]

if (kP < 0) {
  kP = -kP;
  direction = REVERSE;  // Отрицательный Kp = режим REVERSE
}

Использование вторых параметров

store->setpoint = item->itemVal->valuefloat;  // Установка из JSON value

11. out_humidifier (Type 21) — Форсуночное увлажнение

Конфигурация

"hum": [21, [
  [pumpPin, flushPin, pressurePin, maxPumpTime, idleTime, capacity, minLevel, startLevel],
  {
    "zone1": {"N": 1, "pin": 24},
    "zone2": {"N": 2, "pin": 33}
  },
  {"item": "pumpctr"},
  255,
  2
]]

Параметры конфигурации [0] (массив переменной длины)

Индекс Тип Описание По умолч. Обязателен
[0] int GPIO пин насоса (отрицательное = инвертировать) 22 ✓
[1] int GPIO пин очистки (отрицательное = инвертировать) 23 опционально
[2] int GPIO пин датчика давления (аналоговый) 54 опционально
[3] int Макс. время работы насоса (сек) 255 опционально
[4] int Время ожидания между циклами (мс) 2500 опционально
[5] int Максимум одновременно открытых форсунок 4 опционально
[6] int Минимальный уровень (%) для включения форсунки 10 опционально
[7] int Пороговый уровень для запуска цикла (%) 20 опционально

Параметры зон (объект)

Каждая зона — это объект с полями:

"zone_name": {
  "N": 1,           // номер зоны для балансировки нагрузки
  "pin": 24         // GPIO пин электромагнитного клапана форсунки
}
Поле Тип Описание
N int Номер группы (1-4) для ограничения одновременно открытых клапанов
pin int GPIO пин клапана (отрицательное = инвертировать логику)
set float Требуемый уровень влажности (создаётся автоматически)
cmd int Статус команды (создаётся автоматически)

Счётчик импульсов

{"item": "pumpctr"}  // привязка к счётчику для контроля расхода

Пороги и состояния

Из кода определены константы:

PREPARATION_TIME = 10000 мс      // подготовка к пуску
PRESSURE_ACHIEVING_TIME = 8000 мс // время достижения давления
MIN_KEEP_TIME = 2500 мс            // минимальное время работы форсунки
FLUSH_PRESSURE = 200               // давление очистки
FLUSH_TIMEOUT = 125000 мс          // таймаут очистки
MIN_OPERATION_PRESSURE = 400       // минимальное рабочее давление
MAX_OPERATION_PRESSURE = 600       // максимальное рабочее давление

Состояния модуля

Состояние Код Описание
H_UNKNOWN 0 Неизвестное состояние
H_READY 1 Готов к работе
H_PREPARE_FOR_START 2 Подготовка к пуску
H_PREPARE_VALVES 3 Открытие форсунок
H_MOTOR_ON 4 Включение насоса
H_OPERATE 5 В режиме увлажнения
H_MOTOR_PAUSE 6 Пауза насоса
H_MOTOR_OFF 7 Выключение насоса
H_MOTOR_OFF_OK 10 Насос остановлен
H_FLUSH 8 Промывка системы
H_IDLE 9 Ожидание
H_FAULT_PRESSURE -1 Ошибка давления
H_FAULT_PRESSURE_KEEP -2 Потеря давления во время работы
H_FAULT_OVERPRESSURE -3 Перепад давления
H_FAULT_MOTOR_OFF -4 Отказ насоса

Логика работы

  1. Инициализация: модуль ждёт команду включения или когда уровень влажности > startLevel
  2. Подготовка: открывает клапаны форсунок, ждёт достижения давления
  3. Работа: включает насос, поддерживает давление в диапазоне [MIN_OPERATION_PRESSURE, MAX_OPERATION_PRESSURE]
  4. Балансировка: одновременно открыто не более capacity форсунок из группы N
  5. Очистка: периодическая промывка при давлении FLUSH_PRESSURE
  6. Контроль: отключение при падении давления ниже MIN_OPERATION_PRESSURE

Примеры конфигурации

Простая система увлажнения

{
  "items": {
    "humidifier": [21, [
      [22, 23, 54, 255, 2500, 4, 10, 20],
      {
        "bedroom": {"N": 1, "pin": 24},
        "living": {"N": 2, "pin": 25}
      },
      {"item": "waterctr"}
    ]]
  }
}

Многозональная система (из официального примера)

{
  "items": {
    "hum": [21, [
      [22, 15, 30, 4, 10, 20],
      {
        "bedr1": {"N": 1, "pin": 24},
        "ktc1": {"N": 1, "pin": 25},
        "dinner1": {"N": 1, "pin": 9},
        "bedr2m": {"N": 1, "pin": 8},
        "bedr21": {"N": 1, "pin": 11},
        "bedr22": {"N": 1, "pin": 12},
        "zal2": {"N": 2, "pin": 33},
        "cab3": {"N": 1, "pin": 32},
        "zal3": {"N": 4, "pin": 31},
        "bedr3": {"N": 1, "pin": 30}
      },
      {"item": "pumpctr"},
      255,
      2
    ]]
  }
}

12. out_Mercury (Type 22) — Счётчик электроэнергии

Конфигурация

"merc": [22, [
  0,                    // [0] адрес Modbus (обычно на выходе item)
  9600,                 // [1] скорость UART (baud)
  "8N1",                // [2] параметры кадра
  2,                    // [3] уровень доступа
  [2,2,2,2,2,2],       // [4] пароль (массив из 6 чисел)
  10000,                // [5] период опроса (мс)
  {}                    // [6] параметры (обычно пусто)
]]

Параметры массива

Индекс Тип Назначение
[0] int Адрес устройства (из item->getArg(0))
[1] int Скорость UART
[2] string Параметры (8N1, 8E1, 8O1)
[3] int Уровень доступа (обычно 2)
[4] array/string Пароль (6 символов или массив 6 чисел)
[5] int Интервал опроса (мс)
[6] object Дополнительные параметры

Примеры

"electricity_meter": [22, [
  1,
  9600,
  "8N1",
  2,
  [0x01, 0x02, 0x03, 0x04, 0x05, 0x06],
  60000,
  {}
]]

13. out_AC (Type 10) — Управление кондиционером

Конфигурация

"ac": [10, portNum],
"ac": [10, [
  portNum,          // [0] номер UART порта
  {callbacks}       // [1] объект колбэков: fan / set / temp / cmd
]]

Загружаемые параметры

portNum = item->getArg(0);  // 0=Serial, 1=Serial1, 2=Serial2, 3=Serial3

Проприетарный UART-протокол Haier (9600 baud), не Modbus; modbus-шаблонов для AC нет.

Поддерживаемые команды

Модуль работает с 37-байтовым протоколом:

Байт Назначение
13 Текущая температура
17 Статус команды
23 Режим (04=DRY, 01=COOL, 02=HEAT, 00=AUTO, 03=FAN)
25 Скорость вентилятора
27 SWING
28 Блокировка пульта
29 Питание
31 Fresh
35 Установка температуры

14. out_Modbus (тип MBUS) — Modbus устройства

Конфигурация общая

"modbus": {
  "device_name": {
    "baud": 9600,
    "serial": "8N1",
    "poll": {
      "regs": [[0, 40], [100, 20]],
      "irs": [[0, 10]],
      "coils": [0, 1],
      "dins": [0],
      "delay": 5000
    },
    "par": {
      "parameter_name": {
        "reg": 0,
        "type": "i16",
        "id": 1,
        "map": {}
      }
    }
  }
}

Items использование Modbus

"device_instance": [14, [
  96,                 // [0] modbus-адрес устройства (обязательно)
  "device_name",      // [1] имя шаблона (строка)
  {
    "power": {"emit": "home/ac/power"},
    "temp": {"emit": "home/ac/temp"}
  }
]]

Загружаемые параметры

// From template:
baud = baudObj->valueint;              // скорость (по умолчанию 9600)
serialParam = str2SerialParam(...);    // формат (по умолчанию 8N1)

// Poll strategy:
pollingRegisters = aJson.getObjectItem(pollObj, "regs");   // блоки Holding Reg
pollingIrs = aJson.getObjectItem(pollObj, "irs");           // Input Reg
pollingCoils = aJson.getObjectItem(pollObj, "coils");       // Coil Reg
poolingDiscreteIns = aJson.getObjectItem(pollObj, "dins");  // Discrete In
pollingInterval = delayObj->valueint;  // по умолчанию 1000 мс

Типы данных в параметрах

type Описание
i16 int16
i32 int32
u16 uint16
u32 uint32
i8h старший байт
i8l младший байт
u8h старший байт unsigned
u8l младший байт unsigned
x10 ×0.1 (сырое значение / 10)
100 ×0.01 (сырое значение / 100)

Параметры в "par"

"parameter": {
  "reg": 0,              // Holding Register номер
  "ir": 0,               // Input Register номер
  "coil": 0,             // Coil номер
  "type": "i16",         // тип данных
  "id": 1,               // ID команды
  "map": {               // маппинг значений
    "cmd": [["OFF",0], ["ON",1]],
    "val": null,
    "def": "acmode"
  }
}

15. out_Multivent (Type 18) — Многозональная вентиляция

Конфигурация

itemArg — объект с зонами (не массив), рабочая форма [[18, нач_значение], {зоны}]:

"vac": [[18, 5],
  {
    "": {            // AC-узел: привязка к AC item
      "item": "ac_2"
    },
    "zone1": {       // зона 1
      "pid": [490, 100, 9879, 40],
      "set": 21.0,
      "fan": 0,
      "cmd": 14,
      "item": "ac_zone1/set"
    }
  }
]

Параметры зоны

Параметр Тип Описание
pid [kP, kI, kD, dT] Коэффициенты PID (массив ≥3)
set float Уставка температуры (число)
fan int (0-255) Текущий процент открытия
cmd int Текущая команда
item string Привязка к другому item
V int Номинальный объём (для балансировки)
AlarmTime int Время срабатывания аварии, деф 120
AlarmValue float Значение аварии, деф 0

Практические примеры конфигурации

Система со счётчиками

{
  "items": {
    "pumpctr": [20, [0.02, 1.2]],
    "gasctr": [20, 0.1],
    "waterctr": [20, 0]
  },
  "in": [
    {"#": 41, "item": "waterctr/set", "scmd": "%0.01", "rcmd": ""},
    {"#": 39, "item": "gasctr/set", "scmd": "%0.1", "rcmd": ""}
  ]
}

Система с реле и мотором

{
  "items": {
    "pump": [6, 33],
    "blind": [12, [32, 33, 36, 0, 1023, 120000]]
  }
}

PID регулятор

{
  "items": {
    "heater": [13, [
      [1.0, 0.05, 0.02, 5.0],
      {"item": "heater_output"},
      null
    ], 22.0]
  }
}

Ключевые правила конфигурации

  1. Инверсия логики: отрицательное значение пина = инвертировать логику
  2. Единицы времени:
    • counter/relay: float конвертируется в миллисекунды (* 1000)
    • mercury: миллисекунды напрямую
  3. Параметры по умолчанию:
    • relay period = 5000 мс
    • motor maxOnTime = 10000 мс
    • modbus baud = 9600
    • modbus polling = 1000 мс
  4. Массивы переменной длины: PID и Mercury поддерживают опциональные параметры

Документ основан на анализе C++ кода без домыслов
Версия: 1.0
Дата: 2026-01-21