L’intérêt de connaître et collecter des information sur sa consommation électrique est de pouvoir la maîtriser et, éventuellement, faire des économies. Si les informations sont collectés à intervalle régulière assez courte, par exemple toutes les minutes, il est possible de surveiller si les appareils ont une consommation normale ou s’ils ne sont pas défectueux.
La sortie téléinformation est accessible via les connecteurs L1 et L2 du compteur électrique.
Pour les compteurs Linky, la sortie téléinformation est également disponible via des connecteurs nommés L1 et L2 mais n’ayant pas testé sur ce type de compteur, je ne sais pas si les informations sont de même nature et présentés de la même façon, théoriquement oui.
Les informations sont transmisses via une sortie série modulée à 50kHz à environ 5V :
- pour un 1, pas de signal.
- pour un 0, signal 50Khz.
En gros, voilà ce que ça donne schématiquement :
Une fois démodulé, on obtient un signal série classique qui suit les caractéristiques suivantes :
- 1200 bauds
- 7 bits/caractère
- parité paire
- 1 bit de stop
J’avais déjà fait un circuit en 2014 pour récupérer ma consommation mais celui ci souffrait de quelques défauts et je voulais refaire toute la partie logicielle plus propre en Java. En septembre dernier, le vieux disque dur IDE de 8Go que j’utilisais depuis 3 ans en continu a fini par montrer des signes de fatigue en faisant des bruits bizarres. Je l’ai donc changé par un autre puis j’ai revu toute l’électronique et le code.
Pour pouvoir connecter mon circuit avec une certaine isolation et récupérer le signal du compteur, j’ai utilisé un optocoupleur 6N138 [pdf] et un condensateur 10nF pour lisser le signal. On obtient ainsi un signal série directement exploitable et connectable à l’entrée série d’un RaspberryPi.
A l’époque, j’avais choisi d’en utiliser un pour sa faible consommation (environ 1,5A sous 5V avec le disque dur) et sa puissance de traitement faible mais largement suffisante pour la collecter des informations, les stocker dans une base de données et les envoyer par la suite sur un serveur.
J’utilisais un afficheur 5510 connecté via SPI qui m’indiquait l’état de ma consommation du jour et de la veille. Pour le manipuler, je faisais appel à un script Python qui utilisait une librairie faite par Adafruit. Cette librairie n’étant plus maintenue, l’afficheur n’a plus fonctionné à la suite d’une mise à jour de Python. Ce sera un truc que j’essaierai de me pencher plus tard. Pour l’instant, ça fait juste déco, c’est pas important pour le fonctionnement global du circuit.
Malgré le fait que le RaspberryPi modèle B d’origine (pas B+ !) ait 3 ans dans la tronche, il fonctionne encore très bien. Mais je me suis rendu compte qu’il avait un défaut assez pénible, comme sur les autres modèles, il supporte assez mal les impulsions magnétiques un peu trop proches.
L’ensemble du circuit étant placé juste au dessus de mon placard à disjoncteurs, je pense que l’alimentation de mon chauffe-eau remonte juste derrière dans le mur et lors du passage des heures pleines vers creuses ou inversement, et donc de l’activation ou de la coupure de son alimentation, il arrivait que le Raspberry freeze tout simplement vers 6h31 ou 22h31.
Au début, j’ai cru que c’était un simple freeze pas méchant mais vu la précision répétée de l’heure du freeze, je me suis dit que ça devait être ça. Cela finissait par être lourd, surtout quand je m’en rendait compte quelques jours après ...
Pour palier à ce problème et faire en sorte qu’il redémarre tout seul, j’ai ajouté mon circuit de reset automatique. Ainsi, s’il n’y pas plus d’activité depuis 5 minutes, un relais désactive puis réactive l’alimentation du Raspberry.
Cliquez pour agrandir ou version PDF
Toute l’électronique étant prête, il faut maintenant configurer le Raspberry pour activer le port série. De base, la connexion utilisée comme entrée série sert de port GPIO classique. Activer le port série a pour effet de désactiver ce port GPIO pour laisser place à l’interface série.
L’activation le port série se fait via l’interface de configuration raspi-config qui est disponible avec le système Raspbian :
Commande:1.sudo raspi-config
Sélectionner "Interfacing Options" :
Puis "Serial" :
Désactiver l’accès à la console depuis l’interface série :
Activer le port série (ben oui!) :
Si on a ça, c’est bon :
Faire "Finish" et rebooter :
Après avoir rebooté et s’être logué à nouveau, il est possible de tester la réception des informations sur le port série "/dev/ttyAMA0" en utilisant une console série (ici minicom mais il est possible d'en utiliser une autre) et en définissant les paramètres de réception décrits plus haut :
Commande:1.minicom -D /dev/ttyAMA0
Et là ... Oh, ça défile ! Toute la consommation électrique qui arrive en boucle ! C’est normal que ça arrive en boucle tout le temps, le compteur ne pouvant recevoir aucun ordre depuis son interface, il envoi en permanence, toutes les secondes, un nouvel ensemble d’informations.
Les données sont reçus sous forme de blocs d’informations (trames) composés de plusieurs lignes. Chaque trame commence par le code 0x02 (start text) et se termine par 0x03 (end text).
Les lignes sont définis de la sorte :
- caractère LF (0x0A)
- un code de 4 à 8 définissant la nature de l’information
- un espace (0x20)
- une valeur de 1 à 12 caractères
- un espace (0x20)
- un caractère de checksum correspondant à la somme des caractères entre le code et la valeur.
- caractère CR (0x0D)
Il existe tout un ensemble de codes à prendre en compte suivant son abonnement électrique :
- ACDO : identifiant du compteur
- OPTARIF : option tarifaire (en gros, quel est l’abonnement)
- ISOUSC : intensité maximale définie par l’abonnement
- BASE : compteur Wh si abonnement basique (compteur bleu)
- HCHC : compteur Wh pendant les heures creuses si abonnement heures pleines/creuses
- HCHP : compteur Wh pendant les heures pleines si abonnement heures pleines/creuses
- EJP HN : compteur Wh pendant les heures pleines si abonnement EJP (Effacement des Jours de Pointe)
- EJP HPM : compteur Wh pendant les heures de pointe mobile si abonnement EJP
- BBR HC JB : compteur Wh pendant les heures creuses bleus si abonnement tempo
- BBR HP JB : compteur Wh pendant les heures pleines bleus si abonnement tempo
- BBR HC JW : compteur Wh pendant les heures creuses blancs si abonnement tempo
- BBR HP JW : compteur Wh pendant les heures pleines blancs si abonnement tempo
- BBR HC JR : compteur Wh pendant les heures creuses rouges si abonnement tempo
- BBR HP JR : compteur Wh pendant les heures pleines rouges si abonnement tempo
- PEJB : préavis EJP si abonnement EJP
- DEMAIN : couleur du lendemain si abonnement tempo
- PTEC : période tarifaire en cours
- IINST : intensité instantanée en Ampères arrondie à l’entier près
- ADPS : avertissement en cas de dépassement de puissance souscrite
- IMAX : intensité maximale mesurée historique (votre record de consommation quoi!) en Ampères
- PAPP : puissance apparente en Watts
- HHPHC : groupe horaire si abonnement heures pleines/creuses ou tempo
- MOTDETAT : mot d’auto-contrôle du compteur
Globalement, pour moi qui suis en abonnement avec heures pleines/creuses, les principales informations qui m’intéressent sont :
- ACDO : pour contraire sur quel compteur je suis (même si j’en ai qu’un seul)
- HCHC : l’état de ma consommation en heures creuses
- HCHP : l’état de ma consommation en heures pleines
- PAPP : la puissance en Watts en cours que je consomme
Comme indiqué plus haut, j’ai voulu refaire la partie logicielle en Java. J’ai donc fait appel à la librairie JSSC (Java Simple Serial Connector) (Maven) pour récupérer les informations. La suite est juste de l’analyse de texte en détectant les trames et les lignes.
Code:1.
2.
3.SerialPort serial = new SerialPort("/dev/ttyAMA0"); serial.openPort(); serial.setParams(SerialPort.BAUDRATE_1200, SerialPort.DATABITS_7, SerialPort.STOPBITS_1,
SerialPort.PARITY_EVEN);
J’ai configuré des timers afin qu’un relevé soit fait chaque minute et soit stocké dans une base de données locale MySQL.
Puis, chaque minute également mais avec 30 secondes de décalage par rapport aux relevés, les relevés sont transmis à un serveur. Si un relevé a été transmis avec succès, il est effacé de la base de données locale mais si le code n’arrive pas à le transmettre parce à cause d’un problème réseau, le serveur ne répond pas ou autre, le relevé est conservé et sera envoyé plus tard.
Binaire exécutable et sources du logiciel de récupération de consommation :
TeleinformationEDF.jar / TeleinformationEDF-sources.zip
Un fichier de config est ajouté à la racine où ce trouve le jar :
Fichier "config.properties" :1.
2.
3.
4.
5.
6.
7.
8.compteur.identifiant=identifiantCompteur db.serveur=localhost db.nom=nomBDD db.identifiant=user db.motdepasse=password serveurEnvoiReleve.adresseTemplate=http://ipServeur/acquisition.php?dateHeure={dateHeure}&
ACDO={identifiantCompteur}&PTEC={periodeTarifaireEnCours}&ISOUSC={intensiteSouscrite}&
HCHC={compteurHeuresCreuses}&HCHP={compteurHeuresPleines}&PAPP={puissanceApparente}
Pour lancer le jar, il suffit juste de faire :
Commande:1.java -jar TeleinformationEDF.jar
J’ai créé un script dans init.d pour lancer automatiquement le logiciel au démarrage du RapberryPi :
Commande:1.sudo nano /etc/init.d/teleinformation
Contenu du fichier "/etc/init.d/teleinformation":1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.#!/bin/sh case "$1" in start) echo "Lancement relevé Téléinformation" sleep 10 screen -A -m -d -S teleinformation screen -S teleinformation -p 0 -X stuff 'sh /home/pi/start.sh ' ;; stop) echo "Arrêt relevés" screen -rd teleinformation -X -p0 eval "stuff '^C'^m" screen -rd teleinformation -X -p0 eval "stuff 'exit'^m" ;; *) echo "Usage: /etc/init.d/teleinformation {start|stop}" exit 1 ;; esac exit 0
Commandes:1.
2.sudo chmod 755 /etc/init.d/teleinformation sudo update-rc.d teleinformation defaults
Il est possible de lancer ou d’arrêter manuellement les relevés via les commandes :
Commandes:1.
2.sudo /etc/init.d/teleinformation start sudo /etc/init.d/teleinformation stop
Les données sont collectés sur mon serveur via un simple script PHP qui stock le tout proprement dans une base de données :
Script BDD : consommation_edf.sql
Avec toutes ces informations collectés, je me suis fait une petite interface web qui me permet de visualiser en temps réel ma consommation et voir combien cela m’a coûté par jour :
Code source PHP interface web + script d’acquisition des données : Consommation_edf-sources.zip
Je me suis également fait une requête SQL qui me sort le coût estimé par mois afin de me faire un bilan mensuel :
Code SQL:1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.SELECT mois, ROUND((conso_h_creuses * tarif_heures_creuses) * 100) / 100 as prix_h_creuses, ROUND((conso_h_pleines * tarif_heures_pleines) * 100) / 100 as prix_h_pleines, ROUND(((conso_h_creuses * tarif_heures_creuses) + (conso_h_pleines * tarif_heures_pleines))
* 100) / 100 as total FROM ( SELECT mois, conso_h_creuses, ( SELECT tarif FROM consommation_edf.tarif_periode_tarifaire WHERE DATE_FORMAT(date_debut, "%Y-%m")<=mois AND id_periode_tarifaire=1 ORDER BY date_debut DESC LIMIT 1 ) as tarif_heures_creuses, conso_h_pleines, ( SELECT tarif FROM consommation_edf.tarif_periode_tarifaire WHERE DATE_FORMAT(date_debut, "%Y-%m")<=mois AND id_periode_tarifaire=2 ORDER BY date_debut DESC LIMIT 1 ) as tarif_heures_pleines FROM ( SELECT DATE_FORMAT(date_heure, "%Y-%m") as mois, (MAX(valeur_heures_creuses) - MIN(valeur_heures_creuses)) / 1000 as conso_h_creuses, (MAX(valeur_heures_pleines) - MIN(valeur_heures_pleines)) / 1000 as conso_h_pleines FROM releve GROUP BY DATE_FORMAT(date_heure, "%Y-%m") ) as recup_conso ) AS valeurs_mensuelles
Il existe un petit hat qui gère ça justement : PitInfo (https://www.tindie.com/products/Hallard/pitinfo/). Facile à brancher, ça marche relativement bien.