[2026-09-17] eagle: family/how-to/zont-config-compiler.md family/tech/zont-config-object-types.md
This commit is contained in:
@@ -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_<HW>__<FW>_<PROFILE>.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_<HW>__<FW>_<PROFILE>.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.
|
||||
|
||||
| Файл | Статус |
|
||||
|---|---|
|
||||
|
||||
@@ -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]].
|
||||
|
||||
Reference in New Issue
Block a user