Bonjour à tous.
Je vous l’avez promis dans ce premier sujet, comme en plus j’ai reçu de l’aide (infini merci à @stan77), rien de plus normal que de restituer ce que j’ai pu apprendre et finalement réussi à faire fonctionner.
Donc, avant tout je vous présente Emporia Energy Vue Gen 2
Je n’ai aucune action chez eux, évidemment. Mais juste, cet objet connecté me permet d’analyser plusieurs circuits pour :
- Identifier mes circuits gourmands
- Monitorer ma consommation d’énergie.
- Améliorer ma consommation d’énergie.
À noter, même si je ne l’utilise pas pour ma part, que l’outil permet aussi de :
- Gérer le triphasé
- Gérer le photovoltaïque.
L’outil vient de UK et pour ma part, je l’ai acheté sur Amazon dans sa version 8 pinces.
Le principe est qu’il est livré avec 3 pinces « master » pour les phases d’arrivée (je n’en utilise donc qu’un)
Et 8 pinces pour les circuits que l’on veut monitorer.
Le boitier Emporia est évidemment à l’extérieur du boitier électrique (et il est livré avec une antenne SMA si le compteur est éloigné de la box). Idéalement les pinces de phases doivent être positionnées avant le disjoncteur général. Et les pinces dédiés aux circuits dans le coffret.
On ne va pas se mentir, faire rentrer tout cela dans le coffret électrique n’est pas d’une simplicité biblique. Mais on pousse avec du pain… et on finit pas y arriver.
L’outil permet d’afficher via un app mobile et web les consommations, les ratios etc…
Ainsi qu’une donnée nommée « Balance » qui correspond à l’écart entre le général et la somme de tous les circuits monitorés. Histoire de vérifier
Et maintenant, le lien avec Jeedom !
Je fournis ici les explications, mais on peut faire fonctionner tout cela sans pour autant tout comprendre et maitriser. Donc, allez jusqu’au bout !
Officiellement, Emporia Energie ne livre pas d’API. Officiellement. Car en réalité elle existe et elle même documenté, notamment grâce au boulot de fou de magico13 : GitHub - magico13/PyEmVue: Python Library for the Emporia Vue Energy Monitor.
Un bon script python, que nous allons utiliser en le détournant.
A noter j’étais très jaloux, car il a développé la brique Home Assistant.
Du coup dans un premier temps, pour éviter de coder, j’ai tenté l’énorme contournement : j’ai monté un HA, qui via un Node-Red, envoyait tout cela en MQTT. Oubliez… j’y ai laissé quelques neurones.
Donc je suis parti sur l’idée d’utiliser le plugin script et j’ai appelé la communauté à l’aide. (ici). Et grâce à @stan77, nous (surtout lui) sommes arrivés au bout du script.
Donc dans l’ordre :
Etape 1: installer le plugin « script »
Etape 2: installer les dépendances
ou l’équivalent ;-), le jour où le plugin tout fait existera
un simple accès SSH et comme le script de magico13 est disponible sur PyPI, un simple bash de ce type permet de tout faire :
python3 -m pip install "pyemvue"
L’install des dépendances se fait automatiquement (sur un RPI). Sinon c’est le même process à faire sur d’autres environnement.
Etape 3: installer le plugin JeeXplorer
Il va vous permettre d’installer le script au bon endroit.
Dans /plugins/scripts/datas, créer un dossier PyEmVue
Puis créer un nouveau fichier, pour y copier le code suivant.
Attention ! pensez à l’enregistrer en mettant l’extension PY en majuscule sinon, par défaut, jeedom va l’exécuter en python 2 :
#!/usr/bin/python3.7
# Script recupere infos de PyEmVue
# import librairies
import sys, os
# Variables de connexion
user = "votre-adresse-mail"
passuser = "votre_mdp"
duree = "1MIN"
token = 'keys.json'
resultat = "PyEmVue.log"
# recupere la date et l'heure actuelle
from datetime import datetime
now = datetime.now()
ma_date = now.strftime("%d/%m/%Y %H:%M:%S")
from pyemvue import PyEmVue
def print_recursive(usage_dict, info, depth=0):
for gid, device in usage_dict.items():
for channelnum, channel in device.channels.items():
name = channel.name
if name == 'Main':
name = info[gid].device_name
print('-'*depth, f'{gid} {channelnum} {name} {channel.usage} kwh')
fichier.write(f'{gid} {channelnum} {name} {channel.usage} kwh\n')
if channel.nested_devices:
print_recursive(channel.nested_devices, depth+1)
vue = PyEmVue()
vue.login(username=user, password=passuser, token_storage_file=token)
devices = vue.get_devices()
device_gids = []
info = {}
# Fichier pour ecrire le resultat
PyEmVueFile = os.path.abspath(os.path.dirname(sys.argv[0])) + "/" + resultat
fichier = open(PyEmVueFile, "a")
#fichier.write("Date " + ma_date)
fichier.write("Date " + ma_date + "\n")
for device in devices:
if not device.device_gid in device_gids:
device_gids.append(device.device_gid)
info[device.device_gid] = device
else:
info[device.device_gid].channels += device.channels
device_usage_dict = vue.get_device_list_usage(deviceGids=device_gids, instant=None, scale=duree, unit="KilowattHours")
print_recursive(device_usage_dict, info)
fichier.write("\n*** C'est fini ***")
fichier.close()
# Supprime le fichier si il n'y a pas d'infos PyEmVue
if not(device_gids):
if os.path.exists(PyEmVueFile):
os.remove(PyEmVueFile)
exit
Ce qu’il faut comprendre :
- l’api de emporia nécessite une authentification avec un token. Ce script permet de générer le fichier d’authentification. Il créé pour cela un fichier keys.json
2- le script va d’abord aller chercher les devices (les appareils emporia, car on peut en avoir plusieurs), puis les pinces principales, puis les pinces liées, puis la balance.
3- pour chaque pince trouvée, il va créer dans Jeedom une variable qui répond à une nomenclature pour ne pas se mélanger les pinces avec à l’id, le nom, l’unité et la consommation
4- à chaque fois que le script s’exécute, il créer un fichier PyEmVue.log, dans lequel on va ensuite venir lire les données. Ne vous étonnez pas de ne pas le trouver, il va être effacer régulièrement pour ne pas se mélanger les pinceaux.
Vous aurez peut-être besoin de le rendre exécutable :
chmod +x PyEmVue.PY
Pour le tester vous pouvez aussi le lancer en ligne de commande :
python3 PyEmVue.PY
Etape 4: paramétrer le plugin script
Votre fichier étant installé, il vous reste à la mobiliser via le plugin :
Etape 5: paramétrer le scénario
L’objectif du scénario est de:
- lancer le script qui va donc générer le fichier PyEmVue.log
- aller lire le fichier PyEmVue.log
- affecter les valeurs aux variables
- effacer le fichier PyEmVue.log
- se relancer une minute après.
Voici le code du scénario :
$DEBUG=1;
if($DEBUG) { $scenario->setLog('[DEBUG] : DEBUT'); }
// Le script PyEmVue.py crée le fichier PyEmVue.log avec les infos de consommation
$file_PyEmVue='/var/www/html/plugins/script/data/PyEmVue/PyEmVue.log';
// Init les variables
$emporia=array();
$id_emporia=0;
$nb_prise=0;
$nom_eq=0;
$mesure_eq=0;
$n=0;
$i=0;
// test si le fichier speedtest existe
if(file_exists($file_PyEmVue)) {
$scenario->setLog(' [INFO] : MAJ des infos emporia');
// on lit le contenu des infos du fichier PyEmVue ligne par ligne
$lines = file($file_PyEmVue);
foreach($lines as $n => $ligne){
// On décompose la ligne
$valeurs = explode(" ", $ligne);
if($DEBUG) {
$scenario->setLog(' [DEBUG] : ['.$id_emporia.'] ['. $n.'] $ligne= ' . $ligne);
}
// La 1ere ligne c'est le datage
if($n==0) {
// on enregistre les infos de datage dans les variables Jeedom
if($DEBUG) {
$scenario->setLog(' [DEBUG] : PyEmVue_date = ' . $valeurs[1]);
$scenario->setLog(' [DEBUG] : PyEmVue_heure = ' . $valeurs[2]);
}
$scenario->setData('PyEmVue_date', $valeurs[1]);
$scenario->setData('PyEmVue_heure', $valeurs[2]);
}
else {
// infos des l'equipements emporia
// saute les lignes vides
if(count($valeurs) > 2) {
// regarde si c'est un appareil = arg[0]
if($emporia[$id_emporia]['id_emporia'] != $valeurs[0]) {
// Si c'est la fin du fichier on sort
if ($valeurs[0]==='***') {
if($DEBUG) { $scenario->setLog(' [DEBUG] : ON SORT !'); };
break;
}
$id_emporia++; // pointe l'emporia suivant
$emporia[$id_emporia]['id_emporia']=$valeurs[0]; // id_emporia
// id des prises ampermétrique = arg[1]
$emporia[$id_emporia]['id_ampermetrique']=$valeurs[1];
// nom de l'appareil = arg[2]
$emporia[$id_emporia]['nom']=$valeurs[2];
// conso totale de l'appareil = arg[3]
$emporia[$id_emporia]['conso_totale']=$valeurs[3];
}
else {
// c'est un équipement, on l'ajoute a l'appareil
// Le nom pose problème si y a un espace dedans...
if(count($valeurs)!==5) {
// On concataine le nom
$eq_nom='';
for ($i=2; $i < count($valeurs)-2; $i++) {
$eq_nom.=$valeurs[$i] . ' ';
}
$eq_nom=trim($eq_nom);
// on refait l'array de l'equipement avec le nouveau nom
array_splice($valeurs, 2, count($valeurs), array($eq_nom , $valeurs[count($valeurs)-2], $valeurs[count($valeurs)-1]));
}
// On enregistre les infos de l'equipement dans le tableau
$emporia[$id_emporia][$valeurs[1]]['nom']=$valeurs[2];
$emporia[$id_emporia][$valeurs[1]]['conso_eq']=$valeurs[3];
$emporia[$id_emporia][$valeurs[1]]['unite']=$valeurs[4];
}
}
}
}
// recupere les infos du tableau
if($DEBUG) {
$scenario->setLog(' [DEBUG]');
$scenario->setLog(' [DEBUG] : Mise à jour des variables PyEmVue_*');
}
foreach($emporia as $app => $arrayAp) {
foreach($arrayAp as $eq => $value) {
if(is_array($value)) {
foreach($value as $Eq => $valueEQ) {
if($DEBUG) {
$scenario->setLog(' [DEBUG] : PyEmVue_' . $app .'_'. $eq .'_' . $Eq . ' = '. $valueEQ);
}
// on enregistre les infos de l'emporia dans les variables Jeedom
$scenario->setData('PyEmVue_'. $app .'_'. $eq .'_' . $Eq, $valueEQ );
}
}
else {
if($DEBUG) {
$scenario->setLog(' [DEBUG] : PyEmVue_' . $app . '_' . $eq . ' = ' . $value);
}
// on enregistre les infos de l'equipement dans les variables Jeedom
$scenario->setData('PyEmVue_'. $app .'_'. $eq, $value);
}
}
}
// supprime le fichier
unlink($file_PyEmVue);
}
else {
$scenario->setLog(' [ERREUR] : impossible de trouver le fichier : ' . $file_PyEmVue);
}
if($DEBUG) { $scenario->setLog('[DEBUG] : FIN'); };
** Etape 6: créer un virtuel par circuit monitorer.
Pensez à historiciser pour pouvoir afficher toutes les courbes que vous voulez
Et désormais vous avez toutes les données mises à jour toutes les minutes et vous avez plein de jolies courbes et autres usages pour améliorer votre consommation
Encore plein de trucs à faire, et plein d’amélioration.
Tant sur le tuto que sur l’install, mais déjà cela permet d’avoir pas mal de datas utiles.