[2026-09-17] eagle: family/how-to/zont-config-compiler.md
This commit is contained in:
@@ -108,6 +108,99 @@ updated: '2026-09-17e'
|
||||
|
||||
---
|
||||
|
||||
## 2.1 Формат сценариев (type 11 / 45 / 46 / 49) — разобран 2026-09-17
|
||||
|
||||
🔴 **Ключевое открытие:** поле 2 сценария — это **не список шагов типа 46**, а последовательность
|
||||
ссылок, куда попадают и **шаги (46)**, и **задержки (45)**. Проверено на 65 сценариях боевого конфига.
|
||||
|
||||
```
|
||||
#Z<step_46_id>=46,<priority>,[<action_ids…>],[]
|
||||
#Z<act_id>=9,'<имя>',<relay_id>,'0|1' ← действие (тип 9)
|
||||
#Z<delay_id>=45,<ms> ← задержка (тип 45)
|
||||
#Z<cond_id>=49,<relay_id>,<operator>,<value> ← условие (тип 49)
|
||||
#Z<scen_id>=11,'<имя>',[<step_46_id>…],0,0,<enabled>,0,0
|
||||
```
|
||||
|
||||
| Поле | Значение |
|
||||
|---|---|
|
||||
| `11` поле 2 | список ссылок: шаги 46 **и** задержки 45 |
|
||||
| `46` поле 2 | `[action_ids]` — действия 9 **и** задержки 45 внутри шага |
|
||||
| `45` | пауза в **мс**; `45,0` = пауза 0 (заглушка) |
|
||||
| `11` поле 6 | `1` = сценарий включён, `0` = выключен |
|
||||
| `11` число полей | свежая прошивка — **8**, старая (`-2`) — **7** |
|
||||
|
||||
**Пример — `#Z11109` «Передернуть Автомат Котельной»** (единственный многошаговый из 65):
|
||||
|
||||
```
|
||||
#Z11109=11,'Передернуть Автомат Котельной',[11827,11828],0,0,0,0,0 ← 11828 = задержка-«хвост»
|
||||
#Z11827=46,0,11823,[11191,11030,11824,11029,11825,11192,11826],[] ← 7 действий, 2 из них задержки
|
||||
#Z11823=49,11190,1,0 ← virt.Запретить == 0
|
||||
#Z11824=45,20000 #Z11825=45,60000 #Z11826=45,0 #Z11828=45,0
|
||||
```
|
||||
|
||||
Читается как: *вкл `virt.Запретить` → выкл Автомат → пауза 20 с → вкл Автомат → пауза 60 с →
|
||||
выкл `virt.Запретить` → пауза 0*. Поле 6 = `0` → **сценарий выключен**, защиты от повторного
|
||||
передёргивания нет.
|
||||
|
||||
### Как это выглядит в YAML
|
||||
|
||||
Одношаговые сценарии (64 из 65) сохраняют плоский вид `when`/`then` — старые YAML не ломаются.
|
||||
Многошаговые получают список `steps`, а хвостовые задержки — `extra_links`:
|
||||
|
||||
```yaml
|
||||
scenarios:
|
||||
- id: 11109
|
||||
name: Передернуть Автомат Котельной
|
||||
enabled: false
|
||||
steps:
|
||||
- id: 11827
|
||||
when: {id: 11823, relay_id: 11190, operator: equals, value: 0}
|
||||
then: {actions: [11191, 11030, 11824, 11029, 11825, 11192, 11826]}
|
||||
extra_links: [11828]
|
||||
delays:
|
||||
- {id: 11824, ms: 20000}
|
||||
- {id: 11825, ms: 60000}
|
||||
- {id: 11826, ms: 0}
|
||||
- {id: 11828, ms: 0}
|
||||
```
|
||||
|
||||
**Как дописывать логику:** задержки правятся в секции `delays` (поле `ms`), порядок срабатывания
|
||||
задаётся порядком id в `actions` шага. Чтобы включить сценарий — `enabled: true`.
|
||||
|
||||
---
|
||||
|
||||
## 2.2 Round-trip: все 4 конфига чистые
|
||||
|
||||
Проверено `test_roundtrip.py` (новый скрипт в репо) — TXT → YAML → TXT, сравнение по множеству
|
||||
строк с нормализацией кодировки:
|
||||
|
||||
| Конфиг | Объектов | Результат |
|
||||
|---|---|---|
|
||||
| `zont_config/config_0FA7C33CC89F_…_2026-09-17_12-12-28.txt` | 598 | ✅ чисто |
|
||||
| `zont_config/archive/H2000_PRO_config_actual-4.txt` | 558 | ✅ чисто |
|
||||
| `zont_config/archive/H2000_PRO_config_actual-3.txt` | 558 | ✅ чисто |
|
||||
| `zont_config/archive/H2000_PRO_config_actual-2.txt` | 594 | ✅ чисто |
|
||||
|
||||
```bash
|
||||
cd /Users/admin/Automation/HA-ZONT-Modbus
|
||||
python3 test_roundtrip.py # свежий конфиг из zont_config/
|
||||
python3 test_roundtrip.py zont_config/archive/H2000_PRO_config_actual-4.txt
|
||||
```
|
||||
|
||||
**Что исправлено 2026-09-17** (правки в обоих конвертерах):
|
||||
|
||||
| # | Проблема | Причина | Правка |
|
||||
|---|---|---|---|
|
||||
| 1 | Падение «поддерживается только 1 шаг» | `require(len(steps) == 1)` — не знал про задержки в поле 2 | цикл по ссылкам; не-46 → `extra_links` |
|
||||
| 2 | Падение «поддерживается только 1 действие» | `require(len(actions) == 1)` | список действий целиком |
|
||||
| 3 | Тип **45** отсутствовал | не было парсера/энкодера | секция `delays`, `KNOWN_TYPES += 45`, `TYPE_ORDER += delays` |
|
||||
| 4 | Тип 5, поле 3 (`1`→`0`) терялось | энкодер хардкодил `1` | `_raw_field3` |
|
||||
| 5 | `1.0` → `1` (порча float) | `parse_atom` превращал whole-float в int | whole-float остаётся float |
|
||||
| 6 | Сценарии старой прошивки (7 полей) → 8 | энкодер всегда писал 8 | `_raw_field_count` |
|
||||
| 7 | `divider=1.0` → `1` | дефолт подавлялся | `_raw_divider` |
|
||||
|
||||
---
|
||||
|
||||
## 3. Как пользоваться
|
||||
|
||||
**Требования:** `python3` + `PyYAML`. Проверка: `python3 -c 'import yaml; print(yaml.__version__)'`
|
||||
|
||||
Reference in New Issue
Block a user