diff --git a/family/how-to/zont-config-compiler.md b/family/how-to/zont-config-compiler.md index 7bce84b7..f9830733 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-17 +updated: 2026-09-17g --- # ⚙️ ZONT Config Compiler — конвертеры `.txt ⇄ .yml` @@ -333,6 +333,8 @@ diff A.txt B.txt # пусто = round-trip чистый | 28 | ⚠️ **`object_display_name` нужен и раньше по файлу, чем определён** | Вложенная функция видна только ниже места вызова → `NameError` в секции type 9. Вынести на **уровень модуля** `object_display_name()`, оставить shim для вложенных вызовов | | 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` подлежит удалению** | ### Ограничения конвертера (найдено 2026-09-17) — ВСЕ ЗАКРЫТЫ @@ -403,6 +405,12 @@ diff A.txt B.txt # пусто = round-trip чистый > **Подстановки `target_name`/`target_type`/`raw_value` удалены** — поля YAML = поля строки конфига. > **YAML стал вдвое короче: 6093 → 5452 строки.** **Не закоммичено** — ждёт команды Alex. > +> 🔴 **ОТКРЫТЫЙ БЛОКЕР (конец сессии):** модель `trigger` **опровергнута** Alex — +> `TRIGGER_KINDS` (`1=manual`, `8=расписание`, `9=триггер`) **выдумка**, поле 5 работает иначе. +> Подробности и факты — [[family/tech/zont-scenario-logic-11109]] §8.16(а). +> Также открыт вопрос Alex про саму форму YAML («не script editing language ли это») — §8.16(в). +> Код не тронут, ждём решения. +> > 📄 **Артефакты (в проекте):** `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` — предыдущий. @@ -499,6 +507,28 @@ Alex: «ЕСЛИ БЛЯДЬ В КОНФИГЕ `#Z8817=9,'…',10034,'2782'` ТО > либо через явный проход. Убрать секцию из `TYPE_ORDER` ≠ «объект пропадёт» — он пропадёт > **молча**, и это видно только по счётчику round-trip. +### 5d. 🔴 Незакрытые задачи конца сессии 2026-09-17 (ждать Alex) + +| # | Задача | Статус | +|---|---|---| +| 1 | **`TRIGGER_KINDS` — удалить.** Модель поля 5 типа 11 опровергнута фактами | ⏸ код не тронут, нужен ответ Alex про UI | +| 2 | **Форма YAML** — Alex усомнился, что получился не конфиг, а «script editing language» | ⏸ решение не принято | +| 3 | `git commit` правок парсера/энкодера | ⏸ не закоммичено, ждёт команды | +| 4 | YAML `16-13-28` — перегенерировать после последней правки (`relay_commands` decode) | ⏸ на диске старая версия | +| 5 | Раскрыть `8195` (type 3 SMS) из YAML-якоря | ⏸ отложено | + +**Уроки методологии этой сессии** (проверять в следующих): + +1. **Round-trip ≠ корректность.** Зелёный round-trip уживается с: + - одним объектом с разными `value` в двух секциях (условие 31); + - выдуманной таблицей `trigger` (условие 32). + Он проверяет **байты**, не **смысл**. Главный кейс смотреть глазами (питфолл 21). +2. **Не подставлять производные поля.** `target_name`/`target_type` — дорисовка; Alex потребовал + убрать. В YAML должны быть **поля строки конфига**, ничего сверх. +3. **Не кодировать формулу по 2 точкам.** `(t+273)*10` вшита только после третьей точки от Alex. +4. **Не переносить данные между сценариями.** Расписание `61,3354` принадлежит `8597`, я приписал + его `8456` (у которого нули) — Alex поймал. + **Задача Alex (исходная):** «переписать блок парсинга/сборки сценариев чтобы он составлял синтаксис как у Home Assistant automations вместо текущей разбросанной структуры. с опциональными айдишниками у операторов». ### 🔴 Правка постановки Alex'ом (ключевое — не повторять ошибку) diff --git a/family/tech/zont-scenario-logic-11109.md b/family/tech/zont-scenario-logic-11109.md index 860a8dc0..04a68b1d 100644 --- a/family/tech/zont-scenario-logic-11109.md +++ b/family/tech/zont-scenario-logic-11109.md @@ -19,7 +19,7 @@ tags: - homeautomation title: 🔁 ZONT — сценарная логика и конструктор (11/46/47/48/49/50/59/45/9/5) type: tech -updated: 2026-09-17f +updated: 2026-09-17g --- # 🔁 ZONT — сценарная логика и конструктор логики @@ -225,17 +225,24 @@ scenarios: > Alex создал тестовые сценарии в UI, «постарался использовать все доступные триггеры и варианты > логики». Это позволило вскрыть **полноценный визуальный конструктор логики** со скриптовым движком. -### 8.1. 🔴 ИСПРАВЛЕНИЕ: поле 5 типа 11 — ТИП ЗАПУСКА, а не `enabled` +### 8.1. 🔴🔴 ОТМЕНЕНО 2026-09-17: поле 5 типа 11 — НЕ тип запуска. Таблица ниже ОШИБОЧНА -Прежняя модель (§1, строка `[11, name, [step_ids], 0, 0, enabled, 0, 0]`) **неверна**. -Поле 5 (индекс 5) — **тип запуска сценария**: +> 🔴 **ЭТА МОДЕЛЬ ОТВЕРГНУТА ALEX (2026-09-17, конец сессии). Читать §8.16.** +> +> Alex: сценарий `9628` («Автомат.: Рад. ванная 2эт ВКЛ») — **по триггеру**, а поле 5 у него `1`, +> не `9`. Сценарий `8456` («Простой тестовый сценарий») — **такой же ручной, как остальные, но +> disabled**, а поле 5 у него `8`, не `1`. Оба противоречат таблице ниже. +> +> **Что осталось верным:** поле 5 — не просто `enabled` (§1 устарела тоже). +> **Что неверно:** сопоставление `8=расписание`, `9=триггер`, `0/1=ручной`. +> Актуальный разбор — **§8.16**. Таблица сохранена как история ошибки. -| Значение | Что это | Доказательство из тестовых сценариев | +| Значение | Что это (❌ ОШИБОЧНО) | Доказательство из тестовых сценариев | |---|---|---| -| `0` / `1` | ручной запуск (кнопка), вкл/выкл | 64 старых сценария = `1`; `11109` = `0` | -| `8` | по **расписанию** | `#Z8597` — поле 4 = `61`, поле 6 = `3354` ✅ расшифровано | -| `9` | по **триггеру** (условию) | `#Z8547`, `#Z8551` — оба триггерные (подтверждено Alex) | -| `10` | по **интервалу** | `#Z8599` — поле 6 = `43200000` мс = **12 ч** | +| `0` / `1` | ❌ ручной запуск (кнопка), вкл/выкл | 64 старых сценария = `1`; `11109` = `0` — **но `9628` с `1` триггерный** | +| `8` | ❌ по **расписанию** | `#Z8597` — поле 4 = `61`, поле 6 = `3354` ✅ расшифровано — **но `8456` с `8` ручной+disabled** | +| `9` | ❌ по **триггеру** (условию) | `#Z8547` «по времени» и `#Z8551` «по триггеру» — **разные типы, а поле 5 у обоих `9`** | +| `10` | по **интервалу** | `#Z8599` — поле 6 = `43200000` мс = **12 ч** (не перепроверено) | **Поле 6** — параметр запуска (для `10` — интервал в мс; для `8` — время запуска). @@ -658,5 +665,89 @@ scenarios: | YAML | `zont_config/config_local_2026-09-17_16-13-28.yml` | в проекте, round-trip ✅ | Round-trip чистый на **6/6** конфигах (боевой, 3 архива, `14-16-35`, `16-13-28`). -Осталось два `raw`: `8195` (SMS, тело — YAML-якорь `*id002`) и `9500` (type 5, `params` содержит якорь). + +> ⚠️ **УСТАРЕЛО после правок конца сессии** (см. §8.16): `target_name`/`target_type`/`raw_value` +> удалены, секции-дубли убраны, YAML = **5452 строки**. Актуальное состояние — §8.16. + +### 8.16. 🔴 Разбор конца сессии 2026-09-17 — поле 5 и удаление подстановок + +#### (а) Поле 5 типа 11 — модель §8.1 ОПРОВЕРГНУТА + +Alex, разбирая YAML, наткнулся на сценарий `9628`: + +```text +#Z9628=11,'Автомат.: Рад. ванная 2эт ВКЛ',[9756],0,0,1,0,0 +``` + +> «сценарий `Автомат.: Рад. ванная 2эт ВКЛ`: там ахинея какая-то! это сценарий **по триггеру**. +> почему он **manual**?» + +Парсер выводил `trigger: {type: manual}` — по таблице §8.1 (`1` = manual). Alex: неверно. + +Дальше — прямое опровержение всей таблицы: + +| Сценарий | Что сказал Alex | Поле 5 | Поля 3/4 | +|---|---|---|---| +| `9628` … 64 шт `Автомат.:*` | **по триггеру** | `1` | `0,0` | +| `8456` «Простой тестовый сценарий» | «**точно такой же manual как и другие два, но он disabled**» | `8` | `0,0` | +| `8547` «тестовый сценарий по времени» | по времени | `9` | `0,0` | +| `8551` «Тестовый сценарий по триггеру» | по триггеру | `9` | `0,0` | +| `8597` «Тестовый сценарий по расписанию» | расписание пн,ср,чт,пт,сб 13:26 | `8` | `61,3354` | + +**Вывод: `8` и `9` не различают «расписание/триггер».** Два сценария с `9` — «по времени» +и «по триггеру» — Alex сделал специально как **разные типы**. `8456` с `8` — ручной. +`9628` с `1` — триггерный. + +**Распределение поля 5 по 70 сценариям боевого конфига:** + +| Код | Кол-во | Что известно | +|---|---|---| +| `1` | 64 | `Автомат.:*` — по триггеру (условие внутри шага) | +| `0` | 2 | `11109` и ещё один | +| `9` | 2 | `8547` (по времени), `8551` (по триггеру) | +| `8` | 1 | `8597` (расписание `61,3354`) + `8456` (disabled) | +| `10` | 1 | `8599` (интервал) | + +> 🔴 **ЧЕГО Я НЕ ЗНАЮ (не выдумывать):** +> 1. Что означает `1` vs `9` — оба могут быть «включён и запускается по своему условию». +> 2. Как кодируется **disabled** (`8456` = `8` + нули, `8597` = `8` + заполненные поля — +> возможно, disabled = «тип есть, параметры сброшены»). +> 3. Где вообще хранится «по триггеру / по времени / ручной», если не в поле 5. +> Кандидаты: поле 4, поле 6, поле 7 — у `9628` и `8547`/`8551` все нули. +> +> **Статус: `TRIGGER_KINDS` в `config-to-yml.py` — ВЫДУМКА, подлежит удалению.** +> Ждём ответ Alex, что показано в UI у `9628` / `8547` / `8551` / `8456`. + +#### (б) Структура YAML — работы конца сессии + +| # | Что | Итог | +|---|---|---| +| 1 | Секции-дубли `delays`/`scenario_steps`/`scenario_conditions`/`scenario_scripts`/`scenario_raw_objects` | **удалены** из парсера, `TYPE_ORDER` и вывода. Осталась одна служебная — `scenario_orphans` (недостижимые объекты) | +| 2 | Переименование `command`→`descr`, `output`/`output_id`→`target`, `temp_c`→`value` | ✅ сделано, имена = поля строки конфига | +| 3 | `target_name` / `target_type` / `raw_value` | ✅ **удалены** (5 мест в парсере + энкодер) | +| 4 | Энкодер пересчитывает код из `value` | ✅ хелпер `_encode_type9_value()`: `True→'1'`, `False→'0'`, число → `str(round((v+273)*10))` | +| 5 | `object_display_name()` вынесен на уровень модуля | ✅ (был вложенной функцией ниже места вызова → `NameError`, питфолл 28) | + +**Три питфолла, каждый ловил round-trip** (`Duplicate ID 8640/9826` → `потеряно 45` → `потеряно 189`) +подробно в [[family/how-to/zont-config-compiler]] §5c. + +#### (в) Открытый вопрос Alex: «получается script editing language?» + +Alex сформулировал **корневое** сомнение по форме YAML: + +> «хуйня какая-то получается, не правда ли?» → «я говорю хуйня а не script editing language +> выходит какая-то» + +Смысл: в YAML появились `if`/`then`/`else`/`group: and`/`op: '>'`/`wait`/`args` — **структура, +которой в конфиге нет**. Это не отображение данных, а интерпретация поверх них. +Отсюда же растут «две правды» (`'2782'` vs `5.2` в разных секциях) — симптом, не причина. + +**Рассмотренный, но НЕ принятый вариант:** `steps` = те же плоские записи, что в `#Z`-строках, +плюс человеческие имена только для доказанных полей. Без `if`/`then`/`group`/`op`. +**Решение не принято — ждёт Alex.** + +> 🔴 **Урок для методологии:** при правке одной секции проверять, не отображается ли тот же +> объект в другой. Раскодировал `value` в `steps[]`, но забыл про `relay_commands` → один объект, +> два разных `value`. Alex нашёл это глазами, round-trip был зелёным. +> **Round-trip не ловит смысловые расхождения между секциями.**