La téléinfo de votre compteur linky avec le module PiTInfo
- domotique
- diy
- rpi
- nodered
- linky
- Introduction
- Installation du matériel
- Le mode de fonctionnement du compteur linky
- Configuration de l'interface serial
- Observation du flux de message avec picocom
- pitinfo2mqtt
- Affichage dans NodeRed
- Le mot de la fin
Introduction
Ca faisait un moment que je voulais récupérer les métriques de consommation électrique du compteur Linky, pour pouvoir les analyser, et pourquoi pas ensuite optimiser ma consommation ou mon monde de facturation. Par exemple quand j'ai emménagé dans mon logement actuel j'ai souscris à l'option Heure pleines / Heures creuses, et j'aimerais avec ces métriques pouvoir calculer et me rendre compte si cette option est la plus intéressante économiquement par rapport à ma consommation.
Dans un premier temps j'avais cherché si il était possible de récupérer les métriques par API. J'ai donc été voir du côté de mon fournisseur qui est Engie, et il s'avère que les métriques sont consultables depuis l'interface web en se connectant à son compte, mais aucune API publique n'est disponible pour les récupérer de manière programmatique. En me renseignant j'ai ensuite vu qu'Enedis le gestionnaire du réseau avait une API "Data Connect" qui fournit bien les métriques de consommation, mais qui présentes plusieurs limites :
- réservé aux professionel (besoin d'un SIRET...)
- pas de temps réel
- nécessite d'autoriser dans son compte Enedis à mettre à disposition ses données de consommation
- certains sur le net remontent un problème de fiabilités de l'API
J'ai donc finis par abandoné l'idée d'utiliser une API pour avoir ces métriques, et commencé à explorer les moyens de récupérer ces données en mode DIY. En effet les compteurs linky disposent d'une interface TIC (Télé-Info Client), il s'agit d'une prise qui apparait quand on enlève le cache du boitier. Plusieurs modules existent sur le marché pour s'interfacer avec cette prise et envoyer les données via des protocoles tels que Zigbee ou Wifi. Pas de bol, côté domotique je suis équipé de Zwave et RF433, et apparemment aucun de ces modules ne fait du Zwave ou RF433. Et pour des raisons de coût, il n'était pas question d'investir ni dans une nouvelle gateway + un module Zigbee, ni dans un module Wifi.
C'est alors que je suis tombé sur PiTInfo. Il s'agit d'un module à brancher sur les GPIO d'un raspberry qui se connecte sur le TIC via un bornier, et qui remonte via l'interface serial les métriques en temps réel. Bingo ! Le raspberry utilisé dans le projet précédent pour l'écran de contrôle domotique pourra servir également pour ce projet, surtout que mon compteur linky est à 30 cm du raspberry 😉
Installation du matériel
5 GPIO sont nécessaires pour connecter le module au raspberry :
Petit bémol, dans mon cas le module ne peut être directement branché (comme indiqué dans le schéma ci-dessus) car les GPIO 2 (5V) et 6 (Ground) sont déjà utilisés pour l'écran de contrôle. J'ai donc utilisé des câbles pour connecter le rapsberry au module, et utilisé le GPIO 14 à la place du 6 :
Pour le raccordement à la prise TIC, j'ai recyclé un vieu câble USB :
Le mode de fonctionnement du compteur linky
2 modes de fonctionnement du linky existent :
- mode historique : mode par défaut
- mode standard : fournit un débit plus important des données, et un format différent avec plus de données
Pour l'instant le mode historique me convient, donc pas besoin de changer. On verra dans le temps si c'est nécessaire (https://particuliers.engie.fr/aide-contact.html?question=comment-changer-le-mode-de-fonctionnement-de-mon-compteur).
Pour vérifier le mode utilisé par le compte, on faut défiler les paramètres jusqu'à arriver à l'écran suivant :
Configuration de l'interface serial
Le raspberry utilisé ici est le modèle 3B, et l'interface UART hardware (serial) est, depuis ce modèle, dédiée au bluetooth, alors qu'une autre interface UART est gérée par le software. Pour pouvoir utiliser l'interface serial dans de bonnes conditions, il faut utiliser la vrai interface hardware. Un peu de configuration pour ce faire :
echo "enable_uart" >> /boot/config.tx
echo "dtoverlay=pi3-disable-bt" >> /boot/config.tx
Un reboot est nécessaire pour prendre en compte :
reboot
Observation du flux de message avec picocom
L'outil picocom permet de voir les messages sur l'interface serial (pour sortir de picocom, on fait CTRL+A puis CTRL+X) :
picocom -b 1200 -d 7 -p e -f n /dev/ttyAMA0
Ici un exemple, et en rouge un cycle complet de métriques :
Pour comprendre ce que signifient tout ces messages, on va se référer au document d'enedis : https://www.enedis.fr/media/2035/download (page 15) :
Les 3 métriques qui m'intéressent pour l'instant sont :
- PAPP : puissance instantanée (VA)
- HCHC : index Heure Creuses (Wh)
- HCHP : index Heure Pleines (Wh)
pitinfo2mqtt
Le script
Ce que je souhaite c'est poussé ces métriques sur mon système de domotique pour l'affichage dans des dashboards. Il faut donc :
- lire en continu l'interface serial
- construire la trame sous forme d'objet
- lorsque la trame est complète, transmettre au système domotique sur le réseau wifi
Pour ce dernier point, on va publier sur un topic MQTT. MQTT est un protocole de messagerie type event très utilisé dans le monde DIY de la domotique. Son avantage est qu'il est très léger.
On commence par installer les dépendances du script :
pip3 install pyserial
pip3 install paho-mqtt
Puis on crée le script python /scripts/teleinfo-python.py :
import serial
import time
import random
import json
from paho.mqtt import client as mqtt_client
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
broker = 'xx.xx.xx.xx'
port = 1883
topic = "puissance_apparente_VA"
client_id = f'python-mqtt-{random.randint(0, 1000)}'
client = mqtt_client.Client(client_id)
client.on_connect = on_connect
client.connect(broker, port)
terminal = serial.Serial()
terminal.port = "/dev/ttyAMA0"
terminal.baudrate = 1200
terminal.parity = serial.PARITY_EVEN
terminal.stopbits = serial.STOPBITS_ONE
terminal.bytesize = serial.SEVENBITS
start_frame_key = "ADCO"
end_frame_key = "MOTDETAT"
excepted_keys = ["ADCO", "OPTARIF", "ISOUSC", "HCHC", "HCHP", "PTEC", "IINST", "IMAX", "PAPP", "HHPHC", "MOTDETAT"]
frame = None
terminal.open()
while True:
line = terminal.readline().decode('ascii').rstrip()
key = line.split(" ")[0]
if key in excepted_keys:
value = line.split(" ")[1]
if start_frame_key == key:
frame = {}
frame[key] = value
elif frame is not None:
if end_frame_key == key:
frame[key] = value
msg = json.dumps(frame)
result = client.publish(topic, msg)
result: [0, 1]
status = result[0]
if status == 0:
print(f"Send `{msg}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
frame = None
terminal.close()
time.sleep(30)
terminal.open()
else:
frame[key] = value
Un interval de 30 secondes est définit entre chaque récupération de données.
Le service
Pour que le script se lance automatiquement au démarrage, il faut créer un service.
Créer le fichier /etc/systemd/system/teleinfo-python.service :
[Unit]
Description=Python script fetching teleinfo metrics from serial and publishing to MQTT topic
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/bin/python3 /scripts/teleinfo-python.py
WorkingDirectory=/scripts/
[Install]
WantedBy=multi-user.target
Puis activer le service :
systemctl daemon-reload
systemctl enable teleinfo-python
systemctl start teleinfo-python
Affichage dans NodeRed
L'implémentation est simple :
- une node MQTT in pour recevoir les messages du topic "puissance_apparente_VA"
- une node fonction par métrique qui va lire la propriété de la trame
- une node dashboard par métrique pour l'affichage
Le résultat :
Le mot de la fin
Le fait de visualiser en temps réel les métriques tels que la puissance instantanée sous forme de graphe permet de mieux mesurer et comprendre sa consommation. La prochaine étape d'amélioration va être la consolidation et l'analyse dans un but d'optimisation. Pour ce faire il faudra stocker ces métriques avec une plus grande rétention (par exemple sur une base InfluxDB), identifier les indicateurs pertinents (consommation au jour, au mois, à l'année, répartition heures pleines / heures creuses...), pour pouvoir ensuite analyser et comparer dans un rendu (soit garder NodeRed, soit partir sur du Grafana).