--- aliases: - ZONT API - zont-online API - ZONT cloud API - ZONT update_device created: '2026-09-17' namespace: family related: - '[[family/how-to/zont-config-compiler]]' - '[[family/tech/zont-scenario-logic-11109]]' - '[[family/tech/zont-config-object-types]]' - '[[family/how-to/home-automation]]' tags: - family - tech - zont - api - reference title: "\U0001F310 ZONT Cloud API — что умеет и чего в нём нет" type: reference updated: '2026-09-17' --- # 🌐 ZONT Cloud API — что умеет и чего в нём нет > **Исследовано 2026-09-17** по запросу Alex: «У зонта есть api и вероятно свой какой-то формат > включая все датчики и автоматику. Изучай подробно вопрос… что нам для комфортного управления > контроллером на самом деле надо. Доделывать конвертер или переделать все с 0.» > > **Итог одной строкой:** облачный API ZONT **не работает с конфигом** (сценарии, реле, шаги, > условия). Конвертер `.txt ⇄ .yml` — по-прежнему **единственный** путь к правке сценариев. > API годится только для **мониторинга** и узкого набора настроек (отопление). > > ⚠️ **Уточнено 2026-09-17 (см. §6bis):** это верно для *облачного* API. **Локальный** > интерфейс контроллера конфиг отдаёт — причём `GET /config.txt` **вообще без авторизации**, > в формате нашего парсера. Прошивка локально не обновляется. --- ## 1. Локальная копия доки (в проекте) Доки скачаны в проект, не в `/tmp` (указание Alex: «качай доки в папку в проекте а не в темп»): | Файл | Размер | Что это | |---|---|---| | `/Users/admin/Automation/HA-ZONT-Modbus/zont_api_docs/zont_api_docs.html` | 250 KB | полная дока как есть (одна страница) | | `…/zont_api_docs.txt` | 99 KB / 3381 строка | читаемый текст, таблицы → ` \| ` | | `…/convert.py` | — | воспроизводимая HTML→text конвертация | ```bash cd /Users/admin/Automation/HA-ZONT-Modbus/zont_api_docs curl -s -L 'https://zont-online.ru/api/docs/' -o zont_api_docs.html # обновить python3 convert.py # → zont_api_docs.txt ``` > 📌 **Вся дока — ОДНА страница.** Отдельных URL вида `/api/docs/update_device` **нет** (404). > Ссылки `#update_device` — это внутренние якоря. Не пытаться качать методы по отдельности. --- ## 2. Полный список методов API (всего 11) | Метод | Назначение | Пишет конфиг? | |---|---|---| | `get_authtoken` | получить токен (Basic auth → `X-ZONT-Token`) | — | | `devices` | список устройств + **Настройки**; `load_io: true` → ещё и **Состояния** | — | | `update_device` | **изменение Настроек** устройства | ⚠️ узкий набор, см. §4 | | `set_io_port` | управление Состоянием: `guard-state`, `siren`, `engine-block`, `webasto` | — | | `send_custom_command` | послать пользовательскую команду по `command_id` | — | | `load_data` | **история** данных за период (типы: `temperature`, `events`, `z3k_*`…) | — | | `raw_events` | история событий (обёртка над `load_data`) | — | | `temperature` / `thermostat_work` / `custom_controls` / `ztc_state` | история / состояние | — | | `generate_archive` / `download_generated_archive` | выгрузка архива | — | | `add_device` / `delete_device` | добавить / удалить устройство | — | ### Формат запроса ``` POST https://my.zont.online/api/ Header: X-ZONT-Client: (обязательный) Auth: Basic ИЛИ X-ZONT-Token: Body: JSON (предпочтительно) / form-encoded / GET-параметры Ответ: JSON, всегда поле "ok": true|false; при ошибке "error" + "error_ui" ``` Рекомендованный поток аутентификации: `get_authtoken` (с логином/паролем) → дальше по токену, пароль не хранить. При `403` токен мог быть отозван — перезапросить. --- ## 3. 🔴 Главный вывод: конфига в API НЕТ **Проверено фактом по локальной копии доки:** | Что искали | Найдено в доке | |---|---| | слово `scenario` | **0 раз** | | слово `relay` | **1 раз** | | `z3k_config` (конфиг контроллера) | **2 раза** — только как ссылка для ID | | метод для чтения/записи `z3k_config` | **нет** | Наши объекты конфига — сценарии (**11**), реле (**14**), шаги (**46**), условия (**49**), задержки (**45**) — в API **не представлены вообще**. Ни чтения, ни записи. `z3k_config` упоминается лишь как источник числовых ID: в `z3k_temperature` «ключом является ID объекта из `z3k_config`», в `z3k_boiler_adapter` — «ID адаптера из `z3k_config` (например 4097, 4098)». То есть API **ссылается** на конфиг, но **работать с ним не даёт**. > ⚠️ Это не «ещё не нашли метод» — это перебор **всех** 11 методов из оглавления доки. > `send_custom_command` — не то: он шлёт заранее заданную в настроечной утилите команду по `command_id`. --- ## 4. Что `update_device` реально умеет Единственный метод, который меняет Настройки. Доступные области (по разделам доки): | Раздел | Ключи настроек | |---|---| | Общие | `name`, `serial`, `timezone` | | Беспроводная сеть | `balance` (`ussd`/`warning`/`limit`), `trusted_phones`, `gsm_roaming` | | Управление отоплением (ZONT H) | `thermostat_mode`, `thermostat_mode_temps`, `thermostat_ext_mode`, `thermostat_ext_modes_config`, `tempschedule`, `thermometers`, `ot_*` (OpenTherm) | | Пользовательские команды (ZTC-7xx, Mega SX) | `custom_controls` — **не наш случай** (H-2000 PRO) | | Авто (ZTC) | `auto-ignition`, двери/капот/багажник | > 🔴 **Для H-2000 PRO через API доступно практически только отопление** — режимы, целевые > температуры, расписание, параметры OpenTherm. Сценариев/реле там нет. **Семантика:** для составного параметра можно передать **часть** внутренних полей — остальные сохранят прежние значения. Ответ содержит **только изменённые** параметры и их новые значения. ```json // запрос {"device_id": 1580, "thermostat_mode_temps": {"comfort": 21}} // ответ — изменилось только comfort, остальные вернулись как есть {"ok": true, "thermostat_mode_temps": {"comfort": 21, "econom": 16, "idle": 5, "full_off": false}} ``` --- ## 5. `load_data` — история (только чтение) ```json POST https://my.zont.online/api/load_data {"requests": [ {"device_id": 1580, "data_types": ["temperature", "events"], "mintime": 1495011600, "maxtime": 1495022400} ]} ``` Ответ: `responses[]` в том же порядке, что `requests`, каждый с полями по имени типа данных. Времена — **unix time** (секунды, UTC). Вложенные параметры → **только** `Content-Type: application/json`. **Формат значений — Delta-time Array (DTA):** массив пар `[delta_секунд, значение]`, где первая метка абсолютная, последующие — **отрицательные смещения** назад во времени. **Типы данных (`data_types`), релевантные нашему контуру:** | Тип | Для чего | Модели | |---|---|---| | `temperature` | показания температурных датчиков | — | | `events` | события | — | | `z3k_temperature` | история датчиков, **ключ = ID объекта из `z3k_config`** | H-2000+, H-2000 PRO, Climatic, H1V.02, SMART NEW | | `z3k_radio_sensor` | радиодатчики | по аналогии | | `z3k_heating_circuit` | контуры отопления | по аналогии | | `z3k_web_element` | пользовательские кнопки | по аналогии | | `z3k_boiler_adapter` | котёл по OpenTherm / EMS / BSB — **шаг до 1 мин** | H-2000+ / PRO / PRO.V2 | | `custom_controls` | пользовательские статусы (битовая маска) | Mega SX, H-1000, ZTC | | `ztc_state` | питание, GSM, Wi-Fi | — | > `z3k_boiler_adapter` даёт те же ряды, что графики в личном кабинете: `s` (флаги состояния > `ch`/`dhw`/`fl`/`cl`/`ch2`/`di`/`f`), `cs`/`cs2` (расчётная t теплоносителя), `bt` (фактическая), > `rwt` (обратка), `dt` (ГВС), `ot` (улица), `rml` (модуляция горелки), `wp` (давление), > `ff` (авария `{c, f}`), `rp`/`rt`/`rors`/`db`/`b` (уставки) и др. **`custom_controls` — битовая маска:** значение — целое, каждый бит = состояние статуса с этим id. ``` [[1498710120, 0], [-86, 6], [-5, 2]] → все статусы выкл → через 86 с включились статусы 1 и 2 (6 = 110₂) → ещё через 5 с статус 2 выключился ``` --- ## 6. Ответ на вопрос «доделывать или переделать с 0» **Переделать с 0 — не на что.** API не предоставляет доступа к сценариям/реле, поэтому «переписать управление на API» технически невозможно. Переписать можно было бы только **мониторинг**, и это дополнение, а не замена. | Путь | Что даёт | Ограничение | |---|---|---| | **1. Конвертер `.txt ⇄ .yml`** (текущий) | правка сценариев, реле, датчиков, Modbus | загрузка в контроллер **руками** | | **2. API-обвязка (дополнение)** | онлайн-состояния (`devices?load_io=true`), история (`load_data`), отопление (`update_device`), сирена/охрана (`set_io_port`) | сценарии **недоступны** | | **3. Локальный интерфейс (§6bis)** | 🔴 `GET /config.txt` — **весь конфиг без авторизации**, в формате парсера | только чтение; запись — WS `#S=` + `#S15=1` | | **4. «Переделать с 0»** | ❌ не существует API, на который переписать | | ### Рекомендация (доложена Alex, решения пока нет) - **Конвертер не выкидывать** — он единственный путь к сценариям. Доделывать §5c (`blocks/if/then`, см. [[family/how-to/zont-config-compiler]]) имеет смысл. - **API-обвязка — отдельная задача на потом:** мониторинг реле/датчиков, графики из `load_data`, правка режимов отопления. **Дополняет** конвертер, не заменяет. - **Открытый вопрос Alex'у:** нужен ли онлайн-мониторинг ZONT в HA. От ответа зависит, браться ли за API-часть вообще. --- ## 6bis. 🟢 ЛОКАЛЬНЫЙ интерфейс контроллера — вот где реально есть конфиг > **Исследовано 2026-09-17** (вторая половина того же дня, после починки транзита > Rasputin → `192.168.0.0/24`, см. [[family/how-to/rasputin-router]]). > > **Итог одной строкой:** облачный API конфига не даёт (§3), но **локальный HTTP/WS интерфейс > самого контроллера отдаёт ВЕСЬ конфиг**, причём `config.txt` — **вообще без авторизации**. Это меняет вывод §6: путь «снять конфиг с прибора» больше не требует настроечной утилиты и ручного экспорта — достаточно `curl`. ### Адрес и доступ | Параметр | Значение | |---|---| | Хост | `192.168.0.50` (GPON-сегмент, за `192.168.0.1`) | | Модель | `H2000_PRO`, прошивка `723 678` (`#S7`) | | Версия веб-интерфейса | `25.11.1` (видна в `.version` при заходе в «Сервис») | | Логин | `admin` | | Пароль | `1316261` (сервисный) | | WebSocket | `ws://192.168.0.50/ws` | > 🔴 **Пароль локального UI — НЕ пароль от аккаунта `my.zont.online`.** Официальная дока > (support.microline.ru → «Локальное управление приборами ZONT»): > логин = «Имя пользователя» из `Настройки → Пользователи`; пароль = «**Пароль для управления > с другого телефонного номера**». Для универсальных контроллеров в заводской конфигурации > пользователя **нет вообще** — тогда авторизация не требуется. ### 🔴 `GET /config.txt` — весь конфиг без авторизации ```bash curl -s http://192.168.0.50/config.txt -o zont-config-live.txt # 623 строки ``` Отдаёт **ровно тот формат `#S`/`#Z`**, который парсит `config-to-yml.py` (см. [[family/how-to/zont-config-compiler]]). Ни логина, ни токена не нужно. Остальные испытанные HTTP-пути → **404**: `/api`, `/config`, `/config.json`, `/backup`, `/download`, `/firmware`, `/update`, `/upgrade`, `/fw.bin`, `/ota`, `/flash`, `/log`, `/status`, `/users`, `/export`, `/import`, `/sdcard`, `/cgi-bin/*`, `/z3k_config`. ### Протокол WebSocket Вход (виден в JS страницы, воспроизведён вручную): ```json → {"user":"admin","pass":"1316261"} ← {"auth":200} // 401 при неверной паре ``` Дальше три вида команд: | Команда | Что делает | Пример ответа | |---|---|---| | `{"req_ids":N}` | список id объектов класса N | `{"ids":[8560,8669,9877,…]}` | | `{"scmd":"#S?"}` | **чтение** любой системной настройки | `{"scmdres":"#S217:mqtt://…"}` | | `{"scmd":"#S="}` | **запись** настройки | `{"cmdres":0}` (0 = ок) | | `{"scmd":"#S15=1"}` | 🔴 **СОХРАНИТЬ** изменения | — | | `{"id":N,"cmd":M}` | команда объекту (реле, режим) | — | | `{"id":N,"req_state":0}` | запросить состояние объекта | — | Классы для `req_ids` (из JS): `16` отопит. контуры, `20` режимы отопления, `1` виртуальные датчики, `27` датчики температуры, `0` дискретные датчики, `8` радиодатчики, `10` GUI-элементы, `6` адаптеры. > 🔴 **Неявная кнопка «сохранить» — `#S15=1`.** UI шлёт её после смены Wi-Fi-настроек > (`#S208='ssid','pass'` + `#S15=1` + через 3 с `#S208?` для проверки). Без неё запись > не применяется. В веб-морде этой кнопки нет. ### 25 настроек `#S` в живом конфиге — UI показывает только 9 Веб-интерфейс показывает `#S7`, `#S200`, `#S202`, `#S204`, `#S208`, `#S54`, `#S198`, `#S205`, `SDATE`. В конфиге их **25**. Неявные: | Ключ | Значение (живое, 2026-09-17) | Что это | |---|---|---| | `#S217` | `mqtt://zont:mqtt1z3$@192.168.0.10:1883` | MQTT-брокер **с паролем в открытом виде** | | `#S218` | `'zont','qwertyui'` | MQTT логин/пароль | | `#S219` | `'zont'` | MQTT клиент-id | | `#S221` | `homeassistant` | префикс discovery | | `#S124` | `1,9600,0,0` | параметры Modbus-шины (slave, baud, …) | | `#S201` | `52200` | порт облачного сервера | | `#S203` | `auto` | режим выбора канала связи | | `#S12` | `*100# 0` | USSD-запрос баланса | | `#S210` | `2147483647,2147483647,2147483647,2147483647` | лимиты | | `#S207` | `+780****7291 0` | доверенный номер | | `#S36`, `#S206`, `#S209`, `#S211`, `#S212`, `#S214`, `#S222`, `#S223`, `#S225`, `#S226` | — | нигде не задокументированы | ### Прошивка — локально её НЕТ - Все HTTP-пути к прошивке → **404** (список выше). - Кнопка «Обновить интерфейс» в разделе «Сервис» — это **перезагрузка веб-страницы**, не прошивка. - Прошивка обновляется **только через облако ZONT** либо **настроечной утилитой с ПК**. Локальный веб-UI загрузку `.bin` не умеет. - Версии: модель/прошивка читаются из `#S7` (`H2000_PRO 723 678`), серийник — из `#S54` (`0FA7C33CC89F`). ### 🔴 Утечка секретов В `config.txt` **без авторизации** лежат: пароль облака ZONT (`#S202` — серийник + `ktqs42047wd58t0i`), пароль MQTT (`#S217`/`#S218`), и **сервисный пароль локального UI** (`#Z8192=4,'admin','+792****5401,…','1316261',0`). Любой, кто дотянется до `192.168.0.50`, получает их без входа. > Практический смысл: доступ к GPON-сегменту = доступ ко всем учёткам контроллера. > Транзит из `192.168.6.0/24` был сломан ([[family/how-to/rasputin-router]]) — это, > по иронии, единственное, что закрывало эти данные от домашней LAN. ### Инструменты разведки (на Mac, проект не трогают) | Файл | Назначение | |---|---| | `~/rasputin-tmp/zont-auth-probe.js` | проверка пары логин/пароль (`node zont-auth-probe.js `) | | `~/rasputin-tmp/zont-recon.js` | перебор HTTP-путей | | `~/rasputin-tmp/zont-recon2.js` | перебор путей прошивки/конфига (печатает только не-404) | | `~/rasputin-tmp/zont-ws-probe.js` | WS: auth + `req_ids` + чтение `#S` | | `~/rasputin-tmp/zont-config-live.txt` | живой дамп `config.txt` (623 строки) | ```bash cd ~/rasputin-tmp node zont-auth-probe.js 192.168.0.50 admin 1316261 # → AUTH OK (200) node zont-ws-probe.js ws://192.168.0.50/ws admin 1316261 ``` --- ## 7. Питфоллы | # | Питфолл | Как обойти | |---|---|---| | 1 | 🔴 Вся дока — **одна страница**; `/api/docs/` → **404** | Качать только `https://zont-online.ru/api/docs/` целиком | | 2 | 🔴 `send_custom_command` **всегда возвращает `ok: true`**, даже если связи нет или отправка не удалась | Не считать `ok` подтверждением доставки | | 3 | `load_data` принимает вложенные параметры → **только JSON**, не form-encoded | `Content-Type: application/json` обязателен | | 4 | `mintime`/`maxtime` — **unix time в секундах, UTC** | Не путать с миллисекундами | | 5 | `custom_controls` — **битовая маска**, не массив состояний | Разбирать побитово; биты считаются с нуля от младшего | | 6 | DTA — вторая и последующие метки **отрицательные** (смещения назад) | Не читать их как абсолютное время | | 7 | `update_device` при `403` — токен мог быть отозван | Перезапросить `get_authtoken` | | 8 | Дока **обновляется**, часть функций может отсутствовать | При нехватке метода — писать на `admin@zont.online` | | 9 | 🔴 Пароль локального UI — **не** пароль от `my.zont.online` | Это «Пароль для управления с другого телефонного номера» из `Настройки → Пользователи` (§6bis) | | 10 | 🔴 Запись через WS **не применяется** без `{"scmd":"#S15=1"}` | Всегда досылать команду сохранения после записи `#S=…` | | 11 | 🔴 `GET /config.txt` отдаёт секреты **без авторизации** | Не считать GPON-сегмент доверенной сетью; см. §6bis | --- ## 8. Связанные заметки - [[family/how-to/zont-config-compiler]] — конвертеры `.txt ⇄ .yml`; §5c — план переработки YAML - [[family/tech/zont-scenario-logic-11109]] — структура сценариев 11/46/49/45 - [[family/tech/zont-config-object-types]] — таблица типов объектов конфига - [[family/how-to/home-automation]] — контур автоматизации, ZONT, Modbus (§6) - [[family/how-to/rasputin-router]] — транзит в GPON-сегмент `192.168.0.0/24` (нужен для доступа к `192.168.0.50`)