Files
obsidian-vault/family/how-to/zont-config-compiler.md
T

198 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: ⚙️ ZONT Config Compiler — конвертеры .txt ⇄ .yml
aliases:
- ZONT config compiler
- config-to-yml
- yml-to-config
- HA-ZONT-Modbus
- ZONT конфиг конвертеры
tags:
- family
- how-to
- zont
- modbus
- homeautomation
created: '2026-09-17'
updated: '2026-09-17'
type: how-to
namespace: family
related:
- '[[family/tech/zont-config-object-types]]'
- '[[family/how-to/home-automation]]'
- '[[family/how-to/gitea-config]]'
---
# ⚙️ ZONT Config Compiler — конвертеры конфига (.txt ⇄ .yml)
> **Что это:** двусторонние конвертеры между форматом конфига контроллера **ZONT** (`.txt`) и читаемым **YAML**. Позволяют править конфиг руками (имена реле, адреса Modbus, датчики), не лазя в UI контроллера.
> **Справочник типов объектов:** [[family/tech/zont-config-object-types]]
> **Контекст (ZONT в общем контуре, slave ID, регистры):** [[family/how-to/home-automation]] §6
> **Repo (private):** `https://git.mallexxx.duckdns.org/git_admin/HA-ZONT-Modbus` — [[family/how-to/gitea-config]]
---
## 1. Где лежит
| | |
|---|---|
| **Локальный путь (Mac)** | `/Users/admin/Automation/HA-ZONT-Modbus` |
| **Git remote** | `https://git.mallexxx.duckdns.org/git_admin/HA-ZONT-Modbus.git` (private) |
| **Скрипты** | `config-to-yml.py` (TXT → YAML), `yml-to-config.py` (YAML → TXT) |
| **README конвертеров** | `README_converters.md` в корне проекта |
| **Рабочие конфиги** | `zont_config/` (свежие), `zont_config/archive/` (историчные `H2000_PRO_config_actual-*`) |
| **Инфраструктурный контекст проекта** | `INFRASTRUCTURE.md` в корне — **описывает старый стек на TrueNAS** (docker-контейнеры `homeassistant`/`modbus-bridge`/`mbusd` там уже погашены, автоматизация переехала на t610). Актуальный контур — [[family/how-to/home-automation]] |
> ⚠️ `INFRASTRUCTURE.md` + `docker-compose.yml` + `docker run.txt` в репозитории — **исторические** (TrueNAS-стек). Не использовать как инструкцию по текущей инфраструктуре.
> 🔴 `zont_config/*.yml` в репозитории частично удалены/пересозданы — `git status` в проекте грязный (6 удалений + новые файлы незакоммичены).
---
## 2. Как работает
### Формат конфига ZONT
Текстовый файл, по одной записи на строку, **CRLF**, кодировка **windows-1251** (fallback чтения — UTF-8):
```
#Z<id>=<type>,<поле>,<поле>,...
#S<id>=<значение>
```
- `#Z…` — объекты конфигурации (реле, датчики, сценарии, Modbus-устройства и т.д.). Порядок строк значим — сохраняется.
- `#S…` — системные настройки (`#S7=` модель, `#S202=` серийник, `#S217=` MQTT-URL и пр.).
- Тип объекта — **числом первым полем**: `#Z12=14,'Спальня левый',...` = объект id 12, тип 14 (реле).
- Специальные записи-маркеры: `#Z<id>=*`.
- Значения в `'одинарных кавычках'`; списки — `[...]`; числа — как есть.
### Идентификаторы объектов
| Префикс | Смысл | В YAML |
|---|---|---|
| `#Z<id>` | объект конфигурации | разложен по секциям (`relays`, `modbus_devices`, …) |
| `#S<id>` | системная настройка | секция `system_settings` (сохраняется как `id` + `raw_payload`) |
### Что делает `config-to-yml.py`
1. Читает файл, определяет кодировку (UTF-8 → windows-1251).
2. Парсит строки по регекспу `^#([ZS])(\d+)=(.*)$`**хвостовые пробелы в payload сохраняются**.
3. `split_payload()` — разбирает payload с учётом вложенности `[…` и кавычек (запятые внутри кавычек/скобок не разделяют).
4. `parse_atom()``''`/пусто → `None`, `'строка'` → строка, `[список]` → список, иначе int → float → строка.
5. Раскладывает объекты по секциям YAML, вложенные объекты прячет под родителя (регистры типа 52 → внутрь Modbus-устройства типа 51).
6. `system_settings` выносит **в начало** файла — чтобы было видно при правке.
### Что делает `yml-to-config.py`
1. Загружает YAML.
2. Едет обратно по секциям **в порядке типов** и собирает строки `#Z<id>=…`.
3. Форматирование: числа — без кавычек, строки — в `'…'`, bool → `0/1`, пустая строка → `''`, списки → `[…]`.
4. Восстанавливает вложенное: регистры типа 52 пишутся отдельными строками после своего устройства.
5. `validate_config()` — проверяет структуру **до вывода**; при ошибках печатает `❌ VALIDATION ERRORS`, exit code **4**, файл не отдаётся.
6. Вывод: **windows-1251** (`errors='replace'`), строки через **CRLF**, финальный перевод строки — как в оригинале.
### Коды возврата
| Скрипт | Код | Значение |
|---|---|---|
| `yml-to-config.py` | 1 | файл не найден |
| | 2 | `ConversionError` (нет `raw`, неизвестный тип) |
| | 3 | прочее исключение |
| | 4 | ❌ ошибки валидации |
| `config-to-yml.py` | 1 | неверное число аргументов |
| | 2 | `ParseError` (неизвестный формат строки, неразбираемое значение) |
---
## 3. Как пользоваться
### Зависимости
- `python3`
- `PyYAML` (`import yaml`). Проверить: `python3 -c 'import yaml; print(yaml.__version__)'`
### ⚠️ Правильный обход (важно: имена файлов и каналы)
Оба скрипта **пишут в stdout**, а `yml-to-config.py` **отдаёт windows-1251** — редирект через `>` в терминале Mac сохранит байты как надо, но копипаст из терминала кодировку убьёт.
```bash
cd /Users/admin/Automation/HA-ZONT-Modbus
# 1. Снять текущий конфиг с контроллера → положить в zont_config/
# (файлы вида config_<SN>_<SN>_<YYYY-MM-DD_HH-MM-SS>.txt)
# 2. TXT → YAML
python3 config-to-yml.py zont_config/config_XXXX.txt > /tmp/zont.yml
# 3. Правка YAML (имена, адреса, пороги)
# ⚠️ НЕ добавлять/удалять объекты с новыми id без нужды — порядок и id значимы
# 4. YAML → TXT
python3 yml-to-config.py /tmp/zont.yml > /tmp/zont_new.txt
# 5. Сверить: число строк #Z и #S до/после
grep -c '^#Z' /tmp/zont_new.txt
# 6. Только после сверки — загружать zont_new.txt в контроллер
```
### Разделение «сырое» ↔ «человеческое»
Часть полей в YAML декодирована (адрес, интервал опроса, регистры), часть остаётся как `raw` / `raw_params` / `raw_field_N` — это **страховка**. `yml-to-config.py` при пустом `raw` подставит дефолты (для типа 0 — жёстко зашитый набор, для типа 36 — `[],[],[],10,0`), и такие объекты **потеряют исходные значения**.
> 🔴 **Правило: правь декодированные поля, `raw` не трогай вообще.** Если поле не декодировано — правка возможна только с пониманием исходного формата.
### Поддерживаемые типы объектов (по README)
Типы: `1, 3, 4, 5, 6, 7, 9, 10, 11, 14, 16, 20, 24, 25, 27, 28, 42, 46, 49, 51, 52, 53, 57`
➕ фактически обрабатываются ещё **`0`** (дискретные датчики — индикаторы состояния реле) и **`36`** (конфиги дискретных датчиков, вытащенные из вложенной структуры).
Полная таблица — [[family/tech/zont-config-object-types]].
Неизвестный тип → скрипт **падает с ошибкой**, а не молча теряет объект. Это сделано намеренно, чтобы не портить конфиг.
---
## 4. Round-trip (проверка целостности)
Заявлено в `README_converters.md`: **round-trip 130/130 объектов, TXT → YAML → TXT идентичен**.
> ⚠️ **Не воспроизводил** — при подготовке этой доки прогон не выполнялся. Относиться как к заявлению README, а не как к проверенному факту.
Команда для самостоятельной проверки (безопасна, работает в `/tmp`):
```bash
cd /tmp && rm -rf zont-rt && mkdir zont-rt && cd zont-rt
SRC=/Users/admin/Automation/HA-ZONT-Modbus/zont_config/<файл>.txt
python3 /Users/admin/Automation/HA-ZONT-Modbus/config-to-yml.py "$SRC" > a.yml
python3 /Users/admin/Automation/HA-ZONT-Modbus/yml-to-config.py a.yml > b.txt
tr -d '\r' < "$SRC" > A.txt; tr -d '\r' < b.txt > B.txt
diff A.txt B.txt # пустой вывод = round-trip чистый
grep -c '^#Z' A.txt B.txt
```
> 📌 **Нюанс:** источник бывает в UTF-8, а вывод `yml-to-config.py` — всегда windows-1251. При diff кириллица в именах даст различия на уровне байтов. Сравнивать по структуре (`#Z` / `#S` + числовые поля), либо предварительно нормализовать кодировку с обеих сторон.
---
## 5. Питфоллы
| # | Питфолл | Обход |
|---|---|---|
| 1 | 🔴 **`yml-to-config.py` пишет windows-1251**, не UTF-8 | Редирект в **файл** (`> out.txt`), не копипаст. Файл загружать байтами, не через текстовый редактор с перекодировкой |
| 2 | 🔴 **CRLF-переводы строк** обязательны | Скрипт сам ставит `\r\n`. Не «нормализовать» вывод |
| 3 | 🔴 **Потеря `raw` → подстановка дефолтов** | Не трогать `raw*`-поля. Пустой `raw` у типа 0/36 → жёсткие дефолты в скрипте |
| 4 | **`#S`-настройки сохраняются как `raw_payload`** | Править их руками в YAML бессмысленно/опасно — только через UI контроллера |
| 5 | **Кодировка чтения автоопределяется** (UTF-8 → windows-1251) | Не пересохранять исходник в редакторе — можно уехать в другую кодировку |
| 6 | **Неизвестный тип объекта = exit 2, а не тихий пропуск** | Читать stderr; файл не создаётся |
| 7 | **`validate_config` отдаёт exit 4 без вывода файла** | При `❌ VALIDATION ERRORS` смотреть список; вывод пустой — это норма |
| 8 | **`INFRASTRUCTURE.md` в проекте описывает мёртвый TrueNAS-стек** | Актуальное — [[family/how-to/home-automation]]. Не искать docker-контейнеры `modbus-bridge`/`mbusd` на TrueNAS |
| 9 | **Изменённый конфиг загружать в ZONT руками (UI/облако), не скриптом** | Скрипты только конвертируют. Проверку результата делает Alex |
| 10 | **`jsonschema`/`ruamel` НЕ нужны** | Только `pyyaml` |
---
## 6. Связанные заметки
- [[family/tech/zont-config-object-types]] — таблица типов объектов (1…57, 0, 36)
- [[family/how-to/home-automation]] — общий контур автоматизации, ZONT, Modbus slave ID и регистры (§6)
- [[family/how-to/gitea-config]] — Gitea, креды, создание репо
- [[family/how-to/ha-automations]] — автоматизации HA