Maîtrisez votre consommation électrique avec une solution DIY

Une réalisation DIY !

Les compteurs Linky, et les anciens compteurs électronique sont équipés d’une sortie de données appelée TIC (Télé-Information Client) qui peut être utilisée pour récupérer les informations de consommation d’électrique et traiter par soi-même ces informations.

Il s’avère que nous ne sommes pas contraints de dépendre des services en ligne pour accéder en temps réel à nos données de compteur ! Depuis l’avènement des compteurs électroniques d’électricité (depuis 1985-1990), ces informations sont directement accessibles en ajoutant un module supplémentaire à notre compteur. Cette option était disponible avant l’installation des compteurs Linky ; J’ai mis au point ce projet personnel sur un compteur Sagem.

C’est une réalisation DIY. Je n’ai pas trouvé dans le commerce ce genre de dispositifs qui ne dépendent pas d’Internet. Et, dans tous mes projets, j’attache une importance particulière à minimiser ma dépendance constante au réseau internet.

Depuis quelques années, je gère les données de mon compteur en local en utilisant un Raspberry Pi associé à un Wemos R1D1. La chance a été de mon côté avec l’arrivée du compteur Linky, car aucune mise à jour de mon système n’a été nécessaire. Il est même possible de coupler ses informations de production solaire (je l’ai fait avec un onduleur hybride) avec celles du réseaux national et afficher de superbes graphiques de nos besoins, de notre production, et de notre consommation …

Pour concrétiser ce projet, j’ai utilisé les éléments suivants :

Pour traiter les informations :

Pour collecter les informations en sortie des bornes télé infos du compteur électrique :

Si vous possédez déjà Home Assistant, ce petit module pour suivre en temps réel votre consommation électrique vous coûtera environ 10€. Le projet est largement adaptable sur un ESP8266.

Il est envisageable donc d’utiliser un ESP8266 pour récupérer les données du compteur. Je prévois d’ajuster mon projet pour le rendre compatible avec l’ESP8266, ce qui simplifierait la conception d’un boîtier pouvant se fixer directement sur le compteur (la carte est bien plus petite), éliminant ainsi le besoin de connexions filaires. Les dimensions de l’espace disponible sur le compteur sont précisées par Enedis 🙂 La modélisation sur Fusion 360 ne devrait pas être trop complexe.

Le Raspberry Pi n’est pas utile si vous utilisez déjà Home Assistant.

Des boitiers :

  • Des petites impressions 3d pour protéger l’ensemble (créés sous fusion 360 et imprimés sur une ender 3). Avant d’avoir mon imprimante, je m’étais amusé à construire des boites avec des légos lol Ca fonctionne aussi, c’est moins esthétique. (20€/kg de PLA; une boite 50g de PLA nécessaire)

Montage du circuit, prototypage avant soudure sur PCB :

Le circuit est connecté aux bornes I1 et I2 (Les fils gris et violet), indépendamment de leur position. Le cache vert du compteur Linky peut être retiré très facilement en utilisant le clipse situé en haut et un autre en bas.

J’utilise ma LiveBox pour rendre l’application de suivi électrique accessible depuis n’importe quel appareil de mon réseau local et depuis l’extérieur de mon domicile (mes données sont évidement stockées à mon domicile et ne transitent jamais par internet). Il est également possible de se connecter directement au Raspberry Pi pour accéder à l’application. Un serveur web peut également être installé sur votre boîte domotique Home Assistant, offrant ainsi plusieurs options. Le choix de la configuration reste personnel. Si votre compteur est éloigné de votre box ou de votre serveur Home Assistant, une solution économique consiste à créer un petit répéteur Wi-Fi avec un ESP (matériel entre 2 et 5€).

Pour que ce projet soit autonome (sans Home Assistant), j’ai téléversé mon code sur la carte Wemos à l’aide de l’application Arduino IDE. Ce code permet d’envoyer les informations du compteur à un serveur web (et de stoker les informations sur une base de données Mysql) sur le Raspberry Pi3 B+ en wifi.

#include <ESP8266WiFi.h> // Inclut la bibliothèque WiFi
#include <SoftwareSerial.h> // Inclut la bibliothèque SoftwareSerial pour la communication série logicielle

#define startTrame 0x02 // Définit le début d'une trame
#define endTrame 0x03 // Définit la fin d'une trame
#define startLigne 0x0A // Définit le début d'une ligne
#define endLigne 0x0D // Définit la fin d'une ligne
SoftwareSerial serialPort(D8, D9); // Initialise le port série logiciel avec les broches D8 et D9

String donneesPost; // Variable pour stocker les données à envoyer
String variablePost = "var1="; // Variable pour le préfixe des données POST

