Работа с хабом по HTTP

⚠️ Эта страница о самостоятельной прошивке хаба. У хаба с пакетом ESPHome нет REST API, WebSocket и MQTT — это устройство ESPHome, и Home Assistant общается с ним через панель RBgrid и действие rbgrid_cmd. Всё ниже предполагает, что хаб отдаёт собственное веб-приложение. → Запуск внутри Home Assistant

Всё, что делает приложение, оно делает по HTTP с хабом в вашей собственной сети. В этом пути нет облака и нет учётной записи: если вы можете достучаться до хаба, вы можете его прочитать, а с его токеном — и изменить.

Эта страница — о том, чего таблица маршрутов не расскажет: какой токен, как часто спрашивать и несколько ошибок, которые похожи на неисправности хаба, но ими не являются. Сами маршруты — в генерируемом справочнике API, файле репозитория, который хаб создаёт из собственной схемы и который пересоздаётся при каждом выпуске. Здесь список намеренно не повторяется: скопированная вручную таблица маршрутов через один выпуск становится неверной, и неверной молча.


Два токена

Токен Для чего
админ-токен изменение хаба. Когда он задан, каждая запись требует его — и хаб отвечает Нужен админ-токен., если его нет
токен чтения чтение хаба, если вы его задали

Задаются в приложении: Настройки → Безопасность. Пока админ-токен не задан, любой, кто может достучаться до хаба, может его изменить — поэтому приложение держит предупреждение на экране, пока не сделаны оба этих пункта и пароль точки доступа. → Настройки

Передавайте токен как bearer-токен в запросе. В генерируемом справочнике у каждого маршрута, которому для записи нужен админ-токен, стоит отметка.

⚠️ Чего не говорит генерируемый справочник — так это какие чтения требуют токен чтения; он сам говорит об этом в своём заголовке. Правило, которому следует приложение: когда у хаба заданы оба токена, чтения тоже требуют токен чтения. Если вы строите что-то, что только читает, задайте токен чтения и передавайте его; ошибка 401 на маршруте, который вы ожидали открытым, почти всегда означает именно это.

Для пяти маршрутов цен разделение прописано: GET принимает токен чтения, POST — админ-токен. Поэтому панели, которая только читает цены и журнал применённых цен, админ-токен не нужен — и давать его не следует.

Браузерный клиент не должен передавать токен в адресе

Для страницы, которая открывает WebSocket, токен в адресе — верный способ, чтобы он попал в журналы, историю и скриншоты. У хаба есть выход: POST /api/v1/ws-ticket возвращает одноразовый билет, действующий 30 секунд, который сокет предъявляет вместо токена. → Живые данные по WebSocket

Разрешить браузеру с другого источника обращаться к хабу

Страницу, которая отдаётся с другого места, блокирует браузер, а не хаб. Источник разрешается в /api/system/security — до восьми штук. Это намеренная дверь, поэтому открывайте её только для тех источников, которые вы используете, и ни для каких других.


Что опрашивать, а что нет

Не опрашивайте живые значения. Хаб сам их передаёт: по WebSocket и по MQTT, в своём собственном ритме. Опрос /api/v1/summary в цикле даёт те же числа с запозданием, отнимает у хаба работу, которую тот мог бы потратить на измерения, и даёт интервал выборки, который расходится с ритмом хаба.

Запрашивайте медленно меняющееся, и частоту подбирайте под то, как быстро оно меняется на самом деле:

Что Меняется Запрашивайте
записи истории когда закрывается период не чаще одного раза за период; по from/to, а не перечитыванием всего дня
экономика вместе с записями, на которых она основана так же
состояние цены когда приходят цены или меняется состояние уведомление о цене — это состояние, на которое можно подписаться; см. ниже
настройки когда вы их меняете после того, как вы их изменили

⚠️ Цикл без задержки между попытками — единственный шаблон, из-за которого вы потеряете выходные. Если маршрут не отвечает, честная реакция — подождать дольше перед следующей попыткой, а не стараться сильнее. Хаб — микроконтроллер, который одновременно отдаёт веб-приложение, держит соединение с брокером, ведёт цикл измерений и обслуживает вас; клиент, который бьёт по нему в плотном цикле повторов, со стороны хаба неотличим от клиента, который делает это намеренно.


Чтение измеренного хабом

История хранится по точкам и по периодам; это те же данные, что показывает страница «История» приложения, — включая качество каждой записи. Именно эту часть интеграторы чаще всего теряют, а потом не могут объяснить цифру. Запись несёт признаки того, что она неполная, пересчитанная, оценочная или покрывает перерыв. Переносите их в то, что вы строите: число, качество которого вы отбросили, нельзя защитить. → История

Экономика — это стоимость и стоимость отдачи, которые хаб считает по цене, действовавшей в каждом периоде, а не пересчитывает по текущей ставке. → Как считается стоимость

