Files
obsidian-vault/family/tech/zont-scenario-logic-11109.md
T

24 KiB
Raw Blame History

aliases, created, namespace, related, tags, title, type, updated
aliases created namespace related tags title type updated
ZONT сценарий 11109
Передернуть Автомат Котельной
ZONT тип 45 задержка
ZONT сценарная логика
ZONT поле 2 сценария
2026-09-17 family
family/how-to/zont-config-compiler
family/tech/zont-config-object-types
family/how-to/home-automation
family
tech
zont
modbus
homeautomation
🔁 ZONT — сценарная логика и конструктор (11/46/47/48/49/50/59/45) tech 2026-09-17d

🔁 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 сценариев). Контекст конвертеров — family/how-to/zont-config-compiler.


1. Структура сценария

Сценарий — это 4 связанных типа объектов:

#Z<sid>=11,'Имя',[<шаг>,<шаг>,…],0,0,<enabled>,0,0     ← сценарий
#Z<step>=46,<prio>,<cond>,[<действие>,…],[]            ← шаг
#Z<cond>=49,<relay_id>,<operator>,<value>              ← условие
#Z<act>=…                                              ← действие (тип 5, 9 или 45)
Тип Роль Формат Поля
11 Сценарий [11, name, [step_ids], 0, 0, enabled, 0, 0] 8 полей. enabled — поле v[5] (0/1)
46 Шаг [46, prio, cond_id, [action_ids], []] 5 полей. prio и последнее поле — всегда 0/[]
49 Условие [49, relay_id, operator, value] 4 поля. operator: 1=equals, иначе not_equals
45 Задержка [45, <миллисекунды>] 2 поля

Каноническая форма (99% конфига): 1 сценарий → 1 шаг → 1 условие → 1 действие.


2. Действия в шаге — три разных типа

Список действий шага (46 поле 3) может содержать объекты трёх типов:

Тип Что это Формат Декодирование
5 Действие над выходом контроллера [5, name, output_ref, 1, delay, impulse_dur, [], sched_bmp, sched_time, impulse_period, value] 11 полей. output_ref >> 4 = id выхода; delay — поле 4 (мс)
9 Команда реле [9, name, target_relay, '1'/'0'] 4 поля. valueстрока '1'/'0', не число
45 Пауза между действиями [45, ms] 2 поля

⚠️ Тип 45 ≠ delay_ms типа 5. delay_ms — задержка внутри действия перед его выполнением. Тип 45 — отдельный объект-пауза в последовательности. Их часто путают при чтении конфига.


3. Разобранный кейс: #Z11109 «Передернуть Автомат Котельной»

Единственный сценарий в конфиге с нестандартной формой — 7 действий в шаге и задержка (45) прямо в поле 2 сценария (11828) вместо второго шага. См. §5 «Уточнение семантики поля 2».

#Z11109=11,'Передернуть Автомат Котельной',[11827,11828],0,0,0,0,0
#Z11823=49,11190,1,0                                    ← условие
#Z11827=46,0,11823,[11191,11030,11824,11029,11825,11192,11826],[]
#Z11828=45,0                                            ← шаг 2
#Z11824=45,20000   #Z11825=45,60000   #Z11826=45,0
#Z11029=9,'Включить реле «20/1 Автомат Котельная»',11028,'1'
#Z11030=9,'Выключить реле «20/1 Автомат Котельная»',11028,'0'
#Z11191=9,'Включить реле «virt. Запретить передергивание»',11190,'1'
#Z11192=9,'Выключить реле «virt. Запретить передергивание»',11190,'0'
#Z11028=14,'20/1 Автомат Котельная',175728,0
#Z11190=14,'virt. Запретить передергивание',179904,0

Что происходит по шагам

Условие: relay 11190 ('virt. Запретить передергивание') == 0 — т.е. передёргивание не запрещено.

Шаг 1 (11827) — 7 действий подряд:

# Объект Действие Пауза после
1 11191 (type 9) включить virt. Запретить передергивание
2 11030 (type 9) выключить 20/1 Автомат Котельная
3 11824 (type 45) пауза 20 000 мс
4 11029 (type 9) включить 20/1 Автомат Котельная
5 11825 (type 45) пауза 60 000 мс
6 11192 (type 9) выключить virt. Запретить передергивание
7 11826 (type 45) пауза 0

Шаг 2 (11828) — на деле это не шаг, а задержка [45, 0] прямо в поле 2 сценария: пустая пауза-заглушка. Оставлена планировщиком ZONT, функциональной нагрузки не несёт.

