[2026-09-17] eagle: personal/projects/zont-config-compiler.md
This commit is contained in:
@@ -3,7 +3,7 @@ title: ⚙️ ZONT Config Compiler — конвертеры .txt ⇄ .yml
|
||||
namespace: personal
|
||||
type: how-to
|
||||
created: '2026-09-17'
|
||||
updated: '2026-09-17b'
|
||||
updated: '2026-09-17d'
|
||||
tags:
|
||||
- personal
|
||||
- zont
|
||||
@@ -192,7 +192,7 @@ python3 test_roundtrip.py zont_config/config_X.txt
|
||||
| 52 | Modbus-регистры | `name`, `register`, `bit_width`, `repeat_period`, `num_vars` | вложены в устройство 51 |
|
||||
| 53 | Аналоговые выходы | `name`, `min`, `max`, `value`, `offset`, `scale`, `flags`, `address` | `analog_outputs` |
|
||||
| 57 | MQTT-топики | `topic`, `sensors` | `mqtt_topics` |
|
||||
| **59** | Мини-скрипт ZONT | `descr`, `args[]` | инлайн в `then`/`else` |
|
||||
| **59** | Мини-скрипт ZONT | `descr`, `args[]` (+ `target`/`value` для `objcmd *`); тела `set var`/`puts`/`storeev` — §5.10 | инлайн в `then`/`else` |
|
||||
|
||||
> 🔴 Для каждого типа указаны только **реально декодируемые** поля; остальное — `raw` и пишется как есть.
|
||||
|
||||
@@ -407,7 +407,41 @@ enabled = not (f5 & 8)
|
||||
|
||||
---
|
||||
|
||||
## 6. Проверка целостности (round-trip)
|
||||
### 5.10. Тела записи 59 — таксономия (разобрано 2026-09-17)
|
||||
|
||||
Разведка по снимку `19-53-21` (686 строк, 661 `#Z`, round-trip 🟢 чистый). **28 записей типа 59**
|
||||
разложены по телу (поле 1, `descr`) — три названные Alex конструкции + вызовы подсистем:
|
||||
|
||||
| Тело (`descr`) | Кол-во | Что это | Где живёт значение |
|
||||
|---|---|---|---|
|
||||
| `set var1` | 12 | **запись значения объекту** | `args[0]` = id целевого объекта (`8844`, `8831`, `8429`) |
|
||||
| `puts "…"` | 5 | **print log** — вывод текста | args = `0,0,0` (текст в самом `descr`) |
|
||||
| `storeev I "…"` / `storeev A "…"` | 5 | **журнал событий**: `I` = инфо, `A` = alert | args = `0,0,0` |
|
||||
| `objcmd <id> "fmt"` | 3 | команда объекту (в т.ч. с хвостом `;#a` / `;#h`) | `args[0]` = id/операнд |
|
||||
| `expr "%0 + %1"` | 1 | вычисление | `args[0]`, `args[1]` = операнды (`8819`, `8820`) |
|
||||
| `objstate <id> 0 0` | 2 | запрос состояния | — |
|
||||
| `3`, `2 ;#p` | 2 | короткие скрипты-заглушки | — |
|
||||
|
||||
Полный список тел — в живом конфиге:
|
||||
`#Z8472=59,'set var1',0,0,0` · `#Z8549=59,'puts "test"',0,0,0` ·
|
||||
`#Z8598=59,'storeev I "инфо событие в пн, ср, чт, пт, сб"',0,0,0` ·
|
||||
`#Z8818=59,'objcmd 8700 "1 %0"',14.5,0,1` · `#Z8821=59,'expr "%0 + %1"',8819,8820,0`
|
||||
|
||||
**В YAML сейчас:** `{id, descr: 'set var1', args: [8829, 0, 0]}` — verbatim, без семантики.
|
||||
`target`/`value` дорисовываются только для тел, начинающихся с `objcmd `.
|
||||
|
||||
> 🔴 **Alarm — отдельного типа НЕТ.** Сигнализация/события выражаются телом `storeev` (журнал
|
||||
> событий) и условием на битовую маску. Не искать «тип alarm» в конфиге.
|
||||
|
||||
> 🔴 **Дыра в читаемости:** 12 записей `set var1` **переиспользуют** один и тот же `descr` — по YAML
|
||||
> не видно, что они разные. А несущие объекты (`#Z8830` → `#Z8829=49,8450,1,0`; маски `#Z8844=50,1,0,0,123`)
|
||||
> лежат в `scenario_orphans` как raw-склад и в теле сценария **не развёрнуты**.
|
||||
|
||||
> ⚠️ **Артефакт парсера:** `#Z8195` (SMS) в `steps` → `raw: *id002` — PyYAML-анкор на секцию
|
||||
> `sms_notifications`. Два анкора в файле (`&id001` sensors, `&id002` SMS) — **законные**, это не
|
||||
> баг формы §5. Round-trip при них зелёный.
|
||||
|
||||
---
|
||||
|
||||
```bash
|
||||
cd /Users/admin/Automation/HA-ZONT-Modbus
|
||||
@@ -482,6 +516,8 @@ diff A.txt B.txt # пусто = чисто
|
||||
| 26 | 🔴 **Правка комментария — не правка кода** | Три ответа подряд «готово, зелёный», при том что горячий блок стоял выше моего нового. Мёртвый новый код = ложный зелёный |
|
||||
| 27 | ⚠️ **`>` в шелле затирает `.yml` до старта питона** | Проверять exit-код |
|
||||
| 28 | ⚠️ **Один шаг может принадлежать нескольким сценариям** | Хелпер `_register()` — обновляет запись по id, не добавляет дубль |
|
||||
| 28a | 🔴 **12 разных `set var1` выглядят в YAML одинаково** | `descr` у всех один, различие — только в `args[0]`. Не «оптимизировать» их обратно в одну запись. Смысл теряется: см. §5.10, план §10.1 |
|
||||
| 28b | ⚠️ **Несущие объекты 49/50 живут в `scenario_orphans`, не в теле шага** | `#Z8830` → `#Z8829=49,8450,1,0`. Sweep (§7.4) докидывает их только как raw-склад. Раскрытие = отдельное решение (вариант B §10.1), не «попутная починка» |
|
||||
|
||||
### 7.3. Проверка гипотез
|
||||
|
||||
@@ -578,15 +614,18 @@ https://lk.zont-online.ru/download/firmwares/H2000_PRO_<HW>__<FW>_<PROFILE>.zip
|
||||
|
||||
| Что | Состояние |
|
||||
|---|---|
|
||||
| Round-trip | 🟢 **ЗЕЛЁНЫЙ, байт-в-байт** — `661 → 661`, `686 → 686`, `diff` = 0 |
|
||||
| Round-trip | 🟢 **ЗЕЛЁНЫЙ, байт-в-байт** — `661 → 661`, `686 → 686`, `diff` = 0 (проверен на `19-53-21`) |
|
||||
| Форма сценария | ✅ закрыта (§5), оба конвертера переведены |
|
||||
| Тела типа 59 | 📖 таксономия собрана (§5.10) · ⏳ `set_var` не развёрнут — **план §10.1, ждём ответа** |
|
||||
| Коммит | `823fabd` на `main` — «Scenario YAML shape: bare action ids, no anchors» (3 файла, +200/−1000) |
|
||||
| Последний | `b75c51f` — «Drop stale YAML snapshots in old scenario shape» |
|
||||
| Предыдущий | `1cc010a` — **содержит сломанные версии** (анкоры, лишний `if`, `then` вместо `action`); закрыт §9.1 |
|
||||
| Документация | ✅ **три дока сведены в один** — `personal/projects/zont-config-compiler.md` (§9.2) |
|
||||
| Push | ❌ **не сделан** |
|
||||
|
||||
**Проверка на снимке `18-43-24` (файл с диска):** `trigger:` 66 · `action:` 66 · `if:` 2 · `then:` 2 ·
|
||||
анкоров 3 (законные: `[]`, `raw`, `sensors`). `type`, `field5`, `kind`, `_f5`, `_kind`, `_else` — **0 вхождений**.
|
||||
**Проверка на снимке `19-53-21`:** `trigger:` 66 · `action:` · `if:`/`then:` (тест `8456`) ·
|
||||
анкоров **2** (`&id001` sensors, `&id002` SMS — оба законные, §5.10).
|
||||
`type`, `field5`, `kind`, `_f5`, `_kind`, `_else` — **0 вхождений**.
|
||||
|
||||
**Не в коммите** (untracked): 14 скриптов разбора (`read_scenarios.py`, `dump_new_types.py`, `probe_types.py`,
|
||||
`trace_scenarios.py`, `audit2.py`, `fit_temp*.py`, …, ), папки `zont_api_docs/`, `zont_local_ui_recon/`.
|
||||
@@ -644,25 +683,57 @@ git commit -m "Scenario YAML shape: bare action ids, no anchors"
|
||||
Alex: «это выбор дней недели, то же самое что ставится в значение var1». Сейчас `raw`.
|
||||
2. **`set var1` с `args: [8844, 0, 0]`** — внутри объекта `8844` лежит та же маска дней недели,
|
||||
объект не раскрыт: «что какого-то хуя уехало вовне сценария вообще — только там пн, вт, чт, пт, сб, вс».
|
||||
→ **см. §10.1, план в работе.**
|
||||
3. **`unresolved: true`** у `#Z8860`, `#Z8864`, `#Z8601` — этих объектов нет в конфиге.
|
||||
4. **Тип 3** (SMS `8195`) — тело лежит якорем в `sms_notifications`, не раскрыто.
|
||||
5. **Тип 11 внутри `steps` другого сценария** — ссылка на сценарий голым `id` (`#Z8456` держит `11109`).
|
||||
6. **Старые снапшоты `14-16-35.yml` / `16-02-18.yml`** — по 2 вхождения старого `type:`, не перегенерированы.
|
||||
|
||||
### 10.1. 📋 ПЛАН: развернуть `set var` / `print log` / alarm (2026-09-17, ОЖИДАЕТ ОТВЕТА)
|
||||
|
||||
**Запрос Alex:** «Теперь разверни set var, print log и alarm нотификации».
|
||||
|
||||
**Разведка (сделана):** снят живой конфиг `config_local_2026-09-17_19-53-21.txt` (686 строк,
|
||||
661 `#Z`), round-trip 🟢 чистый, таксономия §5.10. Три конструкции = тела **типа 59**.
|
||||
|
||||
| Шаг | Что | Файл |
|
||||
|---|---|---|
|
||||
| 1 | ✅ **Бэкап** | `zont_config/backups_before_scripts_20260917_195411/` (оба конвертера + `test_roundtrip.py` + txt) |
|
||||
| 2 | В `dump` типа 59: если `descr` начинается с `set var` → добавить `set_var: <args[0]>` (голый id; резолв имени **запрещён** §5.7) | `config-to-yml.py` |
|
||||
| 3 | В `emit_action`: `set_var` → собрать `[59, 'set var<N>', set_var, 0, 0]` | `yml-to-config.py` |
|
||||
| 4 | ⚠️ Развернуть 12 несущих условий (`#Z8829`/`8831`/…/`8847`, типы 49/50) из `scenario_orphans` | оба |
|
||||
| 5 | Round-trip + правка §4/§5.7 + снять п.2 этого списка | док |
|
||||
|
||||
**Открытый вопрос (задан Alex, ответа нет):** делать ли шаг 4.
|
||||
|
||||
- **Вариант A (рекомендован)** — только `set_var` в 59 (шаги 2, 3, 5). Минимум риска,
|
||||
round-trip гарантированно зелёный. Шаг 4 не трогаем.
|
||||
- **Вариант B** — A + развернуть несущие условия 49/50. Полный смысл, но **меняет форму `8456`**
|
||||
(сейчас та байт-совместима через `scenario_orphans`).
|
||||
|
||||
**Порядок работ (правило Alex):** коммит ДО → правка → заливка → проверка Alex → коммит ПОСЛЕ.
|
||||
|
||||
**Текущее состояние:** разведка + бэкап сделаны, **правок кода НЕТ**. Ждём «A» или «B».
|
||||
|
||||
---
|
||||
|
||||
## 11. Файлы проекта
|
||||
|
||||
| Файл | Статус |
|
||||
|---|---|
|
||||
| `config-to-yml.py` | ✅ форма §5: `trigger:` подъём через `pop('if')`, шаг = `{id, [flag], action}` или `{id, [flag], if, then, [else]}` |
|
||||
| `yml-to-config.py` | ✅ `emit_step` читает `then`/`action`/`else`/`flag`; `f5` из `trigger:`/`interval_ms` + бит 8 |
|
||||
| `config-to-yml.py` | ✅ форма §5: `trigger:` подъём через `pop('if')`, шаг = `{id, [flag], action}` или `{id, [flag], if, then, [else]}` · ⏳ тип 59 без `set_var` (§10.1) |
|
||||
| `yml-to-config.py` | ✅ `emit_step` читает `then`/`action`/`else`/`flag`; `f5` из `trigger:`/`interval_ms` + бит 8 · ⏳ тип 59 без `set_var` (§10.1) |
|
||||
| `test_roundtrip.py` | ✅ без изменений (в коммите `199f2b1`) |
|
||||
| `zont_config/config_local_2026-09-17_18-43-24.{txt,yml}` | 🆕 **актуальный** снапшот, форма §5 |
|
||||
| `zont_config/config_local_2026-09-17_19-53-21.{txt}` | 🆕 **актуальный** снимок с прибора (686 строк, 661 `#Z`) |
|
||||
| `zont_config/config_local_2026-09-17_18-43-24.{txt,yml}` | предыдущий снимок, форма §5 |
|
||||
| `zont_config/backups_before_scripts_20260917_195411/` | 🆕 бэкап **перед** правками типа 59 (оба конвертера + `test_roundtrip.py` + txt) |
|
||||
| `zont_config/config_local_2026-09-17_{17-45-00,16-13-28,16-02-18,14-16-35}.*` | исторические снапшоты |
|
||||
| `zont_config/config_0FA7C33CC89F_…_12-12-28.txt` | боевой конфиг (598 `#Z`, 25 `#S`) |
|
||||
| `zont_config/archive/` | `-2`/`-3`/`-4` — закоммичены (`7ae0e32`) |
|
||||
|
||||
> 📌 **Бэкап кода — только git** (питфолл 8), но **перед правкой типа 59** Alex просил бэкап
|
||||
> рабочей копии — он лежит в `backups_before_scripts_<TS>/`, не в `/tmp`.
|
||||
|
||||
**Не относится к конвертерам** (исторический TrueNAS-стек, **декомиссирован**):
|
||||
`INFRASTRUCTURE.md`, `docker-compose.yml`, `docker run.txt`, `modbus_*_bridge.py`,
|
||||
`nodered-flows-*.json`, `homeassistant/`, `floorplan/`. Актуальный контур — [[family/how-to/home-automation]].
|
||||
|
||||
Reference in New Issue
Block a user