export.csv даёт то же самое файлом — по точке, периоду и типу. Для всего, чему нужна таблица или длинный архив, это более дешёвый путь: один запрос вместо цикла.

⚠️ Почасовая история хранится 60 дней, затем — по дням, месяцам и годам. Если часы целого расчётного периода нужны задним числом, заберите их до того, как они свернутся: обычно для этого используют export.csv по расписанию.


Маршруты цен (прошивка 1.2.0 и новее)

Три маршрута, и они отвечают на три разных вопроса:

Маршрут Отвечает на вопрос
/api/v1/dynprice как настроена оценка цен, какие поставщики есть и каково текущее состояние
/api/v1/price итоговая цена по каждому 15-минутному периоду; а с log=1 — по какой цене был записан каждый закрытый период, за 40 дней
/api/v1/signal текущее уведомление о цене: цена сейчас, её источник, место периода в дне, какие дешёвые окна открыты и два флага

/api/v1/price — это ещё и запись. Клиент, который знает ваши цены — интеграция Home Assistant или ваш собственный скрипт, — может передать в хаб до 200 периодов, и хаб оценивает энергию по ним. Так подключается поставщик, для которого у хаба нет источника. Вы указываете, что именно передаёте: биржевая цена или цена «всё включено»; ошибиться здесь — самая дорогая ошибка из возможных, потому что она молча умножает каждую цифру стоимости. → Откуда берётся ваша цена

Для уведомления предпочитайте сохраняемый (retained) топик MQTT опросу /api/v1/signal. Это состояние: хаб публикует его заново на каждой границе 15-минутного периода и в момент любого изменения, а сохранённое сообщение передаёт текущее состояние клиенту, который подключится позже. Опрашивающий клиент получит то же самое, но с запозданием, и ничего не пропустит, только если спрашивает постоянно. → Когда энергия дешевле всего


Изменение настроек

Запись требует админ-токен, а для некоторых маршрутов — перезапуска, чтобы вступить в силу; в генерируемом справочнике есть колонка, которая это указывает. Несколько правил, которых нет ни в одной таблице:

  • Отказ при записи называет поле. Хаб отвечает 400 с полем, которое он не принял, — это намного полезнее кода состояния. Прочитайте его: обычно там правда о вашей настройке, например ценовая зона в валюте, которой нет в вашем плане.
  • Названия ограничены байтами, а не символами — 24 байта для короткого названия, 31 — для названия. Кириллическая или акцентированная буква занимает два байта, поэтому название, которое выглядит коротким, всё равно может быть отклонено.
  • На некоторых маршрутах настройка — это целый документ. Если маршрут принимает раздел настроек, отправка неполного раздела заменяет весь раздел. Прочитайте его, измените то, что хотели изменить, и отправьте обратно.

Чего API не делает

  • Ни облака, ни учётной записи, ни удалённого доступа. Хаб обслуживает вашу сеть. Всё, что дальше, — ваш туннель, ваш VPN и ваша ответственность.
  • Он ничем не управляет. Нет маршрута, который переключает нагрузку. Хаб измеряет, оценивает цены и публикует; действовать по этому — задача того, что вы строите. → Когда энергия дешевле всего
  • Нет ограничения частоты для каждого маршрута, на которое можно опереться. Его отсутствие — не разрешение; см. предупреждение о задержке выше.

Если вызов работает не так, как вы ожидаете: что проверить

401 на том, что вчера работало. С тех пор на хабе задали токен. Чтение требует токен чтения, когда заданы оба токена; запись — админ-токен.

Нужен админ-токен. при записи, которую вы уверены, что вам разрешено делать. Токен задан, но до хаба не доходит — проверьте, что это bearer-токен в самом запросе, а не параметр строки запроса.

Браузер выдаёт ошибку CORS, а curl работает. Это отказ браузера, а не хаба. Добавьте свой источник в /api/system/security; там место для восьми.

Запись возвращает 400 и называет поле, которое вы не отправляли. Некоторые маршруты принимают весь раздел настроек. Поле находится в разделе, который вы заменили, и в текущем состоянии хаба оно было недопустимо — чаще всего это зона с валютой, не совпадающей с валютой плана.

Настройка сохранилась, но ничего не изменилось. Некоторым маршрутам нужен перезапуск, чтобы вступить в силу; генерируемый справочник указывает это в своей колонке.

В истории есть пробелы. Пробелы — это записи, которых у хаба нет, а не потерянные записи: он перезапускался, обновлялся или был без питания. Признаки качества у соседних записей говорят, что произошло. → История

В журнале цен за день меньше 96 строк. Причина та же, и смысл тот же: журнал хранит периоды, в которых работал хаб. Отсутствующий период — не отсутствующая цена.

Живые значения приходят медленно или не совпадают с приложением. Вы опрашиваете там, где надо подписываться. → Живые данные по WebSocket

⚠️ Для любых работ внутри электрощитка вызывайте квалифицированного электрика.