homebridge-enlighten-power
Version:
Homebridge dynamic platform plugin that exposes Enphase Envoy solar production and consumption as HomeKit sensors. Supports local HTTPS access (firmware D8+, Bearer token) and the Enphase Cloud API v4 (OAuth 2.0 refresh_token). Multiple accessories share
369 lines (266 loc) âą 15.6 kB
Markdown
<p align="center">
<a href="https://github.com/homebridge/homebridge"><img src="https://raw.githubusercontent.com/homebridge/branding/master/logos/homebridge-color-round-stylized.png" height="140"></a>
</p>
<span align="center">
# homebridge-enlighten-power
[](https://www.npmjs.com/package/homebridge-enlighten-power) [](https://www.npmjs.com/package/homebridge-enlighten-power) [](https://github.com/homebridge/homebridge/wiki/Updating-To-Homebridge-v2.0)
</span>
> đ [English version](README.md) · **Français**
> â ïž **Mise Ă niveau depuis la 2.x ?** La version 3.0.0 est un changement non rĂ©tro-compatible â le plugin est dĂ©sormais une **platform dynamique**. Voir le [guide de migration](#migration-depuis-la-2x) ci-dessous.
## Description
Ce plugin Homebridge expose votre systĂšme solaire Enphase Envoy dans HomeKit sous forme d'un ou plusieurs capteurs. Chaque accessoire surveille soit la **production** (Ă©nergie gĂ©nĂ©rĂ©e), soit la **consommation** (Ă©change net avec le rĂ©seau), et bascule dans son Ă©tat dĂ©clenchĂ© quand la valeur franchit un seuil configurable â pratique comme source d'Ă©vĂ©nement pour les automatisations HomeKit.
Tous les accessoires partagent une seule connexion Envoy et un seul token d'authentification. Trois mĂ©thodes de connexion sont supportĂ©es. Le dĂ©pĂŽt fournit aussi trois [scripts Python](#scripts-python-compagnons) autonomes pour piloter un relais Piface2 depuis un Raspberry Pi â **complĂštement indĂ©pendants de Homebridge**.
## Le plugin Homebridge
### Installation
- **RecommandĂ© :** via l'interface Homebridge â onglet *Plugins* â recherche **Homebridge Enlighten Power** â *Install*.
- **Manuel :** `npm install -g homebridge-enlighten-power`.
### Choisir une méthode de connexion
| # | Méthode | Avantages | Inconvénients |
| - | --- | --- | --- |
| **1** | [Local + **token statique**](#méthode-1--local--token-statique) | Simple, configuration la plus rapide. | Rotation manuelle du token ~une fois par an. |
| **2** | [Local + **token auto-renouvelé**](#méthode-2--local--auto-refresh) | Plus jamais de rotation manuelle. | Mot de passe Enlighten stocké dans `config.json`. |
| **3** | [**API Cloud v4** (OAuth 2.0)](#méthode-3--api-cloud-v4) | Fonctionne sans accÚs LAN à l'Envoy. Production + consommation. | 1 000 req/mois ; intervalle 60 min recommandé ; mise en place OAuth ponctuelle. |
> Dans l'interface Homebridge, le menu *Connection* gĂšre la mĂ©thode 3 face aux mĂ©thodes locales, et le menu *Authentication method* gĂšre la mĂ©thode 1 face Ă la mĂ©thode 2. Si vous Ă©ditez `config.json` Ă la main, vous pouvez omettre `auth_method` â le plugin dĂ©duit la mĂ©thode (le `token` l'emporte si les deux groupes sont remplis).
### MĂ©thode 1 â Local + token statique
AccĂšs HTTPS local avec un JWT longue durĂ©e que vous gĂ©nĂ©rez vous-mĂȘme, **une fois**.
#### 1. Générer le token
1. Ouvrir <https://entrez.enphaseenergy.com> et se connecter.
2. Générer un token pour votre Envoy (l'outil demande le numéro de série).
3. Copier le JWT dans `config.json` (voir ci-dessous). Il expire au bout d'environ 1 an.
#### 2. config.json
```json
{
"platforms": [
{
"platform": "EnlightenPower",
"name": "Enlighten Power",
"connection": "bonjour",
"token": "eyJraWQiOiI......biQETMEQ",
"update_interval": 1,
"accessories": [
{ "name": "> 6000 W production", "measurement": "production", "power_threshold": 6000 }
]
}
]
}
```
URL personnalisée (accÚs par IP) :
```json
{
"platforms": [
{
"platform": "EnlightenPower",
"name": "Enlighten Power",
"connection": "url",
"url": "https://192.168.1.x",
"token": "eyJraWQiOiI......biQETMEQ",
"update_interval": 1,
"accessories": [
{ "name": "> 6000 W production", "measurement": "production", "power_threshold": 6000 },
{ "name": "Export > 4500 W", "measurement": "consumption", "power_threshold": 4500 }
]
}
]
}
```
> **Ă propos de l'API locale.** `envoy.localdomain` est le nom mDNS utilisĂ© par les firmwares D8+. L'Envoy fournit un certificat auto-signĂ© â le plugin dĂ©sactive la vĂ©rification TLS stricte uniquement pour les connexions locales. Au dĂ©marrage, le plugin appelle `/ivp/meters` pour associer le `eid` de chaque compteur Ă son `measurementType` (`"production"` ou `"net-consumption"`). Ă chaque cycle, il appelle `/ivp/meters/readings` et retrouve les entrĂ©es par `eid` â pas par position dans le tableau.
### MĂ©thode 2 â Local + auto-refresh
MĂȘme accĂšs local qu'Ă la mĂ©thode 1, mais le plugin **obtient et renouvelle le JWT pour vous**, automatiquement.
```json
{
"platforms": [
{
"platform": "EnlightenPower",
"name": "Enlighten Power",
"connection": "bonjour",
"auth_method": "auto_refresh",
"enlighten_user": "vous@example.com",
"enlighten_pass": "MOT_DE_PASSE_ENLIGHTEN",
"envoy_serial": "1234XXXXXXXX",
"update_interval": 1,
"accessories": [
{ "name": "> 6000 W production", "measurement": "production", "power_threshold": 6000 }
]
}
]
}
```
Ce qui se passe à l'exécution :
1. Au démarrage, le plugin se connecte à `enlighten.enphaseenergy.com` avec vos identifiants.
2. Il demande à `entrez.enphaseenergy.com` un JWT frais lié au numéro de série de votre Envoy.
3. Le JWT est mis en cache en mémoire et réutilisé à chaque poll.
4. Quand le JWT arrive Ă moins de 7 jours d'expiration â ou aprĂšs un `401` de l'Envoy â un nouveau JWT est rĂ©cupĂ©rĂ© automatiquement.
### MĂ©thode 3 â API Cloud v4
AccÚs OAuth 2.0 à l'API développeur Enphase. à utiliser quand Homebridge ne peut pas joindre l'Envoy sur le réseau local. Les mesures `production` et `consumption` sont disponibles via l'endpoint `latest_telemetry`.
Plans : <https://developer-v4.enphase.com/plans>. Le quota du plan gratuit a Ă©tĂ© **rĂ©duit de 10 000 Ă 1 000 requĂȘtes/mois** par Enphase. RĂ©glez `update_interval` Ă **60** (1 requĂȘte/heure = 720/mois) pour rester dans le budget. Le plugin effectue un premier poll au dĂ©marrage, puis aligne les suivants sur les limites de l'horloge â avec `update_interval: 60` les donnĂ©es sont rafraĂźchies Ă l'heure pile (10:00, 11:00, âŠ).
#### Ătape 1 â CrĂ©er l'application
Sur <https://developer-v4.enphase.com>, créez une application. La page affiche :
- **API Key** · **Client ID** · **Client Secret**
- **Authorization URL** de la forme `https://api.enphaseenergy.com/oauth/authorize?response_type=code&client_id=VOTRE_CLIENT_ID`
Vous avez aussi besoin de votre **System ID** (identifiant numérique du systÚme Enlighten, anciennement *site_id*).
#### Ătape 2 â Obtenir un code d'autorisation
> â ïž L'Authorization URL du portail est **incomplĂšte** â il manque `redirect_uri`. Ajoutez `&redirect_uri=https://api.enphaseenergy.com/oauth/redirect_uri`, sinon vous obtenez `OAuth Error: A redirect_uri must be supplied.`
URL complĂšte :
```text
https://api.enphaseenergy.com/oauth/authorize?response_type=code&client_id=VOTRE_CLIENT_ID&redirect_uri=https://api.enphaseenergy.com/oauth/redirect_uri
```
Ouvrez-la, connectez-vous Ă Enlighten, approuvez. La page de redirection affiche un code court Ă usage unique (p. ex. `2TJk7M`), valable seulement quelques minutes.
#### Ătape 3 â Ăchanger le code contre un refresh_token
```bash
curl -X POST \
-u "CLIENT_ID:CLIENT_SECRET" \
"https://api.enphaseenergy.com/oauth/token?grant_type=authorization_code&redirect_uri=https://api.enphaseenergy.com/oauth/redirect_uri&code=AUTH_CODE"
```
Ou avec [`examples/get_refresh_token.py`](examples/get_refresh_token.py) :
```bash
python3 examples/get_refresh_token.py 2TJk7M
```
Copiez le `refresh_token` de la rĂ©ponse â valable ~1 mois. Le plugin renouvelle l'access token 24h automatiquement. Ă l'expiration du refresh token, refaites les Ă©tapes 2-3.
#### Ătape 4 â config.json
```json
{
"platforms": [
{
"platform": "EnlightenPower",
"name": "Enlighten Power",
"connection": "api",
"api_key": "API_KEY",
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"system_id": "SYSTEM_ID",
"refresh_token": "REFRESH_TOKEN",
"update_interval": 60,
"accessories": [
{ "name": "> 6000 W production", "measurement": "production", "power_threshold": 6000 }
]
}
]
}
```
### Accessoires
Chaque entrée du tableau `accessories` est un capteur HomeKit indépendant. Tous partagent la connexion et l'authentification de la plateforme.
| Champ | Requis | Défaut | Description |
| --- | --- | --- | --- |
| `name` | â
| â | Nom affichĂ© dans HomeKit. Doit ĂȘtre unique. |
| `measurement` | | `production` | `production` (énergie solaire générée) ou `consumption` (échange net réseau). Disponible pour toutes les connexions. |
| `power_threshold` | | `1000` | Seuil de déclenchement en W. Voir ci-dessous. |
| `accessory_type` | | `co2sensor` | Type de capteur HomeKit â voir [Type d'accessoire HomeKit](#type-daccessoire-homekit). |
**Mode production** â se dĂ©clenche quand `production â„ seuil` ; se rĂ©initialise en dessous.
**Mode consommation** â reproduit l'hystĂ©rĂ©sis des scripts Piface :
- `detected â 1` quand `net †âseuil` (la maison exporte plus que le seuil vers le rĂ©seau).
- `detected â 0` quand `net â„ 0` (la maison importe depuis le rĂ©seau).
- Le niveau affiché est la valeur absolue de l'échange réseau en W.
> La mesure `consumption` est disponible pour toutes les connexions, y compris l'API Cloud (via l'endpoint `latest_telemetry`).
### Type d'accessoire HomeKit
| Valeur | Service HomeKit | Comportement |
| --- | --- | --- |
| `co2sensor` (défaut) | Capteur CO2 | Puissance en ppm + drapeau Détecté au-dessus du seuil. |
| `motion` | Détecteur de mouvement | Mouvement détecté au-dessus du seuil. |
| `occupancy` | Détecteur de présence | Occupé au-dessus du seuil. |
| `contact` | Capteur de contact | Ouvert au-dessus du seuil. |
| `lightsensor` | Capteur de luminosité | Puissance en lux (plafonnée à 100 000). |
### Test rapide depuis un shell
Envoy local â lectures des compteurs :
```bash
curl -sk -H "Authorization: Bearer TOKEN" "https://envoy.localdomain/ivp/meters/readings" \
| python3 -c "import sys, json; d=json.load(sys.stdin); print('prod', d[0]['activePower'], 'W net', d[1]['activePower'], 'W')"
```
## Migration depuis la 2.x
> â ïž **DĂ©sinstallation propre obligatoire.** Le type du plugin ayant changĂ© d'`accessory` Ă `platform`, Homebridge gĂ©nĂšre les UUIDs diffĂ©remment et les donnĂ©es de cache de l'ancien accessoire entrent en conflit. **Ne faites pas une simple mise Ă jour** â suivez les Ă©tapes ci-dessous.
### Ătapes de migration â via l'interface Homebridge
1. **Onglet Plugins â Homebridge Enlighten Power â DĂ©sinstaller.** Confirmer. Cela arrĂȘte le child bridge et supprime le plugin.
2. **Onglet Accessories** â si l'ancien accessoire est encore listĂ©, cliquer sur l'icĂŽne âïž â *Supprimer l'accessoire*. Si l'onglet est vide ou que l'accessoire a disparu, passer Ă l'Ă©tape suivante.
3. **Settings â Config** (Ă©diteur JSON) â vĂ©rifier que le tableau `"accessories"` ne contient plus aucun bloc `"accessory": "enlighten-power"`. Sauvegarder.
4. **Settings â Homebridge Settings â RedĂ©marrer Homebridge** une fois pour vider le cache des accessoires.
5. **Onglet Plugins â rechercher "Homebridge Enlighten Power" â Installer**, ou depuis un terminal : `npm install -g homebridge-enlighten-power`.
6. **Configurer** le plugin via l'interface graphique des réglages ou en éditant `config.json` comme indiqué ci-dessous.
7. **Supprimer de HomeKit** si l'accessoire apparaĂźt toujours comme non rĂ©pondant dans l'app Maison : appui long â *Supprimer l'accessoire*.
### Ătapes de migration â via terminal (avancĂ©)
```bash
# 1. Désinstaller
npm uninstall -g homebridge-enlighten-power
# 2. Supprimer le cache des accessoires
rm /homebridge/accessories/cachedAccessories
rm /homebridge/accessories/cachedAccessories.*.json 2>/dev/null
# 3. Réinstaller
npm install -g homebridge-enlighten-power # version stable
# 4. Ăditer config.json, puis redĂ©marrer Homebridge
```
### Changements de config
Le plugin est dĂ©sormais une **platform** (`"platform": "EnlightenPower"`) et non plus un accessoire (`"accessory": "enlighten-power"`). La config doit ĂȘtre dĂ©placĂ©e de la section `accessories` vers la section `platforms`.
**Avant** (`config.json` â v2.x) :
```json
{
"accessories": [
{
"accessory": "enlighten-power",
"name": "> 6000 W",
"connection": "bonjour",
"token": "...",
"power_threshold": 6000,
"accessory_type": "motion"
}
]
}
```
**AprĂšs** (`config.json` â v3.x) :
```json
{
"platforms": [
{
"platform": "EnlightenPower",
"name": "Enlighten Power",
"connection": "bonjour",
"token": "...",
"accessories": [
{
"name": "> 6000 W",
"measurement": "production",
"power_threshold": 6000,
"accessory_type": "motion"
}
]
}
]
}
```
## Scripts Python compagnons
Le dĂ©pĂŽt fournit Ă©galement trois scripts Python autonomes dans [`examples/`](examples/). Ils sont **indĂ©pendants de Homebridge** â pour les utilisateurs qui veulent piloter directement un **relais Piface2** depuis un Raspberry Pi Ă partir des donnĂ©es de l'Envoy.
### Installer pifacedigitalio
Merci à @rfennel qui a [partagé la procédure](https://github.com/piface/pifacedigitalio/issues/39#issuecomment-633291166) sous Buster :
```bash
sudo apt-get install python3-pip
sudo pip3 install pifacedigitalio pifacecommon
sudo sed -i 's/#dtparam=spi=on/dtparam=spi=on/' /boot/config.txt
sudo reboot
```
### [`examples/check_power_local.py`](examples/check_power_local.py)
AccĂšs local Ă l'Envoy (HTTPS + token Bearer). Lit production et consommation depuis `/ivp/meters/readings` et pilote un ou deux relais Piface2.
- `--mode production --value <W>` â relais ON quand la production â„ valeur, OFF sinon.
- `--mode consumption --value <W>` â relais ON quand la maison exporte plus que la valeur ; OFF dĂšs qu'elle importe (hystĂ©rĂ©sis).
- `--relay {0,1} [{0,1} ...]` â index(es) du/des relais. DĂ©faut : `0`. `--relay 0 1` actionne les deux.
### [`examples/check_power_api.py`](examples/check_power_api.py)
API Cloud v4 â autonome. GĂšre le flux OAuth complet, stocke le refresh token dans `refresh_token.txt` et renouvelle automatiquement l'access token.
### [`examples/get_refresh_token.py`](examples/get_refresh_token.py)
Utilitaire autonome pour l'échange OAuth.
```bash
python3 examples/get_refresh_token.py <CODE_AUTORISATION>
```
### Exemple cron
```cron
# Mode production â relais 0 ON quand production â„ 6000 W
* * * * * python3 /home/pi/check_power_local.py --mode production --value 6000
# Mode consommation â relais 1 ON quand export > 4500 W vers le rĂ©seau
* * * * * python3 /home/pi/check_power_local.py --mode consumption --value 4500 --relay 1
# Les deux relais en miroir sur l'export
* * * * * python3 /home/pi/check_power_local.py --mode consumption --value 4500 --relay 0 1
```