Téléinfo via wifi

Salut @Sylvain_G

Tu peux trouver toutes les infos ici.
Les fichiers pour créer la carte électronique sont sur le github

Bonjour à tous.
J’aimerais récupérer les informations de mon Linky en direct.
Désolé de demander ça, mais malgré la lecture de tous vos liens j’ai du mal à savoir exactement ce dont j’ai besoin en matériel.
J’ai déjà commandé :

  • Un AZDelivery D1 mini
  • Un PiTInfo de Charles Hallard avec connecteurs soudés

@djtef, la carte Wemos-TIC du lien que tu as donné permet de relier le D1 au PiTInfo ?
Merci pour vos éclaircissements.

@Jcpas, est-ce que tu as lu cet article de Canaletto sur Home Assistant, ESP & Téléinfo, ça peut peut-être t’aider…

Merci pour ta réponse @Sylvain_G.
Oui j’avais aussi ce lien dans mes favoris, c’est d’ailleurs en lisant ce tuto que je me suis lancé dans l’achat du PiTInfo et du D1 mini.
Mais en lisant cette discussion j’ai eu un gros doute sur la nécessité d’autres éléments.

Salut @Jcpas
PiTinfo sert à la base à se connecter directement sur le Raspberry Pi sur le port série, donc si t’as Home Assistant qui tourne sur un Raspberry ça doit pouvoir s’utiliser tout seul sans rien d’autre, mais je garantis pas que ce sera intégré facilement, j’ai jamais testé.
Mais comme l’ESP a aussi une entrée série via l’UART t’as raison tu dois pouvoir l’utiliser aussi, ça t’évites de te faire un montage toi-même, t’auras juste le port série et l’alim à souder sur le PiTinfo.
Tiens-nous au courant

@Schmurtz, j’ai installé ton code qui marche nickel :clap: à part un petit truc.

Je me suis rendu compte que j’avais beaucoup de valeur à zéro de l’index (j’espère qu’EDF va me faire payer quand il sera à 0 :grin:)

image

idem pour la puissance qui varie très peu malgré la mise en route d’appareils.

En me connectant sur l’interface Web de mon ESP32, j’ai vu que le n° ADCO était régulièrement tronqué :

Est-ce que cela pourrait venir de là ?

Sinon il existe un super montage nommé REMORA, qui a débuté il y a quelques années, toujours administrer par hallard.

Ce projet est top, car en plus de récupérer tes infos téléinfo par wifi, tu peux gérer l’ensemble de tes chauffages (via fils pilotes) mais aussi ton chauffe-eau.
En plus, un plugin Home Assistant existe et il est top !
Vraiment rien à redire, si ce n’est qu’il faut un peu bidouiller (DIY :stuck_out_tongue: ) et faire renaître un peu la communauté, car ce projet vaut le coup.

J’ai un soucis avec le code de @Schmurtz. Les valeurs des sensors sont de temps en temps bizarres (l’index qui revient à zéro, données tronquées, etc…).
Est-ce que quelqu’un pourrait m’aider à modifier le code pour que les données ne soient envoyées QUE si la trame et les données sont valides.
Exemple :

  • l’index ne doit pas être inférieur à l’ancien
  • ADCO doit avoir n caractères

J’avais déjà fait ça, il y a longtemps en Python mais je ne connais pas le langage utilisé dans l’ESP32, pourriez-vous m’indiquer où trouver de la doc sur ce langage.
J’ai à peu près cibler le code à faire évoluer :
Mais faut encore que je trouve comment …

