Téléinfo via wifi

Bon tout est câblé, modifié, branché mais planté !
L’ESP cause bien car je vois les notifications wifi arriver dans home assistant ( ainsi que dans le log d’ESPHOME) mais pas de décodage .
J’ai suivi avec la méthode du casque et Condo le circuit.
J’entends bien les trames à l’entrée de la prise TIC.
Le niveau est beaucoup plus fort en sortie de l’optocoupleur
Mais rien à l’entrée de l’ESP.
J’en déduit qu’à priori le BS170 est mort .
J’en ai commandé 10 et les attends
Qui a eu le même soucis ou un soucis équivalent ?
Merci d’avance
Phil

Ayant eu des instabilités de l’ESP32, je suis en train de tester avec moins de logs, j’ai ajouté ces paramètres dans le bloc logger :

# Enable logging
logger:
  baud_rate: 0
  level: INFO

Ce qui donne :

substitutions:
  name: teleinfo
  
esphome:
  name: ${name}
  platform: ESP32
  board: nodemcu-32s

wifi:
  networks:
  - ssid: !secret wifi_ssid
    password: !secret wifi_pass

  # Optional manual IP
  manual_ip:
    static_ip: !secret ip_teleinfo
    gateway: !secret ip_gateway
    subnet: !secret ip_subnet

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

web_server:
  port: 80

captive_portal:

# Enable logging
logger:
  baud_rate: 0
  level: INFO

# Enable Home Assistant API
api:
  password: !secret ota_pass

ota:
  password: !secret ota_pass

# ajout du composant uart pour la communication série avec la sortie TIC du compteur
# GPIO3 = Pin Rx sur ESP32-WROOM-32D
uart:
  id: uart_bus
#  tx_pin: GPIO1
  rx_pin: GPIO3
  baud_rate: 1200
  parity: EVEN
  data_bits: 7
  #stop_bits: 1

# déclaration des sensors numérique
# les sensors doivent être déclarés dans l'ordre de la fonction lambda
sensor:
  - platform: wifi_signal
    name: "WiFi Signal Sensor"
    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: 60s
    unit_of_measurement: s
    accuracy_decimals: 0
    force_update: false
    icon: mdi:timer
  - platform: teleinfo
    tags:
     - tag_name: "ADCO"
       sensor:
        name: "ADCO"
        unit_of_measurement: ""
        icon: mdi:eye
     - tag_name: "BASE"
       sensor:
        name: "Index"
        unit_of_measurement: "kWh"
        icon: mdi:home-analytics
        filters:
          - multiply: 0.001
     - tag_name: "BASE"
       sensor:
        name: "Index (Wh)"
        unit_of_measurement: "Wh"
        icon: mdi:home-analytics
     - tag_name: "ISOUSC"
       sensor:
        name: "Intensité souscrite"
        unit_of_measurement: "A"
        icon: mdi:information
     - tag_name: "IMAX"
       sensor:
        name: "Intensité maximale"
        unit_of_measurement: "A"
        icon: mdi:information
     - tag_name: "IINST"
       sensor:
        name: "Intensité"
        unit_of_measurement: "A"
        icon: mdi:power-plug
     - tag_name: "PAPP"
       sensor:
        name: "Puissance"
        unit_of_measurement: "VA"
        icon: mdi:flash
    update_interval: 2s
    historical_mode: true

binary_sensor:
  - platform: status
    name: "Status"

switch:
  - platform: restart
    name: "${name} reboot"

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() };
      }

Pour l’instant, pas de perte de connexion depuis le 12 mai 14:26. Je vous tiens au courant du résultat de mes essais.

hello
tu as aussi devalidé la ligne stop _bits =1
une raison ?

Ah oui, j’avais oublié cette ligne. Dans mes recherches sur l’instabilité, j’ai vu quelqu’un qui avait cette idée donc je l’ai aussi testé.
Avec cette configuration, je n’ai toujours pas eu de plantage depuis le 12 mai à 14h26.

BS170 reçus et remplacé . C’était bien lui qui était cramé .
Tout fonctionne parfaitement.
Merci à Sylvain pour sa carte et son programme
Phil

1 « J'aime »

Bonjour a tous,

tous les exemples de ce fil utilisent le mode historique (historical_mode: true). Cependant, j’aimerais utiliser le mode standard. Cela fournit des données beaucoup plus complètes.

