Dialoguer avec le hub en HTTP

⚠️ Cette page concerne le firmware autonome du hub. Un hub qui exécute le paquet ESPHome n'a ni API REST, ni WebSocket, ni MQTT : c'est un appareil ESPHome, et Home Assistant communique avec lui via le panneau RBgrid et l'action rbgrid_cmd. Tout ce qui suit suppose que le hub sert sa propre application web. → Run it inside Home Assistant

Tout ce que fait l'application, elle le fait en HTTP, avec le hub sur votre propre réseau. Il n'y a ni cloud sur le chemin ni compte : si vous pouvez atteindre le hub, vous pouvez le lire, et avec son jeton vous pouvez le modifier.

Cette page couvre ce qu'une table de routes ne peut pas dire : quel jeton utiliser, à quelle fréquence interroger, et les quelques erreurs qui ressemblent à des pannes du hub sans en être. Les routes elles-mêmes figurent dans la référence API générée, un fichier du dépôt que le hub produit à partir de son propre schéma et qui est régénéré à chaque version. Rien de cette liste n'est repris ici, volontairement : une table de routes recopiée à la main devient fausse une version plus tard, et elle le devient silencieusement.


Les deux jetons

Jeton À quoi il sert
admin modifier le hub. Une fois défini, chaque écriture l'exige, et le hub répond Admin token required. lorsqu'il manque
read lire le hub, lorsque vous en avez défini un

Définissez-les dans l'application, Settings → Security. Tant qu'un jeton admin n'est pas défini, quiconque peut atteindre le hub peut le modifier : c'est pourquoi l'application garde un avertissement affiché tant que ce point et le mot de passe du point d'accès ne sont pas réglés. → Settings

Envoyez un jeton comme bearer token dans la requête. La référence générée marque chaque route qui exige le jeton admin pour les écritures.

⚠️ Ce que la référence générée ne dit pas, c'est quelles lectures exigent le jeton de lecture : elle le signale elle-même dans son en-tête. La règle que suit l'application : lorsque le hub a les deux jetons, les lectures exigent aussi le jeton de lecture. Si vous construisez quelque chose qui ne fait que lire, définissez un jeton de lecture et envoyez-le ; un 401 sur une route que vous croyiez ouverte signifie presque toujours cela.

Pour les cinq routes de prix, la répartition est précisée : GET prend le jeton de lecture, POST prend le jeton admin. Ainsi, un tableau de bord qui ne fait que lire les prix et le journal des prix appliqués n'a jamais besoin du jeton admin, et ne doit pas le recevoir.

Un client navigateur ne devrait pas transporter un jeton dans une URL

Pour une page qui ouvre un WebSocket, mettre un jeton dans l'adresse est la façon dont les jetons finissent dans les journaux, l'historique et les captures d'écran. Le hub propose une issue : POST /api/v1/ws-ticket renvoie un ticket à usage unique, valable 30 secondes, que le socket présente à la place. → Live data over WebSocket

Autoriser un navigateur d'une autre origine à appeler le hub

Une page servie depuis un autre endroit est bloquée par le navigateur, et non par le hub. /api/system/security est l'endroit où vous autorisez une origine, jusqu'à huit. C'est une porte délibérée : ouvrez-la pour les origines que vous utilisez, et pour aucune autre.


Ce qu'il faut interroger, et ce qu'il ne faut pas

N'interrogez pas pour obtenir les valeurs en direct. Le hub les pousse : via WebSocket et via MQTT, à sa propre cadence. Interroger /api/v1/summary en boucle vous donne les mêmes chiffres plus tard, coûte au hub un travail qu'il pourrait consacrer aux mesures, et vous donne un intervalle d'échantillonnage qui dérive par rapport à celui du hub.

Interrogez pour ce qui change lentement, et adaptez la fréquence à la vitesse réelle de changement :

Quoi Change Demande
enregistrements d'historique lorsqu'une période se clôt au plus une fois par période ; par from/to, et non en relisant la journée
économie avec les enregistrements sous-jacents de même
état des prix lorsque des prix arrivent ou qu'un état change la notification de prix est un état auquel vous pouvez vous abonner ; voir ci-dessous
configuration lorsque vous la modifiez après l'avoir modifiée

⚠️ Une boucle sans temporisation est le schéma qui vous coûtera un week-end. Si une route échoue, la réponse honnête est d'attendre plus longtemps avant le prochain essai, et non d'insister. Le hub est un microcontrôleur qui sert une application web, une connexion au courtier, la boucle de mesure et vous, à la fois ; un client qui martèle en réessais serrés est, vu du hub, indiscernable d'un client qui le fait exprès.


Lire ce que le hub a mesuré

History est par point et par période, et ce sont les mêmes données que celles affichées sur la page History de l'application, y compris la qualité de chaque enregistrement : c'est la partie que les intégrateurs omettent le plus souvent, puis ne peuvent pas expliquer un chiffre. Un enregistrement porte des bits indiquant s'il est partiel, recalculé, estimé ou s'il couvre une coupure. Conservez-les dans tout ce que vous construisez ; un nombre dont vous avez écarté la qualité est un nombre que vous ne pouvez pas défendre. → History

Economics correspond au coût et à la valeur d'export, calculés par le hub avec le prix en vigueur pour chaque période, et non recalculés à partir d'un tarif actuel. → How cost is calculated

