Files
lighthub/documentation/modules_real_config.md

723 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LightHub: Модули управления и конфигурация
> Описание реальных параметров модулей, загружаемых кодом.
> Основано исключительно на анализе исходных файлов C++.
---
## Типы модулей (numbers в JSON)
| Type | Модуль | Класс | Описание |
|------|--------|-------|---------|
| 1 | Реле | out_relay | Управление электромагнитным реле |
| 3 | Мотор | out_Motor | Управление моторами с обратной связью |
| 6 | Счётчик | out_counter | Счётчик импульсов |
| 9 | PWM | out_pwm | Широтно-импульсная модуляция |
| 10 | SPI LED | out_SPILed | Адресуемые светодиоды WS2812/APA102 |
| 11 | DMX | out_dmx | DMX512 управление освещением |
| 14 | Multivent | out_Multivent | Многоканальный кондиционер/вентиляция |
| 17 | PID | out_pid | PID-регулятор |
| 20 | Счётчик v2 | out_counter | Счётчик (улучшенная версия) |
| 21 | Увлажнитель | out_humidifier | Форсуночное увлажнение |
| 22 | Меркурий | out_Mercury | Счётчик электроэнергии Меркурий |
| 50 | Лифт | out_Elevator | Управление лифтом (UART) |
| 55 | UART Bridge | out_UARTbridge | UART-мост между портами |
| 128 | AC | out_AC | Управление кондиционером |
| MBUS | Modbus | out_Modbus | Modbus устройства (general) |
---
## 1. out_counter — Счётчик импульсов
### Конфигурация (Type 20)
```json
"pumpctr": [20, [0.02, 1.2]],
"gasctr": [20, 0]
```
### Параметры массива
| Индекс | Тип | Описание | Пример |
|--------|-----|---------|--------|
| [0] | float | Импульс (накопление за период) | 0.02 л/импульс |
| [1] | float | Период накопления (сек) | 1.2 сек |
### Логика работы
1. Модуль ждёт команду (S_SET или любой CMD)
2. При получении команды с процентом > 0 запускается таймер
3. По истечении периода [1] добавляется значение [0] * TENS_BASE
4. Считанное значение публикуется в MQTT
### Пример использования
```json
{
"items": {
"water_meter": [20, [0.01, 5.0]],
"gas_meter": [20, [0.1, 10.0]]
}
}
```
---
## 2. out_relay — Электромагнитное реле
### Конфигурация
```json
"pump": [1, [pin, period]]
```
### Параметры
| Индекс | Тип | Описание | Диапазон |
|--------|-----|---------|----------|
| [0] | int | GPIO пин (отрицательное = инвертировать) | 0-54 |
| [1] | float | Период (мс) | любой > 0 |
### Логика
- HIGH (или LOW если инвертировано) = ON
- LOW (или HIGH если инвертировано) = OFF
- Если pin < 0, используется инверсия логики
### Примеры
```json
"relay_normal": [1, [33]],
"relay_inverted": [1, [-33]],
"relay_with_period": [1, [32, 5000]]
```
---
## 3. out_Motor — Управление моторами
### Конфигурация
```json
"roller_blind": [3, [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)
### Примеры
```json
"blind_motor": [3, [32, 33, 36, 0, 1023, 120000]],
"gate_motor": [3, [-10, -11, 12, 100, 900, 60000]]
```
### Управление
```
Команда: CMD_ON → движение вверх до конца
Команда: CMD_OFF → движение вниз до конца
Значение 0-255 → позиция (0=полностью открыто, 255=полностью закрыто)
```
---
## 4. out_PID — PID-регулятор
### Конфигурация
```json
"heater": [17, [
[Kp, Ki, Kd, dT, alarmTO, alarmVal, outMin, outMax],
{"in": {...}, "set": 22.0, "out": {...}}
]]
```
### Параметры массива [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 = период опроса в секундах
### Примеры
```json
"room_temperature": [
17,
[
[1.0, 0.05, 0.02, 5.0],
{
"in": {"emit": "sensors/room/temp"},
"set": 21.5,
"out": {"emit": "hvac/heating"}
}
]
]
```
---
## 5. out_PWM — ШИМ управление
### Конфигурация
```json
"led_brightness": [9, [channel, freq, {}]]
```
### Параметры
| Индекс | Тип | Описание |
|--------|-----|---------|
| [0] | int | Канал / GPIO пин |
| [1] | int | Частота PWM (Hz) |
### Примеры
```json
"pwm_led": [9, [5, 1000]],
"pwm_fan": [9, [6, 500]]
```
---
## 6. out_relay (Type 1) — детально
### Загружаемые параметры (getConfig)
```cpp
pin = item->getArg(0); // основной параметр
if (pin < 0) {
pin = -pin;
inverted = true; // инвертировать логику
}
period = item->getFloatArg(1) * 1000.0; // период в мс
if (!period) period = 5000UL; // по умолчанию 5 сек
```
**Вывод**: модуль загружает ровно 2 параметра
---
## 7. out_counter (Type 20) — детально
### Загружаемые параметры (Poll)
```cpp
uint32_t impulse = item->getFloatArg(0) * TENS_BASE; // [0]
uint32_t period = item->getFloatArg(1) * 1000.0; // [1] в мс
```
**Логика**:
1. Модуль ждёт активации (getExt() = 0)
2. При получении команды ON/HEAT/COOL/etc запускает таймер
3. По истечении period добавляет impulse к накопленному значению
4. Публикует обновлённое значение
---
## 8. out_Motor (Type 3) — детально
### Загружаемые параметры (getConfig)
```cpp
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 мс
```
### Обработка отрицательных значений
```cpp
if (pinUp < 0) {
pinUp = -pinUp;
inverted = true;
}
if (pinDown < 0) {
pinDown = -pinDown;
inverted = true;
}
```
---
## 9. out_PID (Type 17) — детально
### Загружаемые параметры (getConfig)
```cpp
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
}
```
### Использование вторых параметров
```cpp
store->setpoint = item->itemVal->valuefloat; // Установка из JSON value
```
---
## 11. out_humidifier (Type 21) — Форсуночное увлажнение
### Конфигурация
```json
"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 | опционально |
### Параметры зон (объект)
Каждая зона — это объект с полями:
```json
"zone_name": {
"N": 1, // номер зоны для балансировки нагрузки
"pin": 24 // GPIO пин электромагнитного клапана форсунки
}
```
| Поле | Тип | Описание |
|------|-----|---------|
| `N` | int | Номер группы (1-4) для ограничения одновременно открытых клапанов |
| `pin` | int | GPIO пин клапана (отрицательное = инвертировать логику) |
| `set` | float | Требуемый уровень влажности (создаётся автоматически) |
| `cmd` | int | Статус команды (создаётся автоматически) |
### Счётчик импульсов
```json
{"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
### Примеры конфигурации
#### Простая система увлажнения
```json
{
"items": {
"humidifier": [21, [
[22, 23, 54, 255, 2500, 4, 10, 20],
{
"bedroom": {"N": 1, "pin": 24},
"living": {"N": 2, "pin": 25}
},
{"item": "waterctr"}
]]
}
}
```
#### Многозональная система (из официального примера)
```json
{
"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) — Счётчик электроэнергии
### Конфигурация
```json
"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 | Дополнительные параметры |
### Примеры
```json
"electricity_meter": [22, [
1,
9600,
"8N1",
2,
[0x01, 0x02, 0x03, 0x04, 0x05, 0x06],
60000,
{}
]]
```
---
## 13. out_AC (Type 128) — Управление кондиционером
### Конфигурация
```json
"ac": [128, [
portNum, // [0] номер UART порта (опционально)
{parameters} // параметры управления
]]
```
### Загружаемые параметры
```cpp
portNum = item->getArg(0); // 0=Serial, 1=Serial1, 2=Serial2, 3=Serial3
```
### Поддерживаемые команды
Модуль работает с 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 устройства
### Конфигурация общая
```json
"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
```json
"device_instance": [14, [
"device_name",
{
"power": {"emit": "home/ac/power"},
"temp": {"emit": "home/ac/temp"}
}
]]
```
### Загружаемые параметры
```cpp
// 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 | умножить на 10 |
| 100 | умножить на 100 |
### Параметры в "par"
```json
"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 14) — Многоканальный кондиционер
### Конфигурация
```json
"vac": [14, [
"haier", // имя шаблона Modbus
{
"": { // центральная установка
"val": {"emit": "home/ac/temp"},
"mode": {"emit": "home/ac/mode"}
},
"zone1": { // зона 1
"pid": [490, 100, 9879, 40],
"set": 21.0,
"fan": 0,
"cmd": 14,
"item": "ac_zone1/set"
}
}
]]
```
### Параметры зоны
| Параметр | Тип | Описание |
|----------|-----|---------|
| `pid` | [Kp, Ki, Kd, dT] | Коэффициенты PID |
| `set` | float | Требуемая температура |
| `fan` | int (0-255) | Текущий процент открытия |
| `cmd` | int | Текущая команда |
| `item` | string | Привязка к другому item |
| `V` | int | Номинальный объём (для балансировки) |
---
## Практические примеры конфигурации
### Система со счётчиками
```json
{
"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": ""}
]
}
```
### Система с реле и мотором
```json
{
"items": {
"pump": [1, [33]],
"blind": [3, [32, 33, 36, 0, 1023, 120000]]
}
}
```
### PID регулятор
```json
{
"items": {
"heater": [17, [
[1.0, 0.05, 0.02, 5.0],
{
"in": {"emit": "sensors/temp"},
"set": 22.0,
"out": {"emit": "heating/power"}
}
]]
}
}
```
---
## Ключевые правила конфигурации
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**
1. * 1.