17 KiB
8.17. ✅ МОДЕЛЬ ЗАКРЫТА (2026-09-17, финал) — поле 5, форма сценария, type 47/49
🔴 ЧАСТИЧНО УСТАРЕЛО — актуальная форма в family/how-to/zont-config-compiler §8. Что здесь неверно:
if/then/elseНЕ выдумка (§(б) ниже утверждает обратное). Это поля записи 46 — поле 3 =then-список, поле 4 =else-список, поле 2 = условие. Alex: «Then конечно!!!». Параthen/elseобязательна там, где у шага есть свойif.action— не выдумка, но и не универсальное имя: у шага с поднятым условием (trigger:наверху) список действий называетсяaction; у шага со своимif—then.trigger:не дублируется в шаге: условие переносится (pop), иначе PyYAML ставит анкоры&id061/*id061(было 69 штук)._kind/_f5/_thenв примерах §(б) — выдуманные служебные ключи, вырезаны.- Поле 5 в YAML не хранится вообще (
type/field5тоже вырезаны) — собирается из тела.
Статус (исторический): все открытые вопросы §8.16 закрыты. Ниже — подтверждённые факты. Таблица
TRIGGER_KINDSудалена из кода; доказательство получено тостингом сценариев в UI: Alex выключил/включил тестовые сценарии, поле 5 снято до и после, плюс повторный тостинг8597/8599дал включённые значенияschedule/interval(0и2).
(а) 🔴 Поле 5 типа 11 = тип сценария + флаг «выключен». ПОДТВЕРЖДЕНО прибора + Alex
type = field5 & 7 # 0 = manual | schedule, 1 = trigger, 2 = interval
enabled = not (field5 & 8) # бит 8 = сценарий ВЫКЛЮЧЕН
🔴 Слово —
type, неkind. Словаkindв конфиге и UI нет; я его выдумал. Alex: «какой нахуй kind?? что это блядь значит?! я его откуда тебе высру?!» Типы назвал Alex:manual,trigger,interval,schedule.
| Сценарий | Выкл | Вкл | type |
Прочие поля |
|---|---|---|---|---|
8456 «Простой тестовый» |
8 |
— | 0 = manual |
— |
8597 «по расписанию» |
8 |
0 |
0 = schedule |
поля 3/4 = 61, 3354 |
11109 «Передернуть Котельной» |
— | 0 |
0 = manual |
2 элемента в поле 2 |
8547 «по времени» |
9 |
— | 1 = trigger |
— |
8551 «по триггеру» |
9 |
— | 1 = trigger |
— |
9628 «Автомат.: Рад. ванная 2эт ВКЛ» |
9 |
1 |
1 = trigger |
— |
8599 «по интервалу» |
10 |
2 |
2 = interval |
поле 6 = 43200000 мс |
🔴 Включённые 0 (8597) и 2 (8599) получены тостингом на приборе: Alex включил оба
сценария в UI, конфиг снят заново (curl -s http://192.168.0.50/config.txt). До этого момента
включённые значения schedule/interval были неизвестны — были только выключенные 8/10.
Итог: у каждого типа есть вкл/выкл, и всегда вкл + 8 = выкл:
| тип | вкл | выкл |
|---|---|---|
manual |
0 (11109) |
8 (8456) |
schedule |
0 (8597) |
8 (был) |
trigger |
1 (64 шт) |
9 (8547, 8551) |
interval |
2 (8599) |
10 (был) |
⚠️
manual(0) иschedule(0) — один и тот жеtype. Различаются наличием полей 3/4 (days_mask+time): у расписания они заполнены, у ручного — нули. Alex: «manual от schedule очевидно отличаются наличием блядь schedule!» Кодировку расписания см. §8.1 (61= ПН,СР,ЧТ,ПТ,СБ;3354=(13<<8)|26= 13:26).
Почему старая модель {0:manual,1:manual,8:schedule,9:trigger,10:interval} была неверна:
она читала число как «класс запуска» целиком. На самом деле число двухбитовое по смыслу:
младшие 3 бита = тип, бит 8 = выключено. Отсюда все противоречия §8.16.
❌ Снятые гипотезы (не возвращаться): «
field5 & 7= значение из условия шага 46» (32 расхождения из 70 — пары ВКЛ/ВЫКЛ9628/9629имеют одинаковое поле1при противоположных условиях); «поле 5 не выводится из содержимого» (выводится: тип + бит 8).
Что в коде: TRIGGER_KINDS, _raw_trigger_kind, _raw_trigger_params, time_raw удалены.
Заголовок сценария в YAML теперь: enabled, type, days/days_mask, time, interval_ms.
Служебные _f5/_kind тоже убраны — поле 5 полностью восстанавливается из enabled + type.
(б) Форма YAML сценария — ПЕРЕСМОТРЕНА Alex'ом (финал сессии)
Alex отверг if/then/else в YAML как выдумку:
«у тебя в
9819сейчас в yml написанif! а это неifа триггер»
Проверка конфига подтвердила: слов if, then, else, condition, object, operator, group,
op в конфиге нет. Это была интерпретация парсера поверх данных.
Корневое требование: trigger — это триггер, а не if; steps — это шаги, а не ветвление.
Согласованная форма (принята Alex)
- id: 9691
name: 'Автомат.: Прихожая (н/п) (14/14) ВКЛ'
enabled: true
trigger:
- id: 9729
object: '9495'
value: 1
steps:
- id: 9819
action: 9563
Соответствие строкам конфига — #Z9691 «Прихожая (н/п) 14/14 ВКЛ»
#Z9691=11,'Автомат.: Прихожая (н/п) (14/14) ВКЛ',[9819],0,0,1,0,0
#Z9819=46,0,9729,[9563],[] ← шаг: условие 9729, действие 9563
#Z9729=49,9495,1,1 ← триггер: объект 9495, значение 1
#Z9495=14,'Датч 14/14: Прихожая (н/п)',151408,0
#Z9563=5,'Включить выход 14/14: Прихожая (н/п)',146064,1,0,0,[],0,0,0,512
| YAML | Строка конфига | Поля |
|---|---|---|
id: 9691, name |
#Z9691=11,… |
1, 2 |
enabled: true |
#Z9691 поле 5 = 1 |
not (1 & 8) |
trigger[].id: 9729 |
#Z9729=49,… |
1 (id самого условия) |
trigger[].object: '9495' |
#Z9729 |
2 (id объекта, на который смотрит триггер) |
trigger[].value: 1 |
#Z9729 |
4 (значение; поле 3 = оператор) |
steps[].id: 9819 |
#Z9819=46,… |
1 (id шага) |
steps[].action: 9563 |
#Z9819 |
4 (первый id из [9563]) |
| тело действия | #Z9563=5,'…',146064,1,… |
живёт своей строкой |
Терминология Alex — точная
| Id | Что это по Alex | Где в YAML |
|---|---|---|
9691 |
сценарий | id верхнего уровня |
9729 |
триггер (не if!) |
trigger[].id |
9495 |
объект, за которым следит триггер | trigger[].object |
9819 |
шаг (if of the step по формулировке Alex) |
steps[].id |
9563 |
действие — «выполнить пользовательское действие» | steps[].action |
Alex: «
#Z9563=5,…— это шаг «выполнить пользовательское действие» (action)9563».
Единая модель вложенных id
Разница между trigger и steps — только в том, какое поле #Z9819 (тип 46) на них указывает:
#Z9819 = 46, 0, 9729, [9563], []
│ │
│ └── steps[].action ← поле 4 (список действий)
└───────── trigger[].id ← поле 3 (условие)
object выбран словом для ссылки на объект, потому что в остальном коде уже так
(dump_condition для type 49: 'object': node[1]), рядом с target (реле/контур) и descr.
Следствия для кода — ✅ ПУНКТЫ 1–3, 5 СДЕЛАНЫ (2026-09-17)
| # | Что | Статус |
|---|---|---|
| 1 | dump_condition type 49 → {id, object, value} вместо {id, condition: {object, operator, value}} |
✅ сделано |
| 2 | dump_step type 46 → {id, action: <первый then id>}; trigger вынимается на уровень сценария |
✅ сделано |
| 3 | Заголовок сценария — kind/kind_raw/_kind/_f5 убраны, вместо них видимое поле type |
✅ сделано |
| 4 | Непустые then/else / второй+ id → что писать в форме |
🔴 открытый вопрос, ждёт Alex |
| 5 | dump_action — делегирование в dump_step (чтобы type 5/9 в телах не падали в raw) |
✅ сделано |
| 6 | Энкодер под новую форму | ⏸ не начат — ждёт подтверждения формы. Round-trip сломан |
| 7 | type для 11109 выходит trigger вместо manual |
⚠️ баг, гипотеза правки: trigger = ровно один элемент в steps И он типа 46. Прогон не выполнен |
✅ Фактический вывод парсера после правок (проверено 2026-09-17)
Перегенерация zont_config/config_local_2026-09-17_17-45-00.yml (exit 0, 4405 строк — было 5376):
- id: 9691
name: 'Автомат.: Прихожая (н/п) (14/14) ВКЛ'
enabled: true
_kind: 1
_f5: 1
steps:
- id: 9819
trigger:
id: 9729
object: 9495
value: 1
action: 9563
if/then/else/condition/operator из YAML ушли полностью. Три служебных ключа
(_kind, _f5, _op) содержат то, что энкодеру нужно для байт-в-байт сборки:
_op пишется только когда оператор ≠ 1; _kind — только когда field5 & 7 ≠ 0; _f5 — всегда.
Многошаговый 11109 — форма подтвердила проблему:
- id: 11109
name: Передернуть Автомат Котельной
enabled: true
_f5: 0
steps:
- id: 11827
trigger:
id: 11823
object: 11190
value: 0
action: 11191
_then:
- 11191
- 11030
- 11824
- 11029
- 11825
- 11192
- 11826
- id: 11828
wait: 0
🔴 Это и есть открытый вопрос №4. У 11109 в then семь id — цепочка, а не одно действие.
action: 11191 показывает только первое, остальные шесть ушли в служебный _then. Для 11109
_then — не служебный ключ, а реальное содержимое. Форма «один триггер → одно действие»
описывает 64 из 65 сценариев; 11109 из неё выпадает. Ждём решения Alex: action остаётся
одиночным, а цепочка — отдельная тема, или появляется actions:. Правка кода остановлена
на этом вопросе, энкодер не тронут.
(в) Методология: почему форма переделывалась дважды
blocks/extra_links— отвергнуто: порядок терялся, сценарий превращался в список цифр.when/then+if/group/op— отвергнуто как выдумка: слов нет в конфиге.trigger/steps+action— принято (эта форма).
🔴 Правило, выведенное из трёх итераций: в YAML попадают только слова, которые есть в конфиге или в UI.
object— есть (здесь так называется ссылка),descr/target/value— есть (поля строки).if/then/condition/operator/group/op/kind— нельзя: их в данных нет, это интерпретация.
🔴 Второе правило:
descrставить только там, где текст реально есть в строке. Для#Z9819(шаг) текста нет — значит иdescrу него быть не должно (Alex: «нахуй там тогда descr?! если его нет в оригинале?»).
⚠️ Не забегать вперёд с вопросами о том, чего в кейсе нет. Вопрос «что писать, когда в
triggerокажется type 47» Alex воспринял как шум («что за type 47? нихуя не понятно») — в разбираемом сценарии его нет. Сначала форма на текущем кейсе, потом обобщение.
(г) Состояние на конец сессии (обновлено 2026-09-17, после правок кода)
| Что | Статус |
|---|---|
| Форма YAML сценария | ✅ согласована (см. (б)) |
Правка config-to-yml.py под форму |
✅ сделана — 3 патча (dump_condition type 49, dump_step type 46, заголовок) |
| YAML перегенерирован | ✅ config_local_2026-09-17_17-45-00.yml — 4405 строк (было 5376), if/then ушли |
| Проверка формы глазами | ✅ блок 9691 и 11109 прочитаны |
| Round-trip | ⏸ не прогнан после правок формы (энкодер ещё не подогнан — прогон осмыслен только после пункта 6) |
Многошаговые сценарии (11109) в форме |
🔴 открытый вопрос №4 — ждёт Alex |
| Энкодер под новую форму | ⏸ не начат |
git commit |
⏸ не закоммичено, ждёт команды |
Артефакты:
zont_config/config_local_2026-09-17_17-45-00.yml— актуальный, перегенерирован под новую форму (4405 строк)/tmp/backup-174500.yml— бэкап предыдущей генерации (5376 строк, форма со старымif/then)
⚠️ Питфолл, найденный в этой сессии:
config-to-yml.pyпишет YAML в stdout, а не в файл.main()не принимает пути вывода (sys.argv= только входной.txt). Первый прогонpython3 config-to-yml.py f.txt -o /tmp/x.ymlмолча проигнорировал-o— скрипт напечатал «Использование: zont_to_yaml.py <config.txt>» иexit 1, а YAML остался старым. Из-за этого первый просмотр блока 9691 показал неисправленную форму и выглядел как «патч не сработал». Правильный вызов: редирект в файл —python3 config-to-yml.py in.txt > out.yml, и всегда проверятьexit=и размер целевого файла.
⚠️ Питфолл (продолжение):
grep -n "id: 9691"по YAML находит несколько совпадений (объект живёт и в своей секции, и внутри сценария). Номер строки в старом файле (4877) и в новом (3932) различается — индексировать по первому совпадению нельзя, надо смотреть окрестности.