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

15 KiB
Raw Blame History

aliases, created, namespace, related, tags, title, type, updated
aliases created namespace related tags title type updated
ZONT config compiler
config-to-yml
yml-to-config
HA-ZONT-Modbus
ZONT конвертеры конфига
2026-09-17 family
family/tech/zont-config-object-types
family/how-to/home-automation
family/how-to/gitea-config
family
how-to
zont
modbus
homeautomation
⚙️ ZONT Config Compiler — конвертеры .txt ⇄ .yml how-to 2026-09-17c

⚙️ ZONT Config Compiler — конвертеры .txt ⇄ .yml

Двусторонние конвертеры между конфигом контроллера ZONT (.txt) и читаемым YAML. Позволяют править конфиг руками — имена реле, адреса Modbus, интервалы опроса, датчики — не заходя в UI контроллера.

Проект (Mac) /Users/admin/Automation/HA-ZONT-Modbus
Repo (private) https://git.mallexxx.duckdns.org/git_admin/HA-ZONT-Modbus
Скрипты config-to-yml.py (TXT → YAML) · yml-to-config.py (YAML → TXT)
Конфиги zont_config/ — свежие · zont_config/archive/ — историчные
Типы объектов family/tech/zont-config-object-types
ZONT в общем контуре family/how-to/home-automation §6

1. Формат конфига ZONT

Текстовый файл, одна запись = одна строка, разделитель строк CRLF, кодировка windows-1251:

#Z<id>=<тип>,<поле>,<поле>,…
#S<id>=<значение>
Префикс Что это Пример
#Z<id> объект конфига: реле, датчик, сценарий, Modbus-устройство #Z12=14,'Спальня левый',… — id 12, тип 14 (реле)
#S<id> системная настройка #S7=H2000_PRO 723 678 — модель и версии ПО
  • Тип объекта — первое поле после =.
  • Строки — в 'одинарных кавычках', списки — [...], числа — как есть.
  • #Z<id>=* — служебный маркер (пустой/унаследованный объект).
  • Порядок строк значим и сохраняется при конвертации.

2. Как работает