Mais le mode standard ne fonctionne pas correctement pour moi. Je peux facilement recevoir le flux de données du Linky (avec une configuration ESPHome correspondante, voir l’exemple ci-dessous). Les données sont absolument correctes. Ce qui ne fonctionne pas, c’est l’évaluation des données via le composant ESPHome Teleinfo. Tout ce que je vois dans le journal, sont des messages réguliers de la forme:
[17:23:53] [W] [teleinfo: 058]: Internal buffer full

Les entités dans HA sont créées correctement (une pour chaque étiquette / tag que je configure). Mais ils sont tous dans le statut «unknown».

Est-il possible que le composant Teleinfo soit simplement cassé pour le mode Standard?


Voici ma config:

esphome:
  name: mcu_d1_mini_01
  platform: ESP8266
  board: d1_mini

wifi:
  ssid:     !secret fritzbox_wlan_sid
  password: !secret fritzbox_wlan_pwd

# Enable logging
logger:
  level: VERBOSE #makes uart stream available in esphome logstream
  baud_rate: 0 #disable logging over uart

# Enable Home Assistant API
api:
  password: !secret esps_api_pwd

ota:
  password: !secret esps_ota_pwd

uart:
  id: uart_bus
  tx_pin: GPIO1
  rx_pin: GPIO3
  baud_rate: 9600
  parity: EVEN
  data_bits: 7

sensor:
  - platform: teleinfo
    update_interval: 15s
    historical_mode: false
    tags:
      - tag_name: "EAST"
        sensor:
          name: "Index (Wh)"
          unit_of_measurement: "Wh"
          icon: mdi:home-analytics

Et voici un extrait du flux de données (reçu avec une configuration qui reçoit simplement des données série à 9600 baud et les écrit dans le journal):

