Jelora.fr

Récupération consommation électrique via sortie téléinformation compteur EDF

Depuis pas mal de temps, sur les compteurs EDF numériques, il est possible d’obtenir des informations sur sa consommation via une interface appelée téléinformation qui est accessible directement sur le compteur.
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.

20171029_200623.jpg

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.

20170610_173051.jpg20170610_173107.jpg

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 :

signal_teleinfo.jpg

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.

20171029_200653.jpg
20171029_200736.jpg

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.

circuit_recup_teleinformation.JPG
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" :
Capture.JPG

Puis "Serial" :
Capture2.JPG

Désactiver l’accès à la console depuis l’interface série :
Capture3.JPG

Activer le port série (ben oui!) :
Capture4.JPG

Si on a ça, c’est bon :
Capture5.JPG

Faire "Finish" et rebooter :
Capture6.JPG
Capture7.JPG


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


Capture11.JPG

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.

Capture8-2.JPG

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.

Capture9.JPG

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 :

Capture12.JPG
Ça en fait des relevés depuis 2014 !

Capture13.JPG

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 :

Capture10.JPG

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



6 Novembre 2017 09:36
Salut,
Il existe un petit hat qui gère ça justement : PitInfo (https://www.tindie.com/products/Hallard/pitinfo/). Facile à brancher, ça marche relativement bien.

Lelex64734
22 Août 2018 22:09
J'pensais quand j'ai vu "- 1200 bauds
- 7 bits/caractère
- parité paire
- 1 bit de stop
5v "

Si j'branche ça direct dans la prise péri-informatique du MINITEL ça irait tout seul nan ?

Jelora
22 Août 2018 22:31
@Lelex64734 Je dirais en théorie oui :)

AbelJOUVE
23 Août 2018 22:19
Salut,
À ton avis est ce qu'il serait possible d'alimenter une carte ESP8266-01 via le signal du compteur puis de traiter ce signal avec la carte sur son port série. Il faudrait un pont de diodes, un petit condensateur et un régulateur de tension 3.3 v, sachant que la carte consomme environ 100 mAh. Ensuite il faudrait programmer un petit serveur web sur la carte, et peut-être une application mobile pour rendre le tout plus digeste.

Jelora
23 Août 2018 22:31
@AbelJOUVE Je ne pense pas que ce soit possible directement. La sortie du compteur étant un simple signal série modulé. Tu auras peut-être quelques mA tout au plus. Il te faudra une alimentation externe.

3 Janvier 2020 17:36
bonjour,
je possède des connaissances très limitées en informatique, j'essaie de décoder mes infos Linky à partir d'un pi zero, j'ai réussi à lire les trames à partir de minicom, je bute sur la suite, si quelqu'un pouvait m'aider ...
merci d'avance
cordialement

18 Janvier 2020 13:07
Je suis aussi bloque , je lit aussi les donne du port série mais après je suis bloque.

ROMA
25 Janvier 2020 18:21
Bon après 1 semaine j'ai réussi a bidouiller quelle que chose qui marche , j'ai rassemble sont travail avec le travail d'un autre et ça marche.

Au lieux d'utiliser le programme JAVA ( dont j'ai pas réussi a le faire marche ) je me connecte a mon convertisseur USB a travers une page PHP puis les donnes sont envoyer a la base de donne, par contre sont graphique marche après quelle que changement.

(PS je suis pas un informaticien)

27 Janvier 2020 10:57
Après 1 semaine de teste j'ai réussi a faire quelle que chose qui marche , j’ai combine sont travail avec le travaille d'un autre.
J'ai pas réussi a faire fonctionner le .jar , du coup je recuper les donne du port USB a l'aide d'une page php et je envoie tout dans sa base de donne. Le graphique marche aussi.

(Je suis pas un informaticien ^^)

kennou asma
4 Février 2020 16:21
i have a question why did you use a RASPBERRY and not a STM32 ?

Ajouter un commentaire

Nom/Pseudo :

Email (optionnel) :

Site web (optionnel) :

Commentaire :

Vérification: