Article un peu plus technique et ciblé aujourd’hui ! Nous allons parler un peu des API pour interconnecter les produits Enphase avec d’autres composants. Par exemple pour réaliser des intégrations avec des hubs domotiques ou de gestionnaires d’énergie (p. ex. Home Assistant).
Pour ceux qui ne connaissent pas la marque, Enphase est le leader des “micro-onduleurs”, c’est-à-dire un onduleur par panneau solaire. Contrairement à l’onduleur centralisé proposé par la majorité des autres fabricants. En 2021, Enphase détenait 48% du marché total aux États-Unis et Solar Edge, son principal concurrent 40%. Autant dire qu’il ne restait pas grand-chose aux autres compagnies… Bref, je m’égare, mais vous savez au moins de quoi nous parlons désormais.
Durant longtemps, Enphase était connu pour être un système peu ouvert et difficilement interfaçable avec d’autres solutions. La politique de l’entreprise a bien changé depuis et de plus en plus de produits arrivent sur le marché pour plus d’ouverture. Des API locales améliorées font partie du lot… Alors c’est parti, on attaque !
Cet article possède une suite détaillée qui aide à prendre en main des projets open source en Python. Vous pouvez le trouver ici si intérêt.
API locales et API cloud
Enlighten Systems API
Pour commencer, il est important de comprendre qu’historiquement, Enphase proposait des API au travers de son service cloud Enlighten. Ce système est extrêmement bien documenté et permet d’obtenir beaucoup d’informations historiques sur votre installation.
Le problème principal des API Enlighten étant la vitesse de rafraichissement. Il n’est pas possible d’obtenir des informations instantanées, au mieux, nous avons des informations toutes les 15 minutes. Avec un rafraichissement aussi lent, il est quasi impossible d’utiliser ces informations pour de la domotique ou de l’optimisation solaire avec un gestionnaire d’énergie…
Vous avez déjà compris, ce ne sont pas ces API là qui vont nous intéresser dans cet article…
IQ Gateway/Envoy-S local API
La seconde possibilité offerte était l’accès aux API locales de votre passerelle de communication Enphase. Celle-ci se nomme Envoy-S ou IQ Gateway en fonction de la génération dont vous disposez. Derrière ces noms, il s’agit du même boitier. C’est uniquement un changement de nom pour mieux coller à la gamme de produits “IQ” du fabricant.
Les API locales possèdent deux versions très différentes. Les passerelles en version inférieure à 7.x.x possèdent un jeu très simple d’API (mais ça existe contrairement aux rumeurs !). Il permettait déjà d’obtenir des informations simples comme la consommation, la production ou l’énergie nette de l’installation.
Dans le cas de cet article, nous n’allons pas nous intéresser à ce que se faisait avant la version 7.x.x. Le changement étant majeur, nous allons directement parler de la version la plus complète ! On peut simplement dire qu’avant la version 7.x.x toute la partie authentification n’était pas nécessaire… Mais ça, c’était avant !
Prérequis
Avant de pouvoir débuter tout ce micmac un peu plus technique, il faut être conscient qu’il y a trois prérequis importants :
1 Votre passerelle IQ Gateway/Envoy-S doit être à jour dans une version 7.x.x, sans quoi vous ne disposerez pas des nouvelles API. Pour ce faire, vous pouvez vous adresser au support d’Enphase ou à votre installateur. À ma connaissance, une majorité des passerelles depuis l’Envoy-S sont compatibles avec cette nouvelle version (attention, pas l’Envoy “tout court” avec l’écran). Pour vérifier la version de votre passerelle, celle-ci est disponible dans l’application pour smartphone Enphase Enlighten dans Menu -> Système -> Périphérique -> Passerelle.
2 Vous devez disposer de la version “Metered” de la passerelle IQ Gateway/Envoy-S. Il existe deux versions des passerelles dans le commerce. L’une dispose de compteurs supplémentaires permettant de comptabilité la consommation de la maison. La version standard ne permet pas d’obtenir des informations à la seconde. Ce n’est pas bloquant si vous ne disposez pas de la version “Metered”, néanmoins vous disposerez de beaucoup moins d’informations et elles ne seront pas instantanées (sauf erreur…).
3 Pour réaliser les exercices que je vous montre, vous devez posséder une machine permettant d’exécuter des scripts Shell (macOS, Linux, Windows Subsystem Linux,…). Il est aussi indispensable d’installer l’application “jq” qui permet de manipuler facilement le format de données JSON.
Documentations officielles
Les informations que je vais vous partager ci-dessous sont en grande partie extraite/adaptée depuis la base documentaire officielle. Celle-ci est disponible sur le site d’Enphase sous la forme d’un fichier PDF. Au moment où j’écris ces lignes, je me base sur les informations publiées en août 2023. Une copie du fichier est ici si nécessaire (si par hasard ça viendrait à disparaitre) :
Authentification
Pour permettre une connexion à votre IQ Gateway/Envoy-S localement, vous devez tout d’abord préparer ce qu’il faut pour vous authentifier. Pour ce faire, il faut générer un token d’authentification (un “jeton” pour nos amis québécois, je ne veux vexer personne). Ensuite seulement, nous pouvons commencer à obtenir les premières valeurs depuis l’API.
Pour générer le token, vous devez disposer de deux informations :
- Le numéro de série de votre IQ Gateway/Envoy-S. Celui-ci est disponible dans l’application pour smartphone Enphase Enlighten dans Menu -> Système -> Périphérique -> Passerelle.
- votre compte Enphase Enlighten (votre nom d’utilisateur et le mot de passe).
🎓 La demande de token se fait en deux étapes. Vous devez d’abord obtenir un ID de session confirmant que vous avez bien été authentifié. Ensuite, passer l’ID de session à une autre URL pour demander le token.
Les deux URL pour votre demande de token sont les suivantes et je vous les détaille dans les prochains chapitres :
https://enlighten.enphaseenergy.com/login/login.json
https://entrez.enphaseenergy.com/tokens
Obtenir le “Session ID”
Donc, si on commence par un exemple en utilisant cURL pour faire simple :
curl -X POST https://enlighten.enphaseenergy.com/login/login.json? -F "user[email]=VOTREADRESSEEMAIL" -F "user[password]=VOTREMOTDEPASSE"
Attention à remplacer VOTREADRESSEEMAIL et VOTREMOTDEPASSE par les vraies informations de votre compte Enphase Enlighten.
La réponse sera quelque chose de similaire à la suivante et nous pouvons trouver la première information que nous avons besoin en gras :
{"message":"success","session_id":"3aab3ebdff231af701f32a3ebdfd1f75","manager_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQeyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQeyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQeyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQeyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c","is_consumer":false,"system_id":1234567}%
Dans le cas de ce premier exemple, nous indiquons à l’URL indiquée que nous postons dans les champs du formulaire “user[email]” et “user[password]” les données que vous avez indiquées.
Pour vous culturer un peu je vous montre ci-dessous le code source de la page avec les deux champs du formulaire comme indiqué. On peut trouver ces informations si l’on passe par un navigateur par exemple :
En allant donner un coup d’œil à l’inspecteur de votre navigateur, vous allez trouver aussi un nouveau cookie nommé “_enlighten_4_session” qui possède l’information du “session ID” :
Voilà, c’est terminé pour le Session ID, on peut attaquer la suite…
Obtenir le token d’authentification
Maintenant que nous possédons le session ID, nous pouvons utiliser une autre API Enphase pour demander un token d’authentification. Ce token sera utilisé pour tous les prochains appels. Mais au fond… C’est quoi un token ?
Un token c’est une “clé d’identification unique” que vous devez conserver comme un mot de passe. Celui-ci est généré normalement de manière sécurisée (c’est le cas chez Enphase… j’espère !) et il permet de remplacer un utilisateur/mot de passe durant une période donnée. Car oui, un token possède une date d’expiration et c’est important d’en tenir compte ensuite dans vos développements.
Reprenons un peu de code pour continuer de bien comprendre. Nous allons à nouveau utiliser cURL, mais cette fois pour manipuler du JSON. Il est donc important d’ajouter l’option “-H” pour indiquer que nous utilisons du JSON dans le header.
Dans la demande de token, l’API d’Enphase s’attend à recevoir trois informations dans votre requête. Le Session ID que nous avons récupéré avant, le numéro de série de votre IQ Gateway/Envoy-S et votre nom d’utilisateur Enphase Enlighten.
Ci-dessous un exemple que vous pouvez utiliser pour tester :
curl -X POST https://entrez.enphaseenergy.com/tokens -H "Content-Type: application/json" -d "{\"session_id\": \"LESESSIONID\", \"serial_num\": \"LENUMEROEDESERIEDEVOTREPASSERELLE\", \"username\": \"VOTRENOMDUTILISATEUR\"}"
En réponse, vous allez recevoir le token si tout s’est bien passé ! Il devrait être sous une forme similaire à la chaine de caractère suivante. Par contre, ne perdez pas votre temps bande de petits malins, ce n’est pas un vrai token celui que je vous montre :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQeyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQeyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQeyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQeyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Il est beau votre premier token ! C’est maintenant qu’on peut attaquer les choses sérieuses pour obtenir nos premières valeurs… parce que c’était un peu le but tout de même.
⚠️ Petite note importante, si vous êtes l’utilisateur/client final, le token généré sera valide une année. Par contre, si vous êtes un installateur et utilisez votre compte installateur pour créer un token pour un client, celui-ci ne sera valide que quelques heures par mesure de sécurité.
BONUS 1 : Script complet
Si vous êtes un peu flemmard, ce chapitre bonus est pour vous ! Dans la documentation Enphase mentionnée plus haut, un script Shell tout prêt est disponible.
La documentation inclut aussi des informations similaires pour Python si vous êtes intéressés. Je vous les copie 1:1 ici, mais je n’ai pas testé et il faudra très certainement adapter un peu en fonction de votre environnement de travail :
Version shell
user='VOTRENOMDUTILISATEURENPHASE'
password='VOTREMOTDEPASSE!'
envoy_serial='LENUMEROEDESERIEDELAPASSERELLE'
session_id=$(curl -X POST https://enlighten.enphaseenergy.com/login/login.json? -F "user[email]=$user" -F "user[password]=$password" | jq -r ".session_id")
web_token=$(curl -X POST https://entrez.enphaseenergy.com/tokens -H "Content-Type: application/json" -d "{\"session_id\": \"$session_id\", \"serial_num\": \"$envoy_serial\", \"username\": \"$user\"}")
echo $web_token
Version python
import json
import requests
user=’VOTRENOMDUTILISATEURENPHASE’
password='VOTREMOTDEPASSE'
envoy_serial=’LENUMEROEDESERIEDELAPASSERELLE’
data = {'user[email]': user, 'user[password]': password}
response = requests.post('http://enlighten.enphaseenergy.com/login/login.json?',
data=data) response_data = json.loads(response.text)
data = {'session_id': response_data['session_id'], 'serial_num': envoy_serial, 'username':
user}
response = requests.post('http://entrez.enphaseenergy.com/tokens', json=data)
token_raw = response.text
BONUS 2 : Vérifier la date d’un token
Encore un dernier petit truc… Il est important de vérifier la date du token (JWT pour les initiés) pour savoir quand il va expirer. Soit on peut stocker la date à laquelle on a généré le token, soit on peut directement lire dans le token la date d’expiration.
La deuxième méthode est bien plus propre, car elle permet d’éviter les erreurs. Je vous partage ci-dessous un exemple.
# Stocker le token dans une variable
token="VOTRETOKENTROPBIEN"
# Extraire la deuxième partie du token
token_base64=$(echo "$token" | cut -d'.' -f2)
# Décoder la base64 et convertir au format JSON
token_json=$(echo "$token_base64" | base64 -D | jq .)
# Extraire la date d'expiration
expiration_date=$(echo "$token_json" | jq -r '.exp')
# Convertir la date Unix en une date lisible
formatted_date=$(date -r "$expiration_date" +"%d/%m/%Y %H:%M:%S")
# Afficher la date d'expiration du token
echo "$formatted_date"
Le script suivant est fait pour macOS, il est possible que certaines commandes utilisent des options différentes. Donc, un peu d’adaptation sera très certainement nécessaire 😊.
Voilà, vous avez fait le plus difficile ! Maintenant, il sera simple d’obtenir des informations depuis votre passerelle via les API !
Opérations de base avec l’API
Requête de base
Tout d’abord, il faut comprendre la requête de base que vous allez utiliser pour tous les appels à l’API. On va utiliser encore cURL, car c’est simple à comprendre et tester :
curl -s -f -k -H 'Accept: application/json' -H 'Authorization: Bearer VOTRETOKEN’ -X GET https://ADRESSEIPDEVOTREPASSERELLE/URLDELAPI
On voit donc qu’il y a trois informations à remplir. Le token que l’on a généré plus haut, l’adresse IP de la passerelle et l‘URL de l’API pour obtenir les informations désirées.
Production
Pour obtenir la production de l’installation solaire :
/usr/bin/curl -s -f -k -H 'Accept: application/json' -H 'Authorization: Bearer VOTRETOKEN' -X GET https://ADRESESEIPDEVOTREPASSERELLE/ivp/meters/reports/production
Le résultat va ressembler à quelque chose comme ça :
{
"createdAt": 1699042964,
"reportType": "production",
"cumulative": {
"currW": -2.977,
"actPower": -2.977,
"apprntPwr": 418.898,
"reactPwr": 409.963,
"whDlvdCum": 30070851.900,
"whRcvdCum": 82526.584,
"varhLagCum": 9234818.306,
"varhLeadCum": 0.835,
"vahCum": 36381259.591,
"rmsVoltage": 694.393,
"rmsCurrent": 1.810,
"pwrFactor": -0.02,
"freqHz": 50.00
},
<valeurs par phases volontairement supprimées pour simplifier>
}
Oui, ma production est négative dans cet exemple… J’ai fait l’article de nuit 😆
Consommation
Pour obtenir la consommation et la consommation nette du logement :
/usr/bin/curl -s -f -k -H 'Accept: application/json' -H 'Authorization: Bearer VOTRETOKEN' -X GET https://ADRESESEIPDEVOTREPASSERELLE/ivp/meters/reports/consumption
Le résultat va ressembler à quelque chose comme ça :
[
{
"createdAt": 1699042766,
"reportType": "total-consumption",
"cumulative": {
"currW": 193.271,
"actPower": 193.271,
"apprntPwr": 3473.023,
"reactPwr": -1046.916,
"whDlvdCum": 41564788.467,
"whRcvdCum": 0.000,
"varhLagCum": 19666341.239,
"varhLeadCum": 16548631.100,
"vahCum": 66266595.332,
"rmsVoltage": 693.656,
"rmsCurrent": 5.007,
"pwrFactor": 0.06,
"freqHz": 50.00
},
<valeurs par phases volontairement supprimées pour simplifier>
{
"createdAt": 1699042766,
"reportType": "net-consumption",
"cumulative": {
"currW": 195.899,
"actPower": 195.899,
"apprntPwr": 740.596,
"reactPwr": -639.659,
"whDlvdCum": 32066802.815,
"whRcvdCum": 20572866.248,
"varhLagCum": 10431545.589,
"varhLeadCum": 16548630.265,
"vahCum": 66266595.332,
"rmsVoltage": 693.698,
"rmsCurrent": 3.201,
"pwrFactor": 0.25,
"freqHz": 50.00
},
<valeurs par phases volontairement supprimées pour simplifier>
}
]
BONUS 3 : Extraction JSON
Pour simplifier un peu le résultat, vous pouvez utiliser la commande “jq” mentionnée plus haut pour traiter du JSON. Si nous reprenons l’exemple de la consommation, nous pouvons extraire la valeur du champ assez simplement :
/usr/bin/curl -s -f -k -H 'Accept: application/json' -H 'Authorization: Bearer VOTRETOKEN' -X GET https://ADRESESEIPDEVOTREPASSERELLE/ivp/meters/reports/consumption | jq '.[0].cumulative.actPower'
Je ne vais pas donner plus de détail, mais en gros elle permet de se positionner assez simplement dans le fichier JSON et sortir la donnée que l’on désire.
Liste des API documentées
Ci-dessous, je vous reprends dans un tableau les API documentées par Enphase avec les traductions en français suisse romand :
URL DE L’API | DESCRIPTION |
---|---|
http://ADRESSE_IP/ivp/meters | Renvoie l’état du compteur, le type de compteur et le nombre de phases mesurées. |
http://ADRESSE_IP/ivp/meters/readings | Renvoie toutes les mesures depuis les pinces CT (production, consommation, batterie…). |
http://ADRESSE_IP/api/v1/production | Renvoie les valeurs de production d’énergie et de puissance active pour aujourd’hui, les sept derniers jours et la durée de vie en wattheures. L’API fonctionne même si le compteur de production n’est pas installé et activé sur le site. |
http://ADRESSE_IP /ivp/pdm/energy | Renvoie les valeurs d’énergie et de puissance active pour les micro-onduleurs, les compteurs pour aujourd’hui, les sept derniers jours et la durée de vie en watts-heure. L’API fonctionne même si le compteur de production n’est pas installé et activé sur le site. |
http://ADRESSE_IP/api/v1/production/inverters | Renvoie le maximum et la dernière puissance active des micro-onduleurs disponibles. |
http://ADRESSE_IP/ivp/livedata/status | Renvoie les données en direct avec les tâches et les compteurs. |
http://ADRESSE_IP/ivp/meters/reports/consumption | Renvoie la consommation d’énergie. |
Pour aller plus loin…
Si vous désirez aller plus loin et obtenir beaucoup plus de détails sur des projets open source existants pour vous aider à prendre en main tout ça, je vous invite à lire un autre article qui traite du sujet :
Conclusion
Avec cet article vous avez découvert la base des API Enphase locales (pas Enlighten, je répète si des fois vous n’avez rien suivi). Je me suis attardé surtout sur la partie la plus compliquée qui consiste à comprendre comment fonctionne le mécanisme d’authentification.
Avec ces informations, vous allez pouvoir découvrir les possibilités d’intégration avec les API locales et leur rafraichissement à la seconde. C’est en préparant les informations à transmettre à l’équipe de Solar Manager que cet article est né via mes notes personnelles… D’ailleurs, Solar Manager supporte désormais les passerelles Enphase IQ Gateway et Envoy-S (disons, à quelques détail près…) grâce à ça.
Néanmoins, ces informations pourront ensuite être utilisées dans différentes solutions comme Home Assistant, openHAB ou vos propres scripts !
On reviendra d’ailleurs là dessus pour l’intégrer avec quelques solutions que je possède, comme la bride pour chauffe-eau Askoheat+…
Mais bon… En espérant que cet article peut être utile à quelqu’un un jour… 😅