[2026-09-17] eagle: family/how-to/zont-config-compiler.md family/tech/zont-config-object-types.md family/tech/zont-scenario-logic-11109.md
This commit is contained in:
@@ -21,7 +21,7 @@ tags:
|
||||
- homeautomation
|
||||
title: ⚙️ ZONT Config Compiler — конвертеры .txt ⇄ .yml
|
||||
type: how-to
|
||||
updated: 2026-09-17g
|
||||
updated: 2026-09-17h
|
||||
---
|
||||
|
||||
# ⚙️ ZONT Config Compiler — конвертеры `.txt ⇄ .yml`
|
||||
@@ -146,10 +146,9 @@ updated: 2026-09-17g
|
||||
|
||||
### Как это выглядит в YAML
|
||||
|
||||
> ✅ **НОВАЯ форма (2026-09-17, §5c).** Все сценарии — один плоский список `steps[]` в исходном
|
||||
> порядке поля 2, каждый элемент с телом на месте; плюс блок `trigger:`. Плоские `when`/`then` и
|
||||
> дележ на `blocks`/`extra_links` убраны (тот вариант был отвергнут Alex — см. §5c).
|
||||
> **Форма `11109` ниже — устаревшая**, оставлена для истории; актуальная — §5c.
|
||||
> ✅ **АКТУАЛЬНАЯ форма (2026-09-17).** Сценарий = `trigger:` (условие) + `steps[]` (шаги,
|
||||
> каждый со своим `action:`), тела инлайн. **Форма — §5c.** Здесь оставлены только исторические
|
||||
> варианты, чтобы было видно, что отвергнуто Alex и почему.
|
||||
|
||||
**Устаревшая форма (коммит `199f2b1`)** — плоский `when`/`then` для 1-шаговых + `steps` + `extra_links`:
|
||||
|
||||
@@ -334,7 +333,12 @@ diff A.txt B.txt # пусто = round-trip чистый
|
||||
| 29 | ⚠️ **Удаление `raw_value` требует пересчёта кода в энкодере** | Если убрать сырьё, но оставить `value` (Цельсии), энкодер напечатает `5.2` вместо `'2782'` → round-trip падает. Нужен `_encode_type9_value()`: `True→'1'`, `False→'0'`, число → `str(round((v+273)*10))` |
|
||||
| 30 | ⚠️ **Ветки type 5 / type 9 в энкодере различать по признаку, а не по наличию удалённого поля** | Различались через `'raw_value' not in step` — после удаления признак мёртв. Теперь: type 5 — есть `value` и `target > 255` (output_ref), type 9 — нет `args` |
|
||||
| 31 | 🔴 **Один объект в двух секциях → два разных `value`** | Раскодировал `value` в `steps[]` (`5.2`), но забыл секцию `relay_commands` (осталось `'2782'`). **Round-trip зелёный** — он сравнивает строки конфига, а не смысл полей. Правило: правя декодирование, пройти **все** места, где объект отображается. Нашёл Alex глазами |
|
||||
| 32 | 🔴🔴 **Поле 5 типа 11 — модель `TRIGGER_KINDS` ОШИБОЧНА (выдумка)** | Сопоставление `1=manual, 8=расписание, 9=триггер, 10=интервал` **опровергнуто** Alex: `9628` с `1` — по триггеру; `8456` с `8` — ручной+disabled; `8547`/`8551` оба `9`, но это «по времени» и «по триггеру». Разбор — [[family/tech/zont-scenario-logic-11109]] §8.16. **`TRIGGER_KINDS` подлежит удалению** |
|
||||
| 32 | 🔴🔴 **Поле 5 типа 11 — модель `TRIGGER_KINDS` ОШИБОЧНА (выдумка)** | ✅ **ИСПРАВЛЕНО 2026-09-17**: таблица удалена из кода, поле 5 = `kind = f5 & 7` + `enabled = not (f5 & 8)`. Подтверждено тостингом 5 сценариев — [[family/tech/zont-scenario-logic-11109]] §8.17(а) |
|
||||
| 33 | 🔴 **`config-to-yml.py` пишет YAML в stdout, `-o` не существует** | `main()` принимает **только** входной `.txt` (`sys.argv[1]`). Вызов с `-o file` молча печатает `Использование: zont_to_yaml.py <config.txt>` → **exit 1**, целевой файл остаётся **старым** (выглядит как «патч не сработал»). Правильно: `python3 config-to-yml.py in.txt > out.yml` + проверка `exit=` |
|
||||
| 34 | 🔴 **`if`/`then`/`else` в YAML — выдумка парсера, не поля конфига** | Alex: «у тебя в `9819` сейчас в yml написан `if`! а это не `if` а **триггер**». Слов `if`/`then`/`condition`/`operator`/`group`/`op` в конфиге **нет**. Форма: `trigger:` (условие) + `steps[].action:` (что зовёт шаг). Правило — только слова из конфига/UI |
|
||||
| 35 | 🔴 **`descr` не ставить туда, где текста нет в строке** | У `#Z9819` (шаг) своего текста нет — значит `descr` у него быть не должно. Alex: «нахуй там тогда descr?! если его нет в оригинале?» |
|
||||
| 36 | ⚠️ **`grep -n "id: N"` по YAML даёт несколько совпадений** | Объект живёт и в своей секции, и внутри сценария. Номер строки меняется между генерациями (4877 → 3932) — индексировать по первому совпадению нельзя |
|
||||
| 37 | ⚠️ **Не забегать вперёд с вопросами о том, чего в кейсе нет** | Вопрос «что писать, если в `trigger` окажется type 47» Alex воспринял как шум («что за type 47? нихуя не понятно»). Сначала форма на текущем кейсе, потом обобщение |
|
||||
|
||||
### Ограничения конвертера (найдено 2026-09-17) — ВСЕ ЗАКРЫТЫ
|
||||
|
||||
@@ -398,25 +402,59 @@ diff A.txt B.txt # пусто = round-trip чистый
|
||||
|
||||
## 5c. 🔄 Переработка структуры YAML сценариев — ✅ СДЕЛАНО 2026-09-17
|
||||
|
||||
> ✅ **СТАТУС (2026-09-17, финал): парсер и энкодер дописаны, форма — плоский `steps[]`,
|
||||
> round-trip чистый на 4/4 конфигах.** Семантика типов 47/48/50/59 раскрыта (ответы Alex —
|
||||
> [[family/tech/zont-scenario-logic-11109]] §8.7), операторы и логика подтверждены фактами
|
||||
> конфига. **Type 9 и type 5 раскрыты из `raw` в читаемую форму.**
|
||||
> ✅ **СТАТУС (2026-09-17, после правок формы): парсер дописан под форму `trigger`/`steps`,
|
||||
> YAML перегенерирован, `if`/`then` из вывода убраны.**
|
||||
> Семантика типов 47/48/50/59 раскрыта (ответы Alex — [[family/tech/zont-scenario-logic-11109]] §8.7).
|
||||
> **Type 9 и type 5 раскрыты из `raw` в читаемую форму.**
|
||||
> **Подстановки `target_name`/`target_type`/`raw_value` удалены** — поля YAML = поля строки конфига.
|
||||
> **YAML стал вдвое короче: 6093 → 5452 строки.** **Не закоммичено** — ждёт команды Alex.
|
||||
> **YAML: 6093 → 4405 строк** после перехода на форму `trigger`/`steps`.
|
||||
>
|
||||
> 🔴 **ОТКРЫТЫЙ БЛОКЕР (конец сессии):** модель `trigger` **опровергнута** Alex —
|
||||
> `TRIGGER_KINDS` (`1=manual`, `8=расписание`, `9=триггер`) **выдумка**, поле 5 работает иначе.
|
||||
> Подробности и факты — [[family/tech/zont-scenario-logic-11109]] §8.16(а).
|
||||
> Также открыт вопрос Alex про саму форму YAML («не script editing language ли это») — §8.16(в).
|
||||
> Код не тронут, ждём решения.
|
||||
> 🔴 **ОТКРЫТЫЙ ВОПРОС (конец сессии):** форма «один триггер → одно действие» описывает
|
||||
> **64 из 65** сценариев. Многошаговый `11109` (7 id в `then`) из неё выпадает — сейчас они уходят
|
||||
> в служебный `_then`. Ждём решения Alex. Детали — [[family/tech/zont-scenario-logic-11109]] §8.17(б).
|
||||
>
|
||||
> 📄 **Артефакты (в проекте):** `zont_config/config_local_2026-09-17_16-13-28.yml` — **финальный**
|
||||
> разобранный конфиг (5452 строки, уставка 5.2 + «Температура Детская»);
|
||||
> `zont_config/config_local_2026-09-17_16-02-18.yml` — предыдущий.
|
||||
> Оба в `zont_config/`, не в `/tmp`.
|
||||
> 🔴 **Модель `TRIGGER_KINDS` опровергнута и удалена** — поле 5 типа 11 работает как
|
||||
> `kind = field5 & 7` + `enabled = not (field5 & 8)`. Подтверждено тостингом 5 сценариев,
|
||||
> разбор — [[family/tech/zont-scenario-logic-11109]] §8.17(а).
|
||||
>
|
||||
> 📄 **Артефакты (в проекте):** `zont_config/config_local_2026-09-17_17-45-00.yml` — **актуальный**
|
||||
> (4405 строк, форма `trigger`/`steps`, уставка 5.2 + «Температура Детская»);
|
||||
> `zont_config/config_local_2026-09-17_16-13-28.yml` — предыдущая генерация (5452 строки).
|
||||
> Оба в `zont_config/`, не в `/tmp`. **Не закоммичено** — ждёт команды Alex.
|
||||
|
||||
### 🔴 Главное изменение формы: секции-дубли убраны (2026-09-17, финал)
|
||||
### 🔴 Актуальная форма сценария в YAML (принята Alex, 2026-09-17)
|
||||
|
||||
```yaml
|
||||
- id: 9691
|
||||
name: 'Автомат.: Прихожая (н/п) (14/14) ВКЛ'
|
||||
enabled: true
|
||||
_kind: 1
|
||||
_f5: 1
|
||||
steps:
|
||||
- id: 9819
|
||||
trigger:
|
||||
id: 9729
|
||||
object: 9495
|
||||
value: 1
|
||||
action: 9563
|
||||
```
|
||||
|
||||
**Правило:** в YAML попадают **только слова, которые есть в конфиге или в UI**.
|
||||
`if`/`then`/`else`/`condition`/`operator`/`group`/`op`/`kind` — **нельзя**, их в данных нет.
|
||||
Служебные ключи (`_kind`, `_f5`, `_op`, `_then`, `_else`) — с подчёркиванием, для энкодера.
|
||||
|
||||
| YAML | Строка конфига | Поля |
|
||||
|---|---|---|
|
||||
| `id: 9691`, `name` | `#Z9691=11,…` | 1, 2 |
|
||||
| `enabled: true` | `#Z9691` поле 5 | `not (f5 & 8)` |
|
||||
| `_kind`, `_f5` | `#Z9691` поле 5 | `f5 & 7`, `f5` целиком |
|
||||
| `trigger[].id: 9729` | `#Z9729=49,…` | 1 (id условия) |
|
||||
| `trigger[].object: 9495` | `#Z9729` | 2 (объект) |
|
||||
| `trigger[].value: 1` | `#Z9729` | 4 (значение; поле 3 = оператор → `_op` если ≠ 1) |
|
||||
| `steps[].id: 9819` | `#Z9819=46,…` | 1 (id шага) |
|
||||
| `steps[].action: 9563` | `#Z9819` | 4 (первый id из `[9563]`) |
|
||||
|
||||
### 🔴 Секции-дубли убраны (2026-09-17)
|
||||
|
||||
Раньше каждый сценарный объект (45/46/47/48/49/50/59) жил **дважды**: тело инлайн в `steps[]`
|
||||
и голым id в отдельной служебной секции. Alex: «`delays:`, `scenario_conditions`,
|
||||
@@ -511,11 +549,13 @@ Alex: «ЕСЛИ БЛЯДЬ В КОНФИГЕ `#Z8817=9,'…',10034,'2782'` ТО
|
||||
|
||||
| # | Задача | Статус |
|
||||
|---|---|---|
|
||||
| 1 | **`TRIGGER_KINDS` — удалить.** Модель поля 5 типа 11 опровергнута фактами | ⏸ код не тронут, нужен ответ Alex про UI |
|
||||
| 2 | **Форма YAML** — Alex усомнился, что получился не конфиг, а «script editing language» | ⏸ решение не принято |
|
||||
| 1 | ~~`TRIGGER_KINDS` — удалить~~ | ✅ **сделано** — таблица удалена, модель `kind = f5 & 7` / `enabled = not (f5 & 8)` подтверждена тостингом (§5j) |
|
||||
| 2 | **Форма YAML** — Alex отверг `if`/`then` как выдумку | ✅ форма согласована (§5j), **код ещё не приведён** |
|
||||
| 3 | `git commit` правок парсера/энкодера | ⏸ не закоммичено, ждёт команды |
|
||||
| 4 | YAML `16-13-28` — перегенерировать после последней правки (`relay_commands` decode) | ⏸ на диске старая версия |
|
||||
| 4 | YAML `17-45-00` — перегенерировать после правок | ⏸ **не перегенерирован** — блок `9691` в нём всё ещё со старым `if`/`then` |
|
||||
| 5 | Раскрыть `8195` (type 3 SMS) из YAML-якоря | ⏸ отложено |
|
||||
| 6 | 🔴 **Открытый вопрос:** что писать в `steps[].action`, если в `then` больше одного id или есть `else` | ⏸ ждёт Alex |
|
||||
| 7 | 🔴 **Round-trip сломан** — правка `dump_action` → `dump_step` задела обход (3 конфига падают) | ⏸ домучить или откатить до зелёного |
|
||||
|
||||
**Уроки методологии этой сессии** (проверять в следующих):
|
||||
|
||||
@@ -543,6 +583,14 @@ Alex отклонил:
|
||||
|
||||
### ✅ Реализованная форма — плоский `steps[]` (ФИНАЛЬНАЯ, 2026-09-17)
|
||||
|
||||
> 🔴🔴 **ПЕРЕСМОТРЕНА в конце сессии 2026-09-17 (третья итерация).** Форма ниже (`when`/`then`,
|
||||
> `if`/`group`/`op`) **отвергнута Alex** как выдумка:
|
||||
>
|
||||
> > «у тебя в `9819` сейчас в yml написан `if`! а это не `if` а **триггер**»
|
||||
>
|
||||
> Слов `if` / `then` / `else` / `condition` / `operator` / `group` / `op` **в конфиге НЕТ**.
|
||||
> Актуальная согласованная форма — **§5j**. Текст ниже оставлен как история двух отвергнутых итераций.
|
||||
|
||||
> 🔴 **ИСПРАВЛЕНО в конце сессии.** Первый вариант делил поле 2 на `blocks` (шаги 46) и
|
||||
> `extra_links` (голые id остальных объектов) — **`blocks` выводился первым, и весь сценарий
|
||||
> превращался в список цифр**: тела «установка температуры», `puts`, `set var1`, пауза 5 суток
|
||||
@@ -642,14 +690,26 @@ scenarios:
|
||||
**Логика type 48:** `0`=`and`, `1`=`or`, `2`=`not`.
|
||||
|
||||
|
||||
**Триггер (поле 5 типа 11):**
|
||||
**Триггер (поле 5 типа 11) — ✅ МОДЕЛЬ ИСПРАВЛЕНА 2026-09-17 (тостинг в UI):**
|
||||
|
||||
| Поле 5 | `trigger.type` | Доп. поля |
|
||||
|---|---|---|
|
||||
| `0`/`1` | `manual` | `enabled: bool` |
|
||||
| `8` | `schedule` | `days[]`, `days_mask`, `time`, `time_raw` (поле 4 = маска дней, бит 0=ПН; поле 6 = `(час<<8)\|мин`) |
|
||||
| `9` | `trigger` | — |
|
||||
| `10` | `interval` | `interval_ms` |
|
||||
```text
|
||||
kind = field5 & 7 # 0 = ручной/расписание, 1 = триггер, 2 = интервал
|
||||
enabled = not (field5 & 8) # бит 8 = ВЫКЛЮЧЕН
|
||||
```
|
||||
|
||||
| Поле 5 вкл / выкл | `kind` | Что это | Доп. поля |
|
||||
|---|---|---|---|
|
||||
| `0` / `8` | 0 | ручной **или** расписание (различаются полями 3/4) | у расписания `days_mask`, `time` |
|
||||
| `1` / `9` | 1 | триггер | — |
|
||||
| `2` / `10` | 2 | интервал | поле 6 = `interval_ms` |
|
||||
|
||||
Тосты: `8456` `8⇄0`, `8597` `8⇄0` (поля 3/4 = `61`,`3354`), `8547`/`8551`/`9628` `9⇄1`,
|
||||
`8599` `10⇄2` (поле 6 = `43200000` мс).
|
||||
|
||||
> 🔴 **Таблица `{0:manual, 1:manual, 8:schedule, 9:trigger, 10:interval}` — ОШИБКА (выдумка),
|
||||
> удалена из кода.** Она читала число целиком, тогда как бит `8` — это «выключен».
|
||||
> Из-за неё `9628` (триггерный, поле 5 = `1`) рендерился как `manual`.
|
||||
> Формат `time`: `(час << 8) | минута`; `days_mask`: бит 0 = ПН.
|
||||
|
||||
### Реализация (код)
|
||||
|
||||
@@ -893,6 +953,79 @@ https://lk.zont-online.ru/download/firmwares/H2000_PRO_<HW>__<FW>_<PROFILE>.zip
|
||||
|
||||
---
|
||||
|
||||
## 5j. 🔴 ФОРМА СЦЕНАРИЯ В YAML — согласована с Alex (2026-09-17, финал сессии)
|
||||
|
||||
> **Статус:** форма **согласована**, код **ещё не приведён** (правка в работе, round-trip сломан).
|
||||
> Полный разбор модели — [[family/tech/zont-scenario-logic-11109]] §8.17.
|
||||
|
||||
### Почему третья итерация
|
||||
|
||||
| Итерация | Форма | Что сказал Alex |
|
||||
|---|---|---|
|
||||
| 1 | `blocks` + `extra_links` | «почему там блядь if идет первым блоком?! где все что до него происходит?!» — порядок терялся |
|
||||
| 2 | `steps[].{when, then}`, `if`/`group`/`op` | «у тебя в `9819` сейчас в yml написан `if`! а это не `if` а **триггер**» |
|
||||
| 3 | `trigger` + `steps[].{id, action}` | ✅ принято |
|
||||
|
||||
**Проверено по конфигу:** слов `if`, `then`, `else`, `condition`, `object`(как имя ветки),
|
||||
`operator`, `group`, `op` **в конфиге нет**. В `#Z9691`/`#Z9819`/`#Z9729` есть только числа и
|
||||
`#Z9563` с текстом. Всё остальное — интерпретация парсера.
|
||||
|
||||
### Форма
|
||||
|
||||
```yaml
|
||||
- id: 9691
|
||||
name: 'Автомат.: Прихожая (н/п) (14/14) ВКЛ'
|
||||
enabled: true
|
||||
trigger:
|
||||
- id: 9729
|
||||
object: '9495'
|
||||
value: 1
|
||||
steps:
|
||||
- id: 9819
|
||||
action: 9563
|
||||
```
|
||||
|
||||
Исходный конфиг (для сверки):
|
||||
|
||||
```text
|
||||
#Z9691=11,'Автомат.: Прихожая (н/п) (14/14) ВКЛ',[9819],0,0,1,0,0
|
||||
#Z9819=46,0,9729,[9563],[]
|
||||
#Z9729=49,9495,1,1
|
||||
#Z9495=14,'Датч 14/14: Прихожая (н/п)',151408,0
|
||||
#Z9563=5,'Включить выход 14/14: Прихожая (н/п)',146064,1,0,0,[],0,0,0,512
|
||||
```
|
||||
|
||||
### Термины Alex — использовать дословно
|
||||
|
||||
| Id | Слово Alex | Строка | YAML |
|
||||
|---|---|---|---|
|
||||
| `9691` | сценарий | `#Z9691=11,…` | `id`, `name`, `enabled` |
|
||||
| `9729` | **триггер** (НЕ `if`) | `#Z9729=49,9495,1,1` | `trigger[].id` |
|
||||
| `9495` | объект под наблюдением триггера | `#Z9495=14,…` | `trigger[].object` |
|
||||
| `9819` | **шаг** | `#Z9819=46,…` | `steps[].id` |
|
||||
| `9563` | **действие** («выполнить пользовательское действие») | `#Z9563=5,…` | `steps[].action` |
|
||||
|
||||
> Alex: «`#Z9563=5,…` — это шаг «выполнить пользовательское действие» (action) `9563`».
|
||||
|
||||
### Правила формы (выведены из этой итерации)
|
||||
|
||||
1. **Источник полей — `#Z9819` (тип 46):** `trigger` ← поле 3 (`9729`), `steps[].action` ← поле 4
|
||||
(`[9563]`). Одна модель на оба: 46-шаг содержит и условие, и действие.
|
||||
2. **`object`, а не `entity`** — слово уже используется в коде для ссылки на объект
|
||||
(`dump_condition`: `'object': node[1]`), рядом с `target` (реле/контур) и `descr`.
|
||||
3. **`descr` только там, где текст есть в строке.** У `#Z9819` текста нет → `descr` у него быть
|
||||
не должно (Alex: «нахуй там тогда descr?! если его нет в оригинале?»). Текст живёт у `#Z9563`.
|
||||
4. **Никаких `kind`** в видимой части — `kind`/`kind_raw` уходят в служебные ключи
|
||||
(энкодеру нужно поле 5 целиком).
|
||||
5. **`yaml`-теги вида `object: '9495'` — строкой** (id объекта), как в `trigger.id`.
|
||||
|
||||
### 🔴 Открытый блокер
|
||||
|
||||
`#Z9819` поле 4 — **список** (`[9563]`). Если в нём больше одного id или непуст `else` (поле 5) —
|
||||
что писать? Вариант `action: 9563` покрывает только первый. **Решение за Alex.**
|
||||
|
||||
---
|
||||
|
||||
## 6. Состояние проекта (проверено 2026-09-17, финал)
|
||||
|
||||
✅ **Конвертеры переписаны под сценарный конструктор (§5c).** Рабочее дерево — **не закоммичено**,
|
||||
|
||||
Reference in New Issue
Block a user