WiFiClient client; // Initialise un client WiFi

String reseauSansFil = "Mon Wifi"; // Nom du réseau WiFi
const char* motDePasse = "Mon Mot de Passe Wifi"; // Mot de passe du réseau WiFi

String serveur = "https://mon-url-local"; // URL du serveur
// const char* serveur = "192.168.1.100"; // Adresse IP du serveur, en commentaire car non utilisée ici

// Fonction pour obtenir les données de téléinformation
String obtenirTeleInfo() {
    String teleInfo = "";
    char caractere = 0;
    while (caractere != startLigne) {
        caractere = serialPort.read() & 0x7F;
    }
    while (caractere != endLigne) {
        if (serialPort.available() > 0) {
            caractere = serialPort.read() & 0x7F;
            teleInfo += caractere;
        }
    }
    return teleInfo;
}

// Fonction pour afficher les données de téléinformation
String afficherTeleInfo(String motCle, String unite, int longueur) {
    int essai = 0;
    // Nombre d'essais maximum, cf documentation ERDF
    int maxEssais = 10;
    String donnees = "";
    String message = "";
    while(donnees.substring(0,motCle.length()) != motCle && essai != maxEssais) {
        donnees = obtenirTeleInfo();
        essai++;
    }

    if (essai != maxEssais) {
        message += donnees.substring((motCle.length() + 1),(longueur + (motCle.length() + 1)));
    }
    else {
        message += "NA";
    }
    message += " ";
    message += motCle;
    message += " ";
    return message;
}

// Fonction de configuration initiale
void setup() {
    Serial.begin(115200); // Initialise la communication série à 115200 bauds
    serialPort.begin(1200); // Initialise la communication série logicielle à 1200 bauds

    WiFi.begin(reseauSansFil, motDePasse); // Démarre la connexion au réseau WiFi

    // Attente de la connexion au réseau WiFi
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");  
    Serial.println("WiFi connecté à "+reseauSansFil);  
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
}

// Fonction principale exécutée en boucle
void loop() { 
    // Construction des données de téléinformation
    String donneesTeleInfo = afficherTeleInfo("ADCO","",12)+"_"+afficherTeleInfo("ISOUSC","A",2)+"_"+afficherTeleInfo("BASE","Wh",9)+"_"+afficherTeleInfo("HCHC","Wh",9)+"_"+afficherTeleInfo("HCHP","Wh",9)+"_"+afficherTeleInfo("PTEC","",4)+"_"+afficherTeleInfo("IINST","A",3)+"_"+afficherTeleInfo("IMAX","A",3)+"_"+afficherTeleInfo("PAPP","VA",5)+"_"+afficherTeleInfo("HHPHC","",1)+"__"+afficherTeleInfo("PMAX","W",5);    

    // Construction des données POST
    donneesPost = variablePost + donneesTeleInfo;

    // Connexion au serveur
    if (client.connect(serveur, 443)) {
        client.println("POST /enedis/post.php HTTP/1.1");
        client.println("Host: "+serveur);
        client.println("Content-Type: application/x-www-form-urlencoded");
        client.print("Content-Length: ");
        client.println(donneesPost.length());
        client.println();
        client.print(donneesPost);
    }

    // Déconnexion du serveur
    if (client.connected()) {
        client.stop();
    }

    // Attente avant de renvoyer les informations au serveur
    delay(3000); 
}

Une application PHP / Mysql sur le serveur web interprète les informations du compteur.

Par la suite, j’ai adapté le module à Home Assistant. Mes données ne transitent toujours pas par internet.

Code à téléverser sur le Wemos avec ESPHome, code YAML (pour HomeAssistant)

esphome:
  name: esphome-web-78a0de
  friendly_name: ESPHome TeleInfos
  platform: ESP8266

  board: esp01_1m

# Enable Home Assistant API
api:
  encryption:
    key: "Bzhqg6JpUtiG+FncGGiCRDzL7a+m2jB+qQlQ/TT+RUA="


wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-78A0De"
    password: "KXSDKnTLRlVe"


# Example configuration entry
#debug:    # When enabled, logger must be at least debug (default) below.


# Logger configuration
logger:     
  baud_rate: 0   # disable logging via UART
  level: INFO   # INFO for less log
  esp8266_store_log_strings_in_flash: False     # recommanded for ESP8266

# ajout du composant uart pour la communication série avec la sortie TIC du compteur
# GPIO13 = Pin D7 sur Wemos D1
uart:
  id: uart_bus
  rx_pin: GPIO13
  baud_rate: 1200
  parity: EVEN
  data_bits: 7

teleinfo:
  id: esp_teleinfo
  update_interval: 3s
  historical_mode: true

