diff --git a/personal/projects/zont-config-compiler.md b/personal/projects/zont-config-compiler.md index 4e08cc0f..6f91723e 100644 --- a/personal/projects/zont-config-compiler.md +++ b/personal/projects/zont-config-compiler.md @@ -116,6 +116,15 @@ aliases: - ZONT end переименован - ZONT scenario_orphans пустая секция - ZONT push 5d31d6e + - ZONT круг 50 + - ZONT граница диапазона id + - ZONT железо 20551 20554 20555 + - ZONT сопроцессор радиомодуль id + - ZONT окно id 4098 12109 + - ZONT жестоко ограничить диапазон + - ZONT максимум id 12109 + - ZONT переполнение id hard fail + - ZONT аллокатор дыры снизу вверх related: - '[[family/tech/zont-api]]' - '[[family/how-to/home-automation]]' @@ -3594,6 +3603,10 @@ echo "exit=$?"; ls -la zont_config/config_X.yml ## 25. 🎯 План: авто-id для всех сущностей (СОГЛАСОВАНО, не реализовано) +> 🔴 **АКТУАЛЬНО НА 2026-09-18:** граница диапазона уточнена Alex'ом — «жестоко ограничить», +> контракт аллокатора и замер по дампу — в **§30**. Читать §30 вместе с этим планом; шаг 1 ниже +> заменён (энкодер ссылки НЕ разрешает — см. §30.4). + **Запрос Alex:** «я предполагал что id генерятся автоматом для всех сущностей если не прописаны явно». ### 25.1. Состояние кода (проверено, не по памяти) @@ -3635,6 +3648,40 @@ next_id = max(все существующие id) + 1 ← НЕ «перв **Итого ~2 часа**, из них час — шаг 3. +### 25.4. ✅ РЕШЕНИЯ ALEX (2026-09-18) — окно id, до написания кода + +Alex: **«надо жестоко ограничить диапазон»** → **«Фикс»** → **«Дыры»**. + +| Вопрос | Решение Alex | +|---|---| +| Верхняя граница | **Фиксированное окно**, не `max+1` и не «текущий максимум дампа» | +| Порядок занятия | **Дыры снизу вверх** (первый свободный id первым), НЕ `max+1` | +| Железный диапазон (`20xxx`) | **Недостижим по построению** | + +**Окно: `ID_MIN = 4098` … `ID_MAX = 19999`** (модульные константы в `yml-to-config.py`). + +Данные, на которых выбрано (дамп `23-21-20`, 756 записей): + +| Метрика | Значение | +|---|---| +| min id «человеческих» | `4098` | +| Занято внутри окна | 756 | +| Дыр (непрерывных отрезков) | 67 | +| **Свободно внутри окна** | **7435** | +| Первая дыра | `4101..8191` (4091 подряд) | +| Max занятый в окне | `12288` | + +**Причина фикс-окна:** «человеческие» id упираются в `12109` (тип 52/51/5 — регистры, modbus-контроллер), +а всего в 8 тысячах выше лежит **железо прибора**: `20551`/`20554` (`type 24`, «Сопроцессор 1/2»), +`20555` (`type 7`, «Радиомодуль 433МГц»). `max+1` от всего конфига дал бы `20556` — **прыжок через +железо**. Отдельно: единственный id выше `12109` внутри окна — `12288`, тоже не человеческий. + +**Следствие для шага 3 плана:** правило «дыры vs max+1» **схлопнулось** — первая дыра это 4091 id +подряд, выбирать не нужно. Шаг 3 плана упрощается, риск переполнения = 0. + +**Hard fail обязателен:** `_next > ID_MAX` → конвертер падает с текстом `id window exhausted`, +конфиг **не собирается**. Молчаливый прыжок в `20xxx` запрещён. + **Риски:** (а) ссылки в новые объекты — реальная проблема, требует решения шага 3; (б) порядок эмиссии: `S`-блоки первыми, `Z` — после, id нужен раньше строки; (в) **верхняя граница** — `max+1 = 20556` перескочит железо, вопрос к Alex открыт. @@ -4035,3 +4082,76 @@ Alex: *«и `scenario_orphans: []` снеси. и пуш»*. Кельвин `(code-2730)/10` применяется **только** к `set_contour_target` (цель типа 16) и **только** если значение не является id объекта типа 20 — иначе `8574` (id режима) превращался в `584.4 °C`. +--- + +## 30. 🎯 Авто-id: границу диапазона задал Alex — «жестоко ограничить» (2026-09-18) + +**Контекст.** Старт сессии 2026-09-18: HEAD `5d31d6e`, round-trip **9/9 зелёный** (`759 → 759`, +`784 → 784`, расхождений 0), артефакт `zont_config/config_local_2026-09-17_23-21-20.yml` +перегенерён после последней правки. Открыт **ровно один** пункт — **авто-id** (§25, план был согласован, +код не написан). + +### 30.1. 🔴 Решение Alex по верхней границе + +Вопрос был: «генерировать выше `20555` или ограничить снизу диапазоном пользовательских id?» +Alex: **«Я думаю надо жестоко ограничить диапазон»** — то есть **hard-coded окно**, никакого +`max+1` поверх железа. + +### 30.2. Данные для границы (замер по дампу `23-21-20`, 756 записей `#Z`) + +| Диапазон | Кол-во | Что это | +|---|---|---| +| `4000-4999` | 2 | низ, разрозненные | +| `8000-8999` | 56 | приборы/адаптеры | +| `9000-9999` | **579** | основная масса | +| `10000-10999` | 84 | | +| `11000-11999` | 26 | | +| `12000-12999` | 6 | хвост (`12065/12066/12067`, `12107/12108/12109`) | +| `20000-20999` | **3** | 🔴 **ЖЕЛЕЗО прибора** | + +**min = `4098`**, **max = `12109`** (без железа). Итого «человеческое» окно — **`4098..12109`**. + +🔴 **Все три id > `20000` — железо, выдано прибором, не человеком:** + +| id | тип | что | +|---|---|---| +| `20551` | 24 | `'0000','Сопроцессор 1',[],'BL2 654 v98',…` | +| `20554` | 24 | `'0001','Сопроцессор 2',[],'BL2 654 v98',…` | +| `20555` | 7 | `'0001','Радиомодуль 433МГц',2,[],1200000,'v1'` | + +⚠️ Дыра `12999..20000` в дампе **пустая**, но заполнять её снизу вверх (как делал бы `max+1`) — +именно то, что Alex назвал «жестоко ограничить». Железа не касаемся вообще. + +### 30.3. Контракт аллокатора (предложен, ждёт одной цифры от Alex) + +| # | Правило | Почему так | +|---|---|---| +| 1 | **Окно генерации — только человеческий диапазон**, ни байтом выше `12109` | железо `20xxx` — территория прибора | +| 2 | **Сначала дыры** внутри окна (снизу вверх), только потом `max+1` | иначе 75 новых объектов от встанут `12110..12184` и упрутся в железо | +| 3 | **Переполнение → hard fail**, конфиг НЕ собирается, текст внятный | молча прыгнуть в `20xxx` нельзя — это порча чужой территории | +| 4 | **id, явно прописанные в YAML, неприкосновенны** — аллокатор их только читает | источник истины остаётся YAML; автогенерация = только для записей без `id` | + +⏳ **Открытый вопрос (единственный):** верх брать **`12109`** (текущий максимум дампа) или +**фиксированное круглое `19999`** с тем же правилом «сначала дыры»? Фиксированное окно не поедет +при заливке чужих конфигов, но разрешит id, далеко отстоящие от текущих. + +### 30.4. Уточнение плана §25 по шагу 1 (разведка — 5 мин) + +План §25 шаг 1 формулировался как «как `emit_step`/`emit_action`/`emit_condition` + +`scenario_orphans` **разрешают ссылки**». Уточнено по факту: **энкодер ссылки НЕ разрешает** — +все id в YAML прописаны явно, `scenario_orphans` снесён в круге 49 как пустой. +Шаг 1 заменён на: **карта 17 точек `obj['id']`** + как якорятся ссылки шагов. + +Точки `obj['id']` в `yml-to-config.py` (проверено ранее `grep`): строки +`105, 108, 149, 154, 161, 189, 198, 203, 210, 222, 225, 1213, 1219, 1230, 1235, 1242, 1268`. + +### 30.5. Статус + +| Что | Состояние | +|---|---| +| Граница диапазона | 🔴 **концепция принята** Alex («жестоко ограничить»), цифра верха — не названа | +| Аллокатор в коде | ❌ не написан | +| Round-trip база | ✅ 9/9 зелёный до изменений | +| Артефакт | ✅ `zont_config/config_local_2026-09-17_23-21-20.yml` свежий (содержит `call_sub: 11109`, `send_sms: 8195`, `exit: true`) | +| HEAD / origin | ✅ `5d31d6e`, запушено | +