config-to-yml.py — TXT → YAML

  1. Читает файл, определяет кодировку: UTF-8, при неудаче — windows-1251.
  2. Парсит строки регекспом ^#([ZS])(\d+)=(.*)$ (хвостовые пробелы в payload сохраняются).
  3. split_payload() — режет payload по запятым с учётом кавычек и вложенных […].
  4. parse_atom() — пусто/''None, 'строка' → строка, […] → список, иначе int → float → строка.
  5. Раскладывает объекты по секциям YAML. Вложенное прячет под родителя: Modbus-регистры (тип 52) → внутрь своего устройства (тип 51).
  6. system_settings (#S…) выводит в начало файла, чтобы было видно при правке.

yml-to-config.py — YAML → TXT

  1. Загружает YAML (UTF-8) и собирает строки #Z<id>=… обратно, в порядке типов.
  2. Форматирование: числа без кавычек, строки в '…', bool → 0/1, пустая строка → '', списки → […].
  3. Разворачивает вложенное: регистры типа 52 снова становятся отдельными строками после своего устройства.
  4. validate_config() проверяет структуру до вывода. При ошибках — ❌ VALIDATION ERRORS, exit 4, файл не отдаётся.
  5. Вывод: windows-1251, переводы строк CRLF, финальный перевод строки как в оригинале.

Коды возврата

Скрипт Код Значение
config-to-yml.py 1 неверное число аргументов
2 ParseError — неизвестный формат строки или неразбираемое значение
yml-to-config.py 1 файл не найден
2 ConversionError — нет raw или неизвестный тип объекта
3 прочее исключение
4 ошибки валидации (файл не выдан)

Неизвестный тип объекта — падение с ошибкой, а не тихий пропуск. Сделано намеренно: молча потерять объект хуже, чем не отдать файл.

Проверено против исходников (2026-09-17)

Факт Где в коде
config-to-yml.py exit-коды {1, 2} sys.exit(1) — argc; sys.exit(2)ParseError
yml-to-config.py exit-коды {1, 2, 3, 4} argc / FileNotFoundError / ConversionError / общее / validation
validate_config() вызывается до вывода стр. 913 validation_errors = validate_config(data, lines)
Вход YAML — UTF-8, выход — windows-1251 стр. 907 open(…, encoding='utf-8'); стр. 921 stdout.reconfigure(encoding='windows-1251', errors='replace')
Дефолт типа 0 (16 полей) add_z_line(obj['id'], 0, register_ref, name, 0, 0, 1000, 2000, 7424, [], 20, [], [], 1, config_id, 0, 0)
Дефолт типа 36 add_z_line(config_id, 36, [], [], [], 10, 0)
README перечисляет 23 типа; код обрабатывает 25 README пропускает 0 и 36

📌 validate_config() дополнительно проверяет кодируемость каждой строки в windows-1251 (символ вне CP1251 → ошибка валидации).


3. Как пользоваться

Требования: python3 + PyYAML. Проверка: python3 -c 'import yaml; print(yaml.__version__)'

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 объектов и их порядок значимы — не переставлять без нужды

# 4. YAML → TXT
python3 yml-to-config.py /tmp/zont.yml > /tmp/zont_new.txt

# 5. Сверить число объектов до/после
grep -c '^#Z' /tmp/zont_new.txt

# 6. Загрузить /tmp/zont_new.txt в контроллер (UI / облако ZONT)

🔴 Главное правило: raw не трогать

В YAML часть полей декодирована (адрес, интервал опроса, регистры), часть лежит как raw / raw_params / raw_field_N — это страховка от потери данных.

Если у объекта пустой raw, скрипт подставит жёстко зашитые дефолты (тип 0 — набор из 16 полей, тип 36 — [],[],[],10,0), и исходные настройки будут потеряны молча.

Правь декодированные поля. raw-поля не удаляй и не «чисти». Если поле не декодировано — правка возможна только с пониманием исходного формата.

Поддерживаемые типы

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 даёт идентичный файл.

Команда для проверки на любом конфиге:

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 покажет различия на кириллице. Сравнивать структуру и числовые поля, либо нормализовать кодировку с обеих сторон.


5. Питфоллы

# Питфолл Как обойти
1 🔴 Вывод yml-to-config.pywindows-1251 + CRLF, не UTF-8 Редирект в файл и передавать байтами. Не копипастить из терминала, не пересохранять в редакторе
2 🔴 Пустой raw у типов 0/36 → молчаливая подстановка дефолтов Не трогать raw*-поля
3 🔴 Правка #S… в YAML бессмысленна — они хранятся как raw_payload Системные настройки менять только через UI контроллера
4 YAML на входе yml-to-config.py — строго UTF-8; выход — windows-1251. Плюс автоопределение кодировки при чтении .txt (UTF-8 → windows-1251) Править YAML в UTF-8. Исходный .txt не пересохранять в редакторе
5 Неизвестный тип объекта → exit 2, файл не создаётся Смотреть stderr — там причина
6 validate_config() → exit 4 Печатает ❌ VALIDATION ERRORS + список причин; файл намеренно не выдан (вывод пустой)
7 Регистр без своего устройства / аналоговый выход с битой ссылкой WARNING в stderr, конвертация продолжается — проверить ссылки вручную
8 Загрузка конфига в контроллер — руками, скрипты только конвертируют Конвертер не имеет доступа к ZONT
9 INFRASTRUCTURE.md, docker-compose.yml, docker run.txt в проекте — исторический TrueNAS-стек Актуальный контур — family/how-to/home-automation. Не искать modbus-bridge/mbusd на NAS
10 Дополнительных зависимостей нет Только pyyamljsonschema/ruamel не нужны

6. Состояние проекта (проверено 2026-09-17)

Репозиторий /Users/admin/Automation/HA-ZONT-Modbusрабочее дерево грязное, разгребание ждёт отдельной команды Alex:

Файл Статус
zont_config/H2000_PRO_config_actual-2.txt / -2.yml удалены из индекса (целы в zont_config/archive/)
zont_config/H2000_PRO_config_actual-3.txt / -3.yml то же
zont_config/H2000_PRO_config_actual-4.txt / -4.yml то же
zont_config/archive/ не добавлена в git
zont_config/config_0FA7C33CC89F_…_2026-09-17_12-12-28.txt 32 689 байт — свежеснятый конфиг с контроллера, не закоммичен
одноимённый .yml 0 байт — конвертация запускалась и не завершилась

🔴 Пустой .yml (0 байт) рядом с непустым .txt — признак незавершённой конвертации. Пересобрать шагом 2 из §3 перед использованием.

Содержимое проекта, не относящееся к конвертерам:

  • INFRASTRUCTURE.md (342 стр.), docker-compose.yml, docker run.txtисторический TrueNAS-стек (docker-контейнеры homeassistant, mbusd, modbus-bridge, mosquitto, zigbee2mqtt, nodered, caddy, immich, transmission, webdav, inpxer, cups-splix, portainer, watchtower, rclone). Стек декомиссирован, автоматизация живёт на t610 — актуальное: family/how-to/home-automation.
  • modbus_ha_bridge.py, modbus_mqtt_bridge.py — исходники мостов (исторические, для TrueNAS).
  • nodered-flows-backup.json, nodered-flows-updated.json — дампы потоков Node-RED (Node-RED остановлен).
  • homeassistant/, floorplan/ — снапшоты конфига HA и планировки (исторические, там же workflow «fetch from NAS → edit → deploy»).
  • README_converters.md — исходное описание конвертеров (типы: 23, без 0 и 36).
  • .gitignore — исключает *.cur, логи, __pycache__, .venv, .DS_Store, project_home.pdf (крупный бинарь).

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