From 610df81ab1f8bbabc6fb15eb3f250441bd5ebc8f Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Thu, 17 Sep 2026 14:21:52 +0600 Subject: [PATCH] [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 --- family/how-to/zont-config-compiler.md | 41 ++++- family/tech/zont-config-object-types.md | 17 ++ family/tech/zont-scenario-logic-11109.md | 193 ++++++++++++++++++++++- 3 files changed, 245 insertions(+), 6 deletions(-) diff --git a/family/how-to/zont-config-compiler.md b/family/how-to/zont-config-compiler.md index 8b8c7bd9..a7bdea2f 100644 --- a/family/how-to/zont-config-compiler.md +++ b/family/how-to/zont-config-compiler.md @@ -481,9 +481,10 @@ scenarios: реле ставится в 1 первым действием, условие требует 0 → пока реле в 1, сценарий не перезапустится. Минимальный интервал между передёргиваниями = 80 с (20+60). -> 🔴 **Защита в конфиге УЖЕ есть.** Поле v[5] сценария = `0` → сценарий **выключен в контроллере**, -> поэтому защита и функция передёргивания не работают. Вопрос «дописать логику» на деле может быть -> «включить существующую» (`enabled: true`) — это НЕ подтверждено Alex'ом, не додумывать. +> 🔴 **Защита в конфиге УЖЕ есть, но сценарий НЕ активен.** Поле v[5] сценария = `0` → ручной запуск +> в положении «выкл». ⚠️ **Исправлено 2026-09-17:** поле 5 — это **тип запуска** (`0`/`1` ручной, +> `8` расписание, `9` триггер, `10` интервал), а **не** булев `enabled`. См. §5i и +> [[family/tech/zont-scenario-logic-11109]] §8.1. --- @@ -616,10 +617,42 @@ https://lk.zont-online.ru/download/firmwares/H2000_PRO____.zip --- +## 5i. 🔴 Конструктор логики ZONT (типы 47/48/50/59) — НЕ ПОДДЕРЖАН + +> **Найдено 2026-09-17.** Alex создал в UI тестовые сценарии («все доступные триггеры и варианты +> логики»). Разбор локального конфига `config_local_2026-09-17_14-16-35.txt` (660 `#Z`) вскрыл +> **визуальный конструктор логики** со скриптовым движком. + +**Конвертер на этом конфиге падает:** + +```bash +$ python3 config-to-yml.py zont_config/config_local_2026-09-17_14-16-35.txt > /tmp/new.yml +Ошибка: Условие 8496: не type 49 +EXIT=2 +``` + +**Две ключевые находки:** + +1. 🔴 **Поле 5 типа 11 — НЕ `enabled`, а ТИП ЗАПУСКА:** `0`/`1` ручной, `8` расписание, + `9` триггер, `10` интервал. Поле 6 — параметр (для интервала — мс). **Текущий конвертер + теряет эту информацию** (сводит к булеву `enabled`). +2. **Новые типы:** `47` (лист условия), `48` (группа И/ИЛИ), `50` (запуск по id), + `59` (мини-скрипт: `objcmd`/`objstate`/`expr`/`set`/`puts`/`storeev`). + +**Что нужно сделать** (после ответов Alex на семантику — [[family/tech/zont-scenario-logic-11109]] §8.7): +парсер 47/48/50/59 с рекурсивным деревом условий; поле 5 хранить как тип запуска; принимать +непустое поле 4 шага; допускать не-46 типы в поле 2. + +➡️ **Полный разбор — [[family/tech/zont-scenario-logic-11109]] §8** + +--- + ## 6. Состояние проекта (проверено 2026-09-17, вечер) ✅ **Конвертеры закоммичены — `199f2b1`.** Рабочее дерево чистое (после этого коммита). +⚠️ **Но появился конфиг, который конвертер НЕ разбирает** — с конструктором логики (§5i). + | Файл | Статус | |---|---| | `config-to-yml.py`, `yml-to-config.py` | ✅ **изменены и закоммичены** (`199f2b1`, §5b) | @@ -629,6 +662,8 @@ https://lk.zont-online.ru/download/firmwares/H2000_PRO____.zip | `zont_config/archive/` | **не в git** (`untracked`) — лежит в `.gitignore`-нейтральном состоянии | | `zont_config/H2000_PRO_config_actual-{2,3,4}.txt` / `.yml` | ✅ **перемещены в `archive/` и закоммичены** (`7ae0e32`) | | `zont_api_docs/` | ✅ **новая папка** — локальная копия доки облачного API ZONT (`zont_api_docs.html` 250 KB, `zont_api_docs.txt` 99 KB, `convert.py`). **не в git**. Исследование — [[family/tech/zont-api]] | +| `zont_config/config_local_2026-09-17_14-16-35.txt` | 🆕 **34 907 байт, 660 `#Z`, 25 `#S`** — конфиг с **тестовыми сценариями** Alex (все виды триггеров/логики). Снят с `http://192.168.0.50/config.txt`. **не в git** | +| `dump_new_types.py`, `probe_types.py`, `trace_scenarios.py` | 🆕 **новые скрипты разбора** сценарных типов 47/48/50/59. Разбор — [[family/tech/zont-scenario-logic-11109]] §8.8. **не в git** | | `~/rasputin-tmp/zont-util/` | ✅ **новая папка на Mac** (вне репо) — настроечная утилита `H1000 Programmator` 2.8.5, драйвер USB, прошивка `.enc`, скрипт распаковки `extract.py`. Разбор — §5g-2, [[family/tech/zont-api]] §10 | | `~/rasputin-tmp/zont-{auth-probe,recon,recon2,ws-probe}.js` | ✅ скрипты разведки локального WS-интерфейса. **не в git** | diff --git a/family/tech/zont-config-object-types.md b/family/tech/zont-config-object-types.md index cc8f3767..042b1992 100644 --- a/family/tech/zont-config-object-types.md +++ b/family/tech/zont-config-object-types.md @@ -54,11 +54,20 @@ updated: '2026-09-17c' | 42 | GUI-вкладки | `name` | `gui_tabs` | | **45** | Задержка-объект (пауза в мс) в списке действий шага — `[45, ms]` | `ms` | `delays` | | 46 | Шаги сценариев | `[46, prio, cond_id, [action_ids], []]` — 5 полей | `scenario_steps` | +| **47** ⚠️ | **Лист дерева условий (конструктор логики)** — `[47, <оператор>, <объект>, <значение>, <порог>]` | ❌ **НЕ ПОДДЕРЖАН** | — | +| **48** ⚠️ | **Группа условий И/ИЛИ** — `[48, <логика>, []]` | ❌ **НЕ ПОДДЕРЖАН** | — | | 49 | Условия сценариев | `relay_id`, `operator`, `value` | `scenario_conditions` | +| **50** ⚠️ | **Запуск команды/сценария по id** — `[50, 1, 0, 0, ]` | ❌ **НЕ ПОДДЕРЖАН** | — | | 51 | Modbus-устройства | `slave_id`, `name`, `poll_interval`, `timeout`, `registers`, `raw_params` | `modbus_devices` | | 52 | Modbus-регистры | `name`, `register`, `bit_width`, `repeat_period`, `num_vars`, `raw_params` | **вложены в своё устройство 51** | | 53 | Аналоговые выходы | `name`, `min`, `max`, `value`, `offset`, `scale`, `flags`, `address` | `analog_outputs` | | 57 | MQTT-топики | `topic`, `sensors` | `mqtt_topics` | +| **59** ⚠️ | **Мини-скрипт ZONT** — `[59, '<код>', <арг1>, <арг2>, <флаг>]` | ❌ **НЕ ПОДДЕРЖАН** | — | + +> ⚠️ **Типы 47 / 48 / 50 / 59 обнаружены 2026-09-17** в локальном конфиге с контроллера +> (`config_local_2026-09-17_14-16-35.txt`, 660 `#Z`) — это **конструктор логики** ZONT. +> Конвертер на таком конфиге **падает** (`Ошибка: Условие 8496: не type 49`). +> Полный разбор — [[family/tech/zont-scenario-logic-11109]] §8. --- @@ -90,10 +99,18 @@ Modbus-регистры (тип 52) в конфиге — **отдельные ### 2.3. Сценарии (11 + 46 + 49 + 45) +> 🔴 **ИСПРАВЛЕНО 2026-09-17:** поле 5 типа 11 — **НЕ `enabled`**, а **тип запуска сценария** +> (`0`/`1` ручной, `8` расписание, `9` триггер, `10` интервал). Поле 6 — параметр запуска. +> Подробности и доказательства — [[family/tech/zont-scenario-logic-11109]] §8.1. + Тип 11 парсится **целиком** — из него собирается `steps[]` (шаги 46 со своими условиями 49), включая многошаговые сценарии и много действий в шаге. Шаги и условия выводятся отдельными секциями YAML `scenario_steps` / `scenario_conditions`, задержки — `delays`. Полная структура, формат полей и разобранный боевой кейс — [[family/tech/zont-scenario-logic-11109]]. +⚠️ **Полнота парсера ограничена конфигами без конструктора логики.** На локальном конфиге с типами +**47/48/50/59** конвертер **падает** (`Ошибка: Условие 8496: не type 49`). Эти типы — визуальный +конструктор логики ZONT, ещё **не поддержаны** (см. §1 таблицу и [[family/tech/zont-scenario-logic-11109]] §8). + ✅ **Лимиты сняты 2026-09-17** (были жёсткие ограничения, падал с exit 2 на первом невыразимом объекте): - ~~`config-to-yml.py:473` — сценарий ровно с 1 шагом~~ → теперь цикл по всем шагам - ~~`config-to-yml.py:489` — шаг ровно с 1 действием~~ → теперь весь список действий diff --git a/family/tech/zont-scenario-logic-11109.md b/family/tech/zont-scenario-logic-11109.md index 5f6ed07c..95bc9e34 100644 --- a/family/tech/zont-scenario-logic-11109.md +++ b/family/tech/zont-scenario-logic-11109.md @@ -17,12 +17,16 @@ tags: - zont - modbus - homeautomation -title: 🔁 ZONT — сценарная логика (типы 11 / 46 / 49 / 45) +title: 🔁 ZONT — сценарная логика и конструктор (11/46/47/48/49/50/59/45) type: tech -updated: '2026-09-17b' +updated: '2026-09-17d' --- -# 🔁 ZONT — сценарная логика (типы 11 / 46 / 49 / 45) +# 🔁 ZONT — сценарная логика и конструктор логики + +> 🔴 **ВНИМАНИЕ: раздел §1 ниже содержит УСТАРЕВШУЮ модель.** Поле 5 типа 11 — **НЕ «enabled»**, +> это **тип запуска сценария** (0/1 ручной, 8 расписание, 9 триггер, 10 интервал). Исправление и +> полная модель — **§8**. Раздел §1 оставлен как история разбора; актуальная семантика в §8. Как устроены сценарии в конфиге ZONT и что именно разобрано в боевом конфиге `config_0FA7C33CC89F_0FA7C33CC89F_2026-09-17_12-12-28.txt` (598 `#Z`, 25 `#S`, 65 сценариев). @@ -209,3 +213,186 @@ scenarios: - [[family/tech/zont-api]] — облачный API ZONT: конфиг не поддерживает, альтернативы конвертеру нет - [[family/tech/zont-config-object-types]] — полная таблица типов объектов и `#S`-настройки - [[family/how-to/home-automation]] — контур автоматизации, ZONT, Modbus slave ID и регистры + +--- + +## 8. 🔴 КОНСТРУКТОР ЛОГИКИ ZONT — типы 47 / 48 / 50 / 59 (разобрано 2026-09-17) + +> **Источник:** локальный конфиг с контроллера, снят с `http://192.168.0.50/config.txt` +> (без авторизации, см. [[family/tech/zont-api]] §6bis): +> `zont_config/config_local_2026-09-17_14-16-35.txt` — **34 907 байт, 660 `#Z`, 25 `#S`**. +> +> Alex создал тестовые сценарии в UI, «постарался использовать все доступные триггеры и варианты +> логики». Это позволило вскрыть **полноценный визуальный конструктор логики** со скриптовым движком. + +### 8.1. 🔴 ИСПРАВЛЕНИЕ: поле 5 типа 11 — ТИП ЗАПУСКА, а не `enabled` + +Прежняя модель (§1, строка `[11, name, [step_ids], 0, 0, enabled, 0, 0]`) **неверна**. +Поле 5 (индекс 5) — **тип запуска сценария**: + +| Значение | Что это | Доказательство из тестовых сценариев | +|---|---|---| +| `0` / `1` | ручной запуск (кнопка), вкл/выкл | 64 старых сценария = `1`; `11109` = `0` | +| `8` | по **расписанию** | `#Z8597` — поле 4 = `61`, поле 5 = `3354` | +| `9` | по **триггеру** (условию) | `#Z8547`, `#Z8551` — тестовые | +| `10` | по **интервалу** | `#Z8599` — поле 6 = `43200000` мс = **12 ч** | + +Распределение по живому конфигу: `{1: 64, 0: 1, 8: 2, 9: 2, 10: 1}`. + +**Поле 6** — параметр запуска (для `10` — интервал в мс; для `9`/`8` — иное). +**Поле 4** — у `8597` = `61` (вероятно день недели / индекс расписания), у остальных `0`. + +```text +#Z8456=11,'Простой тестовый сценарий',[<26 ссылок>],0,0, 8,0,0 +#Z8547=11,'тестовый сценарий по времени', [8550],0,0, 9,0,0 +#Z8551=11,'Тестовый сценарий по триггеру',[8555],0,0, 9,0,0 +#Z8597=11,'Тестовый сценарий по расписанию',[8598],61,3354, 8,0,0 +#Z8599=11,'Тестовый сценарий по интервалу',[8600,8601],0,0, 10,43200000,0 +``` + +> ⚠️ **Следствие для конвертера:** `enabled` в YAML сейчас выводится из поля 5 как булево — +> это **потеря информации** для значений 8/9/10. Конвертер на новом конфиге **падает** +> (`Ошибка: Условие 8496: не type 49`) — новые типы не поддержаны. + +### 8.2. Новые типы объектов + +| Тип | Что | Формат | Пример | +|---|---|---|---| +| **47** | **лист дерева условий** | `[47, <оператор>, <объект>, <значение>, <порог>]` | `[47, 3, 8552, 0, -5]` — «температура ниже −5» | +| **48** | **группа условий (И/ИЛИ)** | `[48, <логика>, []]` | `[48, 0, [8493,8495]]`, `[48, 1, [...]]`, `[48, 2, [...]]` | +| **50** | **запуск команды/сценария по id** | `[50, 1, 0, 0, ]` | `[50, 1, 0, 0, 123]`, `[50, 1, 0, 0, 109]`, `[50, 0, 1, 3351, 0]` | +| **59** | **мини-скрипт ZONT** | `[59, '<код>', <арг1>, <арг2>, <флаг>]` | `[59, 'expr "%0 + %1"', 8459, 8460, 0]` | + +Наблюдённые значения поля 1 у **47**: `0, 1, 3, 4` (оператор — семантика **не подтверждена**). +У **48**: `0, 1, 2` (логика группы — семантика **не подтверждена**). + +### 8.3. Type 59 — встроенный скриптовый язык + +Найденные команды (в поле 1, в кавычках — аргументы): + +| Команда | Пример | Смысл (предположительно) | +|---|---|---| +| `objcmd ""` | `objcmd 8700 "1 %0"` | команда объекту с подстановкой `%0`, `%1` | +| `objstate ` | `objstate 9838 0 0` | чтение состояния объекта | +| `expr "<формула>"` | `expr "%0 + %1"`, `expr "%0 - %1"` | арифметика | +| `set ` | `set var1` | присваивание переменной | +| `puts "текст"` | `puts "Отладка"`, `puts "test"` | вывод (отладка) | +| `storeev I "z"` / `storeev A "asdf"` | — | запись события (I = integer?, A = alert/array?) | +| просто число/строка | `3`, `2 ;#p` | константа; суффиксы `;#a`, `;#h`, `;#p` | + +Есть **переменные** (`var1`), **подстановки** `%0`/`%1` (аргументы из полей 2/3), **суффиксы** `;#a`/`;#h`/`;#p`. +Это объясняет всё: у ZONT есть **полноценный визуальный конструктор логики** поверх скриптового движка. + +### 8.4. Дерево условий — рабочий пример (`#Z8505`, `#Z8506`) + +Вложенная логика читается так: + +``` +#Z8506 = [46, 0, 8496, [8505], []] ← шаг: условие 8496, действие 8505 +#Z8496 = [48, 0, [8493, 8495]] ← группа: 8493 И 8495 +#Z8493 = [47, 0, 8492, 0, 3] ← лист: объект 8492, значение 0, порог 3 +#Z8492 = [59, 'objstate 9838 0 0', 0, 0, 0] ← объект = скрипт! +#Z8495 = [47, 4, 8472, 8494, 0] +#Z8494 = [59, 'objstate 9838 0 0', 0, 0, 0] + +#Z8505 = [46, 1, 8501, [8502, 8503], [8504]] ← шаг: приоритет 1, доп. список [8504] +#Z8501 = [48, 1, [8497, 8500]] ← группа: 8497 ИЛИ 8500 +#Z8497 = [47, 0, 8472, 0, 2] +#Z8500 = [48, 2, [8499]] ← группа: логика 2 над [8499] +#Z8499 = [47, 1, 8498, 0, 3] +#Z8498 = [59, '2 ;#p', 0, 0, 0] +``` + +> 📌 В `#Z8505` поле 1 (приоритет) = **1**, и поле 4 (последнее) = **непустой список `[8504]`** — +> в отличие от «канонических» шагов, где там всегда `[]`. Конвертер это отвергает +> (`require(step[4] == [])`). Семантика поля 4 — **не подтверждена**. + +### 8.5. Контейнер-сценарий `#Z8456` (поле 2 = смесь типов) + +`#Z8456 = [11, 'Простой тестовый сценарий', [<26 ссылок>], 0, 0, 8, 0, 0]` — поле 2 содержит +объекты **разных типов**, а не только шаги: + +| Тип | Кол-во | Примеры | +|---|---|---| +| 9 (команда реле) | 2 | `8457` «Установить целевую температуру 23.8…», `8470` «Активировать режим…» | +| 59 (скрипт) | 17 | `8458`…`8504` | +| 11 (другой сценарий!) | 1 | `11109` «Передернуть Автомат Котельной» | +| 3 (SMS) | 1 | `8195` «CMC оповещение» | +| 5 (действие) | 1 | `9500` «Вкл. Рад. ванная 2эт» | +| 45 (задержка) | 1 | `8489` = 432 000 000 мс = **5 суток** | +| 46 (шаг) | 1 | `8506` | + +> 🔴 **Сценарий может ссылаться на другой сценарий** (`11109` внутри `8456`). Это **не дерево**, +> а плоский список ссылок. + +### 8.6. Сводка тестового блока (id 8450–8601) + +Типы в блоке: `{9: 2, 11: 3, 14: 1, 16: 1, 27: 1, 45: 1, 46: 4, 47: 5, 48: 3, 49: 11, 50: 3, 59: 26}`. + +| Сценарий | Имя | Поле 5 (запуск) | +|---|---|---| +| `8456` | Простой тестовый сценарий | `8` (расписание) | +| `8547` | тестовый сценарий по времени | `9` (триггер) | +| `8551` | Тестовый сценарий по триггеру | `9` (триггер) | +| `8597` | Тестовый сценарий по расписанию | `8` (расписание) | +| `8599` | Тестовый сценарий по интервалу | `10` (интервал, 12 ч) | + +### 8.7. ⏳ ОТКРЫТЫЕ ВОПРОСЫ (заданы Alex, ответа ещё нет) + +| # | Вопрос | +|---|---| +| 1 | **Type 47, поле 1** — что за оператор? Наблюдены `0, 1, 3, 4`. Гипотеза: `0`=равно, `1`=не равно, `3`=меньше, `4`=больше — **не подтверждено** | +| 2 | **Type 48, поле 1** — логика группы? Наблюдены `0, 1, 2`. Гипотеза: `0`=И, `1`=ИЛИ, `2`=НЕ — **не подтверждено** | +| 3 | **Type 50** — что за объект? `[50, 1, 0, 0, ]` — запуск по расписанию/интервалу? | +| 4 | **Type 11, поле 4** — у `8597` = `61`, у остальных `0`. Минуты? День недели? | +| 5 | **Type 59** — есть ли документация на язык? Или это внутренний формат | + +> 🔴 **Не строить гипотезы вместо ответа.** Alex явно предложил: «если нужна будет подсказка что и +> чем является по типу/значениям — спрашивай меня». Вопросы заданы, ждём ответа. +> До ответа **правки конвертера не делать** — можно закодировать неверную семантику. + +### 8.8. Скрипты разбора (в проекте) + +| Файл | Назначение | +|---|---| +| `dump_new_types.py` | дамп типов 11/45/46/47/48/49/50/59 целиком | +| `probe_types.py` | распределение поля 5 у type 11; тело контейнера; блок 8450–8560 | +| `trace_scenarios.py` | трассировка сценарных графов, поиск сценариев с новыми типами | + +```bash +cd /Users/admin/Automation/HA-ZONT-Modbus +python3 probe_types.py # → семантика поля 5, тестовый блок +python3 dump_new_types.py # → все сценарные объекты +``` + +> ⚠️ `trace_scenarios.py` падает на `TypeError: unhashable type: 'list'` (шаг `8457` — type 9, +> у него `cond` = `[16, 'Контур ГВС', …]`, а скрипт ждёт скаляр). Не критично — `probe_types.py` +> даёт те же данные. Чинить при следующем заходе. + +### 8.9. Состояние: конвертер на новом конфиге ПАДАЕТ + +```bash +$ python3 config-to-yml.py zont_config/config_local_2026-09-17_14-16-35.txt > /tmp/new.yml +Ошибка: Условие 8496: не type 49 +EXIT=2 +``` + +**Причина:** `config-to-yml.py` в блоке сценариев требует `cond[0] == 49` и +`step[4] == []`. Новые типы (47/48/50/59) и непустое поле 4 не поддерживаются. + +**Что нужно (после ответов Alex на §8.7):** +1. Парсер типов **47/48/50/59** + рекурсивная сборка дерева условий +2. Поле 5 типа 11 — хранить как **тип запуска** (0/1/8/9/10) + поле 6 (параметр), не как `enabled` +3. Поле 4 шага — принимать непустые списки +4. Ссылки в поле 2 — допускать не-46 типы (45, 11, 3, 5, 9) +5. Round-trip всех 5 конфигов (боевой + 3 архива + новый локальный) + +**Счётчики нового конфига (для сверки):** `660 #Z`, `25 #S`, байт — 34 907. + +| Тип | Кол-во | | Тип | Кол-во | +|---|---|---|---|---| +| 11 | 70 | | 49 | 76 | +| 46 | 69 | | 47 | 5 | +| 45 | 5 | | 48 | 3 | +| 9 | 44 | | 50 | 3 | +| 59 | 28 | | 0/36 | 13/13 |