# LightHub: Модуль многоканального кондиционера и вентиляции (out_Multivent)

> Документ описывает назначение, архитектуру и конфигурирование модуля управления многозональными системами кондиционирования и вентиляции LightHub.
> Предназначен для инженеров HVAC-систем, интеграторов и разработчиков.

---

## 1. Назначение модуля

### 1.1 Область применения

Модуль `out_Multivent` предназначен для управления системами кондиционирования и вентиляции с **центральной установкой** и **множеством независимых зон/комнат**.

### 1.2 Типовые сценарии

#### Сценарий 1: Многозональный кондиционер
- Центральная сплит-система или компактная установка (1 компрессор, 1 вентилятор)
- Несколько помещений с электромоторными задвижками (воздушными затворами)
- Каждое помещение требует своего микроклимата

#### Сценарий 2: Многозональная приточная вентиляция
- Центральная приточная установка с одним вентилятором
- Несколько независимых воздуховодов с регулируемыми задвижками
- Распределение воздушного потока в зависимости от потребностей зон

#### Сценарий 3: Комбинированная система (климат + вентиляция)
- Центральный кондиционер + приточная вентиляция
- Управление как охлаждением/нагревом, так и циркуляцией воздуха

### 1.3 Ключевые возможности

✅ **Балансировка воздушного потока** — автоматическое распределение производительности между зонами

✅ **PID-регулирование температуры** — независимая стабилизация для каждой зоны

✅ **Интеллектуальное переключение режимов** — автоматическое определение HEAT/COOL по текущей температуре

✅ **Агрегация команд** — управление центральной установкой на основе суммарного спроса от зон

✅ **Каскадное управление** — возможность передачи команд на внешние системы (например, отображение режимов на стеновых панеляж управления)

✅ **Отслеживание прямого управления основным кондиционером** — система понимает, явились ли изменения режима работы основного кондиционера причиной ее управляющих воздействий. И если обнаруживает, что режим поменялся вручную, при помощи пульта управления центральной установкой, принимает это изменение как инструкцию к действию. А именно: при выключении основного блока с пульта - все виртуальные зоны выключаются. (чтобы предотвратить немедленное автоматическое обратное включение) При обратном включении - их состояние восстанавливается. Также, можно определить какую либо из виртуальных зон для управления с пульта главного кондиционера.

❌ **Ограничения**: ?

---

## 2. Архитектура и принцип работы

### 2.1 Компоненты системы

```
┌────────────────────────────────────────────┐
│      Центральная установка (AC)            │
│  (компрессор, вентилятор, датчик temp)     │
│                                            │
│  Управляется через S_MODE и S_FAN          │
└──────────────┬─────────────────────────────┘
               │
         ┌─────┴─────┐
         │           │
    ┌────▼─────┐  ┌─▼─────────┐
    │ Зона 1   │  │  Зона N   │
    │ Задвижка1│  │ ЗадвижкаN │
    │ Датчик1  │  │ ДатчикN   │
    └──────────┘  └───────────┘
```

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

#### Фаза 1: Опрос и сбор информации
1. Модуль считывает текущий режим центральной установки (`mode`)
2. Определяет текущую функцию (HEAT, COOL, FAN)
3. Собирает команды от всех зон

#### Фаза 2: PID-расчёты
Если в зоне определён PID-контроллер:
- Вход PID: текущая температура зоны (`val`)
- Установка: требуемая температура зоны (`set`)
- Выход PID: регулировочный сигнал (`po`, от 0 до 255)

#### Фаза 3: Балансировка
```
balance = Σ(po_zone) где cmd=HEAT
balance = Σ(-po_zone) где cmd=COOL
```

#### Фаза 4: Управление центральной установкой
- **balance > 0** → отправить HEAT на AC
- **balance < 0** → отправить COOL на AC
- **balance = 0** → отправить FAN (если кто-то запросил)
- **else** → OFF

#### Фаза 5: Распределение производительности
Для каждой зоны пересчитывается выходной сигнал задвижки:

$$out = \frac{(V_{requested} \times 255) \times V_{max}}{V \times P_{max}}$$

где:

- $V_{requested}$ — требуемый объём воздуха для зоны
- $V$ — номинальный объём воздуха зоны
- $V_{max}$ — объём максимально требующей зоны
- $P_{max}$ — максимальный процент открытия требующей зоны

---

## 3. Структура JSON-конфигурации

### 3.1 Формат item типа 18 (Multivent)

