Files
lighthub/documentation/modules/multivent_module_description.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

729 lines
37 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: Модуль многоканального кондиционера и вентиляции (out\_Multivent)
> Документ описывает назначение, архитектуру и конфигурирование модуля управления многозональными системами кондиционирования и вентиляции LightHub.
> Предназначен для инженеров HVAC-систем, интеграторов и разработчиков.
> Верифицирован по исходному коду `lighthub/modules/out_multivent.cpp` и
> рабочим конфигурациям.
---
## 1. Назначение модуля
### 1.1 Область применения
Модуль `out_Multivent` предназначен для управления системами кондиционирования и вентиляции с **центральной установкой** и **множеством независимых зон/комнат**.
### 1.2 Типовые сценарии
#### Сценарий 1: Многозональный кондиционер
- Центральная сплит-система или компактная установка (1 компрессор, 1 вентилятор)
- Несколько помещений с электромоторными задвижками (воздушными затворами)
- Каждое помещение требует своего микроклимата
#### Сценарий 2: Многозональная приточная вентиляция
- Центральная приточная установка с одним вентилятором
- Несколько независимых воздуховодов с регулируемыми задвижками
- Распределение воздушного потока в зависимости от потребностей зон
#### Сценарий 3: Комбинированная система (климат + вентиляция)
- Центральный кондиционер + приточная вентиляция
- Управление как охлаждением/нагревом, так и циркуляцией воздуха
### 1.3 Ключевые возможности
- **Балансировка воздушного потока** — автоматическое распределение производительности между зонами
- **PID-регулирование температуры** — независимая стабилизация для каждой зоны
- **Интеллектуальное переключение режимов** — автоматическое определение HEAT/COOL по температуре воздуха в канале центральной установки
- **Агрегация команд** — управление центральной установкой на основе суммарного спроса от зон (boost)
- **Каскадирование** — передача состояний зон и центральной установки на внешние системы (панели, MQTT)
- **Отслеживание ручного управления центральной установкой** — если режим/уставка центрального кондиционера изменены с пульта, модуль принимает это как инструкцию: выключение установки останавливает все зоны (чтобы исключить немедленный автореверс), повторное включение восстанавливает их состояние
---
## 2. Архитектура и принцип работы
### 2.1 Компоненты системы
```
┌────────────────────────────────────────────┐
│ Центральная установка (AC-узел, "") │
│ (компрессор, вентилятор, датчик temp) │
│ Управляется по S_MODE / S_FAN / S_SET │
└──────────────┬─────────────────────────────┘
│
┌─────┴─────┐
│ │
┌────▼─────┐ ┌─▼─────────┐
│ Зона 1 │ │ Зона N │
│ Задвижка1│ │ ЗадвижкаN │
│ PID, V │ │ PID, V │
└──────────┘ └───────────┘
```
### 2.2 Логика работы (Poll)
#### Фаза 1: Определение режима центральной установки
Модуль определяет режим AC по температуре воздуха в канале (`""/val`):
- `val < 15 °C` → COOL
- `15 °C ≤ val ≤ 30 °C` → FAN
- `val > 30 °C` → HEAT
Если температура не поступала более 60 секунд, значение инвалидируется,
и режим берётся из последнего известного режима AC (`""/mode`).
#### Фаза 2: PID-расчёты по зонам
Для зон в режиме HEAT/COOL с активным PID:
- Вход PID: текущая температура зоны (`val`)
- Установка: требуемая температура зоны (`set`)
- Выход PID: `po` (0…255)
Направление PID задаётся автоматически по режиму AC: HEAT → DIRECT,
COOL → REVERSE. Знак коэффициента `kP` в конфигурации задаёт направление
по умолчанию (положительный — DIRECT, отрицательный — REVERSE).
В режимах FAN/AUTO ("слабые" режимы) и в пассивном режиме PID
принудительно включается, как только AC переходит в HEAT/COOL. Пока AC
вентилятирует, PID переводится в MANUAL, и запросы воздуха в зоны
берутся из последнего внешнего значения `/fan` зоны (`fan_in`).
#### Фаза 3: Балансировка (только для зон с активным PID в HEAT/COOL)
```
balance = Σ(po_zone) для зон в HEAT
balance -= Σ(po_zone) для зон в COOL
```
#### Фаза 4: Boost центральной установки
- `balance > boost` (по умолчанию 230) → уставка AC принудительно
поднимается до 30 °C (HEAT) / опускается до 17 °C (COOL), прежняя
уставка запоминается в `@preset`
- `|balance| < 10` (deadband) → активный PID-запрос считается
отсутствующим, boost сбрасывается
#### Фаза 5: Выбор команды центральной установки
- Если активных PID-запросов нет (`pidActive == false`): boost
сбрасывается; если хотя бы одна зона в AUTO (`autoRequested`) или
FAN (`ventRequested`) и вентилятор уже ненулевой (`lastACfan > 0`),
на AC уходит соответствующая команда. Если запросов нет — на AC
команда не отправляется вовсе (экономия)
- Итоговый уровень вентилятора (`lastACfan` от PID зон) отправляется
на AC
#### Фаза 6: Распределение производительности по задвижкам
Для каждой зоны пересчитывается выходной сигнал задвижки:
$$out = \frac{(V\_{zone} \times fan\_{zone}) \times 255}{V\_{zone}} \times \frac{V\_{max}}{V\_{max} \times fan\_{max}} = fan\_{zone} \times \frac{V\_{max}}{fan\_{max} \times V\_{zone}} \times 255$$
практически: относительный запрос зоны нормируется на самую требующую
зону, итоговый `out` в диапазоне 0…255 отправляется в item задвижки
(поле `item` зоны или каскад). Если суммарный запрос равен нулю, задвижки
не трогаются (остаются в текущем положении).
---
## 3. Структура JSON-конфигурации
### 3.1 Формат item типа VENTS (18)
```json
"item_name": [
18,
{
"zone_1": { ... },
"zone_2": { ... },
"": { ... }
}
]
```
Объект маршрутизации содержит **именованные зоны** + **пустую строку** `""`
для центральной установки.
ВАЖНО: поля `fan`, `cmd`, `out` зоны и центральной установки — это
**числовые** ячейки внутреннего состояния, а не маршрутизация. Если вместо
числа записать объект `{"emit": ...}`, зона будет **проигнорирована
целиком** (драйвер проверяет `fan` и `cmd` на целочисленность). Маршрутизация
значений наружу делается полями `item` и `cas` (см. ниже).
### 3.2 Структура зоны
```json
"zone_name": {
"V": 60,
"pid": [-1.0, 0.1, 0.05, 5.0],
"set": 21.0,
"val": 21.0,
"fan": -1,
"cmd": 1,
"out": -1,
"item": "damper_zal1/set",
"cas": {
"fan": {"emit": "house/f_room1/fan"},
"cmd": {"can": [15, 331, "cmd"]},
"set": {"item": "panel1/settemp"}
}
}
```
#### Поля зоны:
| Поле | Тип | Назначение |
|------|-----|-----------|
| `fan` | int (0-255, инициализируется -1) | Текущий запрос воздуха зоны. Управляется суффиксом `/fan` зоны или встроенным PID (в активных режимах). Значение хранится в конфиге и переживает перезагрузку |
| `cmd` | int (код CMD\_*) | Текущий режим зоны (ON/OFF/HEAT/COOL/FAN/AUTO/HEATCOOL/DRY). Инициализируется CMD\_OFF (2) |
| `out` | int (0-255, инициализируется -1) | Финальный выходной сигнал задвижки после балансировки |
| `V` | int | Номинальный объём воздуха зоны (в относительных единицах), по умолчанию 60 |
| `pid` | объект или массив ≥3 | ПИД-регулятор: `[kP, kI, kD, dT(сек, по умолчанию 5)]` либо `{"kP":..,"kI":..,"kD":..,"dT":..}`. Знак kP задаёт направление: `>0` — DIRECT (нагрев), `<0` — REVERSE (охлаждение). При наличии `pid` создаются числовые ячейки `set` (по умолчанию 20.0), `val` (NaN), `po` (-2.0) |
| `set` | float | Уставка температуры зоны (вход PID) |
| `val` | float | Текущая температура зоны (вход PID, суффикс `/val`) |
| `AlarmTime` | сек | Время устаревания данных PID (по умолчанию 120 с) |
| `AlarmValue` | float | Порог аварии PID (по умолчанию 0.0) |
| `item` | строка | Item-цель по умолчанию для выходного сигнала задвижки (`out`). При изменении `out` в item отправляется значение 0-255 |
| `cas` | объект | Каскадирование изменений зоны на внешние объекты. Под-объекты `fan`, `cmd`, `set` — обычные EXEC-объекты (`item`/`emit`/`can`/`map`), исполняются при изменении соответствующего свойства зоны |
### 3.3 Центральная установка (пустая зона `""`)
```json
"": {
"item": "ac_2",
"turnbyfan": 15,
"boost": 200,
"supress": 7,
"overridecmd": 1,
"onextcmd": {"emit": "house/vent/extcmd"}
}
```
#### Поля:
| Поле | Назначение |
|------|-----------|
|`item`| Item центральной установки (обычно MBUS-канал кондиционера/вентустановки). Команды AC (mode/fan/set) отправляются в него |
|`turnbyfan`| Команда (код CMD\_), генерируемая при подаче ненулевого `/fan` в зону, если зона в CMD\_OFF; при `/fan=0` зона автоматически переводится в CMD\_OFF. 0 — отключено |
|`boost`| Порог \|balance\| (по умолчанию 230). При превышении модуль принудительно поднимает/опускает уставку AC (set) до 30/17 °C |
|`supress`| Битмаска подавления повторной отправки на AC: 1=FAN, 2=SET, 4=CMD (по умолчанию 0xF — всё). **В коде ключ пишется «supress» (одна s)** |
|`overridecmd`| Подмена команды, уходящей на AC, любой другой, кроме CMD\_OFF |
|`onextcmd`| EXEC-объект (с опциональной `map`), исполняемый при **ручном** изменении режима или уставки AC на пульте/извне |
| `val` | Температура воздуха в канале AC (вход `/val` центрального item; определяет HEAT/COOL/FAN) |
| `mode` | Текущий режим AC (вход `/cmd` или `/mode` центрального item) |
| `set` | Уставка температуры AC (сохраняется при получении `/set`) |
| `@lastCmd`, `@lastFan`, `@lastSet`, `@preCmd`, `@preset` | Служебные: последнее отправленное состояние, состояние до останова вентилятора, уставка до boost |
---
## 4. Детальная конфигурация компонентов
### 4.1 PID-контроллер
#### Формат
```json
"pid": [1.0, 0.05, 0.02, 5.0]
```
или объектом:
```json
"pid": {"kP": -1.0, "kI": 0.05, "kD": 0.02, "dT": 50},
"AlarmTime": 240,
"AlarmValue": 128
```
- **kP** (пропорциональный коэффициент): 0.5—2.0. Знак задаёт направление
регулятора: положительный — DIRECT (растёт при set > val, нагрев),
отрицательный — REVERSE (растёт при set < val, охлаждение)
- **kI** (интегральный): 0.0—0.2 — устраняет постоянное отклонение
- **kD** (дифференциальный): 0.01—0.1 — снижает колебания
- **dT** (период сэмплирования, сек): по умолчанию 5
`AlarmTime` и `AlarmValue` — поля зоны, а не `pid`.
### 4.2 Объём воздуха (V)
Указывается в **относительных единицах** (не обязательно м³/ч), по
умолчанию 60. Используется для пропорционального распределения между
зонами.
### 4.3 Каскадные команды (`cas`)
`cas` — обычный EXEC-объект с тремя под-объектами: `fan`, `cmd`, `set`.
Каждый исполняется (с полным синтаксисом `item`/`emit`/`can`/`map`) при
изменении соответственно вентилятора, режима или уставки зоны. Полезен
для дублирования состояния зоны на климатическую панель, другой
контроллер по CAN или в MQTT-топик для Home Assistant.
```json
"cas": {
"fan": {"emit": "house/f_room1/fan", "map": {"cmd": "fan"}},
"cmd": {"item": "panel1/mode"},
"set": {"item": "panel1/settemp"}
}
```
Без `cas` изменения зоны всё равно публикуются в статусные топики item'а
(`/cmd`, `/fan`, `/set` зоны) — каскад нужен именно для внешних адресатов.
---
## 5. Режимы работы модуля
### 5.1 Команды зон
Команды задаются в `/cmd` зоны (или через `/fan`):
| Команда | Код | Поведение |
|-----|-----|-----------|
| `ON` | 1 | Включить зону с последним режимом (из `@precmd`, по умолчанию FAN) и последним уровнем вентилятора |
| `OFF` | 2 | Выключить зону (PID в MANUAL, вентилятор 0); предыдущий режим сохраняется в `@precmd` |
| `HEAT` | 0x14 | Нагрев: PID в DIRECT, вентилятор минимум 30 % |
| `COOL` | 0x15 | Охлаждение: PID в REVERSE, вентилятор минимум 30 % |
| `HEATCOOL` | 0x13 | Автовыбор HEAT/COOL по уставке и текущей температуре с гистерезисом 1 °C |
| `FAN` (FAN\_ONLY) | 0xF | Только вентиляция с текущим уровнем `/fan` |
| `AUTO` | 0xE | Пассивный режим: запрос воздуха берётся из внешних значений `/fan` (например, от CO2-PID) |
| `DRY` | 0x16 | Осушение (PID в REVERSE, как COOL) |
| `FREEZE` | 0xD | Заморозка зоны: блокирует `/fan`, ON и OFF |
| `UNFREEZE` | 0xC | Разморозка зоны |
Уровни вентилятора через `/fan` зоны: `HIGH` → 255, `MEDIUM` → 128,
`LOW` → 64; либо число 0-255; `OFF` → 0.
### 5.2 Определение режима центральной установки
```
AC temp < 15°C → CMD_COOL
15°C ≤ AC temp ≤ 30°C → CMD_FAN
AC temp > 30°C → CMD_HEAT
```
Температура подаётся на `/val` корневого item (без subitem). Если данные
от AC не поступали более 60 секунд, режим берётся из `""/mode`.
При обнаружении тепла или холода PID регуляторы зон автоматически
активируются, их выходы направляются в балансировщик, а прямое управление
`/fan` зон блокируется (последнее внешнее значение запоминается в
`fan_in`). При переходе установки обратно в режим вентиляции используется
последнее значение `fan_in` каждой зоны, и система возвращается в режим
распределения воздуха по внешним запросам `/fan`.
### 5.3 Поведение в режимах зон
- **HEAT/COOL (активный режим)**: вентилятор зоны задаётся выходом PID.
Если при этом фактический режим воздуха противоположный (AC дует
холодом, а зона просит HEAT), задвижка зоны закрывается (`fan = 0`).
- **FAN/AUTO (пассивный режим)**: PID работает только когда AC реально
греет/охладит; в остальное время уровень зоны берётся из `fan_in`.
Пассивный режим включается командой `/fan AUTO` (статус публикуется
как `AUTO`), снимается любой явной командой или `/fan <уровень>`.
---
## 6. Примеры конфигурации
### 6.1 Минимальный рабочий пример: приточная вентиляция на 2 зоны
Центральная установка — Modbus-вентустановка (`vent`), зоны открываются
PWM-каналами. Запросы воздуха в зоны приходят по MQTT (`/fan`).
```json
{
"mqtt": ["lh1", "192.168.1.10"],
"topics": {"root": "house"},
"items": {
"ac_multizone": [
[18, 5],
{
"bedroom": {
"V": 40,
"pid": [1.0, 0.05, 0.02, 5.0],
"set": 21.0,
"cmd": 15,
"fan": -1,
"out": -1,
"item": "damper_bedroom/set",
"cas": { "fan": {"emit": "house/climate/bedroom/fan"} }
},
"living_room": {
"V": 80,
"pid": [1.0, 0.05, 0.02, 5.0],
"set": 22.0,
"cmd": 15,
"fan": -1,
"out": -1,
"item": "damper_living/set",
"cas": { "fan": {"emit": "house/climate/living/fan"} }
},
"": {
"item": "vent",
"turnbyfan": 15,
"val": -1,
"mode": 2
}
}
],
"damper_bedroom": [3, 5, null, null],
"damper_living": [3, 6, null, null],
"vent": [14, [4, "airset", {
"tset": {"emit": "house/vent/set", "@V": null},
"pmode": {"emit": "house/vent/cmd", "@V": null},
"fanspeed": {"emit": "house/vent/fan", "@V": null},
"on": {"emit": "house/vent/oncmd", "@V": null},
"$temp": {"item": "ac_multizone/val", "@S": null}
}], null]
}
}
```
Здесь `cmd: 15` (FAN\_ONLY) — зоны стартуют в режиме вентиляции;
`turnbyfan: 15` — подача ненулевого `/fan` в выключенную зону сама
переводит её в FAN\_ONLY. Температура воздуха в канале (`$temp` из Modbus)
заводится на `/val` корневого item — модуль по ней определяет HEAT/COOL.
### 6.2 Многозональный кондиционер Haier + CO2-вентиляция (рабочая схема)
Полный пример рабочей системы: центральный кондиционер Haier по Modbus,
зоны с задвижками на мотор-приводах, температуры зон — по 1-Wire,
запросы воздуха — от PID-регуляторов CO2.
```json
{
"mqtt": ["lh2", "192.168.1.4"],
"topics": {"root": "house"},
"ow": {
"283A3F81E3503CC8": {"emit": "t_ac2", "item": "vac"},
"286C3381E3823CBC": {"emit": "t_zal", "item": "vac/zal"},
"28B41581E3563CDE": {"emit": "t_bedr21", "item": "vac/bedr21"},
"28C1A581E3563C2D": {"emit": "t_bedr22", "item": "vac/bedr22"}
},
"modbus": {
"haier": {
"baud": 9600,
"serial": "8N1",
"poll": {
"regs": [[0, 3]],
"irs": [[0, 1]],
"coils": [0],
"delay": 10000
},
"par": {
"pwr": {
"coil": 0,
"map": {"cmd": [1, ["OFF", 0]], "def": 40001},
"id": 1
},
"acmode": {
"reg": 1,
"map": {
"cmd": [
["FAN_ONLY", 4],
["HEAT", 2],
["COOL", 1],
["DRY", 3],
["AUTO", 5]
],
"val": null
},
"id": 1
},
"$temp": {"ir": 0},
"set": {"reg": 0, "id": 2},
"fan": {
"reg": 2,
"id": 7,
"map": {
"cmd": [
["LOW", 1],
["HIGH", 3],
["MEDIUM", 2],
["AUTO", 4]
],
"val": [1, 255, 1, 3]
}
}
}
}
},
"items": {
"ac_2": [
14,
[
"haier",
{
"pwr": {"emit": "house/ac/cmd", "item": "vac/mode", "@V": null},
"$temp": {"emit": "house/ac/temp", "item": "vac/temp", "@S": null},
"set": {"emit": "house/ac/setpoint", "item": "vac/set"},
"acmode":{"emit": "house/ac/mode", "@V": null},
"fan": {"emit": "house/ac/fan", "@V": null}
}
]
],
"vac": [
[18, 5],
{
"": {"item": "ac_2"},
"zal": {
"pid": {"kP": 490, "kI": 100, "kD": 9879, "dT": 40},
"set": 21.0,
"fan": 0,
"cmd": 14,
"item": "acgzal/set"
},
"bedr21": {
"pid": {"kP": 490, "kI": 100, "kD": 9879, "dT": 40},
"set": 21.0,
"fan": 0,
"cmd": 14,
"item": "acgbedr21/set"
},
"bedr22": {
"pid": {"kP": 490, "kI": 100, "kD": 9879, "dT": 40},
"set": 21.0,
"fan": 0,
"cmd": 14,
"item": "acgbedr22/set"
}
}
],
"acgzal": [7, ["ig2", "og1"]],
"acgbedr21": [7, ["ig4", "og3"]],
"acgbedr22": [7, ["ig1", "og2"]],
"og1": [12, [4, 33, 58, 629, 289, 5000]],
"og2": [12, [5, 32, 59, 631, 296, 5000]],
"og3": [12, [6, 31, 60, 627, 289, 5000]],
"ig1": [12, [8, 29, 62, 623, 286, 5000]],
"ig2": [12, [7, 30, 63, 634, 296, 5000]],
"ig4": [12, [11, 27, 65, 620, 289, 5000]]
}
}
```
**Как это работает:**
- **`ac_2`** (тип MBUS): кондиционер Haier. Опрос 10 сек. Параметр `pwr`
(coil 0) — питание: `map.cmd` по умолчанию (первый элемент) означает
«команда OFF → значение 0», запись 1 включает; `def` подставляет
значение регистра `acmode` при записи питания
питания. `acmode` и `fan` маппят текстовые команды HA в коды регистров.
- **`vac`** (тип VENTS): модуль мультизоны. Корневой AC-узел `""`
связан с `ac_2` (`"item": "ac_2"`): температура из `$temp` идёт на
`/val` (определение HEAT/COOL), команды режима/вентилятора/уставки
уходят обратно в `ac_2`.
- **Зоны**: `cmd: 14` (HEATCOOL) — автопереключение нагрев/охлаждение.
Температура зоны — 1-Wire в `/val` зоны (через item `vac/zal` и т.п.),
уставка `/set` зоны. Выход PID идёт в `fan` зоны, а итоговый `out`
отправляется в item группы (`acgzal` — группа задвижки-вход этой зоны).
- **Задвижки**: тип MOTOR (12) с припасовкой (позиция по резистору
обратной связи), группы `acg*` объединяют мотор задвижки и мотор
привода заслонки.
### 6.3 Каскадирование состояния зоны на панель и CAN (фрагмент)
```json
"zal3": {
"V": 200,
"can": [13, 41, "set"],
"cas": {
"fan": { "can": [13, 31, "fan"] },
"cmd": { "can": [13, 31, "cmd"] }
},
"cmd": 1,
"fan": -1,
"out": -1
}
```
- `"can": [13, 41, "set"]` в теле зоны — target по умолчанию: сигнал
`out` (0-255, положение задвижки) уходит на CAN-устройство 13, item 41,
суффикс `set` (аналогично работает поле `item` для локальных items).
- `cas.fan` / `cas.cmd` — дублирование режима и уровня вентилятора зоны
на другой item/устройство (например, на климатическую панель на
контроллере 13).
---
## 7. Протокол управления через MQTT
Топики статусов: `<root>/s_out/<item>/...`. Команды: `<root>/<controller>/<item>/...`
(контроллер здесь — имя MQTT-подключения, см. конфигурацию `mqtt`).
### 7.1 Отправка команд
```
# Команда зоны
house/lh2/vac/zal/cmd <- HEAT | COOL | FAN_ONLY | AUTO | ON | OFF
# Уровень вентилятора зоны (число 0-255 или HIGH/MEDIUM/LOW)
house/lh2/vac/zal/fan <- 128
# Уставка температуры зоны
house/lh2/vac/zal/set <- 22.5
# Текущая температура зоны (вход PID)
house/lh2/vac/zal/val <- 21.8
```
### 7.2 Получение статусов
```
house/s_out/vac/zal/cmd <- HEAT / COOL / FAN_ONLY / OFF
house/s_out/vac/zal/fan <- 0-255 (текущий запрос зоны)
house/s_out/vac/zal/out <- 0-255 (положение задвижки)
house/s_out/vac/zal/set <- уставка зоны
house/s_out/ac_2/cmd <- режим центральной установки
house/s_out/ac_2/fan <- вентилятор центральной установки
house/s_out/ac_2/temp <- температура в канале AC
```
Фактические значения в статусных топиках зависят от `map` шаблона
Modbus-устройства (в примере §6.2: HEAT=2, COOL=1, FAN\_ONLY=4, DRY=3, AUTO=5).
---
## 8. Алгоритм балансировки воздушного потока
### 8.1 Принцип
Модуль распределяет воздух пропорционально запросам зон, нормируя на
самую требующую зону.
### 8.2 Пример расчёта
Исходные данные (fan в диапазоне 0…255):
- Зона 1: V=40, fan=200 → запрос = 40 × 200 = 8000
- Зона 2: V=80, fan=180 → запрос = 80 × 180 = 14400 (максимальная)
Расчёт выходов:
- Зона 1: `out = (8000 × 255 / 40) × 80 / 14400 ≈ 283 → 255 (кап)`
- Зона 2: `out = (14400 × 255 / 80) × 80 / 14400 = 255`
Результат: обе задвижки полностью открыты, поскольку суммарная
производительность не избыточна. Если бы запросы были меньше (например,
fan=50 и fan=60), вторая зона получила бы 255, а первая пропорционально
меньшую долю — так достигается баланс.
---
## 9. Служебные поля (в конфиг-дереве)
```json
"@lastCmd": -1, // Последняя отправленная AC команда
"@lastFan": -1, // Последнее отправленное значение вентилятора AC
"@lastSet": -1, // Последняя отправленная уставка AC
"@preCmd": 15, // Режим AC до останова вентилятора, восстанавливается при повторном запуске
"@preset": 21, // Уставка AC, сохранённая перед boost
"@precmd": 15, // Режим зоны до OFF, восстанавливается при ON
"@preHaltcmd": 0, // Команда зоны до глобального останова (stopAllzones)
"@pasv": 0, // Флаг пассивного режима зоны
"fan_in": 0, // Последнее внешнее значение /fan зоны
"po": -2.0 // Выход PID (внутреннее)
```
## 10. Интеграция с внешними системами
### 10.1 Задвижки
Выход `out` зоны направляется через `item` зоны (или `can`/`cas`) в
PWM-канал, мотор-привод или группу:
```json
"damper": [3, 5, null, null] // PWM-выход
"damper": [12, [4, 33, 58, 629, 289, 5000]] // мотор-привод с обратной связью
```
### 10.2 Датчики температуры
Текущая температура зоны подаётся на `/val` зоны (1-Wire, Modbus, MQTT):
```json
"ow": {
"283A3F81E3503CC8": {"emit": "t_ac2", "item": "vac"} // корневой item - на AC-узел
}
```
### 10.3 Центральная установка через Modbus
AC-узел `""` связывается с Modbus-каналом через `item` и получает
телеметрию через параметры шаблона (`item`/`emit` в описании параметров):
`$temp` → `/val` корневого item, `acmode` → `/mode`, `fan` → `/fan`,
`set` → `/set`.
---
## 11. Рекомендации по эксплуатации
### 11.1 Настройка PID
1. Начальные значения: kP=1.0, kI=0.05, kD=0.02, dT=5 с
2. Постепенно увеличивайте kP до появления колебаний, затем снижайте
3. Добавьте kI для устранения постоянного отклонения
4. Добавьте kD для демпфирования
5. В рабочих конфигурациях LightHub используются короткие импульсные
исполнительные механизмы, поэтому встречаются сильно форсированные
коэффициенты (например, kP в сотни единиц) с большой dT — не
копируйте их в другую систему без настройки
### 11.2 Распределение объёмов (V)
- Сумма V должна соответствовать производительности центральной установки
- Для равномерного распределения: V ≈ площадь помещения
- Для приоритизации: увеличьте V критичным зонам
### 11.3 Мониторинг
- Следите за `balance` в логах (`VENT: Chan balance=`) — в установившемся
режиме должен быть близок к нулю
- Проверяйте `out` зон — не должны постоянно висеть на 0 или 255
- Контролируйте переходы HEAT↔COOL — они не должны быть частыми
### 11.4 Диагностика проблем
| Проблема | Причина | Решение |
|----------|---------|---------|
| Зона игнорируется целиком (нет в статусах) | `fan` или `cmd` зоны заданы объектом вместо числа | Поля `fan`/`cmd`/`out` — только числовые; маршрутизация через `item`/`cas` |
| Задвижка не реагирует | `out` зоны = 0 | Зона в OFF или фактический режим AC противоположен запросу зоны — проверьте `/cmd` зоны и режим AC |
| Вентилятор AC не включается от запроса зоны | Вентилятор уже был 0 и нет активного PID | Подайте ненулевой `/fan` или настройте `turnbyfan` |
| Колебания температуры | PID слишком агрессивен | Снизьте kP |
| Не достигается setpoint | PID недостаточен | Увеличьте kI |
| AC часто переключается | balance скачет | Увеличьте dT в PID |
---
## 12. Ограничения и известные особенности
1. **Автономный dT**: у каждого PID-регулятора зон свой период
сэмплирования dT, задаётся отдельно для каждой зоны
2. **Порядок обработки**: сначала зоны, потом центральная установка
3. **Гистерезис режимов**: автоматическое переключение AC может быть
медленным (до 60 сек при отсутствии данных о температуре канала)
4. **Состояние хранится в конфиге**: значения `fan`/`cmd`/`out` зон
сохраняются в JSON-конфиге и переживают перезагрузку (в отличие от
истории команд)
5. **Поля-числа**: `fan`, `cmd`, `out` зон и AC-узла — числовые ячейки;
объектная запись в них ломает обработку зоны
---
## 13. Заключение
Модуль `out_Multivent` предоставляет полнофункциональное решение для
управления многозональными системами климатизации:
- Автоматическая балансировка воздушного потока
- Независимое PID-регулирование для каждой зоны
- Автоматическая агрегация команд (boost)
- Каскадирование состояния на внешние системы
---
**Версия документа:** 2.0
**Дата:** 2026-10-11
**Статус:** Верифицировано по исходному коду