mirror of
https://github.com/anklimov/lighthub
synced 2026-03-14 05:16:31 +03:00
723 lines
22 KiB
Markdown
723 lines
22 KiB
Markdown
# 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. |