export.csv vous donne la même chose sous forme de fichier, par point, par période et par type. Pour tout ce qui exige un tableur ou une longue archive, c'est la voie la moins coûteuse : une requête au lieu d'une boucle.

⚠️ L'historique horaire est conservé 60 jours, puis en journalier, mensuel et annuel. Si vous avez besoin des heures d'une période de facturation entière après coup, récupérez-les avant qu'elles ne basculent : un export.csv planifié est la méthode habituelle.


Les routes de prix (firmware 1.2.0 et ultérieur)

Trois routes, qui répondent à trois questions différentes :

Route Répond
/api/v1/dynprice comment la tarification est configurée, quels fournisseurs existent, et l'état en direct
/api/v1/price le prix résolu par période de 15 minutes, et avec log=1, à quel prix chaque période clôturée a été réellement enregistrée, sur 40 jours
/api/v1/signal la notification de prix actuelle : le prix actuel, sa source, le rang de la période dans la journée, les fenêtres bon marché ouvertes, et les deux indicateurs

/api/v1/price est aussi une écriture. Un client qui connaît vos prix (une intégration Home Assistant, votre propre script) peut transmettre jusqu'à 200 périodes au hub, et le hub valorise l'énergie avec elles. C'est la voie pour un fournisseur dont le hub n'a aucune source. Vous indiquez si ce que vous transmettez est un prix spot ou un prix tout compris ; se tromper là-dessus est l'erreur la plus coûteuse possible ici, car elle multiplie silencieusement chaque chiffre de coût. → Where your price comes from

Pour la notification, préférez le sujet MQTT retenu à l'interrogation de /api/v1/signal. C'est un état : le hub le republie à chaque limite de période de 15 minutes et au moment où quoi que ce soit change, et un message retenu transmet l'état actuel à un client qui se connecte plus tard. Un client qui interroge obtient la même chose, avec retard, et n'en manque rien qu'à force de demander en permanence. → Knowing when energy is cheapest


Modifier des réglages

Les écritures exigent le jeton admin et, pour certaines routes, un redémarrage avant d'être appliquées ; la référence générée comporte une colonne qui l'indique. Quelques règles qui ne figurent dans aucune table :

  • Une écriture refusée nomme le champ. Le hub répond 400 avec le champ qu'il n'a pas accepté, ce qui est bien plus utile qu'un code d'état. Lisez-le : il vous dit généralement quelque chose de vrai sur votre configuration, comme une zone de prix libellée dans une devise qui n'est pas celle de votre forfait.
  • Les noms sont limités en octets, pas en caractères : 24 octets pour un nom court, 31 pour un nom. Une lettre cyrillique ou accentuée en compte deux, donc un nom qui paraît court peut tout de même être refusé.
  • La configuration est un document entier sur certaines routes. Lorsqu'une route prend une section de configuration, envoyer une section partielle remplace la section. Lisez-la, modifiez ce que vous voulez changer, renvoyez-la.

Ce que l'API ne fera pas

  • Ni cloud, ni compte, ni accès à distance. Le hub sert votre réseau. Tout ce qui va au-delà relève de votre tunnel, de votre VPN, de votre responsabilité.
  • Il ne commande rien. Aucune route ne commute une charge. Le hub mesure, valorise et publie ; agir en conséquence relève de ce que vous construisez. → Knowing when energy is cheapest
  • Aucune limite de débit par route sur laquelle s'appuyer. L'absence de limite n'est pas une autorisation ; voir l'avertissement sur la temporisation ci-dessus.

Lorsqu'un appel ne fait pas ce que vous attendez : quoi vérifier

401 sur quelque chose qui fonctionnait hier. Un jeton a été défini depuis sur le hub. Les lectures exigent le jeton de lecture une fois que les deux jetons existent ; les écritures exigent celui d'admin.

Admin token required. sur une écriture que vous savez autorisée. Le jeton est défini mais n'atteint pas le hub : vérifiez qu'il s'agit d'un bearer token dans la requête elle-même, et non d'un paramètre de requête.

Un navigateur reçoit une erreur CORS, curl fonctionne très bien. C'est le navigateur qui refuse, et non le hub. Ajoutez votre origine dans /api/system/security ; il y a de la place pour huit.

Une écriture renvoie 400 et nomme un champ que vous n'avez pas envoyé. Certaines routes prennent une section de configuration entière. Le champ se trouve dans la section que vous avez remplacée, et il n'était pas valide dans l'état où se trouve le hub : une zone dont la devise ne correspond pas à celle du forfait est le cas le plus courant.

Un réglage a été enregistré mais rien n'a changé. Certaines routes exigent un redémarrage pour s'appliquer ; la référence générée l'indique dans sa propre colonne.

L'historique présente des trous. Les trous correspondent à des enregistrements que le hub n'a pas, et non à des enregistrements perdus : il redémarrait, se mettait à jour ou était privé d'alimentation. Les bits de qualité des enregistrements voisins indiquent ce qui s'est passé. → History

Le journal des prix compte moins de 96 lignes pour une journée. Même cause, même sens : le journal conserve les périodes pendant lesquelles le hub fonctionnait. Une période absente n'est pas un prix absent.

Les valeurs en direct arrivent lentement, ou pas en phase avec l'application. Vous interrogez là où vous devriez vous abonner. → Live data over WebSocket

⚠️ Pour toute intervention à l'intérieur d'un tableau électrique, faites appel à un électricien qualifié.