Résumé
void processString(String str) {
		//ESP_LOGD("tic_received", str.c_str());
		
		ESP_LOGD("tic", "tic_received %s", str.c_str());
		char separator = ' ';
		if (str.indexOf(separator) > -1)
		{
			String etiquette = str.substring(0, str.indexOf(separator));
			String value = str.substring(str.indexOf(separator) + 1);
			if (value.indexOf(separator) > -1)
			{
				value = value.substring(0, value.indexOf(separator));
				processCommand(etiquette, value);
			}
		}
	}
  
	void processCommand(String etiquette, String value)
	{
		//ESP_LOGD("tic_etiquette", etiquette.c_str());
		//ESP_LOGD("tic_value", value.c_str());
		//ESP_LOGD(etiquette.c_str(), value.c_str());
		
		ESP_LOGD("tic", "tic_etiquette %s", etiquette.c_str());
		ESP_LOGD("tic", "tic_value %s", value.c_str());	  
		if (etiquette == "ADCO") // adresse
		{
			if (adco != value)
			{
				sensor_ADCO->publish_state(value.c_str());
				adco = value;
			}
		}
		else if (etiquette == "BASE")
		{
			if (base != value.toFloat())
			{	
				sensor_BASE->publish_state(value.toFloat() / 1000.0);
				base = value.toFloat();
			}
		}
		else if (etiquette == "ISOUSC")
		{
			if (isousc != value.toFloat())
			{	
				sensor_ISOUSC->publish_state(value.toFloat());
				isousc = value.toFloat();
			}
		}
		else if (etiquette == "IINST")
		{
			if (iinst != value.toFloat())
			{
				sensor_IINST->publish_state(value.toFloat());
				iinst = value.toFloat();
			}
		}
		else if (etiquette == "PAPP")
		{
			if (papp != value.toFloat())
			{
				sensor_PAPP->publish_state(value.toFloat());
				papp = value.toFloat();
			}
		}
	}

Bonjour

Très sympa ce sujet, même si je suis dépassé pour la plupart du temps

pour répondre @Sylvain_G
j’ai le même problème avec le système mise en place via MQTT.

effectivement j’avais des trames qui passent a zéro et du coup mes utility meters partaient en vrille