```json
"item_name": [
  18,
  [
    {
      "zone_1": { ... },
      "zone_2": { ... },
      "": { ... }
    }
  ]
]
```

- Объект маршрутизации содержит **именованные зоны** + **пустую строку** `""` для центральной установки и общих настроек

### 3.2 Структура зоны

```json
"zone_name": {
  "fan": 0,
  "cmd": 2,
  "out": 255,
  "V": 60,
  "pid": [1.0, 0.1, 0.05, 5.0],
  "set": 21.0,
  "val": 21.0,
  "cas":{
                                    "fan":{"item":"panel1${sfx},"emit":"f_room1${sfx}","map":{"cmd":"fan"}}, 
                                    "set":{"item":"panel1${sfx}},
                                    "cmd":{"item":"panel1${sfx}}}}
}
```

#### Поля зоны:

| Поле | Тип | Назначение |
|------|-----|-----------|
| `fan` | int (0-255) | Текущий запрос в воздухе для зоны. Этот параметр устанавливается как встроенным PID регулятором  так и при помощи суффикса /fan данной зоны (изменение запускает процесс пере-балансировки зон, в результате формируется параметр out, который уже подается на задвижки  |
| `cmd` | int | Текущая команда (OFF/ON/HEAT/COOL и т.д. в числовом виде) |
| `out` | int (0-255) | Финальный выходной сигнал задвижки (пересчитанный) |
| `V` | int | Номинальный объём воздуха для этой зоны (м³/ч) |
| `pid` | array[4-6] | Коэффициенты PID: [Kp, Ki, Kd, dT(сек)] |
| `set` | float | Требуемая температура (установка) |
| `val` | float | Текущая температура зоны. Передается через суффикс /val данной зоны |
| `cas` | object | Каскадирование полученной команды на другие обьекты. Полезно, если изменение статуса зоны надо, наример, отразить на климатической панели. Или если скорость вентилятора надо преобразовать в дискретный вид (LOW,MEDIUM,HIGH) и передать в отдельный топик (как в примере) для отображения в интерфейсе Home Assistant. У обьекта cas может быть три под-обьекта: fan, set, cmd которые могут отдельно транслировать скорость вентилятора, команду (режим) зоны и уставку температуры. Следует заметить, что даже без использования данной настройки, изменения зоны передаются в статусный топик зоны (для восстановления состояния при перезапуске и отражения в интерфейсе HA, так что дублировать это в данной настройке не требуется. Но данная настройка крайне полезна именно для дублирования состояния на внешние устройства а также на внутренние обьекты контроллера (отрабатывается весь синтаксис EXEC обьекта, включая возможность передачи по MQTT, CAN, локальные items)   |

### 3.3 Центральная установка (пустая зона `""`)

```
"":{"item":"ac_2",
	"turnbyfan":0,
	"boost":200,
	"supress":7,
	"onextcmd":{"emit":"${sout}/vac/extcmd","item":"vac/zal"}
	}
```

#### Поля:

| Поле | Назначение |
|------|-----------|
|`turnbyfan`||
|`boost`||
|`suppress`|
|`onextcmd`||
| `val` | Температура воздуха от AC (или текущее состояние) |
| `mode` | Текущий режим AC (CMD\_HEAT/CMD\_COOL/CMD\_FAN/CMD\_OFF) |
| `@lastCmd` | Последняя отправленная команда (служебное) |
| `roomtemp` | Дополнительный датчик комнатной температуры |

---
\
## 4. Детальная конфигурация компонентов

### 4.1 PID-контроллер

#### Включение PID

```json
"pid": [1.0, 0.1, 0.05, 5.0, 120, 128]
```

**Формат**: `[Kp, Ki, Kd, dT, alarmTime, alarmValue]`

- **Kp** (пропорциональный коэффициент): 0.5—2.0

- **Ki** (интегральный коэффициент): 0.0—0.2
  - Устраняет постоянное отклонение

- **Kd** (дифференциальный коэффициент): 0.01—0.1
  - Снижает колебания

- **dT** (период сэмплирования, сек): по умолчанию 5 сек


#### Пример для зоны, заданный в виде массива:

```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]
```

## 4.2 Объём воздуха (V)

Указывается в **относительных единицах** (не обязательно м³/ч):

```json
"V": 60
```

Используется для **пропорционального распределения** между зонами.

**Рекомендуемые значения:**
- Спальня: 30—50
- Гостиная: 60—100
- Офис: 40—80
- Кухня: 80—150 (если есть вентиляция)

### 4.3 Маршрутизация MQTT

tbd

### 4.4 Каскадные команды

Возможность передачи команды на другие устройства (например, открыть задвижку, вывести на панель):

```json
  "cas":{
                                    "fan":{"item":"panel1${sfx},"emit":"f_room1${sfx}","map":{"cmd":"fan"}}, 
                                    "set":{"item":"panel1${sfx}},
                                    "cmd":{"item":"panel1${sfx}}}}
```

---

## 5. Режимы работы модуля

### 5.1 Режимы команд для зон

| CMD | Назначение |
|-----|-----------|
| `OFF` | Задвижка закрыта, зона отключена |
| `ON` | Зона активна (используется последний процент) |
| `HEAT` | Зона требует нагрева (минимум 20% вентилятора) |
| `COOL` | Зона требует охлаждения |
| `FAN` | Только вентиляция (без нагрева/охлаждения) |
| `AUTO` | Пассивный режим (зависит от AC) |
| `HEATCOOL` | Автоматическое переключение по PID |
| `DRY` | Осушение |

### 5.2 Режимы работы центральной установки

Модуль автоматически определяет режим AC по текущей температуре воздуха в канале кондиционера, которую надо направить в /val:

```
AC temp < 15°C → CMD_COOL (переоборудование в холод)
15°C ≤ AC temp ≤ 30°C → CMD_FAN (вентиляция)
AC temp > 30°C → CMD_HEAT (переоборудование в тепло)
```
Важно: при обнаружении холода или тепла автоматичесуки активируются PID регуляторы зон. Их выходы направляются на вход блока балансировки зон. Таким образом, система ререходит в режим нагрева или охлаждения зон с контролем температуры.  А прямое управление по входу /fan зон блокируется, (но последее переданное в зону значение запоминается). После того как система обнаруживает переход установки из режима нагрева либо охлаждения в режим вентиляции, она использует последнее полученное на вход /fan зоны значение для балансировки воздушного потока в каждую зону. И система переходит в режим вентиляции. В этом режиме, используются поступающие извне на вход /fan сигналы запросов воздуха в каждую зону (например, от PID регулятора уровня CO2)

### 5.3 PID-режимы

#### DIRECT (Kp > 0)
- Выход растёт при увеличении отклонения (set > val)
- Используется для режима HEAT

#### REVERSE (Kp < 0)
- Выход растёт при уменьшении отклонения (set < val)
- Используется для режима COOL

режим работы регуляторв переключается автоматически в зависимости от температуры воздуха в канале. При нагреве включается прямой режим. При охлаждении - обратный.

**Автоматическое переключение в режиме CMD_AUTO:**
```
AC в HEAT → PID в DIRECT
AC в COOL → PID в REVERSE
```

---

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

### 6.1 Простая двухзональная система

**Сценарий**: кондиционер на два помещения, каждое с вентилятором и датчиком температуры.

```json
{
  "mqtt": ["lh1", "192.168.1.10"],
  "topics": {"root": "home"},
  
  "items": {
    "ac_multizone": [
      14,
      [
        "ac_unit",
        {
          "bedroom": {
            "fan": {"emit": "home/bedroom/fan"},
            "cmd": {"emit": "home/bedroom/cmd"},
            "out": {"emit": "home/bedroom/out"},
            "V": 40,
            "pid": [1.0, 0.05, 0.02, 5.0],
            "set": {"emit": "home/bedroom/setpoint"},
            "val": {"emit": "home/bedroom/temp"}
          },
          "living_room": {
            "fan": {"emit": "home/living/fan"},
            "cmd": {"emit": "home/living/cmd"},
            "out": {"emit": "home/living/out"},
            "V": 80,
            "pid": [1.0, 0.05, 0.02, 5.0],
            "set": {"emit": "home/living/setpoint"},
            "val": {"emit": "home/living/temp"}
          },
          "": {
            "val": {"emit": "home/ac/indoor_temp"},
            "mode": {"emit": "home/ac/mode"}
          }
        }
      ]
    ]
  }
}
```

### 6.2 Трёхзональная система с разными объёмами

```json
{
  "mqtt": ["lh2", "broker.local"],
  "topics": {"root": "climate"},
  
  "items": {
    "ventilation": [
      14,
      [
        "central_vent",
        {
          "zone_a": {
            "fan": {"emit": "climate/a/fan"},
            "cmd": {"emit": "climate/a/cmd"},
            "out": {"emit": "climate/a/out"},
            "V": 50,
            "pid": [-1.5, 0.08, 0.03, 5.0],
            "set": 22.0,
            "val": {"emit": "climate/a/temp"}
          },
          "zone_b": {
            "fan": {"emit": "climate/b/fan"},
            "cmd": {"emit": "climate/b/cmd"},
            "out": {"emit": "climate/b/out"},
            "V": 100,
            "pid": [-1.5, 0.08, 0.03, 5.0],
            "set": 24.0,
            "val": {"emit": "climate/b/temp"}
          },
          "zone_c": {
            "fan": {"emit": "climate/c/fan"},
            "cmd": {"emit": "climate/c/cmd"},
            "out": {"emit": "climate/c/out"},
            "V": 30,
            "pid": [-1.5, 0.08, 0.03, 5.0],
            "set": 20.0,
            "val": {"emit": "climate/c/temp"}
          },
          "": {
            "val": {"emit": "climate/central/temp"},
            "mode": {"emit": "climate/central/mode"}
          }
        }
      ]
    ]
  }
}
```

### 6.3 Система с каскадным управлением задвижками

```json
"zone_main": {
  "fan": {"emit": "hvac/main/fan"},
  "cmd": {"emit": "hvac/main/cmd"},
  "out": {"emit": "hvac/main/out"},
  "V": 60,
  "pid": [0.8, 0.04, 0.01, 5.0],
  "set": {"emit": "hvac/main/setpoint"},
  "val": {"emit": "hvac/main/temp"},
  "cas": {
    "emit": "hvac/main/damper_cmd"
  }
}
```

### 6.4 Реальная система: Haier с четырьмя зонами

**Сценарий**: кондиционер Haier с управлением через Modbus, 4 комнаты с независимыми задвижками и датчиками 1-Wire.

```json
{
  "mqtt": ["ac", "192.168.1.4"],
  "syslog": ["192.168.1.4"],
  "topics": {"root": "home"},
  
  "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]], "val": null, "def": "acmode"},
          "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": "home/ac/cmd", "item": "vac/mode", "@V": null},
          "$temp": {"emit": "home/ac/temp", "item": "vac/temp", "@S": null},
          "set": {"emit": "home/ac/setpoint", "item": "vac/set"},
          "acmode": {"emit": "home/ac/mode", "@V": null},
          "fan": {"emit": "home/ac/fan", "@V": null}
        }
      ]
    ],
    
    "vac": [
      [18, 5],
      {
        "": {"item": "ac_2"},
        "zal": {
          "pid": [490, 100, 9879, 40],
          "set": 21.0,
          "fan": 0,
          "cmd": 14,
          "item": "acgzal/set"
        },
        "bedr21": {
          "pid": [490, 100, 9879, 40],
          "set": 21.0,
          "fan": 0,
          "cmd": 14,
          "item": "acgbedr21/set"
        },
        "bedr22": {
          "pid": [490, 100, 9879, 40],
          "set": 21.0,
          "fan": 0,
          "cmd": 14,
          "item": "acgbedr22/set"
        }
      }
    ],
    
    "acgzal": [7, ["ig2", "og1"]],
    "acgbedr22": [7, ["ig1", "og2"]],
    "acgbedr21": [7, ["ig4", "og3"]],
    
    "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 (ac_2)**: контроллер Haier, управляется через Modbus (скорость 9600, опрос каждые 10 сек)
- **Зоны** (zal, bedr21, bedr22): каждая имеет PID [490, 100, 9879, 40] — агрессивные коэффициенты для точного контроля
- **1-Wire датчики**: подключены четыре датчика температуры
- **Задвижки**: управляются через цифровые выходы (og1-og3) с припасовкой через item [12, ...]
- **Входы**: чтение датчиков через item [12, ...] для каждой зоны

---

## 7. Протокол управления через MQTT

### 7.1 Отправка значений на контроллер

#### Установка команды для зоны
```
Публикуй в: home/bedroom/cmd
Сообщение: 1 (CMD_ON)
```

#### Установка процента вентилятора
```
Публикуй в: home/bedroom/fan
Сообщение: 128
```

#### Установка требуемой температуры
```
Публикуй в: home/bedroom/setpoint
Сообщение: 22.5
```

#### Установка текущей температуры (от датчика)
```
Публикуй в: home/bedroom/temp
Сообщение: 21.8
```

### 7.2 Получение значений от контроллера

#### Выходной сигнал задвижки
```
Подпишись на: home/bedroom/out
Значение: 0—255 (0=закрыто, 255=открыто)
```

#### Режим работы центральной установки
```
Подпишись на: home/ac/mode
Значения: 0=OFF, 1=ON, 2=HEAT, 3=COOL, 4=FAN, ...
```

---

## 8. Алгоритм балансировки воздушного потока

### 8.1 Принцип работы

Модуль обеспечивает **пропорциональное распределение** воздуха между зонами в зависимости от их требований.

### 8.2 Пример расчёта

**Исходные данные:**
- Зона 1: V=40 м³/ч, fan=100%, po=200 → требуемый поток = 40×100% = 40
- Зона 2: V=80 м³/ч, fan=80%, po=180 → требуемый поток = 80×80% = 64
- Макс требуемый поток: 64 (зона 2)

**Расчёт выходов:**
- Зона 1: $out_1 = \frac{40 \times 255 \times 80}{40 \times 80} = 255$
- Зона 2: $out_2 = \frac{64 \times 255 \times 80}{80 \times 80} = 204$

**Результат:**
- Зона 1: открыта на 255 (100%)
- Зона 2: открыта на 204 (80%)

---

## 9. Специальные параметры и флаги

### 9.1 Служебные поля

```json
"@lastCmd": -1,      // Последняя отправленная AC команда
"roomtemp": 0.0,     // Дополнительный датчик комнаты
"po": -2.0,          // Выход PID (внутренне)
```

### 9.2 Таймаут неактивности

Если текущая температура от AC не обновлялась 60 секунд, модуль очищает её.

---

## 10. Интеграция с внешними системами

### 10.1 Подключение задвижек

```json
"zone_name": {
  "out": {
    "emit": "building/room1/damper_position"
  }
}
```

Затем в другом item'е (например, цифровой выход):

```json
"damper": [
  3,
  ["GPIO_PIN_5", {"emit": "building/room1/damper_position"}]
]
```

### 10.2 Подключение датчиков температуры

```json
"zone_name": {
  "val": {
    "emit": "sensors/room1/temperature"
  }
}
```

### 10.3 Управление центральным AC через Modbus

```json
"": {
  "val": {
    "emit": "ac_unit/room_temp"
  },
  "mode": {
    "emit": "ac_unit/operation_mode"
  }
}
```

---

## 11. Рекомендации по эксплуатации

### 11.1 Настройка PID-контроллеров

1. **Начальные значения:** Kp=1.0, Ki=0.05, Kd=0.02, dT=5сек
2. **Тестирование:** постепенно увеличивайте Kp до появления колебаний
3. **Стабилизация:** добавляйте Ki для устранения постоянного смещения
4. **Демпфирование:** добавляйте Kd для снижения колебаний

### 11.2 Распределение объёмов (V)

- Убедитесь, что сумма V соответствует производительности центральной установки
- Для равномерного распределения: V ≈ площадь помещения
- Для приоритизации: увеличьте V критичным зонам

### 11.3 Мониторинг системы

- Отслеживайте `balance` в логах (должен быть близко к нулю в установившемся режиме)
- Проверяйте `out` для каждой зоны (не должны быть постоянно на 0 или 255)
- Контролируйте переходы режимов (HEAT↔COOL) — не должны быть частыми

### 11.4 Диагностика проблем

| Проблема | Причина | Решение |
|----------|---------|---------|
| Задвижки не реагируют | `out` зоны = 0 | Повысить fan или cmd |
| Колебания температуры | PID слишком агрессивен | Снизить Kp |
| Не достигается setpoint | PID недостаточен | Увеличить Ki |
| AC часто переключается | balance скачет | Увеличить dT в PID |

---

## 12. Ограничения и известные особенности

⚠️ **Важно:**

1. **Синхронизм PID:** все PID работают с одинаковым dT
2. **Порядок обработки:** сначала зоны, потом центральная установка
3. **Гистерезис режимов:** автоматическое переключение AC может быть медленным (до 60 сек при отсутствии данных)
4. **Отсутствие истории:** модуль не сохраняет историю команд между перезагрузками

---

## 13. Заключение

Модуль `out_Multivent` предоставляет **промышленную-grade** решение для управления многозональными системами климатизации.

Ключевые преимущества:

- ✅ Интеллектуальная балансировка воздушного потока
- ✅ Независимое PID-регулирование для каждой зоны
- ✅ Автоматическая агрегация команд
- ✅ Каскадное управление внешними системами

---

**Версия документа:** 1.0  
**Дата:** 2026-01-21  
**Статус:** Утверждено
