[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:
@@ -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, <логика>, [<id условий>]]` | `[48, 0, [8493,8495]]`, `[48, 1, [...]]`, `[48, 2, [...]]` |
|
||||
| **50** | **запуск команды/сценария по id** | `[50, 1, 0, 0, <id>]` | `[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 <id> "<args>"` | `objcmd 8700 "1 %0"` | команда объекту с подстановкой `%0`, `%1` |
|
||||
| `objstate <id> <n> <n>` | `objstate 9838 0 0` | чтение состояния объекта |
|
||||
| `expr "<формула>"` | `expr "%0 + %1"`, `expr "%0 - %1"` | арифметика |
|
||||
| `set <var>` | `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, <id>]` — запуск по расписанию/интервалу? |
|
||||
| 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 |
|
||||
|
||||
Reference in New Issue
Block a user