ADSC	041876......	A
VTIC	02	J
DATE	E210519075608		J
NGTF	      BASE      	<
LTARF	      BASE      	F
EAST	020084915	,
EASF01	020084915	?
EASF02	000000000	#
EASF03	000000000	$
EASF04	000000000	%
EASF05	000000000	&
EASF06	000000000	'
EASF07	000000000	(
EASF08	000000000	)
EASF09	000000000	*
EASF10	000000000	"
EASD01	020084915	=
EASD02	000000000	!
EASD03	000000000	"
EASD04	000000000	#
IRMS1	000	.
IRMS2	001	0
IRMS3	003	3
URMS1	227	E
URMS2	237	G
URMS3	241	C
PREF	30	B
PCOUP	30	\
SINSTS	00883	Y
SINSTS1	00050	<
SINSTS2	00211	<
SINSTS3	00623	D
SMAXSN	E210519065305	05215	<
SMAXSN1	E210519065313	01482	.
SMAXSN2	E210519071212	01734	*
SMAXSN3	E210519065237	02042	.
SMAXSN-1	E210518072525	07184	"
SMAXSN1-1	E210518072423	01597	R
SMAXSN2-1	E210518055139	01704	N
SMAXSN3-1	E210518072528	04003	K
CCASN	E210519073000	00762	C
CCASN-1	E210519070000	01798	(
UMOY1	E210519075000	233	1
UMOY2	E210519075000	231	0
UMOY3	E210519075000	238	8
STGE	003A0001	:
MSG1	PAS DE          MESSAGE         	<
PRM	055156........	3
RELAIS	000	B
NTARF	01	N
NJOURF	00	&
NJOURF+1	00	B
PJOURF+1	00008001 NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTIL

De mon côté cela fonctionne une fois R1 remplacée :slight_smile:

Pour la petite histoire on m’a volé les colis en attente de récupération dans ma boîte aux lettres, dedans il y avait une majorité de composants électroniques, donc soit le voleur a perdu son temps, soit c’est quelqu’un qui a besoin absolument de résistance + Bs170 + LTV 814 etc…
J’ai donc improvisé pour avoir les 1k pour R1 :wink:

J’ai deja remplacé R1 par 1 kOhm.
Vous pouvez voir ma transmission de données correct dans l’exemple en haut.

La réception des données fonctionne-t-elle vraiment pour vous avec historical_mode: false et 9600 baud?

J’ai ouvert un message d’erreur:

https://github.com/esphome/issues/issues/2060

J’ai trouvé la source du problème:

Un Linky triphasé en mode Standard crée 53 étiquettes différentes avec une longueur totale de données de plus de 1300 octets. C’est plus que le MAX_BUF_SIZE réservé de 1024 octets dans le composant « Teleinfo ». D’où les messages de Internal buffer full.

Si on augmente le MAX_BUF_SIZE à 2048, le problème est résolu.

Voici mon PR correspondant:
https://github.com/esphome/esphome/pull/1802

1 « J'aime »

Cool ca m’intéresse ca je vais voir ca. Merci

@Jpsy
en attendant le fix de esphome, tu peux expliquer comment fixer temporairement, stp.

→ Chmod on file teleinfo.h to pass PR checks

Merci

Vous devez créer le dossier suivant:
/config/esphome/custom_components/teleinfo/

Après vous copiez les quatre fichiers de le repo suivant dans le nouveau dossier: https://github.com/esphome/esphome/tree/dev/esphome/components/teleinfo

Enfin, modifiez le fichier teleinfo.h et changez la valeur de MAX_BUF_SIZE de 1024 à 2048.

La prochaine fois que vous compilerez dans ESPHome, le nouveau code sera utilisé automatiquement.

1 « J'aime »

@Jpsy
j’ai appliqué et j’ai bien après compilation dans /config/esphome/mon_esp/src/esphome/components/teleinfo/ le fichier teleinfo.h avec : static const uint16_t MAX_BUF_SIZE = 2048;
Donc le custom fonctionne.
Mais malgré tout aucune valeur de la teleinfo.

J’ai même utilisé ton yaml dans ton incident (1802). Vide aussi…
Pourtant cette config fonctionnait quand le linky etait en historique

Tu confirmes que pour toi cela fonctionne en mode Standard ?
Si tu as une idée …

Oui absolument! J’obtiens toutes les données en mode Standard. Le journal du MCU dans ESPHome affiche également les étiquettes reconnues.

Avez-vous vraiment changé le mode de le Linky?
Ou est-il possible que votre circuit optocoupleur pose des problèmes à 9600 bauds?

Ma première étape a été de vérifier la connexion de données sans le composant Teleinfo. Je l’ai fait avec une configuration ESPHome différente. Cela lit simplement les données ligne par ligne à 9600 bauds et les affiche dans le journal:

esphome:
  name: mcu_d1_mini_01
  platform: ESP8266
  board: d1_mini

  build_path: mcu_d1_mini_01_rs232

  includes:
  - uart_read_line_sensor.h

wifi:
  ssid:     !secret fritzbox_wlan_sid
  password: !secret fritzbox_wlan_pwd

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "D1 mini 01"
    password: !secret esps_fallback_hotspot_pwd

captive_portal:

# Enable logging
logger:
  level: VERBOSE #makes uart stream available in esphome logstream
  baud_rate: 0 #disable logging over uart

# Enable Home Assistant API
api:
  password: !secret esps_api_pwd

ota:
  password: !secret esps_ota_pwd

uart:
  id: uart_bus
  tx_pin: GPIO1
  rx_pin: GPIO3
  #baud_rate: 115200
  baud_rate: 9600
  #baud_rate: 1200
  parity: EVEN
  data_bits: 7

text_sensor:
  - platform: custom
    lambda: |-
      auto my_custom_sensor = new UartReadLineSensor(id(uart_bus));
      App.register_component(my_custom_sensor);
      return {my_custom_sensor};
    text_sensors:
      id: "uart_readline"

De plus, vous devez créer le fichier /config/esphome/uart_read_line_sensor.h:

#include "esphome.h"

class UartReadLineSensor : public Component, public UARTDevice, public TextSensor {
 public:
  UartReadLineSensor(UARTComponent *parent) : UARTDevice(parent) {}

  void setup() override {
    // nothing to do here
  }

  int readline(int readch, char *buffer, int len)
  {
    static int pos = 0;
    int rpos;

    if (readch > 0) {
      switch (readch) {
        case '\n': // Ignore new-lines
          break;
        case '\r': // Return on CR
          rpos = pos;
          pos = 0;  // Reset position index ready for next time
          return rpos;
        default:
          if (pos < len-1) {
            buffer[pos++] = readch;
            buffer[pos] = 0;
          }
      }
    }
    // No end of line has been found, so return -1.
    return -1;
  }

  void loop() override {
    const int max_line_length = 80;
    static char buffer[max_line_length];
    while (available()) {
      if(readline(read(), buffer, max_line_length) > 0) {
        publish_state(buffer);
      }
    }
  }
};

Avec ce programme, j’obtiens les données suivantes dans le journal:

[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'ADSC	0418.........	A'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'VTIC	02	J'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'DATE	E210520033243		7'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'NGTF	      BASE      	<'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'LTARF	      BASE      	F'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EAST	020102629	%'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASF01	020102629	8'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASF02	000000000	#'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASF03	000000000	$'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASF04	000000000	%'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASF05	000000000	&'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASF06	000000000	''
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASF07	000000000	('
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASF08	000000000	)'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASF09	000000000	*'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASF10	000000000	"'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASD01	020102629	6'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASD02	000000000	!'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASD03	000000000	"'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'EASD04	000000000	#'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'IRMS1	000	.'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'IRMS2	001	0'
[03:32:40][D][text_sensor:015]: 'uart_readline': Sending state 'IRMS3	002	2'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'URMS1	237	F'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'URMS2	233	C'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'URMS3	239	J'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'PREF	30	B'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'PCOUP	30	\'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SINSTS	00639	X'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SINSTS1	00063	@'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SINSTS2	00156	D'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SINSTS3	00420	?'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SMAXSN	E210520003340	05013	''
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SMAXSN1	E210520003338	01549	)'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SMAXSN2	E210520003338	01672	''
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SMAXSN3	E210520030914	02638	+'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SMAXSN-1	E210519084029	05225	_'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SMAXSN1-1	E210519065313	01482	L'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SMAXSN2-1	E210519071212	01734	H'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'SMAXSN3-1	E210519194707	02972	]'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'CCASN	E210520033000	01716	7'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'CCASN-1	E210520030000	00434	N'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'UMOY1	E210520033000	234	$'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'UMOY2	E210520033000	231	"'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'UMOY3	E210520033000	243	&'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'STGE	003A0001	:'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'MSG1	PAS DE          MESSAGE         	<'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'PRM	055156........	3'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'RELAIS	000	B'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'NTARF	01	N'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'NJOURF	00	&'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'NJOURF+1	00	B'
[03:32:41][D][text_sensor:015]: 'uart_readline': Sending state 'PJOURF+1	00008001 NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTIL'

Oh, et avez-vous changé les noms des étiquettes? Le mode standard utilise des étiquettes différentes du mode historique!

Si ce deuxième PR est accepté, nous aurons également un schéma de circuit dans la documentation ESPHome Teleinfo: Teleinfo: fix tag_name and add circuit example by Jpsy · Pull Request #1185 · esphome/esphome-docs · GitHub

Dans ce PR, j’ai également corrigé la propriété actuellement incorrecte tagtag_name.

@Jpsy
Oui les etiquettes etaient changées pour le mode standard
Tout fonctionne et avec ton debug code et avec mon fichier yaml et surtout ton conseil pour le fix temporaire en attendant la correction officielle esphome teleinfo.
Je pense maintenant que c’etait un probleme de fils et de cables, vu qu j’ai du toucher pour remettre un wemos.Je ne suis pas bon en soudure…

Merci de tes conseils et pour declarer le pb esphome.
Pierre

1 « J'aime »

Hello Sylvain.
D’après ton code, je devrais avoir une mesure toutes les 2 secondes (update_interval: 2s).
Hors je vous dans la base InfluxDB qu’il y a une valeur par seconde .
A quoi sert cette valeur de 2 secondes ?

Je souhaite utiliser ces valeurs pour calculer des W.h sous grafana.
J’ai tenté la fonction integral mais elle ne donne rien de cohérent.
Comment fais tu ?
Merci d’avance
Phil

J’ai créé un nouveau PR pour adresser d’autres problèmes essentielles du mode standard de Linky:
https://github.com/esphome/esphome/pull/1829

Avec ce PR, il est désormais possible de lire des étiquettes contenant un horodatage. Ces étiquettes n’ont renvoyé que 0 jusqu’à présent. Il est également possible de lire l’horodatage soi-même dans un capteur. Cela peut être utilisé, par exemple, pour lire l’heure de la charge la plus élevée en étiquette SMAXSN.

Pour installer le PR directement:

La nouvelle documentation se trouve ici: https://deploy-preview-1197–esphome.netlify.app

De mon avis avec ça il ne manque qu’une seule fonction à réaliser pour le mode standard:
Lire des messages et des informations textuelles avec des capteurs de type Text Sensor. Peut-être je vais addresser ça plus tard.