binary_sensor:
  - platform: status
    id: teleinfo_status
    name: "Teleinfo Status"

sensor:
  - platform: wifi_signal
    name: "Signal wifi"
    update_interval: 60s
    unit_of_measurement: dB
    accuracy_decimals: 0
    force_update: false
    icon: mdi:wifi
    
  - platform: uptime
    id: uptime_seconds
    name: "Uptime Sensor"
    update_interval: 3s
    unit_of_measurement: s
    accuracy_decimals: 0
    force_update: false
    icon: mdi:timer
    
  - platform: teleinfo
    tag_name: "IINST"
    name: "Intensité"
    unit_of_measurement: "A"
    icon: mdi:current-ac

  - platform: teleinfo
    tag_name: "PMAX"
    name: "PMAX"
    unit_of_measurement: "W"
    icon: mdi:current-ac

  - platform: teleinfo
    tag_name: "ISOUSC"
    name: "ISOUSC"
    unit_of_measurement: "A"
    icon: mdi:current-ac

  - platform: teleinfo
    tag_name: "IMAX"
    name: "IMAX"
    unit_of_measurement: "A"
    icon: mdi:current-ac

  - platform: teleinfo
    tag_name: "PAPP"
    name: "Puissance"
    unit_of_measurement: "VA"
    icon: mdi:flash

  - platform: teleinfo
    tag_name: "HCHC"
    id: hchc
    name: "Teleinfo index_hc_kwh"
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: "total_increasing"
    accuracy_decimals: 3 
    filters:
      - multiply: 0.001
    icon: mdi:gauge

  - platform: teleinfo
    tag_name: "HCHP"
    id: hchp
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: "total_increasing"
    name: "Teleinfo index_hp_kwh"
    accuracy_decimals: 3 
    filters:
      - multiply: 0.001
    icon: mdi:gauge

  - platform: teleinfo
    tag_name: "BASE"
    id: base
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: "total_increasing"
    name: "Teleinfo index_kwh"
    accuracy_decimals: 3 
    filters:
      - multiply: 0.001
    icon: mdi:gauge

button:
  - platform: restart
    name: "Teleinfo Restart"

text_sensor:
  - platform: teleinfo
    tag_name: "PTEC"
    name: "Tarif actuel"
    icon: mdi:clock-time-nine-outline
  - platform: template
    name: Uptime
    update_interval: 60s
    icon: mdi:clock-start
    lambda: |-
      int seconds = (id(uptime_seconds).state);
      int days = seconds / (24 * 3600);
      seconds = seconds % (24 * 3600);
      int hours = seconds / 3600;
      seconds = seconds % 3600;
      int minutes = seconds /  60;
      seconds = seconds % 60;
      if ( days ) {
        return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
      } else if ( hours ) {
        return { (String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
      } else if ( minutes ) {
        return { (String(minutes) +"m "+ String(seconds) +"s").c_str() };
      } else {
        return { (String(seconds) +"s").c_str() };
      }      
    

L’avantage de Home Assistant est la possibilité d’ajouter facilement des détails à ma consommation en utilisant d’autres objets connectés (à Home assistant). Ainsi, il devient très simple d’identifier les appareils énergivores dans ma maison, ou déterminer les efforts qui peuvent être fait pour réduire les dépenses en électricité.

On peut également, grâce à Home Assistant mettre en place des scénarios, tels que : « si la consommation instantanée approche trop de la puissance maximale fournie par mon forfait électrique, alors je peux automatiser un délestage pour éviter que mon compteur électrique ne saute et ne coupe l’alimentation de tout mon logement. »

On peut associer un ruban LED connecté pour refléter la situation de la consommation électrique 🙂 Rouge pour une consommation élevée, jaune pour une consommation modérée, vert lorsque tout va bien 🙂 Cela devient un jeu d’essayer d’être aussi souvent que possible dans la zone verte. Un jeu qui peut faire faire des économies sans avoir le nez en permanence sur notre consommation. Les possibilités sont nombreuses… Je suis alerté sur mon téléphone lorsque la consommation reste anormalement élevée pendant un certain laps de temps. Grâce à cela, j’ai pu éviter plusieurs problèmes, comme une pompe de relevage des eaux sales bloquée à pleine puissance, évitant ainsi un débordement et la casse de la pompe.

Pour en savoir plus sur le TIC, Enedis nous propose les documents ci-dessous :

DOCUMENT ENEDIS pour le linky : Sorties de télé-information client des appareils de comptage Linky utilisés en généralisation par Enedis

DOCUMENT ENEDIS pour les compteur Sagem : Sorties de télé-information client des appareils de comptage électroniques utilisés par Enedis

Anciennes captures d’écran de mon appli :

Home Assistant :