Смысл логики

Это защита от повторного передёргивания:

  1. Виртуальное реле virt. Запретить передергивание (id 11190) ставится в 1 первым действием.
  2. Условие сценария (11823) требует == 0 → пока реле в 1, сценарий повторно не запустится.
  3. Снимается реле только после 20 с + 60 с пауз (действие 6), т.е. через 80 секунд после старта → минимальный интервал между передёргиваниями автомата = 80 с.

🔴 Проблема

#Z11109 поле v[5] = 0сценарий выключен в контроллере. Защита и сама функция передёргивания не работают.


4. Полные счётчики по конфигу (для сверки после правок)

Тип Кол-во Комментарий
11 / 46 65 / 65 все одношаговые, кроме 11109
49 65 все ровно 4 поля, op=1 (equals) у всех
45 4 11824, 11825, 11826, 11828 — только в 11109
9 42 21 пара ВКЛ/ВЫКЛ, value — строка '1'/'0'
5 66 действия над выходами
14 40 реле
10 22 GUI-переключатели
0 / 36 13 / 13 дискретные датчики + вложенные конфиги
52 / 51 / 53 93 / 11 / 64 Modbus-регистры / устройства / ещё один слой
16 / 20 10 / 1 контуры и режимы отопления
Всего #Z 598

Проверка после любой правки: grep -c '^#Z' <файл> должен дать 598.


5. Статус разбора конвертером

Что Статус
Многошаговый сценарий ([11827,11828]) разбирается с 2026-09-17
7 действий в шаге 11827 разбирается с 2026-09-17
Тип 45 (4 объекта) парсер + эмиттер, секция YAML delays
Round-trip всех 4 конфигов чисто (test_roundtrip.py, коммит 199f2b1)
Сценарий enabled=0 факт, не баг конвертера

🔴 Уточнение семантики поля 2 (важно)

Поле 2 сценария — не «список шагов», а последовательность ссылок, куда попадают объекты разных типов. Полный список: шаг (46) и задержка (45).

В #Z11109 поле 2 = [11827, 11828], где:

  • 11827 — настоящий шаг (46) с условием и 7 действиями;
  • 11828задержка (45,0), т.е. «шаг-ожидание» без условия.

Поэтому формулировка «2 шага» неточна: шаг один, вторым элементом идёт задержка-заглушка. Отсюда же — extra_links в YAML (см. family/how-to/zont-config-compiler §2.1): не-46 ссылки сохраняются дословно, чтобы round-trip остался байт-точным.

⚠️ Не путать с типом 45 внутри шага. В 11827 задержки 11824/11825/11826 — это действия внутри шага. 11828ссылка в поле 2 сценария, т.е. элемент верхнего уровня.


6. План переработки YAML-структуры (2026-09-17, ждёт апрува)

Сценарии в YAML переписываются в нативную ZONT-форму вложенных инструкций «если … то …»без HA-синтаксиса (triggers, platform: state). Alex: «нет структура должна быть как в zont. триггеров нет.»

Предлагаемая форма для 11109:

scenarios:
  - id: 11109
    name: 'Передернуть Автомат Котельной'
    enabled: false
    blocks:
      - id: 11827
        if: {id: 11823, relay: 11190, operator: equals, value: 0}
        then:
          - {id: 11191, action: relay_on,  relay: 11190}
          - {id: 11030, action: relay_off, relay: 11028}
          - {id: 11824, action: wait, ms: 20000}
          - {id: 11029, action: relay_on,  relay: 11028}
          - {id: 11825, action: wait, ms: 60000}
          - {id: 11192, action: relay_off, relay: 11190}
          - {id: 11826, action: wait, ms: 0}
    tail:
      - {id: 11828, action: wait, ms: 0}   # задержка из поля 2 сценария

Полный план — family/how-to/zont-config-compiler §5c.

РАБОТА ПО §5c ПРИОСТАНОВЛЕНА (2026-09-17). Alex дал «стоп» и запросил исследование облачного API ZONT — есть ли альтернатива конвертеру. Ответ: API конфиг не поддерживает (сценарии/реле/ 11/14/46/49 в API отсутствуют). Переписывать с 0 не на что, конвертер остаётся единственным путём. Разбор — family/tech/zont-api. Форма blocks/if/then выше — предложение, в коде не реализовано.


7. Связанные заметки


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.txt34 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.

#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 84588504
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 84508601)

Типы в блоке: {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 трассировка сценарных графов, поиск сценариев с новыми типами
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. Состояние: конвертер на новом конфиге ПАДАЕТ

$ 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