~~DISCUSSION~~ **Tags** : {{tagging::input}} {{ :articles:domotique:edf_compteur-day.png?nolink |}} --------------------------------------- ====== Suivi de la téléinformation ERDF avec arduino ====== ===== Fonctionnement de la téléinformation EDF ===== La téléinformation s’obtient sur les compteurs possédant les bornes I1 et I2, appelés compteur bleu (modèle pour les particuliers) ou compteur jaune (modèle pour les professionnels). {{ :articles:domotique:compteur_bleu.jpg?nolink |Compteur « bleu »}} Il s’agit d’un port série à 1200 bps, les données voyageant sur un courant porteur (j’ai mesuré 6V environ, mais la documentation erdf/enedis indique que le système doit pouvoir assumer exceptionnellement 220V). On peut obtenir : * le(s) compteur(s) (en Wh, plus précis que les kWh affichés sur l’écran) ; * l’intensité fournie instantanée (en ampères, par phase si triphasé) ; * la période tarifaire ou la couleur des jours si les contrats prévoient cela ; * et d’autres informations, décrites dans la documentation. Pour l'instant, je n'ai pas encore de Linky, donc je ne peux rien dire sur les possibilités avec ce dernier. Néanmoins, il parait que c'est la même chose. ===== Partie arduino ===== ==== Hardware ==== Composants necessaires : * une carte arduino (Uno, mini, ou nano) ; * un shield [[wpfr>ethernet]] (j’utilise le ENC28J60) ; * un [[wpfr>photocoupleur]] : par exemple 4N25 ; * une [[wpfr>diode]] : par exemple 1N4001 ; * deux [[wpfr>Résistance_(composant)|resistances]] : 1 kΩ (resistance de tirage) et 220 Ω (pour la DEL); * une [[wpfr>Diode_électroluminescente|DEL]]. La DEL permet d’avoir un retour de l’activité : elle clignote quand il y a un transfert d’information. Cette partie du montage est optionnelle. La diode permet de supprimer une alternance du signal, le photocoupleur permet d’isoler le signal du circuit électronique. D’après [[http://www.planete-domotique.com/blog/2010/03/30/la-teleinformation-edf/|Planète-domotique]] : * Le signal sur les bornes I1/I2 est un signal modulé à 50kHz. * La présence de modulation correspond à un 0 logique, et l’absence à un 1 logique. * Ces informations sont émises cycliquement sous forme de messages composés d’une étiquette d’identification suivie généralement d’une valeur. * Il est donc nécessaire de démoduler ce signal. Après quoi on obtient une suite de caractères ASCII émise à 1200 bits/s, 7 bits/caractères, parité paire, 1 bit de stop. {{ :articles:domotique:erdf-arduino.png?nolink |Schéma électronique}} ==== Software ==== #include byte mac[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x25 }; byte ip[] = { 192, 168, 1, 25 }; EthernetServer server(80); #include SoftwareSerial cptSerial(2, 3); #define startFrame 0x02 #define endFrame 0x03 #define startLine 0x0A #define endLine 0x0D void setup() { cptSerial.begin(1200); Ethernet.begin(mac, ip); server.begin(); } String GetTeleInfo() { String TeleInfo = ""; char charIn = 0; while (charIn != startLine) { charIn = cptSerial.read() & 0x7F; } while (charIn != endLine) { if (cptSerial.available() > 0) { charIn = cptSerial.read() & 0x7F; TeleInfo += charIn; } } return TeleInfo; } String ShowTeleInfo(String keyword, String unit, int length) { int essai = 0; // Nombre d'étiquettes maximum, cf documentation ERDF int max_essais = 33; String data = ""; String msg = ""; while(data.substring(0,keyword.length()) != keyword && essai != max_essais) { data = GetTeleInfo(); essai++; } msg = "\t<"; msg += keyword; msg += " unit=\""; msg += unit; msg += "\">"; if (essai != max_essais) { msg += data.substring((keyword.length() + 1),(length + (keyword.length() + 1))); } else { msg += "NA"; } msg += ""; return msg; } void loop() { EthernetClient client = server.available(); if (client) { boolean current_line_is_blank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if (c == '\n' && current_line_is_blank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/xml"); client.println(); client.println(""); client.println(""); client.println(ShowTeleInfo("ADCO","",12)); client.println(ShowTeleInfo("OPTARIF","",4)); client.println(ShowTeleInfo("ISOUSC","A",2)); client.println(ShowTeleInfo("BASE","Wh",9)); client.println(ShowTeleInfo("HCHC","Wh",9)); client.println(ShowTeleInfo("HCHP","Wh",9)); client.println(ShowTeleInfo("EJPHN","Wh",9)); client.println(ShowTeleInfo("EJPHPM","Wh",9)); client.println(ShowTeleInfo("BBRHCJB","Wh",9)); client.println(ShowTeleInfo("BBRHPJB","Wh",9)); client.println(ShowTeleInfo("BBRHCJW","Wh",9)); client.println(ShowTeleInfo("BBRHPJW","Wh",9)); client.println(ShowTeleInfo("BBRHCJR","Wh",9)); client.println(ShowTeleInfo("BBRHPJR","Wh",9)); client.println(ShowTeleInfo("PEJP","min",2)); client.println(ShowTeleInfo("PTEC","",4)); client.println(ShowTeleInfo("DEMAIN","",4)); client.println(ShowTeleInfo("IINST","A",3)); client.println(ShowTeleInfo("IINST1","A",3)); client.println(ShowTeleInfo("IINST2","A",3)); client.println(ShowTeleInfo("IINST3","A",3)); client.println(ShowTeleInfo("IMAX","A",3)); client.println(ShowTeleInfo("IMAX1","A",3)); client.println(ShowTeleInfo("IMAX2","A",3)); client.println(ShowTeleInfo("IMAX3","A",3)); client.println(ShowTeleInfo("PMAX","W",5)); client.println(ShowTeleInfo("PAPP","VA",5)); client.println(ShowTeleInfo("HHPHC","",1)); client.println(ShowTeleInfo("MOTDETAT","",6)); client.println(ShowTeleInfo("PPOT","",2)); // On ne retiens pas ADIR(1,2,3) ou ADPS (peuvent être calculés) client.println(""); break; } if (c == '\n') { current_line_is_blank = true; } else if (c != '\r') { current_line_is_blank = false; } } } delay(200); client.stop(); } } === Exemple de sortie XML === 041430244526 HC.. 20 NA 001202472 001965554 NA NA NA NA NA NA NA NA NA HP.. NA 00 001 004 010 01 012 019 025 08230 03340 C 000000 00 Il est bien sûr tout à fait possible de faire la même chose avec une sortie [[wpfr>JavaScript_Object_Notation|json]]. ===== Plugin munin ===== [[wpfr>Munin_(logiciel)|Munin]] est un outil de surveillance des ressources, simple à utiliser et à programmer. #!/bin/python3 from lxml import etree import sys ARDUINO_URL = '192.168.1.25' if "config" in sys.argv: print("graph_title Compteur EDF") print("graph_period hour") print("graph_args --base 1000") print("graph_vlabel Consommation (Wh)") print("graph_category Domotique") print("graph_info Consommation electrique relevee par le compteur") print("hp.label Heures pleines") print("hc.label Heures creuses") print("hp.info Heures pleines") print("hc.info Heures creuses : 0h-8h") print("hp.type COUNTER") print("hc.type COUNTER") else: root = etree.parse('http://{}'.format(ARDUINO_URL)) infos = root.xpath('/teleinformation') HP = infos[0].find('HCHP').text HC = infos[0].find('HCHC').text print("hc.value ", HC) print("hp.value ", HP) {{ :articles:domotique:edf_compteur-day.png?nolink |Exemple de graphique produit par Munin}} ===== Exemples d’applications ===== * Déclencher certains appareils uniquement lors des heures creuses, les jours « EJP », les jours « bleus » ; * Afficher en direct la consommation, ou la puissance donné par le compteurs ; * Créer un système de délestage, afin d’éviter une coupure en cas de surconsommation. * ... ===== Liens ===== * [[http://www.worldofgz.com/electronique/recuperer-la-teleinformation-erdf-sur-larduino/|Récupérer la téléinformation ERDF sur l'Arduino]] * [[http://robinroche.com/wiki/index.php?title=Relev%C3%A9_de_compteur_%C3%A9lectrique_avec_un_Arduino|Relevé de compteur électrique avec un Arduino]] * [[http://www.planete-domotique.com/blog/2010/03/30/la-teleinformation-edf/|La téléinformation EDF]] * [[http://blog.cquad.eu/2012/02/02/recuperer-la-teleinformation-avec-un-arduino/|Récupérer la téléinformation avec un Arduino]] * [[http://www.erdf.fr/medias/DTR_Racc_Comptage/ERDF-NOI-CPT_02E.pdf|Sorties de télé-information client des appareils de comptage électroniques utilisés par ERDF]] ({{ :articles:domotique:erdf-noi-cpt_02e.pdf |copie locale}}) * [[http://memo-geek.blogspot.com/2014_02_01_archive.html|Memo Arduino Teleinfo]] * [[http://munin-monitoring.org/|munin]]