je me suis un peu tiré les cheveux afin de filtrer tout cela via node red ( d’ailleurs c’est pour le moment le seul flow mis en place chez moi.
Désolé de la piètre qualité de ce flow, mais je ne parle par couramment le JSON et encore moins le Java.

[
    {
        "id": "1eb4d24d.5cb37e",
        "type": "tab",
        "label": "TELEINFO",
        "disabled": false,
        "info": ""
    },
    {
        "id": "5ac9bead.08f838",
        "type": "mqtt in",
        "z": "1eb4d24d.5cb37e",
        "name": "HCHP",
        "topic": "WTeleinfo/021861321451/HCHP",
        "qos": "2",
        "datatype": "auto",
        "broker": "1eb4fa04.85f54e",
        "x": 130,
        "y": 180,
        "wires": [
            [
                "b7e01771.e1b508",
                "a3cdb829.7a74f8"
            ]
        ]
    },
    {
        "id": "383e5703.1ad87",
        "type": "mqtt in",
        "z": "1eb4d24d.5cb37e",
        "name": "HCHC",
        "topic": "WTeleinfo/021861321451/HCHC",
        "qos": "2",
        "datatype": "auto",
        "broker": "1eb4fa04.85f54e",
        "x": 130,
        "y": 40,
        "wires": [
            [
                "3553eab9.e73a56",
                "b336ecff.f28a78"
            ]
        ]
    },
    {
        "id": "b64063ca.5aa91",
        "type": "mqtt in",
        "z": "1eb4d24d.5cb37e",
        "name": "IINST",
        "topic": "WTeleinfo/021861321451/IINST",
        "qos": "2",
        "datatype": "auto",
        "broker": "1eb4fa04.85f54e",
        "x": 130,
        "y": 420,
        "wires": [
            [
                "2ca1f1f6.3f3866",
                "13f52c2a.33f8b4"
            ]
        ]
    },
    {
        "id": "d683f5f.3752708",
        "type": "mqtt in",
        "z": "1eb4d24d.5cb37e",
        "name": "IIMAX",
        "topic": "WTeleinfo/021861321451/IIMAX",
        "qos": "2",
        "datatype": "auto",
        "broker": "1eb4fa04.85f54e",
        "x": 130,
        "y": 559,
        "wires": [
            [
                "caf7fb67.94051"
            ]
        ]
    },
    {
        "id": "7d66d9a4.dc9778",
        "type": "mqtt in",
        "z": "1eb4d24d.5cb37e",
        "name": "PAPP",
        "topic": "WTeleinfo/021861321451/PAPP",
        "qos": "2",
        "datatype": "auto",
        "broker": "1eb4fa04.85f54e",
        "x": 130,
        "y": 660,
        "wires": [
            [
                "ba129802.4f52b8"
            ]
        ]
    },
    {
        "id": "df7ee000.2c894",
        "type": "mqtt in",
        "z": "1eb4d24d.5cb37e",
        "name": "PTEC",
        "topic": "WTeleinfo/021861321451/PTEC",
        "qos": "2",
        "datatype": "auto",
        "broker": "1eb4fa04.85f54e",
        "x": 130,
        "y": 320,
        "wires": [
            [
                "f48366c9.e175c8"
            ]
        ]
    },
    {
        "id": "3553eab9.e73a56",
        "type": "function",
        "z": "1eb4d24d.5cb37e",
        "name": "HCHC",
        "func": "msg.payload = Number(msg.payload)/1000; return msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 350,
        "y": 80,
        "wires": [
            [
                "f065bec8.c1f2b"
            ]
        ]
    },
    {
        "id": "c972c6a3.40361",
        "type": "debug",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 870,
        "y": 40,
        "wires": []
    },
    {
        "id": "b7e01771.e1b508",
        "type": "function",
        "z": "1eb4d24d.5cb37e",
        "name": "HCHP",
        "func": "msg.payload = Number(msg.payload)/1000; return msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 350,
        "y": 220,
        "wires": [
            [
                "cb94715d.3d222"
            ]
        ]
    },
    {
        "id": "1c2f628d.8b1ab5",
        "type": "debug",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 870,
        "y": 180,
        "wires": []
    },
    {
        "id": "2ca1f1f6.3f3866",
        "type": "function",
        "z": "1eb4d24d.5cb37e",
        "name": "IINST",
        "func": "msg.payload = Number(msg.payload); return msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 350,
        "y": 460,
        "wires": [
            [
                "47670f25.5281c",
                "96e11fc4.ece0a8"
            ]
        ]
    },
    {
        "id": "47670f25.5281c",
        "type": "debug",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 590,
        "y": 460,
        "wires": []
    },
    {
        "id": "caf7fb67.94051",
        "type": "function",
        "z": "1eb4d24d.5cb37e",
        "name": "IIMAX",
        "func": "msg.payload = Number(msg.payload); return msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 350,
        "y": 560,
        "wires": [
            [
                "17d79178.6cff27",
                "c998cf92.c55938"
            ]
        ]
    },
    {
        "id": "17d79178.6cff27",
        "type": "debug",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 590,
        "y": 560,
        "wires": []
    },
    {
        "id": "ba129802.4f52b8",
        "type": "function",
        "z": "1eb4d24d.5cb37e",
        "name": "PAPP",
        "func": "msg.payload = Number(msg.payload); return msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 350,
        "y": 660,
        "wires": [
            [
                "d665b12d.4cb228",
                "134cbba5.cde98c"
            ]
        ]
    },
    {
        "id": "d665b12d.4cb228",
        "type": "debug",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 590,
        "y": 660,
        "wires": []
    },
    {
        "id": "fcf9b0ad.ab2ef8",
        "type": "mqtt out",
        "z": "1eb4d24d.5cb37e",
        "name": "teleinfo_HCHC",
        "topic": "teleinfo/HCHC",
        "qos": "2",
        "retain": "true",
        "broker": "1eb4fa04.85f54e",
        "x": 880,
        "y": 80,
        "wires": []
    },
    {
        "id": "53a96bcf.7bf934",
        "type": "mqtt out",
        "z": "1eb4d24d.5cb37e",
        "name": "teleinfo_HCHP",
        "topic": "teleinfo/HCHP",
        "qos": "2",
        "retain": "true",
        "broker": "1eb4fa04.85f54e",
        "x": 880,
        "y": 220,
        "wires": []
    },
    {
        "id": "f3a96a9.9b91218",
        "type": "mqtt out",
        "z": "1eb4d24d.5cb37e",
        "name": "teleinfo_PTEC",
        "topic": "teleinfo/PTEC",
        "qos": "2",
        "retain": "true",
        "broker": "1eb4fa04.85f54e",
        "x": 600,
        "y": 360,
        "wires": []
    },
    {
        "id": "96e11fc4.ece0a8",
        "type": "mqtt out",
        "z": "1eb4d24d.5cb37e",
        "name": "teleinfo_IINST",
        "topic": "teleinfo/IINST",
        "qos": "2",
        "retain": "true",
        "broker": "1eb4fa04.85f54e",
        "x": 600,
        "y": 500,
        "wires": []
    },
    {
        "id": "c998cf92.c55938",
        "type": "mqtt out",
        "z": "1eb4d24d.5cb37e",
        "name": "teleinfo_IIMAX",
        "topic": "teleinfo/IIMAX",
        "qos": "2",
        "retain": "true",
        "broker": "1eb4fa04.85f54e",
        "x": 600,
        "y": 600,
        "wires": []
    },
    {
        "id": "134cbba5.cde98c",
        "type": "mqtt out",
        "z": "1eb4d24d.5cb37e",
        "name": "teleinfo_PAPP",
        "topic": "teleinfo/PAPP",
        "qos": "2",
        "retain": "true",
        "broker": "1eb4fa04.85f54e",
        "x": 600,
        "y": 720,
        "wires": []
    },
    {
        "id": "f2ddf52f.48e44",
        "type": "debug",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 590,
        "y": 320,
        "wires": []
    },
    {
        "id": "f48366c9.e175c8",
        "type": "change",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$substring(payload,0,2)",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 380,
        "y": 320,
        "wires": [
            [
                "f2ddf52f.48e44",
                "f3a96a9.9b91218"
            ]
        ]
    },
    {
        "id": "13f52c2a.33f8b4",
        "type": "debug",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 370,
        "y": 420,
        "wires": []
    },
    {
        "id": "b336ecff.f28a78",
        "type": "debug",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 370,
        "y": 40,
        "wires": []
    },
    {
        "id": "a3cdb829.7a74f8",
        "type": "debug",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 370,
        "y": 180,
        "wires": []
    },
    {
        "id": "f065bec8.c1f2b",
        "type": "function",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "func": "var old_value=context.get('old_value') || 0;\ncurrent_value=msg.payload;\n\nif (current_value > old_value)\n    {\n        msg.payload=current_value;\n        old_value=current_value;\n        context.set('old_value',old_value);\n    }\nelse\n    {\n        msg.payload=old_value\n    }\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 580,
        "y": 80,
        "wires": [
            [
                "c972c6a3.40361",
                "fcf9b0ad.ab2ef8"
            ]
        ]
    },
    {
        "id": "cb94715d.3d222",
        "type": "function",
        "z": "1eb4d24d.5cb37e",
        "name": "",
        "func": "var old_value=context.get('old_value') || 0;\ncurrent_value=msg.payload;\n\nif (current_value > old_value)\n    {\n        msg.payload=current_value;\n        old_value=current_value;\n        context.set('old_value',old_value);\n    }\nelse\n    {\n        msg.payload=old_value\n    }\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 580,
        "y": 220,
        "wires": [
            [
                "1c2f628d.8b1ab5",
                "53a96bcf.7bf934"
            ]
        ]
    },
    {
        "id": "1eb4fa04.85f54e",
        "type": "mqtt-broker",
        "name": "",
        "broker": "192.168.1.8",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "willTopic": "",
        "willQos": "0",
        "willPayload": ""
    }
]

Grosso merdo je stocke dans une variable la dernière valeur des index HP et HC et je la compare avec celle arrivant par MQTT.
Si elle est inferieure je renvoie la précédente.
sinon je rafraichi la variable avec la valeur MQTT et envoie la valeur MQTT .
Voila ma modeste contribution.
Et des que la version via ESPHOME est declarée stable je bascule.

En tout cas BRAVO a tous .

MERCI

jrvrcd

1 « J'aime »

@Schmurtz je viens d’intégrer mon Esp grâce à ton github.
Par contre, dans un tuto que j’avais trouvé, on utilisait la pin Rx (GPIO3) mais toi tu utilises la pin D7 (GPIO13).
Est-ce qu’il y a une incidence si j’utilise le GPIO3 ? J’ai bien modifié le fichier de config bien sûr.
Merci.

@Jcpas, ta question m’intéresse, j’ai fait comme toi. J’ai utilisé le GPIO3 pour le RX et GPIO1 pour le TX (pour des problèmes d’accès au PIN sur ma breadboard.

Avant de créer mon PCB définitif, j’aimerais bien avoir la réponse à ta question :grin:.

@djtef tu veux pas regarder ? Tu connais le sujet et tu as fait une PR sur ESPHome récemment.

J’ai créer un repository Projet de Téléinfo sur ESP32 en C.
Si ça peut vous aider à transcrire mon algo en C qui ce trouve dans le fichier teleinfo.h

Pour un balaise en C, s’y iou plait :pleading_face:

P.S. Voici le futur, probable code de l’ESPHome Téléinfo mais j’ai pas tout compris…

Je conseille de partir du nouveau composant téléinfo qui vient d’être ajouté, plus besoin de custom component. Perso j’ai un esp8266 et ça marche très bien, aucune déconnexion, aucune coupure détectée.
Il faut partir de la branche dev de esphome sur github car ça n’a pas encore été mergé.

Voici ma config :

substitutions:
  name: teleinfo


esphome:
  name: ${name}
  platform: ESP8266
  board: nodemcu

wifi:
  ssid: "<ssid>"
  password: "<password>"
  
  manual_ip:
    static_ip: 192.168.0.60
    gateway: 192.168.0.1
    subnet: 255.255.255.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Teleinfo Fallback Hotspot"
    password: "eCNf9nkQ6Nqv"

captive_portal:

logger:     
  baud_rate: 0   # disable logging via UART, help to avoid numerous crash with ESP_LOGD
  level: INFO   # INFO for less log, put DEBUG to view all the linky's "étiquettes" received  in the logs
  esp8266_store_log_strings_in_flash: False     # recommanded for ESP8266 https://esphome.io/components/sensor/custom.html

# Enable Home Assistant API
api:
  password: "<password>"

ota:
  password: "<password>"
  

# Example configuration entry
uart:
  id: uart_bus
  rx_pin: GPIO13
  # tx_pin: GPIO15
  baud_rate: 1200
  parity: EVEN
  data_bits: 7


switch:
  - platform: restart
    name: "${name} reboot"
    
sensor:
  - platform: uptime
    id: uptime_seconds
    name: "Uptime Sensor"
    update_interval: 60s
    unit_of_measurement: s
    accuracy_decimals: 0
    force_update: false
    icon: mdi:timer
    internal: True  # Hide to HA
    
  - platform: teleinfo
    tags:
     - tag_name: "ADCO"
       sensor:
        name: "Identifiant"
        unit_of_measurement: ""
        icon: mdi:barcode
     - tag_name: "ISOUSC"
       sensor:
        name: "Intensite souscrite"
        unit_of_measurement: "A"
        icon: mdi:flash
     - tag_name: "IMAX"
       sensor:
        name: "Intensite maximale"
        unit_of_measurement: "A"
        icon: mdi:flash
     - tag_name: "HCHC"
       sensor:
        name: "Compteur heures creuses"
        unit_of_measurement: "Wh"
        icon: mdi:flash
     - tag_name: "HCHP"
       sensor:
        name: "Compteur heures pleines"
        unit_of_measurement: "Wh"
        icon: mdi:flash
     - tag_name: "PAPP"
       sensor:
        name: "Puissance apparente"
        unit_of_measurement: "VA"
        icon: mdi:flash
    update_interval: 5s
    historical_mode: true
    
text_sensor:
  - platform: template
    name: ${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() };
      }

A noter que le composant ne retourne pas encore de chaîne de caractères comme « HC » ou « HP » mais ça devrait arriver très bientôt.

Comment fais-tu pour utiliser la branche dev ?

Depuis github, tu télécharges l’archive dev.
Puis tu l’installes :

cd esphome/
script/setup

Ensuite c’est en ligne de commande classique :
Pour créer le fichier teleinfo.yaml
esphome teleinfo.yaml wizard
Pour compiler et télécharger le code dans l’esp :
esphome teleinfo.yaml run

Tant que c’est avec dev on peut pas le télécharger directement depuis Home Assistant, sinon il faudrait aussi installer l’addon dev.

On peut trouver la doc du composant (aussi en dev) ici.

Donc il faut que j’installe ça via SSH sur le RPi qui héberge HA ?

Et le jour de l’arrivée officiel du composant, comment on supprime la version dev de ESPHome pour revenir à la version stable ?

Non non tu installes ça sur ton PC, et tu télécharges en USB la première fois et en OTA les suivantes. Home Assistant le détectera comme d’habitude.

OK, tu me rassures. Je vais installer ça sur un PC Debian car j’ai vu que le setup était prévu pour être lancé depuis un bash. Actuellement, je suis sur un PC Win10, faut que j’aille squatter un autre PC de la maison :wink:.
Je vais tester ça demain, merci d’avance :+1:

Je l’ai fait depuis Windows, ça fonctionne sans problème