Contents
- 1 Intro
- 2 Mises à jour
- 3 Pré requis
- 4 Choix du matériel
- 5 Descriptif fonctionnel
- 6 Automatismes
- 7 Blueprint Notification défaut communication:
- 8 Lovelace
- 9 Conclusion
- 10 Publication en lien avec cet article:
Intro
Dans un article précédent https://domo.rem81.com/ha-teleinformation-linky-mode-historique/ , je décrivais la mis en oeuvre d’une communication entre un Linky et Home Assistant en mode Historique.
Après avoir fonctionné un temps en mode « Historique », je suis passé au mode « Standard ». Celui ci offre un plus grand nombre de données.
Raccordement de la télé information de mon compteur Linky. Rien de bien méchant il suffit de se raccorder aux bornes i1/i2 du linky, le plus délicat fut le passage du câble de 60 ml entre le compteur Linky et mon tableau électrique.
Mises à jour
du 23/11/2023:
Ajout d’une version EDF « Tempo »
du 16/08/2022
Ajout du « filter out » dans les HP,HC permettant de rejeter les valeurs nulles si besoin.
du 12/04/2022
Suite à passage Home Assistant 2022.4.0, modification du changement de tarif des utility meter https://www.home-assistant.io/integrations/utility_meter
Pré requis
Mes fichiers « .yaml » sont regroupés dans un dossier « config/packages ». J’utilise la directive « !include_dir_named packages » dans mon « configuration.yaml » très pratique pour organiser son HA.
homeassistant:
name: Crochon
latitude: !secret latitude
longitude: !secret longitude
unit_system: metric
packages: !include_dir_named packages
external_url: !secret external-url
internal_url: !secret internal-url
Choix du matériel
Les informations transmises par le Linky ne sont pas directement exploitables par un ESP, elles nécessitent un adaptateur, vous trouverez beaucoup de modèles sur le Net, perso j’ai choisi la facilité en achetant un module Wemos Teleinfo.
C’est un module pas très cher, correctement étudié et bien fini, compatible avec les esp8266 et ESP32 Mini, qui dispose également d’une Led WS2812 RGB programmable, d’un connecteur I2C disponible pour un afficheur OLED ou autres capteurs compatibles, et d’une led indiquant l’état de la connexion avec le Linky qui se raccorde sur le bornier vert.
Perso j’utilise un L’ESP32 Mini, en effet l’ESP8266 est trop juste en puissance de calcul si on utilise l’intégration ESPHOME plus un afficheur, j’ai galéré avec, je ne le recommande pas, le constructeur du wemos téléinfo non plus d’ailleurs.
L’ESP32 Mini est un ESP32 au format ESP8266 D1, pratique si l’on souhaite utiliser des cartes d’extension, mais avec une puissance de calcul et de traitement bien supérieure.
Descriptif fonctionnel
Les compteurs Linky disposent de 2 modes de téléinformation :
• Le mode Historique, qui correspond à l’ancien mode des compteurs électroniques.
• Le mode Standard, qui est le nouveau format et qui comporte plus d’informations.
Vous trouverez les informations détaillées dans le document Enedis suivant:
Le module WEMOS Teleinfo est compatible, le changement de mode passe obligatoirement par une demande auprès de votre fournisseur d’énergie qui relaye vers Enedis.
Concernant l’intégration dans HA, pas de problème particulier grâce à « teleinfo » disponible sur ESP Home, il est compatible avec les deux modes, les différences étant dans la vitesse de transmission et la validation du mode historique ou pas:
Mode Historique
Mode Standard
Informations collectées
J’utilise le W et non le VA pour l’entité « SINSTS » afin d’exploiter les « Statistiques Longues Durée » qui ne reconnait pas les « Volt Ampéres ». Pour mémoire, en monophasé P en W= P en VA multiplie cos phi, mais come le Linky ne remonte pas le cos phi on se contentera d’un cos phi de 1, les puristes ne m’en voudront pas.
Je divise par 1000 le total de l’énergie active soutirée « EAST » pour obtenir des kWh. C’est cette entité que j’utilise dans les « utility meter » de HA pour calculer mes consommations journalière, semaine, mois, année.
Je calcul en % dans un « template » « Linky P/Pcoup » le ratio entre la puissance instantanée « SINST » et la puissance de coupure « PCOUP », ce qui donne une idée de la réserve de puissance disponible et plus tard, s’en servir pour vérifier si l’abonnement peut être revue à la baisse.
« UMOY1 » nous donne la tension moyenne du secteur.
« IRMS1 » nous donne l’intensité efficace de la phase 1.
« NTARF » nous indique si le tarif est en heure creuse (=1) ou heure pleine (=2), variable utilisée dans l’automatisme de comptabilisation de l’énergie avec les « utility_meter ». J’en profite pour afficher en clair dans un « template », le tarif en cours.
Je remonte la consommation journalière depuis HA vers l’ESP afin de l’afficher en local.
Tableau des informations disponibles
Certaines sont dispo uniquement en tri-phasé et/ou en tant que producteur d’énergie.
Code ESP
Si vous avez des difficultés de flashage avec ESPHome, parcourez mon article https://domo.rem81.com/home-assistant_esp-home/ cela devrait vous aider.
L’afficheur utilise une police de caractère « Arial », vous pouvez télécharger le fichier arial.ttf ici puis le transférer dans un dossier « fonts » de votre « /config/esphome ». Bien entendu vous pouvez utiliser une autre police de caractères, « size » détermine la taille des caractères.
Version « Tempo »
les filtres « filter_out: 0.0 » sont à mettre en action si et seulement si les index sont supérieurs à 0 sinon vous afficherez « indisponible ».
Le filtre « Lambda » permet d’éviter des incohérences dans l’évolution des index, il m’est arrivé de lire des valeurs très faibles mais supérieure à 0 pour des raisons que j’ignore.
L’écart se regle dans la variable « globals » ecart_max.
substitutions:
device_name: esp124-tic
adress_ip: "192.168.0.124"
friendly_name: esp124
time_timezone: "Europe/Paris"
esphome:
name: ${device_name}
platform: ESP32
board: mhetesp32minikit
project:
name: "rem81.esp124-TIC"
version: "1.0.1"
platformio_options:
lib_deps: NeoPixelBus@2.6.0
on_boot:
then:
- light.control:
id: led1
brightness: 0.25
state: on
wifi:
networks:
- ssid: !secret wifi_esp
password: !secret mdpwifi_esp
priority: 1
- ssid: !secret wifi
password: !secret mdpwifi
priority: 0
reboot_timeout: 5min
manual_ip:
static_ip: ${adress_ip}
gateway: 192.168.0.254
subnet: 255.255.255.0
# Enable logging
logger:
# baud_rate: 0
# Enable Home Assistant API
api:
ota:
web_server:
port: 80
font:
- file: "fonts/arial.ttf"
id: arial
size: 15
i2c:
sda: GPIO21 #D2=pin 19
scl: GPIO22 #D1=pin 20
scan: True
id: bus_a
#
uart:
id: uart_a
rx_pin: GPIO23
# tx_pin: GPIO1
baud_rate: 9600
parity: EVEN
data_bits: 7
teleinfo:
id: myteleinfo
uart_id: uart_a
update_interval: 10s
historical_mode: false
# Led WS2812 RGB
light:
- platform: partition
name: led1
id: led1
default_transition_length: 0s
segments:
- id: rgb_led
from: 0
to: 0
- platform: neopixelbus
num_leds: 1
pin: GPIO18
name: "RGB strip"
variant: ws2812
id: rgb_led
default_transition_length: 0s
globals:
# Ecart maximum admissible entre deux lectures
- id: ecart_max
type: float
restore_value: no
initial_value: '50'
sensor:
# Energie Active soutirée totale
- platform: teleinfo
id: hc_hp
tag_name: "EAST"
name: "Linky HPHC KWH"
unit_of_measurement: "kWh"
icon: mdi:flash
teleinfo_id: myteleinfo
device_class: "energy"
state_class: "total_increasing"
filters:
- filter_out: 0.0
- lambda: |-
return x/1000;
- lambda: |-
float MAX_DIFFERENCE = id(ecart_max); // Difference max entre de lecture, à ajuster selon votre cas de figure.
static float last_value = NAN;
if (isnan(last_value) || std::abs(x - last_value) < MAX_DIFFERENCE)
return last_value = x;
else
return {};
# Energie Active soutirée Index01 HC Bleu
- platform: teleinfo
id: hcbleu
tag_name: "EASF01"
name: "Linky HC Bleu kWh"
unit_of_measurement: "kWh"
icon: mdi:flash
teleinfo_id: myteleinfo
device_class: "energy"
state_class: "total_increasing"
filters:
- lambda: return x / 1000;
- filter_out: 0.0
- lambda: |-
float MAX_DIFFERENCE = id(ecart_max); // Difference max entre de lecture, à ajuster selon votre cas de figure.
static float last_value = NAN;
if (isnan(last_value) || std::abs(x - last_value) < MAX_DIFFERENCE)
return last_value = x;
else
return {};
# Energie Active soutirée Index02 HP Bleu
- platform: teleinfo
id: hpbleu
tag_name: "EASF02"
name: "Linky HP Bleu kWh"
unit_of_measurement: "kWh"
icon: mdi:flash
teleinfo_id: myteleinfo
device_class: "energy"
state_class: "total_increasing"
filters:
- lambda: return x / 1000;
- filter_out: 0.0
- lambda: |-
float MAX_DIFFERENCE = id(ecart_max); // Difference max entre de lecture, à ajuster selon votre cas de figure.
static float last_value = NAN;
if (isnan(last_value) || std::abs(x - last_value) < MAX_DIFFERENCE)
return last_value = x;
else
return {};
# Energie Active soutirée Index03 HC Blanc
- platform: teleinfo
id: hcblanc
tag_name: "EASF03"
name: "Linky HC Blanc kWh"
unit_of_measurement: "kWh"
icon: mdi:flash
teleinfo_id: myteleinfo
device_class: "energy"
state_class: "total_increasing"
filters:
- lambda: return x / 1000;
- filter_out: 0.0
- lambda: |-
float MAX_DIFFERENCE = id(ecart_max); // Difference max entre de lecture, à ajuster selon votre cas de figure.
static float last_value = NAN;
if (isnan(last_value) || std::abs(x - last_value) < MAX_DIFFERENCE)
return last_value = x;
else
return {};
# Energie Active soutirée Index04 HP Blanc
- platform: teleinfo
id: hpblanc
tag_name: "EASF04"
name: "Linky HP Blanc kWh"
unit_of_measurement: "kWh"
icon: mdi:flash
teleinfo_id: myteleinfo
device_class: "energy"
state_class: "total_increasing"
filters:
- lambda: return x / 1000;
- filter_out: 0.0
- lambda: |-
float MAX_DIFFERENCE = id(ecart_max); // Difference max entre de lecture, à ajuster selon votre cas de figure.
static float last_value = NAN;
if (isnan(last_value) || std::abs(x - last_value) < MAX_DIFFERENCE)
return last_value = x;
else
return {};
# Energie Active soutirée Index05 HC Rouge
- platform: teleinfo
id: hcrouge
tag_name: "EASF05"
name: "Linky HC Rouge kWh"
unit_of_measurement: "kWh"
icon: mdi:flash
teleinfo_id: myteleinfo
device_class: "energy"
state_class: "total_increasing"
filters:
- multiply: 0.001
- filter_out: 0.0
- lambda: |-
float MAX_DIFFERENCE = id(ecart_max); // Difference max entre de lecture, à ajuster selon votre cas de figure.
static float last_value = NAN;
if (isnan(last_value) || std::abs(x - last_value) < MAX_DIFFERENCE)
return last_value = x;
else
return {};
# Energie Active soutirée Index06 HP Rouge
- platform: teleinfo
id: hprouge
tag_name: "EASF06"
name: "Linky HP Rouge kWh"
unit_of_measurement: "kWh"
icon: mdi:flash
teleinfo_id: myteleinfo
device_class: "energy"
state_class: "total_increasing"
filters:
- lambda: return x / 1000;
- filter_out: 0.0
- lambda: |-
float MAX_DIFFERENCE = id(ecart_max); // Difference max entre de lecture, à ajuster selon votre cas de figure.
static float last_value = NAN;
if (isnan(last_value) || std::abs(x - last_value) < MAX_DIFFERENCE)
return last_value = x;
else
return {};
#Puissance apparente de coupure
- platform: teleinfo
id: pcoup
tag_name: "PCOUP"
name: "Linky PCOUP"
unit_of_measurement: "kVA"
icon: mdi:flash
teleinfo_id: myteleinfo
#Puissance apparente instantanée ph1
- platform: teleinfo
id: papp
tag_name: "SINSTS"
name: "Linky PAPP"
unit_of_measurement: "VA"
device_class: "power"
state_class: "measurement"
icon: mdi:flash
teleinfo_id: myteleinfo
#Tension moyenne ph1
- platform: teleinfo
id: umoy1
tag_name: "UMOY1"
name: "Linky Umoy"
unit_of_measurement: "V"
icon: mdi:flash
teleinfo_id: myteleinfo
#Courant efficace ph1
- platform: teleinfo
id: iinst
tag_name: "IRMS1"
name: "Linky I Inst"
unit_of_measurement: "A"
icon: mdi:flash
teleinfo_id: myteleinfo
# Numero du Tarif en cours
- platform: teleinfo
id: ntarif
tag_name: "NTARF"
name: "linky N Tarif"
unit_of_measurement: ""
icon: mdi:flash
teleinfo_id: myteleinfo
############### TEMPLATE ######################"
# Calcul du ratio de la puissance apparente utilisée en % par rapport au contrat
- platform: template
name: "Linky P/PCoup"
id: p100
icon: mdi:flash
unit_of_measurement: "%"
accuracy_decimals: 0
lambda: |-
return ((id(papp).state/1000)/id(pcoup).state*100);
# Lecture dans HA de la conso du jour
- platform: homeassistant
name: "HCHP J"
unit_of_measurement: "kWh"
entity_id: sensor.compteur_energie_total_jour_tous_tarifs
id: hphcj
#######################################
text_sensor:
# Registre de statuts
- platform: teleinfo
id: stge
tag_name: "STGE"
name: "linky Statuts"
icon: mdi:flash
teleinfo_id: myteleinfo
# nom du calendrier tarifaire
- platform: teleinfo
id: ngtf
tag_name: "NGTF"
name: "linky Nom calendrier tarifaire"
icon: mdi:flash
teleinfo_id: myteleinfo
# Libellé tarif fournisseur en cours
- platform: teleinfo
id: ltarf
tag_name: "LTARF"
name: "linky Libelle tarif fournisseur en cours"
icon: mdi:flash
teleinfo_id: myteleinfo
# Convertion du tarif en cours
- platform: template
id: tarif
name: "Linky PTEC"
lambda: |-
if ( id(ntarif).state == 1 || id(ntarif).state == 3 || id(ntarif).state == 5){
return { "HC.." };
} else {
return { "HP.." };
}
#Etat de la connection
binary_sensor:
- platform: status
name: "${friendly_name} Status"
switch:
- platform: restart
name: "${friendly_name} Restart"
# Affichage
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
address: 0x3C
brightness: 100%
lambda: |-
it.printf(0,0,id(arial),"P=%.0f VA",id(papp).state);
it.printf(75,0,id(arial),"-%.0f %%",id(p100).state);
it.printf(0,15,id(arial),"I Inst=%.0f A",id(iinst).state);
it.printf(0,30,id(arial),"ConsoJ=%.0f kWh",id(hphcj).state);
std::string tarif_ = id(ltarf).state;
it.printf(0,45,id(arial), tarif_.c_str());
## it.printf(0,45,id(arial), "Tarif:%s", tarif_.c_str());
interval:
- interval: 1s
then:
- script.execute: calcul_led_jour
# ------------------------ Scripts
script:
#
# Couleur du Jour en cours
- id: calcul_led_jour
mode: single
then:
- logger.log:
format: "Ltarf= %f"
args: [ 'id(ntarif).state']
- if:
condition:
- lambda: |-
return ( id(ntarif).state == 1 || id(ntarif).state == 2);
then:
- light.control:
id: led1
red: 0%
green: 0%
blue: 100%
- if:
condition:
- lambda: |-
return ( id(ntarif).state == 3 || id(ntarif).state == 4);
then:
- light.control:
id: led1
red: 100%
green: 100%
blue: 100%
- if:
condition:
- lambda: |-
return ( id(ntarif).state == 5 || id(ntarif).state == 6);
then:
- light.control:
id: led1
red: 100%
green: 0%
blue: 0%
Version HC/HP
les filtres « filter_out: 0.0 » sont à mettre en action si et seulement si les index sont supérieurs à 0 sinon vous afficherez « indisponible ».
Le filtre « Lambda » permet d’éviter des incohérences dans l’évolution des index, il m’est arrivé de lire des valeurs très faibles mais supérieure à 0 pour des raisons que j’ignore.
L’écart se regle dans la variable « globals » ecart_max
substitutions:
device_name: esp124-tic
adress_ip: "192.168.0.124"
friendly_name: esp124
time_timezone: "Europe/Paris"
esphome:
name: ${device_name}
platform: ESP32
board: mhetesp32minikit
project:
name: "rem81.esp124-TIC"
version: "1.0.1"
platformio_options:
lib_deps: NeoPixelBus@2.6.0
on_boot:
then:
- light.control:
id: led1
brightness: 0.25
state: on
wifi:
networks:
- ssid: !secret wifi_mi4
password: !secret mdpwifi_mi4
priority: 2
- ssid: !secret wifi_esp
password: !secret mdpwifi_esp
priority: 1
- ssid: !secret wifi
password: !secret mdpwifi
priority: 0
reboot_timeout: 5min
manual_ip:
static_ip: ${adress_ip}
gateway: 192.168.0.254
subnet: 255.255.255.0
# Enable logging
logger:
# baud_rate: 0
# Enable Home Assistant API
api:
ota:
web_server:
port: 80
font:
- file: "fonts/arial.ttf"
id: arial
size: 15
i2c:
sda: GPIO21 #D2=pin 19
scl: GPIO22 #D1=pin 20
scan: True
id: bus_a
#
uart:
id: uart_a
rx_pin: GPIO23
# tx_pin: GPIO1
baud_rate: 9600
parity: EVEN
data_bits: 7
teleinfo:
id: myteleinfo
uart_id: uart_a
update_interval: 10s
historical_mode: false
# Led WS2812 RGB
light:
- platform: partition
name: led1
id: led1
default_transition_length: 0s
segments:
- id: rgb_led
from: 0
to: 0
- platform: neopixelbus
num_leds: 1
pin: GPIO18
name: "RGB strip"
variant: ws2812
id: rgb_led
default_transition_length: 0s
globals:
# Ecart maximum admissible entre deux lectures
- id: ecart_max
type: float
restore_value: no
initial_value: '50'
sensor:
# Energie Active soutirée totale
- platform: teleinfo
id: hc_hp
tag_name: "EAST"
name: "Linky HPHC KWH"
unit_of_measurement: "kWh"
icon: mdi:flash
teleinfo_id: myteleinfo
device_class: "energy"
state_class: "total_increasing"
filters:
- filter_out: 0.0
- lambda: |-
return x/1000;
# Energie Active soutirée Index01
- platform: teleinfo
id: hchc
tag_name: "EASF01"
name: "Linky HC Wh"
unit_of_measurement: "Wh"
icon: mdi:flash
teleinfo_id: myteleinfo
filters:
- filter_out: 0.0
- lambda: |-
float MAX_DIFFERENCE = id(ecart_max); // Difference max entre de lecture, à ajuster selon votre cas de figure.
static float last_value = NAN;
if (isnan(last_value) || std::abs(x - last_value) < MAX_DIFFERENCE)
return last_value = x;
else
return {};
# Energie Active soutirée Index02
- platform: teleinfo
id: hchp
tag_name: "EASF02"
name: "Linky HP Wh"
unit_of_measurement: "Wh"
icon: mdi:flash
teleinfo_id: myteleinfo
filters:
- filter_out: 0.0
- lambda: |-
float MAX_DIFFERENCE = id(ecart_max); // Difference max entre de lecture, à ajuster selon votre cas de figure.
static float last_value = NAN;
if (isnan(last_value) || std::abs(x - last_value) < MAX_DIFFERENCE)
return last_value = x;
else
return {};
#Puissance apparente de coupure
- platform: teleinfo
id: pcoup
tag_name: "PCOUP"
name: "Linky PCOUP"
unit_of_measurement: "kVA"
icon: mdi:flash
teleinfo_id: myteleinfo
#Puissance apparente instantanée ph1
- platform: teleinfo
id: papp
tag_name: "SINSTS"
name: "Linky PAPP"
unit_of_measurement: "VA"
device_class: "power"
state_class: "measurement"
icon: mdi:flash
teleinfo_id: myteleinfo
on_value:
- if:
condition:
sensor.in_range:
id: papp
below: 1000
then:
- light.control:
id: led1
red: 0%
green: 100% # vert
blue: 0%
- if:
condition:
sensor.in_range:
id: papp
above: 1000
below: 3000
then:
- light.control:
id: led1
red: 0%
green: 0% # bleu
blue: 100%
- if:
condition:
sensor.in_range:
id: papp
above: 3000
then:
- light.control:
id: led1
red: 100% #rouge
green: 0%
blue: 0%
#Tension moyenne ph1
- platform: teleinfo
id: umoy1
tag_name: "UMOY1"
name: "Linky Umoy"
unit_of_measurement: "V"
icon: mdi:flash
teleinfo_id: myteleinfo
#Courant efficace ph1
- platform: teleinfo
id: iinst
tag_name: "IRMS1"
name: "Linky I Inst"
unit_of_measurement: "A"
icon: mdi:flash
teleinfo_id: myteleinfo
# Numero du Tarif en cours
- platform: teleinfo
id: ntarif
tag_name: "NTARF"
name: "linky N Tarif"
unit_of_measurement: ""
icon: mdi:flash
teleinfo_id: myteleinfo
############### TEMPLATE ######################"
# Calcul du ratio de la puissance apparente utilisée en % par rapport au contrat
- platform: template
name: "Linky P/PCoup"
id: p100
icon: mdi:flash
unit_of_measurement: "%"
accuracy_decimals: 0
lambda: |-
return ((id(papp).state/1000)/id(pcoup).state*100);
# Lecture dans HA de la conso du jour
- platform: homeassistant
name: "HCHP J"
unit_of_measurement: "kWh"
entity_id: sensor.energie_totale_jour
id: hphcj
# Puissance du signal WIFI
- platform: wifi_signal
id: wif
name: "${friendly_name} WiFi Signal Sensor"
update_interval: 60s
# Temps de fonctionnement de l'ESP
- platform: uptime
id: uptime_seconds
name: "${friendly_name} Uptime"
update_interval: 60s
unit_of_measurement: s
accuracy_decimals: 0
force_update: false
icon: mdi:timer
#######################################
text_sensor:
# Registre de statuts
- platform: teleinfo
id: stge
tag_name: "STGE"
name: "linky Statuts"
icon: mdi:flash
teleinfo_id: myteleinfo
# Convertion du tarif en cours
- platform: template
id: tarif
name: "Linky PTEC"
lambda: |-
if ( id(ntarif).state == 1 ) {
return { "HC.." };
} else {
return { "HP.." };
}
# Affichage du temps de fonctionnement
- platform: template
name: "${friendly_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() };
}
#Etat de la connection
binary_sensor:
- platform: status
name: "${friendly_name} Status"
# Restart de l'ESP
switch:
- platform: restart
name: "${friendly_name} Restart"
# Affichage
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
address: 0x3C
brightness: 100%
lambda: |-
it.printf(0,0,id(arial),"P=%.0f VA",id(papp).state);
it.printf(75,0,id(arial),"-%.0f %%",id(p100).state);
it.printf(0,15,id(arial),"I Inst=%.0f A",id(iinst).state);
it.printf(0,30,id(arial),"ConsoJ=%.0f kWh",id(hphcj).state);
std::string tarif_ = id(tarif).state;
it.printf(0,45,id(arial), "Tarif: %s", tarif_.c_str());
Registre de Statuts
Le registre de statuts « STGE » (uniquement dispo en mode standard) nous donne un état du Linky en général. Il remonte dans un format de huit caractères ascii. Chaque caractères est codés sur 4 bits qui correspondent à une ou plusieurs informations. Le détail est donné au chapitre 6.2.3.14 du document Enedis ci dessous:
J’ai écrit une routine qui décode les caractères du registre de statuts permettent de l’exploiter dans HA via l’Addon AppDaemon.
Celle ci convertit les 8 caractères du registre Statuts de l’ASCII vers du Binaire.
Addon Appdaemon
Cet Addon, pour ceux qui ne connaissent pas, permet d’écrire des programmes en Python très élaborés.
Je décrit son installation dans cet article cet article.
Vous trouverez ci après les fichiers « .yaml » et « .py » à installer dans « votre AppDaemon. »
Code de « linky_status.yaml »
Linky:
class: LinkyStatuts
module: linky_statuts
registre: input_text.linky_test_status
# registre: sensor.linky_statuts
Vous pouvez faire des tests en de-commentant le « registre: input_text.linky_test_status » et en commentant le « registre: input_text.linky_test_status » (il faut un seul « registre » actif à la fois).
Code de « linky_status.py »
import hassapi as hass
# Conversion ASCII vers binaire codé décimal
def repr_bin2(str):
caract = 0
decod=""
for caract in str:
decod += bin(int(caract,16))[2::].zfill(4)
return decod
class LinkyStatuts(hass.Hass):
def initialize(self):
self.listen_state(self.statuts_change, self.args["registre"])
self.log("Initialisation Linky..", log="linky_log")
def statuts_change(self, entity, attribute, old, new, kwargs):
statuts = new
if len(statuts)!=8:
self.log(f"Erreur format registre de statuts= {statuts}", log="linky_log")
else:
self.convertion_status(kwargs)
# Lecture et conversion du registre de statuts du Linky
def convertion_status(self, kwargs):
statuts = self.get_state(self.args["registre"])
statuts_binaire=(repr_bin2(statuts))
# Exploitation des 32 bits du statuts poids forts en tête #
# Bit 0:Contact Sec#
bit_0= statuts_binaire[31]
if bit_0 == "0":
contact_sec = "Ferme"
else:
contact_sec = "Ouvert"
# Bits 1 à 3: Organe de coupure #
bit_1_3= statuts_binaire[28:31]
if bit_1_3 == "000":
organe_de_coupure = "Ferme"
elif bit_1_3 == "001":
organe_de_coupure = "Ouvert sur Surpuissance"
elif bit_1_3 == "010":
organe_de_coupure = "Ouvert sur Surtension"
elif bit_1_3 == "011":
organe_de_coupure = "Ouvert sur Delestage"
elif bit_1_3 == "100":
organe_de_coupure = "Ouvert sur Ordre CPL ou Euridis"
elif bit_1_3 == "101":
organe_de_coupure = "Ouvert sur Surchauffe avec I>Imax"
elif bit_1_3 == "110":
organe_de_coupure = "Ouvert sur Surchauffe avec I<Imax"
else:
organe_de_coupure = "??"
# Bit 4: Etat du cache borne #
bit_4= statuts_binaire[27]
if bit_4 == "0":
cache_borne = "Ferme"
else:
cache_borne = "Ouvert"
# Bit 5: Non utilisé toujours à 0 #
# Bit 6: Surtension sur une des phases #
bit_6= statuts_binaire[25]
if bit_6 == "0":
surtension = "Pas de Surtension"
else:
surtension = "Surtension"
# Bit 7: Dépassement Puissance de Référence #
bit_7= statuts_binaire[24]
if bit_7 == "0":
dep_pref = "Pas de Depassement"
else:
dep_pref = "Depassement en Cours"
# Bit 8: Producteur ou Consommateur #
bit_8= statuts_binaire[23]
if bit_8 == "0":
fonct_prod_conso = "Consommateur"
else:
fonct_prod_conso = "Producteur"
# Bit 9: Sens de L'énergie active #
bit_9= statuts_binaire[22]
if bit_9 == "0":
sens_energie_act = "Energie active positive"
else:
sens_energie_act = "Energie active negative"
# Bits 10 à 13: Tarif en cours contrat fourniture #
bit_10_13= statuts_binaire[18:22]
if bit_10_13 == "0000":
tarif_fourniture = "Energie ventilee sur index 1"
elif bit_10_13 == "0001":
tarif_fourniture = "Energie ventilee sur index 2"
elif bit_10_13 == "0010":
tarif_fourniture = "Energie ventilee sur index 3"
elif bit_10_13 == "0011":
tarif_fourniture = "Energie ventilee sur index 4"
elif bit_10_13 == "0100":
tarif_fourniture = "Energie ventilee sur index 5"
elif bit_10_13 == "0101":
tarif_fourniture = "Energie ventilee sur index 6"
elif bit_10_13 == "0110":
tarif_fourniture = "Energie ventilee sur index 7"
elif bit_10_13 == "0111":
tarif_fourniture = "Energie ventilee sur index 8"
elif bit_10_13 == "1000":
tarif_fourniture = "Energie ventilee sur index 9"
elif bit_10_13 == "1001":
tarif_fourniture = "Energie ventilee sur index 10"
else:
tarif_fourniture = "??"
# Bits 14 à 15: Tarif en cours contrat fourniture #
bit_14_15= statuts_binaire[16:18]
if bit_14_15 == "00":
tarif_distributeur = "Energie ventilee sur index 1"
elif bit_14_15 == "01":
tarif_distributeur = "Energie ventilee sur index 2"
elif bit_14_15 == "10":
tarif_distributeur = "Energie ventilee sur index 3"
elif bit_14_15 == "11":
tarif_distributeur = "Energie ventilee sur index 4"
# Bit 16: Mode dégradé horloge #
bit_16= statuts_binaire[15]
if bit_16 == "0":
mode_horloge = "Horloge correcte"
else:
mode_horloge = "Horloge mode degrade"
# Bit 17: Etat TIC #
bit_17= statuts_binaire[14]
if bit_17 == "0":
etat_tic = "Mode Historique"
else:
etat_tic = "Mode Standard"
# Bit 18: Non utilisé #
# Bits 19 à 20: Etat de la com Euridis #
bit_19_20= statuts_binaire[11:13]
if bit_19_20 == "00":
com_euridis = "Com desactivee"
elif bit_19_20 == "01":
com_euridis = "Com Active sans securite"
elif bit_19_20 == "11":
com_euridis = "Com Active avec securite"
else:
com_euridis = "Com ??"
# Bits 21 à 22: Statut du CPL #
bit_21_22= statuts_binaire[9:11]
if bit_21_22 == "00":
statut_cpl = "New/unlock"
elif bit_21_22 == "01":
statut_cpl = "New/Lock"
elif bit_21_22 == "11":
statut_cpl = "Registered"
else:
statut_cpl = "Com ??"
# Bit 23: Synchro CPL #
bit_23= statuts_binaire[8]
if bit_23 == "0":
synchro_cpl = "Compteur non synchronise"
else:
synchro_cpl = "Compteur synchronise"
# Bits 24_25: Couleur du jour contrat historique Tempo #
bit_24_25= statuts_binaire[6:8]
if bit_24_25 == "00":
couleur_j_tempo = "Contrat non Tempo"
elif bit_24_25 == "01":
couleur_j_tempo = "Bleu"
elif bit_24_25 == "10":
couleur_j_tempo = "Blanc"
elif bit_24_25 == "11":
couleur_j_tempo = "Rouge"
else:
couleur_j_tempo = "Couleur J tempo indefinie"
# Bits 26_27: Couleur du J+1 contrat historique Tempo #
bit_26_27= statuts_binaire[4:6]
if bit_26_27 == "00":
couleur_j1_tempo = "Contrat non Tempo"
elif bit_26_27 == "01":
couleur_j1_tempo = "Bleu"
elif bit_26_27 == "10":
couleur_j1_tempo = "Blanc"
elif bit_26_27 == "11":
couleur_j1_tempo = "Rouge"
else:
couleur_j1_tempo = "Couleur J+1 tempo indefinie"
# Bits 28_29: Préavis Pointes mobiles #
bit_28_29= statuts_binaire[2:4]
if bit_28_29 == "00":
préavis_p_mobiles = "pas de preavis en cours"
elif bit_28_29 == "01":
préavis_p_mobiles = "Preavis PM1 en cours"
elif bit_28_29 == "10":
préavis_p_mobiles = "Preavis PM2 en cours"
elif bit_28_29 == "11":
préavis_p_mobiles = "Preavis PM3 en cours"
else:
préavis_p_mobiles = "Preavis en cours indéfini"
# Bits 30_31: Préavis Pointes mobiles #
bit_30_31= statuts_binaire[2:4]
if bit_30_31 == "00":
pointe_mobile = "Pas de pointe mobile"
elif bit_30_31 == "01":
pointe_mobile = "PM1 en cours"
elif bit_30_31 == "10":
pointe_mobile = "PM2 en cours"
elif bit_30_31 == "11":
pointe_mobile = "PM3 en cours"
else:
pointe_mobile = "Pointe mobile indefinie"
#### Creation et Mise à jour des entités HA ####
# Etat du contact Sec (= 1 = fermé en Heure Creuse) #
if bit_0 == "0":
self.set_state("binary_sensor.linky_contact_sec", state="on", replace=True, attributes= {"icon": "mdi:flash"})
else:
self.set_state("binary_sensor.linky_contact_sec", state="off", replace=True, attributes= {"icon": "mdi:flash"})
# Etat de l'organe de coupure #
self.set_state("sensor.linky_organe_de_coupure", state=organe_de_coupure, replace=True, attributes= {"icon": "mdi:flash"})
# Sens de l'énergie #
if bit_9 == "0":
self.set_state("binary_sensor.linky_sens_energie_active", state="on", replace=True, attributes= {"icon": "mdi:flash"})
else:
self.set_state("binary_sensor.linky_sens_energie_active", state="off", replace=True, attributes= {"icon": "mdi:flash"})
self.set_state("sensor.linky_sens_energie_active", state=sens_energie_act, replace=True, attributes= {"icon": "mdi:flash"})
#### Log de Déboggage
# A commenter ou supprimer si inutile #
self.log(f"Statuts={statuts}", log="linky_log")
self.log(f"Statuts Binaire={statuts_binaire}", log="linky_log")
self.log(f"bit_0={bit_0} / Contact Sec={contact_sec}", log="linky_log")
self.log(f"bit_1_3={bit_1_3} / Organe de coupure={organe_de_coupure}", log="linky_log")
self.log(f"bit_4={bit_4} / Cache_borne={cache_borne}", log="linky_log")
self.log(f"bit_6={bit_6} / Surtension={surtension}", log="linky_log")
self.log(f"bit_7={bit_7} / Depassement Pref={dep_pref}", log="linky_log")
self.log(f"bit_8={bit_8} / Fonctionnement={fonct_prod_conso}", log="linky_log")
self.log(f"bit_9={bit_9} / Sens Energie Active={sens_energie_act}", log="linky_log")
self.log(f"bit_10_13={bit_10_13} / Tarif fourniture={tarif_fourniture}", log="linky_log")
self.log(f"bit_14_15={bit_14_15} / Tarif distributeur={tarif_distributeur}", log="linky_log")
self.log(f"bit_16={bit_16} / Mode degrade horloge={mode_horloge}", log="linky_log")
self.log(f"bit_17={bit_17} / Etat TIC={etat_tic}", log="linky_log")
self.log(f"bit_19_20={bit_19_20} / Com Euridis={com_euridis}", log="linky_log")
self.log(f"bit_21_22={bit_21_22} / Statut CPL={statut_cpl}", log="linky_log")
self.log(f"bit_23={bit_23} / Synchro CPL={synchro_cpl}", log="linky_log")
self.log(f"bit_24_25={bit_24_25} / Couleur Jour tempo={couleur_j_tempo}", log="linky_log")
self.log(f"bit_26_27={bit_26_27} / Couleur J+1 tempo={couleur_j1_tempo}", log="linky_log")
self.log(f"bit_28_29={bit_28_29} / Preavis Pointes Mobiles={préavis_p_mobiles}", log="linky_log")
self.log(f"bit_30_31={bit_30_31} / Pointe Mobile={pointe_mobile}", log="linky_log")
self.log(f"Statuts Linky:{statuts}", log="linky_log")
self.log(f"Statuts Binaire: {statuts_binaire}", log="linky_log")
self.log(f"Sens Energie Active: {sens_energie_act}", log="linky_log")
# self.call_service('notify/telegram', message="Statuts Linky:" + format(statuts))
# self.call_service('notify/telegram', message="Sens Energie Active: " + format(sens_energie_act))
# self.call_service('notify/telegram', message="Tarif Fourniture: " +format(tarif_fourniture))
Dans la rubrique « Mise à jour des entités HA » du code ci-dessus, vous personnalisez les entités que vous souhaitez exploiter. Elles sont crées et mise à jour dans HA. J’en ai quatre dans mon cas.
Les intitulés parlent d’eux-même. Si vous souhaitez en ajouter d’autre, il suffit de les ajouter dans le fichier ci-dessus.
Vous pouvez visualiser vos entités dans HA:
Dans un premier temps, utilisez le mode test et amusez vous, puis basculer sur la lecture du statuts et exploitez les infos via des automatismes ou autres.
Alternative manuelle d’exploitation du statut hors HA
Si vous ne voulez par utilisé « Appdaemon » vous pouvez toujours exploiter vote statut en utilisant le fichier tableur ci- après que j’ai récupéré sur un forum Jeedom (merci à l’auteur dont j’ai perdu le nom!). Je vous le propose en téléchargement, il suffit de saisir votre code du registre.
Affichage local
J’affiche quelques valeurs en local sur un oled SSD1306 128×64, pratique pour une visu rapide à la puissance et l’intensité instantanée, du ratio P/ Pref , la conso du jour.
Je joue également avec la Led WS2812 RGB connectée sur le GPIO18. En fonction de la puissance la led change de couleur:
- Verte de 0 à 1000 VA
- Bleu entre 1000 et 3000 VA
- Rouge si supérieure à 3000 VA
- Les combinaisons sont infinies et facilement programmables.
Codes du fichier linky.yaml Version HC/HP
On y retrouve:
- les « utility meter » qui comptabilisent les energies consommées HC/HP par jour, semaine, mois, année
- Un « input_boolean com_linky » indiquant l’état de la communication avec le Linky = 1 si com ok
- deux « input_number » cout d’un kWh aux HC et HP
- un ‘binary_sensor » HC utilisé dans l’affichage des graphiques de puissance permettant de matérialiser la zone HC
- les « templates » qui cumulent les HC/HP des utility meter et calculent en € les coûts de consommations
- Les entités du registre de statuts
####################################################
# #
# LINKY #
# #
####################################################
utility_meter:
# usage jour
energy_total_usage_daily:
source: sensor.linky_hphc_kwh
cycle: daily
tariffs:
- hp
- hc
# usage semaine
energy_total_usage_weekly:
source: sensor.linky_hphc_kwh
cycle: weekly
tariffs:
- hp
- hc
# usage mois
energy_total_usage_monthly:
source: sensor.linky_hphc_kwh
cycle: monthly
tariffs:
- hp
- hc
#usage an
energy_total_usage_yearly:
source: sensor.linky_hphc_kwh
cycle: yearly
tariffs:
- hp
- hc
##
input_boolean:
com_linky:
name: Comm Linky OK=On
input_number:
# Calcul des coûts journaliers
cout_kwh_hp:
name: Cout du Kwh HP
min: 0
max: 10
unit_of_measurement: €
icon: mdi:currency-eur
step: 0.00001
mode: box
cout_kwh_hc:
name: Cout du Kwh HC
min: 0
max: 10
unit_of_measurement: €
icon: mdi:currency-eur
step: 0.00001
mode: box
input_text:
# Permet de simuler des Statuts pour les tests unitaires
linky_test_status:
name: Test statuts Linky
template:
- binary_sensor:
# Utilisé dans l'affichage des graphiques de puissance permettant de matérialiser la zone HC
# = true si HC
- name: "display_hp_hc"
unique_id: "display_hp_hc"
state: >-
{{ (states.sensor.linky_n_tarif.state == '1') }}" # =1 si HC =2 si H
# Consommation journalière HP + HC - addition des utility meter
- sensor:
- name: "Energie Totale Jour"
unique_id: "energy_total_daily"
state: >-
{% set p = states('sensor.energy_total_usage_daily_hp') | float(default=0) | round(2) %}
{% set o = states('sensor.energy_total_usage_daily_hc') | float(default=0) | round(2) %}
{{ (o + p) | round(2) }}
unit_of_measurement: "kWh"
device_class: "energy"
state_class: "total"
# Consommation semaine HP + HC
- name: "energy_total_weekly"
state: >-
{% set p = states('sensor.energy_total_usage_weekly_hp') | float(default=0) | round(2) %}
{% set o = states('sensor.energy_total_usage_weekly_hc') | float(default=0) | round(2) %}
{{ (o + p) | round(2) }}
unit_of_measurement: "kWh"
device_class: "energy"
state_class: "total"
# Consommation mensuelle HP + HC
- name: "energy_total_monthly"
state: >-
{% set p = states('sensor.energy_total_usage_monthly_hp') | float(default=0) | round(2) %}
{% set o = states('sensor.energy_total_usage_monthly_hc') | float(default=0) | round(2) %}
{{ (o + p) | round(2) }}
unit_of_measurement: "kWh"
device_class: "energy"
state_class: "total"
# Consommation annuelle HP + HC
- name: "energy_total_yearly"
state: >-
{% set p = states('sensor.energy_total_usage_yearly_hp') | float(default=0) | round(2) %}
{% set o = states('sensor.energy_total_usage_yearly_hc') | float(default=0) | round(2) %}
{{ (o + p) | round(2) }}
unit_of_measurement: "kWh"
device_class: "energy"
state_class: "total"
# Cout de l'Energie
# les couts du kWh HP et HC sont calculés dans excel en fonction des factures recues
# et saisis manuellement dans HA
- name: "Cout Energy Total Jour HPHC"
state: >-
{% set hp = states('sensor.energy_total_usage_daily_hp') | float(default=0) | round(2) %}
{% set hc = states('sensor.energy_total_usage_daily_hc') | float(default=0) | round(2) %}
{% set chp = states('input_number.cout_kwh_hp') | float(default=0) | round(5) %}
{% set chc = states('input_number.cout_kwh_hc') | float(default=0) | round(5) %}
{{((hc*chc) + (hp*chp)) | round(2) }}
unit_of_measurement: "€"
device_class: "monetary"
state_class: "total"
unique_id: "cout_energy_total_jour_hphc"
- name: "Cout Energy Total Jour HP"
state: >-
{% set hp = states('sensor.energy_total_usage_daily_hp') | float(default=0) | round(2) %}
{% set chp = states('input_number.cout_kwh_hp') | float(default=0) | round(5) %}
{{(hp*chp) | round(2) }}
unit_of_measurement: "€"
device_class: "monetary"
state_class: "total"
unique_id: "cout_energy_total_jour_hp"
- name: "Cout Energy Total Jour HC"
state: >-
{% set hc = states('sensor.energy_total_usage_daily_hc') | float(default=0) | round(2) %}
{% set chc = states('input_number.cout_kwh_hc') | float(default=0) | round(5) %}
{{(hc*chc) | round(2) }}
unit_of_measurement: "€"
device_class: "monetary"
state_class: "total"
unique_id: "cout_energy_total_jour_hc"
Codes du fichier linky.yaml Version « Tempo »
####################################################
# #
# LINKY #
# #
####################################################
# Sensor à conserver l'historique dans le tableau Energy
# le sensor sensor.linky_hphc_kwh est mis à zero dans tic Linky
# depuis le 3/12/2023
# Date à laquelle le comptage des tarifs tempo a été mis en place
#utility_meter:
# usage jour
# energy_total_usage_daily:
# source: sensor.linky_hphc_kwh
# cycle: daily
# tariffs:
# - hp
# - hc
##
input_boolean:
com_linky:
name: Comm Linky OK=On
input_text:
# Permet de simuler des Statuts pour les tests unitaires
linky_test_status:
name: Test statuts Linky
template:
- binary_sensor:
# Utilisé dans l'affichage des graphiques de puissance permettant de materialiser la zone HC
# = true si HC
- name: "display_hp_hc"
unique_id: "display_hp_hc"
state: >-
{{ states('sensor.linky_ptec')|int(default=0) == "HC.." }} # =on si HC =off si HP
- sensor:
# Template utilisés dans le tableau Energy, ils ont pris le relais des Utility Meter supprimés le 3/11/2023
# Donc NE PAS SUPPRIMER sinon perte de l'historique des consommations
- name: "energy_total_usage_daily_hc"
unique_id: "energy_total_usage_daily_hc"
state: >-
{{ 0 }}
unit_of_measurement: "kWh"
device_class: "energy"
state_class: "total_increasing"
- name: "energy_total_usage_daily_hp"
unique_id: "energy_total_usage_daily_hp"
state: >-
{{ 0 }}
unit_of_measurement: "kWh"
device_class: "energy"
state_class: "total_increasing"
# Calcul du Cout Journalier de l'Energie en fonction du tarif en cours
# Apres passage en Tempo le 3/11/2023
- name: "Cout Energie HC Bleu Jour"
state: >-
{% set en = states('sensor.compteur_energie_hc_bleu_jour') | float(default=0) | round(2) %}
{% set ct = states('input_number.tarif_edf_tempo_bleu_hc') | float(default=0) | round(2) %}
{{(en*ct) | round(2) }}
unit_of_measurement: "€"
device_class: "monetary"
state_class: "total"
unique_id: "cout_energie_hc_bleu_jour"
- name: "Cout Energie HP Bleu Jour"
state: >-
{% set en = states('sensor.compteur_energie_hp_bleu_jour') | float(default=0) | round(2) %}
{% set ct = states('input_number.tarif_edf_tempo_bleu_hp') | float(default=0) | round(2) %}
{{(en*ct) | round(2) }}
unit_of_measurement: "€"
device_class: "monetary"
state_class: "total"
unique_id: "cout_energie_hp_bleu_jour"
- name: "Cout Energie HC Blanc Jour"
state: >-
{% set en = states('sensor.compteur_energie_hc_blanc_jour') | float(default=0) | round(2) %}
{% set ct = states('input_number.tarif_edf_tempo_blanc_hc') | float(default=0) | round(2) %}
{{(en*ct) | round(2) }}
unit_of_measurement: "€"
device_class: "monetary"
state_class: "total"
unique_id: "cout_energie_hc_blanc_jour"
- name: "Cout Energie HP Blanc Jour"
state: >-
{% set en = states('sensor.compteur_energie_hp_blanc_jour') | float(default=0) | round(2) %}
{% set ct = states('input_number.tarif_edf_tempo_blanc_hp') | float(default=0) | round(2) %}
{{(en*ct) | round(2) }}
unit_of_measurement: "€"
device_class: "monetary"
state_class: "total"
unique_id: "cout_energie_hp_blanc_jour"
- name: "Cout Energie HC Rouge Jour"
state: >-
{% set en = states('sensor.compteur_energie_hc_rouge_jour') | float(default=0) | round(2) %}
{% set ct = states('input_number.tarif_edf_tempo_rouge_hc') | float(default=0) | round(2) %}
{{(en*ct) | round(2) }}
unit_of_measurement: "€"
device_class: "monetary"
state_class: "total"
unique_id: "cout_energie_hc_rouge_jour"
- name: "Cout Energie HP Rouge Jour"
state: >-
{% set en = states('sensor.compteur_energie_hp_rouge_jour') | float(default=0) | round(2) %}
{% set ct = states('input_number.tarif_edf_tempo_rouge_hp') | float(default=0) | round(2) %}
{{(en*ct) | round(2) }}
unit_of_measurement: "€"
device_class: "monetary"
state_class: "total"
unique_id: "cout_energie_hp_rouge_jour"
Automatismes
Commutation de HP vers HC et Inversement
Il permet de permuter la tarification des utiliy meter en fonction du tarif récupéré dans le Linky (PTEC)
Code de l’automatisme Simplifié
N’oubliez pas de supprimer les « utility_meter » qui ne vous concerne pas.
alias: 6_1_0 Energie Changement HP<->HC
description: ''
trigger:
- platform: state
entity_id: sensor.linky_n_tarif
id: tarif_hc
from: '2'
to: '1'
- platform: state
entity_id: sensor.linky_n_tarif
from: '1'
id: tarif_hp
to: '2'
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: tarif_hc
sequence:
- service: select.select_option
data:
option: hc
target:
entity_id:
- select.energy_total_usage_daily
- select.energy_total_usage_weekly
- select.energy_total_usage_monthly
- select.energy_total_usage_yearly
- select.energy_pisc_usage_daily
- select.energy_pisc_usage_weekly
- select.energy_pisc_usage_monthly
- select.energy_pisc_usage_yearly
- select.energy_sdb_usage_daily
- select.energy_sdb_usage_weekly
- select.energy_sdb_usage_monthly
- select.energy_sdb_usage_yearly
- select.energy_ecs1_usage_daily
- select.energy_ecs1_usage_weekly
- select.energy_ecs1_usage_monthly
- select.energy_ecs1_usage_yearly
- select.energy_pac1_usage_daily
- select.energy_pac1_usage_weekly
- select.energy_pac1_usage_monthly
- select.energy_pac1_usage_yearly
- select.energy_mal_usage_daily
- select.energy_mal_usage_monthly
- select.energy_mal_usage_weekly
- select.energy_mal_usage_yearly
- select.energy_autres_usage_daily
- select.energy_autres_usage_monthly
- select.energy_autres_usage_weekly
- select.energy_autres_usage_yearly
- select.energy_vmc_usage_daily
- conditions:
- condition: trigger
id: tarif_hp
sequence:
- service: select.select_option
data:
option: hp
target:
entity_id:
- select.energy_total_usage_daily
- select.energy_total_usage_weekly
- select.energy_total_usage_monthly
- select.energy_total_usage_yearly
- select.energy_pisc_usage_daily
- select.energy_pisc_usage_weekly
- select.energy_pisc_usage_monthly
- select.energy_pisc_usage_yearly
- select.energy_sdb_usage_daily
- select.energy_sdb_usage_weekly
- select.energy_sdb_usage_monthly
- select.energy_sdb_usage_yearly
- select.energy_ecs1_usage_daily
- select.energy_ecs1_usage_weekly
- select.energy_ecs1_usage_monthly
- select.energy_ecs1_usage_yearly
- select.energy_pac1_usage_daily
- select.energy_pac1_usage_weekly
- select.energy_pac1_usage_monthly
- select.energy_pac1_usage_yearly
- select.energy_mal_usage_daily
- select.energy_mal_usage_monthly
- select.energy_mal_usage_weekly
- select.energy_mal_usage_yearly
- select.energy_autres_usage_daily
- select.energy_autres_usage_monthly
- select.energy_autres_usage_weekly
- select.energy_autres_usage_yearly
- select.energy_vmc_usage_daily
default: []
mode: single
Automatisme de contrôle de la communication du Linky avec « Automation »
Descriptif fonctionnel
Le but est de surveiller si la communication entre le Linky et HA est établie.
A chaque changement d’état de l’entité « sensor.linky_umoy », l’automatisme est déclenché:
- l' »input_boolean.com_linky » signifiant que la communication entre le linky et HA est OK est forcé sur On
- Un délai d’une heure est déclenché,
- si durant ce délai U_MOY change d’état, l’automatisme est relancé (mode:restart) et « input_boolean.com_linky » reste sur On
- sinon, passé ce délai, l' »input_boolean.com_linky » est forcé sur Off, et la communication est considérée en défaut, il sera remis sur On au prochain changement d’état de PAPP
Je surveillance la puissance PAPP, c’est la valeur plus évolutive, mais il arrive que quelques fois, surtout de nuit que la puissance reste stable pas et déclare donc un défaut fantôme.
Code de l’automatisme avec le module « Automatisation » classique de HA:
Je surveille la tension moyenne car elle varie très souvent contrairement à la puissance ou l’intensité qui peuvent restés stables plus d’une heure la nuit notamment.
- id: '1638118858848'
alias: 2_2_2 Alarme_Notification Time Out Linky
description: ' '
trigger:
- platform: state
entity_id: sensor.linky_umoy
condition: []
action:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.com_linky
- delay:
hours: 1
minutes: 0
seconds: 0
milliseconds: 0
- service: input_boolean.turn_off
target:
entity_id: input_boolean.com_linky
mode: restart
Code de l’automatisme avec le module « AppDaemon »:
Ce module surveille l’évolution de « sensor.linky_umoy » pendant 1 h, si pas de changement on déclare la communication avec le Linky « KO ».
Cet Addon, pour ceux qui ne connaissent pas, permet d’écrire des programmes en Python très élaborés.
Je décrit son installation dans cet article cet article.
Vous trouverez ci après les fichiers « .yaml » et « .py » à installer dans « votre AppDaemon. »
Code de « surveille_activite.yaml »
surveille_com_linky:
module: surveille_activite
class: SurveilleActivite
entite: sensor.linky_umoy #sensor.linky_i_inst # sensor.linky_papp #sensor.linky_umoy #
#entite: input_text.linky_test_status
tempo: 3600 # Tempo de surveillance en secondes
activite_ok: input_boolean.com_linky #switch.test_com_out
Code de « surveille_activite.py »
Les services de notifications sont à adapter à votre configuration.
import hassapi as hass
class SurveilleActivite(hass.Hass):
def initialize(self):
self.listen_state(self.change,self.args["entite"])
nom_entité = self.get_state(self.args["entite"],attribute="entity_id")
duree_tempo=int(self.args["tempo"])
self.turn_on(self.args["activite_ok"])
self.tempo=self.run_in(self.notification, duree_tempo,entité=nom_entité,temps=duree_tempo)
self.log(f'Initialisation de: {nom_entité} pour {duree_tempo}s et {self.tempo}.', log="surveille_log")
def change(self, entity, attribute, old, new, kwargs):
heure = str(self.time())[:8]
duree_tempo=int(self.args["tempo"])
tempo_on = str(entity)
nom_entité = str(entity)
nouvelle_valeur = new
# Mise à on de Com_Ok
self.turn_on(self.args["activite_ok"])
self.log(f'Nouvelle valeur de {entity}: {nouvelle_valeur}-Tempo={duree_tempo}', log="surveille_log")
cle_tempo = self.tempo
if cle_tempo != None:
self.tempo = self.cancel_timer(cle_tempo)
#self.log(f'Info tempo: {self.info_timer(cle_tempo)}', log="surveille_log")
#self.log(f'Fin tempo {cle_tempo}', log="surveille_log")
self.tempo = self.run_in(self.notification, duree_tempo,entité=nom_entité,temps=duree_tempo)
def notification(self, kwargs):
heure = str(self.time())[:8]
nom_entité = kwargs["entité"]
duree_temps= kwargs["temps"]
# Mise à off de Com_Ok
self.turn_off(self.args["activite_ok"])
self.log(f'Alerte! {nom_entité} est out depuis {duree_temps} sec.', log="surveille_log")
message_notification=format(heure)+"Alerte!"+ format(nom_entité)+"est out depuis: "+format(duree_temps)+" sec."
self.call_service('notify/telegram', message_notification)
self.call_service('dwains_dashboard/notification_create', message=message_notification)
Blueprint Notification défaut communication:
J’exploite le défaut avec un blueprint « Nagging Alerting Notification Automation » plus pratique que l’intégration « alert » qui nécessite un redémarrage de HA à chaque modification.
J’utilise également ce blueprint dans d’autres cas de surveillance, portes, température, communication, etc..
Ici aussi, les services de notification sont à adapter à votre configuration.
alias: 2_1_11 Alarme Blueprints Notification Def Com Linky
description: Blue Print
use_blueprint:
path: pavax/nagging_alert_notification.yaml
input:
condition_entity_state: 'on'
sensor_entity: input_boolean.com_linky
alert_state: 'off'
alert_action:
- service: notify.telegram
data:
message: Com Linky off Line{{-"\n"-}}{{states("sensor.date_time") }}
title: Etat Reseau !!!
- service: dwains_dashboard.notification_create
data:
message: Com Linky Off Line {{-"\n"-}}{{states("sensor.date_time") }}
resolved_action:
- service: notify.telegram
data:
message: Com Linky On Line{{-"\n"-}} {{states("sensor.date_time") }}
title: Etat RESEAU!!!
- service: dwains_dashboard.notification_create
data:
message: Com Linky On Line{{-"\n"-}}{{states("sensor.date_time") }}
notify_device: 62cdce054a9d3448484b4df8e44cc499
repeat_delay: 300
initial_delay: 1
max_alerts: 100
resolved_message: Alerte {{ entity_name }} Résolu
notify_message: Alerte {{ entity_name }}Déclenché
Lovelace
Exemple d’affichage des données
Un autre exemple d’affichage utilisant « custom:mini-graph-card » de HACS
type: vertical-stack
cards:
- type: custom:mini-graph-card
entities:
- entity: sensor.energie_totale_jour
name: Conso Linky 7j
hours_to_show: 168
aggregate_func: max
group_by: date
show:
graph: bar
icon: mdi:flash
- type: custom:mini-graph-card
color_thresholds:
- color: '#00FF00'
value: 0
- color: '#FF9900'
value: 4000
- color: '#EA9999'
value: 6000
- color: '#CC0000'
value: 10000
color_thresholds_transition: hard
line_width: 2
icon: mdi:flash
show:
extrema: true
fill: true
icon: true
labels: false
name: true
state: true
hour24: true
points_per_hour: 4
hours_to_show: 24
group: false
state_map:
- label: hp
value: 'off'
- label: hc
value: 'on'
style: |
ha-card {
border: solid 2px var(--primary-color);
}
entities:
- entity: sensor.linky_papp
name: Totale
- color: '#CCC0cCC'
entity: binary_sensor.display_hp_hc
name: HC
show_line: false
y_axis: secondary
name: Puissance Linky 24h
Un autre exemple d’affichage utilisant « custom:apexcharts-card » de HACS
type: custom:apexcharts-card
chart_type: donut
header:
show: true
title: Conso du Jour
show_states: false
colorize_states: true
series:
- entity: sensor.energy_total_usage_daily_hp
name: HP
color: green
- entity: sensor.energy_total_usage_daily_hc
name: HC
color: blue
Affichage du tableau Energie
Affichage dans Grafana
Vous trouverez ci-après le fichier Graphana correspondant.
Salut, je suis actuellement en train de paramétrer la récupération des données linky en utilisant Enedisgateway2mqtt ( https://github.com/m4dm4rtig4n/enedisgateway2mqtt/blob/master/README.md ) ça permet d’éviter d’avoir un tirer un câble et de mettre un module télé info. À voir si le résultat est le même. Qu’en penses-tu ? Avais-tu testé cette possibilité ?
Nico.
Salut, non je n’ai pas essayé mais c’est trop dépendant à mon gout de Enedis et son cloud. Sinon avant ma connection au linky, j’utilisais un ESP avec un PZEM, j’ai écrit un article sur le sujet. https://domo.rem81.com/home-assistant-gestion-piscine-2_mesure-de-puissance-electrique/ , c’est simple et fiable.
@+
Top l’article qu’il me fallait ! Je mis met rapidement 😉. Merci
Merci, n’hésite pas si besoin.
Article vraiment top
Complet et bien écrit
Un lien pour le boîtier avec le couvercle transparent ? Comment fais tu tenir le montage à l’intérieur
Bonjour et merci. le boitier est un Sonoff Ci joint lien Amazon https://www.amazon.fr/Sonoff-IM171017001-Wasserdichtes-Geh-Use/dp/B08XY45JGP/ref=sr_1_36?crid=3EZPIP0OHVV7M&keywords=boitier+sonoff&qid=1644737306&sprefix=boitier+sono%2Caps%2C180&sr=8-36 ou lien Ali https://fr.aliexpress.com/item/1005001526260365.html?spm=a2g0o.productlist.0.0.74ce408filBEBn&algo_pvid=74410f90-4404-4c25-9d06-8b75ea87a0d9&algo_exp_id=74410f90-4404-4c25-9d06-8b75ea87a0d9-0&pdp_ext_f=%7B%22sku_id%22%3A%2212000016469470434%22%7D&pdp_pi=-1%3B4.54%3B-1%3B-1%40salePrice%3BEUR%3Bsearch-mainSearch . J’ai soudé des pattes longues sur l’ESP32 et le tout sur une plaque à souder https://www.amazon.fr/Elegoo-Prototype-Circuit-Imprim%C3%A9-Tailles%EF%BC%BB2X8cm/dp/B073W78G8J/ref=sr_1_5?keywords=plaque+%C3%A0+souder&qid=1644737480&sprefix=plaque+%C3%A0+sou%2Caps%2C108&sr=8-5 elle-même fixée au fond du boitier.En profondeur, c’est pile poil, l’écran est plaqué au couvercle transparent. Bon Courage
Merci au top,
j’avais envoyé un email ya quelques semaine l’adresse marche plus ?
Désolé, mais effectivement le mail ne fonctionne plus, je viens de le mettre à jour.
bonjour, apres avoir testé pleins de solutions dont bcp non fonctionnelles :p , celle ci me semble idéale …
je vais donc tester .
par contre, j ai pas un BASE ni un HP/HC , mais un HP/HC/WE …. je vais essayer de modifier tes scripts et si cela fonctionne, je partagerais 🙂 (mais pas de suite, je fais les choses lentement )
Ok Jérôme, si besoin n’hésites pas à me solliciter, et merci d’avance pour ton retour d’expérience.
Bonjour, Alors, l ESP est en place et me remonte des infos ( il sert aussi pour le gaz et l eau , le gaz ça marche et l eau j ai pas encore recu le capteur inductif )
coté linky, tout ne remonte pas, deja , j ai les entités suivantes vides :
HCHP J = Inconnu
Index Linky kWh = Inconnu
le reste est OK ( j ai un index HP, HC , le pourcentage d utilisation, ect, meme l affichage OLED marche ( saut la conso jour et veille qui affiche NaN )
nous sommes le WE , et donc ej suis pile dans un cas spécial , le ‘linky N tarif = 3 »
mes connaissance en programmation sont limitées, comment modifier ceci pour prendre en compte le « 3 » ? ( il me faudrait juste un truc genre 1=HC, 3=WE sinon HP
# Convertion du tarif en cours
– platform: template
id: tarif
name: « Linky PTEC »
lambda: |-
if ( id(ntarif).state == 1 ) {
return { « HC.. » };
} else {
return { « HP.. » };
}
( en fait je bloque sur la syntaxe )
la page energy ne me permet pas de choisir les entités Linky HC et linky HP , j ai raté une definition quelque part ?
ps : une fois que tout fonctionnera je t enverrais la liste des modifs pour publication et que d autres en profitent 🙂
Bonjour
pour récuperer le troisième index il te faut ajouter dans l’esp apres EAFS02 par ex:
# Energie Active soutirée Index03
– platform: teleinfo
id: we <- Mets ici le nom de l'index souhaitée tag_name: "EASF03" name: "Linky WE Wh" <- Mets ici le nom de l'entité souhaitée unit_of_measurement: "Wh" icon: mdi:flash teleinfo_id: myteleinfo Concernant "Index Linky kWh" c'est fourni par le linky label EAST donc cela doit fonctionné, regarde ta syntax: # Energie Active soutirée totale - platform: teleinfo id: hc_hp tag_name: "EAST" name: "Linky HPHC KWH" unit_of_measurement: "kWh" icon: mdi:flash teleinfo_id: myteleinfo device_class: "energy" state_class: "total_increasing" filters: lambda: |- return x/1000; Concernant HCHP J c'est calculé dans HA dans le linky.yaml Je te réponds dans le commentaire suivant.
je crois qu il me manque aussi le fichier linky.yaml , tu le pose ou , et l apelle comment ?
J’ai ajouté un chapitre « prè requis » expliquant que mes fichiers de configuration « .yaml » sont contenus dans un dossier spécifique « config/packages » et qu’il faut ajouter une ligne « packages: !include_dir_named packages » dans « configuration.yaml » qui indique à HA ou trouver les fichiers de configuration (apres reboot) et donc c’est dans ce dossier qu’il faut déposer le « linky.yaml ». avec cette organisation tu peux mélanger dans un même fichier des « sensors, binary_sensor, template, utility-meter, etc.. »
Regarde dans mon github https://github.com/remycrochon/home-assistant tu comprendra mon organisation.
Une fois fait, tu retrouvera notamment le template « sensor.energie_totale_jour » et appelé dans l’ESP « HPHC J »
Bon courage.
bonjour, alors j ai bien avancé, je recupere bien bcp de choses, mais je rencontre les soucis suivants :
1) pour le graph en donut , je n ai pas sensor.energy_total_linky_usage_daily_hp ( ni hc ) , il est créé a quel moment ?
2 )pour l autre graph , je n’ai pas le sensor.energie_totale_linky_jour pourtant j ai bien dans l ESP :
– platform: homeassistant
name: « HCHP J »
unit_of_measurement: « kWh »
entity_id: sensor.energie_totale_linky_jour
id: hphcj
il y a une raison pour que cela ne remonte pas ?
3) la led verte ne s allume pas , elle est basée sur sensor.linky_index , il ne me semble pas avoir ce sensor …
4) j ai un soucis de sytaxe sur le passage HP/HC pour rajouter le WE
comment je dois ré-écrire ce paragraphe ? ( 3=WE )
# Convertion du tarif en cours
– platform: template
id: tarif
name: « Linky PTEC »
lambda: |-
if ( id(ntarif).state == 1 ) {
return { « HC.. » };
} else {
return { « HP.. » };
}
voila déjà les questions du jour 🙂 merci pour ton aide
Salut
J’ai mis à jour le tuto, notamment les utility-meter du fichier linky.yaml, le donut, le code ESP, veille à mettre en concordance les utility-meter déclarés dans le linky.yaml et utilisés dans l’ESP, l’affichage, l’automatisme, etc.. Une fois fait ça doit fonctionner. C’est peut être pas facile à suivre mais je le fais évolué de mon coté également, pour suivre les modifications tu peux regarder regarde dans les fichiers github qui sont mis à jour quasi en temps réels (une fois le fichier ouvert cliquer sur hytory en haut à droite..)
Pour la Led dans mon code elle est calculée dans:
#Puissance apparente instantanée ph1
– platform: teleinfo
id: papp
tag_name: « SINSTS »
name: « Linky PAPP »
Concernant ta syntaxe essaye ceci:
lambda: |-
if ( id(ntarif).state == 1 ) {
return { « HC.. » };
} else if ( id(ntarif).state == 2 ) {
return { « HP.. » };
else {
return { « WE.. » };
}
Tu peux inspirer du template:
# Affichage du temps de fonctionnement
– platform: template
name: « ${friendly_name} Uptime »
@+
Bonjour Jérome, suite à ta conversation avec Rem81, je n’arrive pas à trouver l’étiquette qui remonte les heures Week-end. Si tu peux m’aider je t’en serai gré.
Merci d’avance et @+
Bonjour ( et merci pour tes réponses )
(il n y a pas le bouton répondre sur ta dernière réponse )
alors pour la led verte, c est le nom du sensor qui n était pas le bon
maintenant que les infos remontent bien,( il me manque les valeurs dans les graphs, peut etre attendre 24h vu que c est des totaux jour ) j ai re modifié les fichier pour prendre en compte le WE , verdict … ce WE pour tester 🙂
si tout est OK je t enverais la liste des modifs, cela pourra toujours aider ceux qui sont en contrat non classique ( ni BASE ni HPHC )
je bloque toujours sur la syntaxe pour le HP/HC/WE ( quand on débute il n y a pas a dire mais le yaml c est chiant :p ) , mais a priori il ne sert que pour l affichage OLED , j ai donc modifié 2=plein tarif sinon tarif réduit … a voir si ca pose des soucis sur d autre scripts.
Jerome
pfui, je cherchais un article de ce type et la quelle claque, super descriptions et explication.
j’ai un module qui ce connecte directement en USB mais je ne trouve rien de bien concluant pour faire l’intégration complete.
je vais surement réfléchir a la solution proposer et voir pour la mettre en place, et je vais aussi regarder les autre article et le github pour avoir de idée 😉
Bonjour et merci pour ton retour. N’hésites pas si besoin.
Rémi,
Vous êtes à un niveau « pro » avec Home Assistant (et pas seulement) , je vous admire : c’est juste impréssionant tout ce que vous faites.
Je suis parti sur une autre solution: une clé Lixee (bien plus chère que la solution que vous avez utilisée), et qui plus est, en utilisant ZHA au lieu de zigbee2mqtt qui marche sans bidouille.
J’ai fait toutes les adaptations pour que le panneau Énergie montre mes infos… et rien.
J’ai compris que la cause est justement mon Linky qui est en mode TIC historique au lieu de standard.
Donc, comment avez-vous réussi à activer le fichu mode Standard du Linky ? Pour moi, jusque-là, c’est une aventure :
1) J’ai appelé Enedis : ils m’ont dit que ça se fait directement sur leur espace client ;
2) Je me suis connecté sur mon espace Enedis, j’ai ajouté mon compteur et j’ai autorisé la collecte de données historiques (vu qu’il n’y a aucune option TIC standard/historique), mais quelques semaines après, mon compteur reste toujours sur mode historique ;
3) Je me connecte sur le site Enedis à nouveau, et il me dit qu’ils ont un ‘problème technique’, pour connecter plus tard ;
4) J’ai appelé EDF : la personne au bout du fil ne savait pas ce qui était mode TIC … après insister, elle me dit que la manip se fait par l’espace-client …
5) Je rentre sur l’espace client, et il n’y a rien de spécifique « TIC Historique/Standard ». J’ai essayé à nouveau – cette fois au site EDF – d’activer les options de suivi à chaque 30 min dans l’espoir que ça m’active le mode standard…
… bref, si vous avez une méthode « coup-sûr » pour changer le TIC en mode standard, je suis preneur ! 🙂
Merci encore une fois.
PS: l’app de contrôle de la piscine marche toujours nickel, inébranlable !
Bonjour, pour le passage en mode standard, il faut faire la dde auprès de ton fournisseur d’énergie. Perso je suis chez Engie, la dde se fait sur son compte internet, assez réactif, ça a dû mettre une semaine. Pour mon fils, chez EDF, ça été plus laborieux, dde par tel, mais plus long à réagir, après de multiples relances par tel, il est passé au mode standard plus d’1 mois après. Bon courage et merci pour tes retours d’expériences. Slts
Bonjour
je fonctionnais en mode historique lorsque je passe en standard j’ai le message suivant:
[11:10:20][W][teleinfo:060]: Internal buffer full
ou faut il modifier la valeur du buffer
Cdlt
Oups désolé cela fonctionne j’avais omis de modifier le UART en mettant 9600 pour le Baud rate en lieu et place de 1200
Bravo Rémi,
J’ai appliqué tes recommandations concernant le mode HISTORIQUE mais étant chez Engie avec un contrat HP-HC-WE, la remontée des HC et HP et WE ne se fait pas. D’où ma décision de passer en mode standard. Demande en cours et en attente de validation…
J’ai parcouru tonexplication qui me paraît très complète et je te tiendrai au courant des résultats.
En core merci.
@ suivre
Paul
Bonjour rémi, l’article est vraiment …. super.
Je démare avec HA, j’ai ajouté mon linky réseau, et un sonoff pow comme appareil individuel.
mais il n’apparait pas comme sur ton graphique, je n’ai que deux ronds « réseau » et « maison ».
Sur ton graphique tu as deux equipements aprés ta maison (58W et 1W)
Bonsoir,
J’utilise la carte testla disponible dans HACS qui affiche des valeurs en temps réel, le 58 w correspond à ma PAC et le 1W à ma piscine. https://github.com/reptilex/tesla-style-solar-power-card
Cdlt
Bonjour,
Ce système est intégré avec succès à mon HA depuis fin 2022. Mais en regardant le panel « Energie », je me rends compte que j’ai parfois des valeurs aberrantes qui plombent mes statistiques (du genre : une valeur de milliers de GigaWatts ! Non, je n’ai pas de centrale nucléaire à la maison ;-)). Il arrive que ces valeurs erronées remontent plusieurs fois dans la même journée. Elle ne concernent que les Heures Creuses ( sensor.electricite_hc), et ce n’est pas lié au changement de tarif (HPHC).
J’ai des difficultés à identifier la cause (bad CRC ? comm réseau ? MAJ ? etc…).
Une idée ?
Bonjour,
Est ce le « sensor » des HC lu dans le Linky (tag_name: « EASF01 ») qui contient ces valeurs incohérentes ou bien c’est le « compteur de service public » journalier qui deconne?
Dans le tableau « energy » tu utilise la valeur lue dans le linky ou bien « le compteur de service public »? Dans le deuxieme cas le passage d’un jour à l’autre dans le module energy et les « compteurs de service public » peux être désynchronisés. Dans le module Energy, Il est préférable de configurer directement les sensor du TIC (en kWh).
Perso j’utilise les deux « compteur de service public » mais je n’ai pas de problème. J’ai eu par le passé des valeurs qui passaient à 0 de temps en temps, j’ai filtré au niveau de l’ESP avec « filter_ou:0.0 ».
Voici quelques pistes de réflexion. Bon courage
Bonjour,
Merci pour ta réponse. J’utilise bien les valeurs lues dans le Linky dans le panneau Energy (sensor.electricite_hc).
J’aurais bien posté une copie d’écran de l’historique sur une journée avec des valeurs incohérentes pour illustrer mais ce n’est pas possible ici.
Il semblerait que ces valeurs soient négatives (un débordement, pb de représentation interne numérique ?). Exemple pris dans l’historique du sensor sur la journée du 30/08 :
30 août 2023 à 00:45:51
Electricité HC:
-2 954 495 Wh
En réalité, les valeurs enregistrées dans l’historique sont de cet ordre de grandeur entre 00:00:00 et 00:45:51, puis passent à des valeurs correctes (+900Wh).
Plus tard, à 09:56:32, une seule valeur incohérente énorme et négative, puis d’autres encore plus tard dans la journée.
C’est vraiment curieux, et seul le sensor HC est concerné. Autre point, j’ai un linky triphasé, mais je ne vois pas ce que cela change…
Bonjour à tous,
Je me permet de « m’incruster » juste pour une question sur un problème que je n’arrive pas à résoudre malgré mes recherches sur le Net ??
A quoi sont dues ces différentes erreur qui me pourissent mes données ?
Si vous avez un conseil et des idées, je suis preneur.
Merci pour vos réponses.
Paul
16:18:04 [E] [teleinfo:038] bad crc: got 52 except 92
16:18:04 [E] [teleinfo:038] bad crc: got 52 except 92
16:18:04 [E] [teleinfo:038] bad crc: got 52 except 38
16:18:04 [E] [teleinfo:038] bad crc: got 52 except 44
16:18:04 [E] [teleinfo:038] bad crc: got 42 except 55
16:18:04 [E] [teleinfo:038] bad crc: got 42 except 89
16:18:04 [E] [teleinfo:038] bad crc: got 34 except 94
16:18:04 [E] [teleinfo:133] No group found
16:18:04 [W] [component:204] Component teleinfo took a long time for an operation (0.12 s).
16:18:04 [W] [component:205] Components should block for at most 20-30ms.
Bonjour, le crc permet de valider la trame reçue, en général les perturbations sont dues à des parasites sur la ligne, quelle longueur fait votre ligne et quelle section de cable utilisez vous?
Est ce que ces erreurs sont systématiques? malgré cela arrivez vous à recueillir des données exploitables?
Slts
Bonjour,
Désolé pour le retard à l’allumage, mais occupé ces derniers temps.
Concernant mon équipement, c’est exactement celui décrit dans cet excellent post.
Le cable utilisé est un JA28 (https://fr.rs-online.com/web/p/cables-audio/3729596)
de 0.22 mm² sur unje longueur de 10-15 mètres environ dans la gaine de la commande J/N qui enclenche le relais des heures creuses. J’ai cherché partout, en tirant un câble différent en « volant » sur la pelouse et le résulat est absolument idem ?????
Après mures réflexions, j’ai pensé que le signal était trop fort et j’ai mis en série avant d’attaquer la carte une résistance de 1.2 Kohms, ce qui m’a permis de résoudre ce problème et ce aujourd’hui (Alléluia…!) Il me reste encore un bad CRC très régulier celui-là qui est certainement dû à une mauvaise requête dans mon code. On progresse.
Pour résumé, avant la remontée des données était d’une trentaine de minutes et les mises à jour étaient très aléatoires. Maintenant c’est INSTANTANE…
J’en profite pour vous remercier de votre excellent article et vous en félicite. Maintent il faut que j’attaque le stockage de ces données ainsi que de beaux graphiques.
Encore bravo et je ne manquerait pas de vous tenir au courant.
Amitiés
Bonjour Rem81, super Tuto qui m’a motivé ,
je me lance pour son intégration dans mon Home Assistant pour un Linky Triphasé mode Tempo.
j’ai déjà le module Wemos Teleinfo avec ESP32C3 mini qui tourne en mode « Standard » donc cela devrait être réalisable 🙂
Eric
Bonjour, oui bien sur sans soucis, il faut lire les variables spécifiques au triphasé, voir le document enedis à ce sujet. piur info j’ai ajouter des ficltres sur les sensors. Bon courage
Merci Rem81, cela tourne maintenant depuis une dizaine de jours avec les infos du triphasé, j’ai un peu transpiré avec vos 2 petits modules appdaemon mais ça tourne maintenant et c’est bien efficace. Je vais décortiquer les utility-meter et le « panneau Energie » pour adapter cela au triphasé et retrouver les variables que vous utilisez. Merci encore pour le tuto.
Ps: les prix de l’Energie en fonction des périodes sont « hard coded », n’est ce pas ? Ces infos ne seraient t’elles pas dispo quelque part dans le cloud?
Bonjour, Novice en domotique je me lance avec HA, et étant producteur avec panneaux solaire et vente du surplus, je souhaite router le surplus sur mon ballon ESC. Je suis en attente du module optocoupleur pour raccorder un ESP32 sur le linky en mode standard. Le but est de récupérer notament l’énergie ou la puissance injectée par les panneaux sur le réseau pour la transferer vers un deuxieme ESP32 et un dimmer 16/24A auprés du chauffe-eau. J’ai bien regardé vos différnt code Yaml mais j’avous je suis perdu dans tout ça. Est-il possible d’avoir de l’aide dans la programmation des ESP32. ?
Merci d’avance pour la réponse
Cordialement
bonjour
bravo pour votre réalisation.
j’ai une question concernant la led ws2812: je ne n’arrive pas a faire allumer en fonction du tarif.
y’a t-il une astuce?
merci pour votre retour
Bonjour, la couleur de la led st calculée dans le script (en de pgm), cela ne fonctionne pas?
Bonjour
Oui le script existe bien en bas du programme la vérification de celui-ci ne donne aucune erreur.
Je vois bien au niveau des logs s’afficher HC bleu, ou autre mais la led (ws2811) reste éteinte
Merci pour votre retour
Bonjour, j’utilise le GPIO18 pour la led, est ce que tu as pu vérifier que ton câblage ou platine correspond à ce GPIO?.