From b7e945e7870556acf531eb2f8ccf607bd37db65e Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Thu, 17 Sep 2026 18:46:26 +0600 Subject: [PATCH] [2026-09-17] eagle: family/how-to/zont-config-compiler.md family/tech/zont-config-object-types.md --- family/how-to/zont-config-compiler.md | 125 ++++++++++++++---------- family/tech/zont-config-object-types.md | 18 ++-- 2 files changed, 88 insertions(+), 55 deletions(-) diff --git a/family/how-to/zont-config-compiler.md b/family/how-to/zont-config-compiler.md index c3a5b7a5..09d9ba88 100644 --- a/family/how-to/zont-config-compiler.md +++ b/family/how-to/zont-config-compiler.md @@ -21,7 +21,7 @@ tags: - homeautomation title: ⚙️ ZONT Config Compiler — конвертеры .txt ⇄ .yml type: how-to -updated: 2026-09-17k +updated: 2026-09-17m --- # ⚙️ ZONT Config Compiler — конвертеры `.txt ⇄ .yml` @@ -429,7 +429,6 @@ diff A.txt B.txt # пусто = round-trip чистый - id: 9691 name: 'Автомат.: Прихожая (н/п) (14/14) ВКЛ' enabled: true - _f5: 1 trigger: - id: 9729 object: 9495 @@ -558,9 +557,9 @@ Alex: «ЕСЛИ БЛЯДЬ В КОНФИГЕ `#Z8817=9,'…',10034,'2782'` ТО | 3 | `git commit` правок парсера/энкодера | ⏸ не закоммичено, ждёт команды | | 4 | YAML `17-45-00` — перегенерировать после правок | ✅ **перегенерирован** — 4405 строк, `trigger` на уровне сценария | | 5 | Раскрыть `8195` (type 3 SMS) из YAML-якоря | ⏸ отложено | -| 6 | 🔴 **Открытый вопрос:** что писать в `steps[].action`, если в `then` больше одного id или есть `else` | ⏸ ждёт Alex | +| 6 | 🔴 **Открытый вопрос:** что писать в `steps[].action`, если в `then` больше одного id или есть `else` | ⏸ ждёт Alex (единственный открытый) | | 7 | 🔴 **Round-trip сломан** — энкодер не переведён под форму §5j (парсер обновлён, `yml-to-config.py` — нет) | ⏸ переписать энкодер | -| 8 | 🆕 🔴 **Поле 5 типа 11** — семантика не раскрыта; `_f5` нужен, но Alex против служебных ключей | ⏸ ждёт Alex (§5j) | +| 8 | ✅ ~~Поле 5 типа 11 — семантика не раскрыта~~ | ✅ **закрыто**: тип (`manual`/`trigger`/`interval`/`schedule`) + `enabled`; `_f5` убран (§5j) | **Уроки методологии этой сессии** (проверять в следующих): @@ -581,6 +580,15 @@ Alex: «ЕСЛИ БЛЯДЬ В КОНФИГЕ `#Z8817=9,'…',10034,'2782'` ТО поясняй». Вопрос должен нести факт + конкретный выбор, а не термин. 8. 🆕 **Не приписывать Alex выбор, который он не делал.** «Что блядь я решаю не ты?» — если значение выводимо из конфига, решать по конфигу, а не перекладывать. +9. 🆕 **Сначала спросить СЛОВА, потом строить модель.** Поле 5 разбиралось час вслепую + (тостинг, гипотезы), пока Alex не назвал типы одним сообщением: + «типы: manual, trigger, interval, schedule». У него была номенклатура UI всё это время. + **Спросить «как это называется в UI» до того, как выводить семантику из чисел.** +10. 🆕 **Проверенная и опровергнутая гипотеза = результат, записать в док.** Гипотеза + «поле5 = значение условия» была правдоподобна (2 точки совпали) и развалилась на 32 + расхождениях. Записана как снятая — чтобы следующая сессия не выводила её заново. +11. 🆕 **Не выдавать пару примеров за правило.** Два совпавших сценария (11109, 9628) дали + уверенность, которой не было. Проверка на всех 70 — обязательна до слова «выяснили». **Задача Alex (исходная):** «переписать блок парсинга/сборки сценариев чтобы он составлял синтаксис как у Home Assistant automations вместо текущей разбросанной структуры. с опциональными айдишниками у операторов». @@ -703,27 +711,33 @@ scenarios: **Логика type 48:** `0`=`and`, `1`=`or`, `2`=`not`. -**Триггер (поле 5 типа 11) — ✅ МОДЕЛЬ ИСПРАВЛЕНА 2026-09-17 (тостинг в UI):** +**Триггер (поле 5 типа 11) — ✅ МОДЕЛЬ ИСПРАВЛЕНА 2026-09-17 (типы назвал Alex):** ```text -kind = field5 & 7 # 0 = ручной/расписание, 1 = триггер, 2 = интервал +поле5 = тип + 8, если сценарий ВЫКЛЮЧЕН +тип = 0 (manual | schedule) | 1 (trigger) | 2 (interval) enabled = not (field5 & 8) # бит 8 = ВЫКЛЮЧЕН ``` -| Поле 5 вкл / выкл | `kind` | Что это | Доп. поля | +| Поле 5 вкл / выкл | тип | Что это | Доп. поля | |---|---|---|---| -| `0` / `8` | 0 | ручной **или** расписание (различаются полями 3/4) | у расписания `days_mask`, `time` | -| `1` / `9` | 1 | триггер | — | -| `2` / `10` | 2 | интервал | поле 6 = `interval_ms` | +| `0` / `8` | 0 | `manual` **или** `schedule` (различаются полями 3/4) | у расписания `days_mask`, `time` | +| `1` / `9` | 1 | `trigger` | — | +| `2` / `10` | 2 | `interval` | поле 6 = `interval_ms` | -Тосты: `8456` `8⇄0`, `8597` `8⇄0` (поля 3/4 = `61`,`3354`), `8547`/`8551`/`9628` `9⇄1`, -`8599` `10⇄2` (поле 6 = `43200000` мс). +Факты боевого конфига: `8456` `manual` выкл = `8`; `8597` `schedule` выкл = `8` +(поля 3/4 = `61`,`3354`); `8547`/`8551` выкл = `9`; `9628`–`9691` вкл = `1`; +`11109` `manual` вкл = `0`; `8599` `interval` выкл = `10` (поле 6 = `43200000` мс). > 🔴 **Таблица `{0:manual, 1:manual, 8:schedule, 9:trigger, 10:interval}` — ОШИБКА (выдумка), > удалена из кода.** Она читала число целиком, тогда как бит `8` — это «выключен». > Из-за неё `9628` (триггерный, поле 5 = `1`) рендерился как `manual`. > Формат `time`: `(час << 8) | минута`; `days_mask`: бит 0 = ПН. +> 🔴 **Гипотеза «поле5 = значение условия шага 46» — тоже ОШИБКА.** Проверена по всем 70 +> сценариям: **32 расхождения** (пары ВКЛ/ВЫКЛ одной линии имели одинаковое поле 5 при +> противоположных условиях). Снята. Полный разбор — §5j. + ### Реализация (код) **`config-to-yml.py`** — рекурсивные хелперы `dump_step()` / `dump_condition()` / `dump_leaf()` / @@ -969,9 +983,10 @@ https://lk.zont-online.ru/download/firmwares/H2000_PRO____.zip ## 5j. 🔴 ФОРМА СЦЕНАРИЯ В YAML — согласована с Alex (2026-09-17, финал сессии) > **Статус:** форма **согласована И реализована в парсере** (`config-to-yml.py`). -> YAML `17-45-00` перегенерирован (4405 строк), блок `9691` вышел в целевой форме. +> YAML `17-45-00` перегенерирован, блок `9691` вышел в целевой форме (`_f5` убран). > **Энкодер (`yml-to-config.py`) ещё не переведён под новую форму** → round-trip сломан. > Полный разбор модели — [[family/tech/zont-scenario-logic-11109]] §8.17. +> ✅ **Поле 5 закрыто:** тип (`manual`/`trigger`/`interval`/`schedule`) + `enabled` — см. ниже. ### Почему третья итерация @@ -991,7 +1006,6 @@ https://lk.zont-online.ru/download/firmwares/H2000_PRO____.zip - id: 9691 name: 'Автомат.: Прихожая (н/п) (14/14) ВКЛ' enabled: true - _f5: 1 trigger: - id: 9729 object: 9495 @@ -1043,49 +1057,59 @@ steps?!»). В конфиге условие лежит внутри `#Z9819` ( (энкодеру нужно поле 5 целиком). 5. **`yaml`-теги вида `object: '9495'` — строкой** (id объекта), как в `trigger.id`. -### ⚠️ Поле 5 типа 11: что реально означает (проверено 2026-09-17) +### ✅ Поле 5 типа 11 — ЧЕТЫРЕ ТИПА + `enabled` (подтверждено Alex, 2026-09-17) -🔴 **Открытая проблема: поле 5 не выводится из содержимого сценария, но и не имеет имени.** -Alex: «какой нахуй kind?? что это блядь значит?! я его откуда тебе высру?!» — `kind` было -**моим выдуманным словом**, в конфиге и UI его нет. +Alex назвал типы прямо: **`manual`, `trigger`, `interval`, `schedule`**. +Сводка по боевому конфигу (70 сценариев): -Распределение по боевому конфигу (70 сценариев): - -| поле 5 | enabled | шт | кто | особенности | +| ТИП | enabled | поле 5 | шт | кто | |---|---|---|---|---| -| `0` | вкл | 1 | `11109` Передернуть Автомат Котельной | 2 шага, **7 действий** в `then`, условие `value: 0` | -| `1` | вкл | 64 | все «Автомат.: …» | **1 шаг, 1 действие**, условие `value: 1` | -| `8` | выкл | 2 | `8456` (27 шагов, без 46), `8597` (расписание, 1 шаг) | — | -| `9` | выкл | 2 | `8547` «по времени», `8551` «по триггеру» | 1 шаг 46 | -| `10` | выкл | 1 | `8599` «по интервалу» | `interval_ms = 43200000` | +| `trigger` | вкл | `1` | 64 | все «Автомат.: …» (ВКЛ и ВЫКЛ, по 32) | +| `manual` | вкл | `0` | 1 | `11109` Передернуть Автомат Котельной | +| `trigger` | выкл | `9` | 2 | `8547` «по времени», `8551` «по триггеру» | +| `schedule` | выкл | `8` | 1 | `8597` «по расписанию» | +| `interval` | выкл | `10` | 1 | `8599` «по интервалу» | +| `manual` | выкл | `8` | 1 | `8456` «Простой тестовый» | -**Что подтверждено:** -- `enabled = not (поле5 & 8)` — держится на всех 5 значениях. -- Поле 5 **не восстанавливается** из остальных полей: `#Z11109` (f5=`0`) и `#Z9628` (f5=`1`) - идентичны по имени/дням/времени/интервалу; `#Z8456` (ручной) и `#Z8597` (расписание) имеют - **одно и то же** f5=`8`, хотя у 8456 нет шага 46, а у 8597 есть. +**Правило (полное, покрывает все 70):** -**Опровергнуто (снято):** -- ❌ `kind = field5 & 7` как «тип сценария» (manual/trigger/schedule/interval) — развалилось - на 11109: он даёт `kind=0`, хотя устроен так же, как триггерные `1`. Формула снята. -- ❌ «Триггерный vs ручной» как внятная пара — оба имеют тип 46 с условием. +```text +поле5 = тип + 8, если сценарий ВЫКЛЮЧЕН +тип: 0 = manual | schedule 1 = trigger 2 = interval +enabled = not (поле5 & 8) ← подтверждено на всех 5 значениях +``` -**Гипотеза в работе (НЕ подтверждена):** `поле5 & 7` = значение из условия шага 46 -(`#Z11823=49,11190,1,0` → `0`; `#Z9729=49,9495,1,1` → `1`). Проверялась скриптом по всем 65 -сценариям с типом 46, но команда была заблокирована и проверка не завершена. **Не вшивать -в код до зелёного round-trip.** +Проверка выключенных: `manual 0+8=8` (8456 ✓), `schedule 0+8=8` (8597 ✓), +`trigger 1+8=9` (8547, 8551 ✓), `interval 2+8=10` (8599 ✓). -### 🔴 Открытый блокер +⚠️ **`manual` и `schedule` дают одно число `0`** — различаются только полями 3/4 +(`days_mask`, `time`): у `8597` = `61`/`3354`, у `8456` = `0`/`0`. + +**Что опровергнуто и снято (не возвращаться):** + +- ❌ `kind = field5 & 7` как отдельная сущность — это не «kind», а **тип**, слова `kind` в + конфиге/UI нет. Alex: «какой нахуй kind?? что это блядь значит?! я его откуда тебе высру?!» +- ❌ **Гипотеза «поле5 & 7 = значение из условия шага 46»** — проверена скриптом по всем 70: + **32 расхождения**. Пары ВКЛ/ВЫКЛ одной линии (`9628` ВКЛ и `9629` ВЫКЛ) имеют **одинаковое** + поле 5 = `1`, но противоположные условия (`1` и `0`). Гипотеза развалилась — **снята**. +- ❌ «Поле 5 не выводится из содержимого» — **неверно**: выводится по правилу выше + (`тип` + бит 8). Ранее записанный вывод был получен до того, как Alex назвал типы. + +### ✅ Служебные ключи — БОЛЬШЕ НЕ НУЖНЫ + +Ранее `_f5` держали в YAML как компромисс. **Теперь не нужно:** поле 5 восстанавливается +из `enabled` + типа сценария. Alex: «ты же сказал только что блядь что это тип + enabled». +`_f5` убран из парсера (`config-to-yml.py`, блок заголовка сценария). + +Остающиеся ключи с подчёркиванием — только на **нестандартных** случаях (не трогать без нужды): +`_op` (оператор ≠ 1), `_then` (больше одного id в поле 4 шага 46), `_else` (непустое поле 5), +`_kind` (непустое поле 2 шага 46). + +### ⚠️ Открытый блокер (один) `#Z9819` поле 4 — **список** (`[9563]`). Если в нём больше одного id или непуст `else` (поле 5) — что писать? Вариант `action: 9563` покрывает только первый. У `11109` их **7** — сейчас уходят -в служебный `_then`. **Решение за Alex.** - -### Служебные ключи — Alex против - -Alex отверг сам подход «служебных ключей» в YAML (`_f5`, `_kind`): «какое нахуй служебное». -Но удалить `_f5` нельзя — 6 сценариев соберутся неверно. **Компромисс не найден, ждёт Alex.** -Ключи с подчёркиванием временно остаются (`_f5`, `_op`, `_then`, `_else`, `_kind`). +в служебный `_then`. **Решение за Alex.** Всё остальное по форме закрыто. --- @@ -1108,8 +1132,11 @@ Round-trip сейчас **не сходится** — `yml-to-config.py` ждё ✅ **YAML сжат вдвое:** 6093 → 4405 строк. Секции-дубли убраны, поля переименованы (`descr`/`target`/`value`). -🔴 **Поле 5 типа 11 — семантика не раскрыта** (§5j). `enabled = not (f5 & 8)` подтверждён; -что значат младшие биты — неизвестно, из содержимого не выводится. +✅ **Поле 5 типа 11 — РАСКРЫТО** (§5j): `тип + 8 при выключенном`; +типы `manual`/`trigger`/`interval`/`schedule` (Alex), `enabled = not (f5 & 8)`. +`_f5` из YAML убран — поле восстанавливается из `enabled` + типа. + +⚠️ **Открыт один вопрос:** `steps[].action` при >1 id в поле 4 шага 46 (у `11109` их 7) — §5j. | Файл | Статус | |---|---| diff --git a/family/tech/zont-config-object-types.md b/family/tech/zont-config-object-types.md index c8495e55..36338a14 100644 --- a/family/tech/zont-config-object-types.md +++ b/family/tech/zont-config-object-types.md @@ -99,10 +99,15 @@ Modbus-регистры (тип 52) в конфиге — **отдельные ### 2.3. Сценарии (11 + 46 + 49 + 45) -> 🔴 **ИСПРАВЛЕНО 2026-09-17 (тостинг в UI):** поле 5 типа 11 = **тип запуска + флаг «выключен»**: -> `kind = field5 & 7` (0 = ручной/расписание, 1 = триггер, 2 = интервал), -> `enabled = not (field5 & 8)`. Ручной и расписание — один `kind`, различаются полями 3/4. -> Подробности и тосты — [[family/tech/zont-scenario-logic-11109]] §8.17(а). +> ✅ **РАСКРЫТО 2026-09-17 (типы назвал Alex):** поле 5 типа 11 = **тип сценария + флаг «выключен»**: +> `тип`: `0` = `manual` | `schedule`, `1` = `trigger`, `2` = `interval`; +> `поле5 = тип + 8`, если сценарий **выключен**; `enabled = not (field5 & 8)`. +> `manual` и `schedule` дают одно число `0` — различаются только полями 3/4 (`days_mask`/`time`). +> Подробности и таблица 70 сценариев — [[family/how-to/zont-config-compiler]] §5j. +> +> ❌ **Снято:** `kind = field5 & 7` (это не «kind», а тип) и гипотеза «поле5 = значение условия +> шага 46» (32 расхождения из 70). Старая модель `{0:manual, 8:schedule, 9:trigger, 10:interval}` +> — выдумка, удалена из кода. Тип 11 парсится **целиком** — из него собирается `steps[]` (шаги 46 со своими условиями 49), включая многошаговые сценарии и много действий в шаге. @@ -116,7 +121,7 @@ Modbus-регистры (тип 52) в конфиге — **отдельные > enabled: true > trigger: > - id: 9729 -> object: '9495' +> object: 9495 > value: 1 > steps: > - id: 9819 @@ -124,7 +129,8 @@ Modbus-регистры (тип 52) в конфиге — **отдельные > ``` > > `trigger` ← поле 3 шага 46 (`9729`), `steps[].action` ← поле 4 (`[9563]`). -> Слова `if`/`then`/`condition`/`operator`/`group` в YAML **запрещены** — их нет в конфиге. +> `trigger` поднят на **уровень сценария**, не шага. Слова `if`/`then`/`condition`/`operator`/ +> `group`/`kind` в YAML **запрещены** — их нет в конфиге. > Полностью — [[family/how-to/zont-config-compiler]] §5j. Полная структура, формат полей и разобранный боевой кейс — [[family/tech/zont-scenario-logic-11109]].