a:6:{s:5:"child";a:1:{s:0:"";a:1:{s:3:"rss";a:1:{i:0;a:6:{s:4:"data";s:3:" ";s:7:"attribs";a:1:{s:0:"";a:1:{s:7:"version";s:3:"2.0";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:1:{s:0:"";a:1:{s:7:"channel";a:1:{i:0;a:6:{s:4:"data";s:49:" ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:3:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:10:"Domo rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:22:"https://domo.rem81.com";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:22:"La domotique pour tous";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:13:"lastBuildDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Wed, 22 Nov 2023 13:28:16 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"language";a:1:{i:0;a:5:{s:4:"data";s:5:"fr-FR";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:9:"generator";a:1:{i:0;a:5:{s:4:"data";s:30:"https://wordpress.org/?v=6.4.3";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"item";a:10:{i:0;a:6:{s:4:"data";s:91:" ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:5:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:27:"PV-Routeur Solaire ESP Home";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:53:"https://domo.rem81.com/2023/07/18/pv-routeur-solaire/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:62:"https://domo.rem81.com/2023/07/18/pv-routeur-solaire/#comments";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:7:"pubDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Tue, 18 Jul 2023 09:15:18 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"category";a:7:{i:0;a:5:{s:4:"data";s:9:"Domotique";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:1;a:5:{s:4:"data";s:14:"Home Assistant";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:2;a:5:{s:4:"data";s:15:"Photovoltaïque";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:3;a:5:{s:4:"data";s:5:"esp32";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:4;a:5:{s:4:"data";s:7:"ESPHOME";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:5;a:5:{s:4:"data";s:2:"HA";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:6;a:5:{s:4:"data";s:10:"routeur pv";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"guid";a:1:{i:0;a:5:{s:4:"data";s:30:"https://domo.rem81.com/?p=2703";s:7:"attribs";a:1:{s:0:"";a:1:{s:11:"isPermaLink";s:5:"false";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:202:"Intro Dans un article précédent, je décrivais une première version de routeur PV monté sur la base d’une mesure de puissance tiers, dans mon cas, délivrée par mon onduleur Victron, … ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:32:"http://purl.org/dc/elements/1.1/";a:1:{s:7:"creator";a:1:{i:0;a:5:{s:4:"data";s:5:"rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:40:"http://purl.org/rss/1.0/modules/content/";a:1:{s:7:"encoded";a:1:{i:0;a:5:{s:4:"data";s:39326:"
Dans un article précédent, je décrivais une première version de routeur PV monté sur la base d’une mesure de puissance tiers, dans mon cas, délivrée par mon onduleur Victron, et un pilotage de Triac via esp8266 délocalisé.
Dans cette version je vous propose un montage développé sous ESP Home donc complètement intégré à HA.
Dans cette version vous aurez besoin à minima:
nota: les liens sont donnés à titre d’exemple, je n’ai aucune relation commerciale avec ces vendeurs





Vous pouvez choisir d’autres modèles, mais il vous faudra modifier le code.

La pince du module JSY est connectée en tête de votre tableau électrique principal en sortie de Linky, il mesure en permanence plusieurs grandeurs électriques, mais les deux qui nous intéressent principalement sont la mesure de puissance et le sens du courant dans la pince. L’ESP interroge en permanence (toutes les 750ms) le module via un port UART sous le protocole Modbus.
Avec ces deux grandeurs, l’ESP calcule le niveau de charge du triac sur une échelle de 0 à 100%.
Par convention , la puissance injectée sur le réseau est négative et la puissance soutirée est positive.
Donc plus la puissance est négative plus on ouvre le triac, on tend vers les 100%. L’algorithme retenu est plutôt simple: S= S+P*Coeff/1000 avec S la sortie triac, P, la puissance mesurée et Coeff un coefficient de réactivité.
A chaque lecture de la puissance la sortie S vers le triac est incrémentée ou décrémentée selon le signe de la puissance mesurée. Le coefficient « Coeff » rend l’algorithme plus ou moins réactif, il faut trouver le compromis pour une plus grande réactivité sans entrer dans un système oscillatoire.
Dans le schéma électronique qui suit vous retrouverez le câblage des différents éléments, vous y trouverez également des éléments non programmés comme le Triac 2 et le relais, c’est en prévision d’extension logicielle.

Si vous souhaitez exploiter pleinement les capacités de votre triac 24A vous devez remplacer le refroidisseur en aluminium d’origine par un refroidisseur plus important.
La modification est clairement expliquez par le prof’solaire dans cette video.
Ce module communique en modbus via un port serie. Il permet de remonter de nombreuses grandeurs physiques électriques via un tore déporté, avec lequel je mesure la puissance soutirée ou injectée sur le réseau, placé directement en sortie Linky, et un tore soudé sur la carte, avec lequel je mesure la puissance soutirée par l’ECS (Ballon Eau Chaude Sanitaire).
Sur chaque Tore, vous pouvez lire, la puissance, l’intensité, la tension, la fréquence, l’énergie.
Vous remarquez que la trame Modbus lit la totalité des grandeurs physiques du JSY (14 registres), cela optimise le temps de lecture en n’envoyant qu’une seule trame Modbus, le fait de supprimer des registres, segmenterai les trames et augmenterai le temps de réponse,cela étant, je n’affiche pas toutes les grandeurs mais libre à vous de les visualiser.
J’interroge le module toutes les 750 ms, ce qui donne une réactivité du système plutôt satisfaisante, en dessous, je rencontre des erreurs de lecture.
Vous trouverez ci après le descriptif des trames modbus du capteur:
Afin que le capteur JSY soit plus réactif, il faut augmenter sa vitesse de communication à 38400 bauds qui par défaut est à 4800 bauds.
La manipulation est très bien décrite sur le site du prof’Solair. Perso, j’ai utilisé le logiciel Windows et ce convertisseur USB<->Port série.
Vous trouverez ci après le code de l’ESP, c’est en service depuis quelques semaines avec des résultats très satisfaisants.
substitutions:
device_name: "esp176-esp32-routeur-1r"
friendly_name: esp176
adress_ip: "192.168.0.176"
time_timezone: "Europe/Paris"
esphome:
name: ${device_name}
platform: ESP32
board: esp32dev
project:
name: "rem81.esp176-esp32-routeur"
version: "1.0.0"
on_boot:
priority: 800
# Force mode auto et tempok au demmarrage
then:
- switch.turn_on: modeauto
- binary_sensor.template.publish:
id: tempok
state: ON
wifi:
networks:
- ssid: !secret wifi
password: !secret mdpwifi
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
level: DEBUG
# logs:
# modbus.component: INFO
# Enable Home Assistant API
api:
ota:
web_server:
port: 80
# Protocole afficheur
i2c:
sda: GPIO21
scl: GPIO22
scan: True
id: bus_a
# Protocole du JSK
uart:
id: mod_bus
tx_pin: 17
rx_pin: 16
baud_rate: 38400
stop_bits: 1
# debug:
# direction: BOTH
# dummy_receiver: false
# after:
# timeout: 150ms
# sequence:
# - lambda: |-
# UARTDebug::log_string(direction, bytes);
modbus:
#flow_control_pin: 5
#send_wait_time: 200ms
id: modbus1
modbus_controller:
- id: jsymk
## the Modbus device addr
address: 0x1
modbus_id: modbus1
update_interval: 0.75s
command_throttle: 50ms
# setup_priority: -10
globals:
- id: increment
type: float
restore_value: no
initial_value: '0'
- id: striac
type: float
restore_value: yes
# Sonde Temperature Dallas
dallas:
- pin: GPIO27 #
update_interval: 60s
# Informations supplementaires sur le WIFI
#text_sensor:
# - platform: wifi_info
# ip_address:
# name: ${friendly_name}_ESP IP Address
# ssid:
# name: ${friendly_name}_ESP Connected SSID
# bssid:
# name: ${friendly_name}_ESP Connected BSSID
# mac_address:
# name: ${friendly_name}_ESP Mac Wifi Address
# scan_results:
# name: ${friendly_name}_ESP Latest Scan Results
binary_sensor:
#Etat de la connection
- platform: status
name: "${friendly_name}_Status"
- platform: template
name: "${friendly_name} Temp Ok"
id: tempok
# Input Number
number:
# Seuil Min/Max sortie triac
- platform: template
name: "${friendly_name} P Max"
id: pmax
optimistic: true
restore_value: true
mode: box
min_value: 50
max_value: 100
unit_of_measurement: "%"
step: 1
- platform: template
name: "${friendly_name} P Min"
id: pmin
optimistic: true
restore_value: true
mode: box
min_value: 0
max_value: 25
unit_of_measurement: "%"
step: 1
# Seuil MAX temperature
- platform: template
name: "${friendly_name} T Max"
id: tmax
optimistic: true
restore_value: true
mode: box
min_value: 0
max_value: 75
unit_of_measurement: "C°"
step: 0.1
# Coeff Réactivité
- platform: template
name: "${friendly_name} Coeff R"
id: coeff_r
optimistic: true
restore_value: true
mode: box
min_value: 0
max_value: 1000
unit_of_measurement: ""
step: 0.1
sensor:
# tension de l'alimentation
- platform: modbus_controller
modbus_controller_id: jsymk
id: Tension
#name: "${friendly_name} Tension JSYMK"
address: 0x0048
unit_of_measurement: "V"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# Intensité traversant le tore
- platform: modbus_controller
modbus_controller_id: jsymk
id: Itore
name: "${friendly_name} I_ECS JSYMK"
address: 0x0049
unit_of_measurement: "A"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# Puissance traversant le tore
- platform: modbus_controller
modbus_controller_id: jsymk
id: puecs
name: "${friendly_name} P_ECS JSYMK"
address: 0x004A
unit_of_measurement: "W"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# Energie lue dans le tore
- platform: modbus_controller
modbus_controller_id: jsymk
id: energietore
name: "${friendly_name} Energie ECS JSYMK"
address: 0x004B
unit_of_measurement: "kWh"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# Energie lue dans le tore
- platform: modbus_controller
modbus_controller_id: jsymk
id: fptore
#name: "${friendly_name} FP Tore JSYMK"
address: 0x004C
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# Energie NEG lue dans le tore
- platform: modbus_controller
modbus_controller_id: jsymk
id: energietoren
name: "${friendly_name} Energie ECS Neg JSYMK"
address: 0x004D
unit_of_measurement: "kWh"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# Sens du courant dans la pince
- platform: modbus_controller
modbus_controller_id: jsymk
id: senspince
#name: "${friendly_name} Sens_Pince JSYMK"
address: 0x004E
register_type: holding
value_type: U_DWORD
bitmask: 0X00010000
filters:
- multiply: 1
register_count: 1
response_size: 4
# Sens du courant dans le tore
- platform: modbus_controller
modbus_controller_id: jsymk
id: senstor
#name: "${friendly_name} Sens_Tore JSYMK"
address: 0x004E
register_type: holding
value_type: U_DWORD
accuracy_decimals: 0
bitmask: 0X01000000
filters:
- multiply: 1
register_count: 1
response_size: 4
# Fréquence de l'alimentation
- platform: modbus_controller
modbus_controller_id: jsymk
id: frequence
#name: "${friendly_name} Frequence JSYMK"
address: 0x004F
unit_of_measurement: "hz"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.01
register_count: 1
response_size: 4
# tension de l'alimentation
- platform: modbus_controller
modbus_controller_id: jsymk
id: Tension2
#name: "${friendly_name} U_Reseau JSYMK"
address: 0x0050
unit_of_measurement: "V"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# Intensité lue dans la pince
- platform: modbus_controller
modbus_controller_id: jsymk
id: Ireseau
#name: "${friendly_name} I_Reseau JSYMK"
address: 0x0051
unit_of_measurement: "A"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# puissance lue dans la pince
- platform: modbus_controller
modbus_controller_id: jsymk
id: pureseau
#name: "${friendly_name} P_Reseau JSYMK"
address: 0x0052
unit_of_measurement: "W"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
on_value:
then:
- lambda: |-
if ( id(senspince).state == 1 ) {
id(pureseau1).publish_state( id(pureseau).state *-1);
} else {
id(pureseau1).publish_state( id(pureseau).state );
}
- lambda: id(afincrement).publish_state( id(increment) );
- script.execute: calcul_injectionv2
- script.execute: etat_production
- lambda: id(afstriac).publish_state( id(striac) );
# Energie lue dans la pince
- platform: modbus_controller
modbus_controller_id: jsymk
id: energiepince
#name: "${friendly_name} Energie Reseau JSYMK"
address: 0x0053
unit_of_measurement: "kWh"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# Energie lue dans le tore
- platform: modbus_controller
modbus_controller_id: jsymk
id: fppince
#name: "${friendly_name} FP Pince JSYMK"
address: 0x0054
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# Energie NEG lue dans le tore
- platform: modbus_controller
modbus_controller_id: jsymk
id: energienegpince
#name: "${friendly_name} Energie ECS Neg JSYMK"
address: 0x0055
unit_of_measurement: "kWh"
register_type: holding
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.0001
register_count: 1
response_size: 4
# Informations WI_FI
- platform: wifi_signal # Affiche le signal WiFi strength/RSSI en dB
name: "${friendly_name} WiFi Signal dB"
id: wifi_signal_db
update_interval: 60s
entity_category: "diagnostic"
- platform: copy # Affiche le signal WiFi strength en %
source_id: wifi_signal_db
name: "${friendly_name} WiFi Signal Percent"
filters:
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
unit_of_measurement: "Signal %"
entity_category: "diagnostic"
############### TEMPLATE ######################"
# Affichage dans HA et sur l'afficheur
- platform: template
name: "${friendly_name} Pu Reseau"
id: pureseau1
unit_of_measurement: "W"
state_class: "measurement"
- platform: template
name: "${friendly_name} Increment"
id: afincrement
unit_of_measurement: ""
accuracy_decimals: 2
state_class: "measurement"
- platform: template
name: "${friendly_name} Sortie Triac"
id: afstriac
unit_of_measurement: "%"
state_class: "measurement"
accuracy_decimals: 2
# Sonde Temperature radiateur
- platform: dallas
address: 0xeb012112e461b128
name: "${friendly_name} Temp triac"
id: temp_triac
filters:
- filter_out: NAN
on_value:
then:
if:
condition:
lambda: 'return id(temp_triac).state < id(tmax).state;'
# Si Temp Triac inferieur au seuil alors OK
then:
- binary_sensor.template.publish:
id: tempok
state: ON
# Sinon attendre 60s avant retour à la normal
else:
- binary_sensor.template.publish:
id: tempok
state: OFF
- delay: 60s
switch:
- platform: gpio
name: "${friendly_name} Relais"
pin: GPIO5
id: relais
- platform: template
name: "${friendly_name} Validation Router"
id: val_router
optimistic: true
restore_mode: RESTORE_INVERTED_DEFAULT_OFF
- platform: template
name: "${friendly_name} Mode Auto"
id: modeauto
optimistic: true
restore_mode: always_on
- platform: restart
name: "${friendly_name} Restart"
output:
#LEDS --------------------------------------
- id: led_conso
platform: gpio
pin: GPIO32
- id: led_injec
platform: gpio
pin: GPIO25
# Pilotage du Dimmer ------------------------
- platform: ac_dimmer
id: ecs
gate_pin: GPIO33
method: leading
zero_cross_pin:
number: GPIO34
mode:
input: true
inverted: yes
min_power: 5%
light:
- platform: monochromatic
name: "${friendly_name}+STriac"
output: ecs
id: gradateur
default_transition_length: 50ms
# Affichage
display:
- platform: lcd_pcf8574
dimensions: 20x4
address: 0x27
update_interval: 2s
lambda: |-
it.printf(0,0,"Pr=%0.0fW",id(pureseau1).state);
it.printf(10,0,"Pe=%0.0fW ",id(puecs).state);
it.printf(0,1,"Tr=%0.1f%%",id(striac));
it.printf(10,1,"Val:%s", id(val_router).state ? "OK" : "NOK");
it.printf(0,2,"Tp=%0.1fc", id(temp_triac).state);
it.printf(10,2,"Etat=%s", id(tempok).state ? "OK" : "NOK");
it.printf(0,3,"Mode=%s", id(modeauto).state ? "Auto" : "Manu");
it.printf(10,3,"Inc=%0.1f ",id(increment));
#interval:
# - interval: 0.5s
# then:
# - script.execute:
# ------------------------ Scripts
script:
#
# ------------------------ Calcul puissance injection V2
- id: calcul_injectionv2
mode: single
then:
- lambda: |-
id(increment) = id(pureseau1).state*id(coeff_r).state/1000*-1;
- lambda: |-
id(striac) = id(striac)+id(increment);
- logger.log:
format: "Log S Triac= %f"
args: [ 'id(striac)']
- lambda: |-
if (id(striac) <= 0){
id(striac) = 0;
} else if(id(striac)>=id(pmax).state){
id(striac) = id(pmax).state;
}
# Si mode routeur validé et mode auto et temp OK alors on active le triac et Sortie Triac superieur au mini
- if:
condition:
and:
- switch.is_on: val_router
- switch.is_on: modeauto
- binary_sensor.is_on: tempok
- lambda: 'return id(striac) >= id(pmin).state;'
then:
- light.turn_on:
id: gradateur
brightness: !lambda |-
return id(striac)/100 ;
# Si mode routeur devalidé ou temp NOK alors on désactive le triac
- if:
condition:
and:
- switch.is_on: modeauto
- or:
- switch.is_off: val_router
- binary_sensor.is_off: tempok
then:
- lambda: |-
id(striac) = 0;
id(increment) = 0;
- light.turn_on:
id: gradateur
brightness: !lambda |-
return id(0) ;
# ------------------------------------------- Pilotage led
- id: etat_production
mode: single
then:
- if:
condition:
sensor.in_range:
id: pureseau1
below: 50
above: -50
then:
- output.turn_on: led_conso
- output.turn_on: led_injec
- if:
condition:
sensor.in_range:
id: pureseau1
above: 50
then:
- output.turn_off: led_injec
- output.turn_on: led_conso
- if:
condition:
sensor.in_range:
id: pureseau1
below: -50
then:
- output.turn_off: led_conso
- output.turn_on: led_injec
Vous pouvez régler:
Vous pouvez piloter:

Vous retrouverez:

La validation du router dépend de votre configuration: Si votre installation solaire ne comporte pas de batteries, vous pouvez vous inspirer de cet article https://domo.rem81.com/2022/11/25/ha-gestion-eau-chaude-sanitaire/. Depuis cet article, mon installation PV a évoluée avec l’ajout de batteries de stockage, depuis leur mise en service je valide le routeur lorsque les batteries sont chargées.Voici le code de cette automatisation pour information:
alias: 01-2-4 ECS Validation Routeur sur Absorption V2
description: float alors routeur ECS Actif
trigger:
- platform: time_pattern
minutes: /1
condition: []
action:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.mp2_status_bus_ve
above: 3
below: 6
enabled: true
- condition: state
entity_id: input_boolean.ecs_av_pv
state: "off"
- condition: numeric_state
entity_id: sensor.mp2_pc_ac_couplet_on_l1
above: 1000
- condition: numeric_state
entity_id: sensor.mp2_niveau_charge_batteries
above: input_number.mp2_seuil_validation_routeur
enabled: false
sequence:
- service: input_boolean.turn_on
data: {}
target:
entity_id: input_boolean.ecs_av_pv
- service: switch.turn_on
data: {}
target:
entity_id:
- switch.esp176_validation_router
- service: notify.telegram
data:
message: >-
Bus VE={{states('sensor.mp2_affichage_status_bus_ve')}}
{{-"\n"-}}SOC={{states('sensor.mp2_niveau_charge_batteries')}}%
{{-"\n"-}}{{states("sensor.date_time") }}
title: Validation Routeur ECS
- conditions:
- condition: not
conditions:
- condition: numeric_state
entity_id: sensor.mp2_status_bus_ve
above: 3
below: 6
enabled: true
- condition: state
entity_id: input_boolean.ecs_av_pv
state: "on"
- condition: numeric_state
entity_id: sensor.mp2_niveau_charge_batteries
below: input_number.mp2_seuil_devalidation_routeur
enabled: false
sequence:
- service: input_boolean.turn_off
data: {}
target:
entity_id: input_boolean.ecs_av_pv
- service: switch.turn_off
data: {}
target:
entity_id:
- switch.esp176_validation_router
- service: notify.telegram
data:
message: >-
Bus VE={{states('sensor.mp2_affichage_status_bus_ve')}}
{{-"\n"-}}SOC={{states('sensor.mp2_niveau_charge_batteries')}}%
{{-"\n"-}}{{states("sensor.date_time") }}
title: De-Validation Routeur ECS
mode: single
trace:
stored_traces: 10
Localement j’affiche:

La courbe ci dessous (extraite de Graphana) illustre l’efficacité et la réactivité du routeur. Ce jour là, à partir de 16:40 l’ECS ne chauffe plus, il a atteint ses 70°C, conclusion: on injecter sur le réseau.

Le graphique suivant illustre les économies réalisées en kWh, les jours à 0 sont dû à un faible ensoleillement, dans mon cas je privilégie la charge des batteries avant de router vers l’ECS.

Bien entendu cette liste est non exhaustive, si vous avez d’autres liens, n’hésiter pas à me les transmettre, je les ajouterai.
Un routeur solaire de plus! Celui ci est complément intégré à Home Assistant, et en plus il coûte pas trop cher. N’hésitez par me faire par de vos remarques.
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:36:"http://wellformedweb.org/CommentAPI/";a:1:{s:10:"commentRss";a:1:{i:0;a:5:{s:4:"data";s:58:"https://domo.rem81.com/2023/07/18/pv-routeur-solaire/feed/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:38:"http://purl.org/rss/1.0/modules/slash/";a:1:{s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:2:"22";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}i:1;a:6:{s:4:"data";s:97:" ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:5:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:18:"HA-Routeur Solaire";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:53:"https://domo.rem81.com/2023/04/14/ha-routeur-solaire/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:62:"https://domo.rem81.com/2023/04/14/ha-routeur-solaire/#comments";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:7:"pubDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Fri, 14 Apr 2023 17:39:07 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"category";a:9:{i:0;a:5:{s:4:"data";s:9:"Domotique";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:1;a:5:{s:4:"data";s:15:"Faire soi-même";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:2;a:5:{s:4:"data";s:14:"Home Assistant";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:3;a:5:{s:4:"data";s:11:"Non classé";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:4;a:5:{s:4:"data";s:15:"Photovoltaïque";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:5;a:5:{s:4:"data";s:5:"esp32";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:6;a:5:{s:4:"data";s:7:"ESP8266";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:7;a:5:{s:4:"data";s:2:"HA";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:8;a:5:{s:4:"data";s:6:"router";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"guid";a:1:{i:0;a:5:{s:4:"data";s:30:"https://domo.rem81.com/?p=2601";s:7:"attribs";a:1:{s:0:"";a:1:{s:11:"isPermaLink";s:5:"false";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:231:"Intro. Dans un article précédent, j’abordais le sujet des routeurs solaires, ces systèmes qui redirige le surplus de production de votre installation photovoltaïque vers généralement un ballon eau chaude sanitaire. … ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:32:"http://purl.org/dc/elements/1.1/";a:1:{s:7:"creator";a:1:{i:0;a:5:{s:4:"data";s:5:"rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:40:"http://purl.org/rss/1.0/modules/content/";a:1:{s:7:"encoded";a:1:{i:0;a:5:{s:4:"data";s:37183:"Dans un article précédent, j’abordais le sujet des routeurs solaires, ces systèmes qui redirige le surplus de production de votre installation photovoltaïque vers généralement un ballon eau chaude sanitaire.
Depuis plusieurs années, j’utilise le modèle P’TIWATT qui remplit parfaitement son role mais qui malheureusement n’offre pas la possibilité d’envoyer des informations de monitoring vers HA par exemple.
Après quelques recherches, j’ai découvert, il y a quelques mois, un routeur à monter soit même chez https://pvrouteur.apper-solaire.org/ , la particularité étant que le routeur, l’élément qui mesure la puissance est séparé du triac, l’élément qui fait varier la puissance aux bornes des résistances du ballon d’ECS, ce que j’avais trouvé sur le coup intéressant. Après quelques essais j’ai été convaincu par la solution mais je suis resté avec mon « P’Titwatt » le temps de la réflexion.
La mise en oeuvre est très bien expliquée dans la documentation. Le flashage initiale des ESP peut se faire depuis une interface WEB ou pour les plus aguerris, vous pouvez personnaliser et télécharger le code avec Visual Studio Code.
Cyril a fait un énorme boulot, il propose les circuits imprimés du routeur et du dimmer à petit prix, par le biais de son association APPER, donnant par la même occasion la possibilité d’en déduire une partie de vos impots.
Vous pouvez « chainer » plusieurs dimmers, soit en parallèle, soit en cascade, quand le premier ballon est chaud, vous basculer vers le second.
La configuration du dimmer se fait depuis une page WEB.

Enfin, la dernière version de son dimmer communique avec HA via MQTT nativement (aucune déclaration .yaml) à écrire dans HA.



Dernièrement, toujours aussi frustré d’avoir un routeur seul dans son coin sans remontée d’information, j’ai ré-ouvert le dossier du « pvrouter » et opté pour une solution mixte.
Mon installation PV est équipée de panneaux PV et de micro onduleur ainsi qu’un onduleur chargeur Victron Multiplus 2, je récupère donc très facilement la puissance injectée ou soutirée sur le réseau en interrogeant cycliquement l’onduleur via le protocole Modbus. Il ne me restait plus qu’a piloter le dimmer en fonction de cette puissance en lui envoyant trame URL « htpp://IP_dimmer/?POWER=xx » avec XX de 0 à 100%.
Pour le dimmer j’utilise un module ESP12F précablé avec alimentation en 220 VCA et un module relais. J’ai décrit ce produit dans un article précédent.


C’est compact et facile à raccorder, cependant il est indispensable de réaffecter les broches définies par défaut dans le code d’origine en les adaptant à la carte. Pour cela il faut modifier le fichier « config.h » avec Visual Studio Code.
Vous trouverez ci après les lignes concernées: les lignes 32 à 40 sont à passer en commentaire et 44 à 49 sont à ajouter.

Ce mapping vous permet de définir facilement le câblage utilisé pour le triac.
Avec cette solution vous avez à câbler 4 fils entre la carte et triac, alimenter la carte (220 Vca, 5V, 12V), intercaler votre triac sur la ligne d’alimentation du ballon. Dans cet article, j’explique mon approche sur le sujet mais rien n’est figé et chacun l’adapte à sa configuration.
Pour le triac j’ai pris celui-ci,

Il existe d’autres modèles plus ou moins performants, Cyril les présente dans sa documentation. Concernant les risques de surchauffe à haute intensité, il est prévu une sortie de commande d’un ventilateur de refroidissement du triac, c’est très bien, mais personnellement je préfère surdimensionner le radiateur et rester avec un refroidissement statique sans risque de panne.


Provisoirement le raccordement entre le triac et la carte ESP est réalisé avec des fils Dupont. Vous remarquerez l’ajout du gros radiateur à ailettes sur le triac et la sonde DS18B20 qui mesure la température du radiateur. A terme, je dois encapsuler le tout dans un boitier.
La mise en oeuvre de la sonde est décrite dans cet article.


Je souhaitais, pour des raisons pratiques implanté l’algorithme dans HA, je me suis tourné vers Node red, ce module complémentaire HA est très pratique, puissant et facile à installer, il existe de nombreux tuto sur le net concernant la programmation Node Red. Je ne suis pas fan, mais le pour le coup, il m’a bien rendu service, de plus, NR est universel et s’installe sur beaucoup de systèmes.

Il est décomposé en 6 Nodes (ou noeuds) principaux:
Et c’est tout, j’ai quand même ajouté un Dahsborad Node Red, histoire de visualiser le résultat et de se donner la possibilité de simuler la sortie ou la puissance réseau.

Pour utiliser le code que je vous propose, il faut installer ces deux palettes complémentaires dans NR:
Vous trouver en annexe le code NR à copier/coller dans « import nodes ».
J’ai fait simple, le principe retenu est le suivant:
| Palier | Pu (W) | Incrément |
| Palier 0 | 0 | 0 |
| Palier 1 | 10 | 1 |
| Palier 2 | 50 | 1 |
| Palier 3 | 100 | 2 |
| Palier 4 | 200 | 3 |
| Palier 5 | 300 | 4 |
| Palier 6 | 600 | 6 |
| Palier 7 | 900 | 7 |

Un des avantages de Node Red est qu’il vous permet de réaliser des tests en temps réels et revenir très facilement en arrière.
J’ai fait quelques tentatives de régulation avec un PID, sans résultat, mais c’est une piste que je compte explorer plus en avant.
A compléter quand j’aurai d’autres courbes significatives à montrer.


Vous l’avez compris, ma solution est simplifiée par le fait que la puissance réseau est disponible en Modbus dans mon onduleur, ce qui n’est pas le cas le plus répandu, j’en convient, mais vous pouvez très bien exemple vous équiper d’un compteur de puissance communiquant en Modbus ou autre protocole, l’important étant d’avoir un temps de rafraîchissement de la mesure de puissance de quelques secondes (2 dans mon cas).
J’anticipe la question, non on ne peut pas utiliser le Linky qui ne délivre qu’une puissance apparente en VA, à une cadence non maîtrisée et aux valeurs incertaines.
La solution avec un module PZEM ne convient pas non plus, la mesure est toujours positive.
Bien entendu cette liste est non exhaustive, si vous avez d’autres liens, n’hésiter pas à me les transmettre, je les ajouterai.
Cette solution est destinée à ceux qui aiment bricoler, mais finalement pas tant que ça. Il existe beaucoup de routeurs prêt à l’emploi, certainement plus performant vu leur prix. Celui ci vous coûtera quelques euros, surtout si vous avez un compteur communiquant.
Code .JSON du Flow Node Red:
[{"id":"99c8e0165e0d303e","type":"tab","label":"Router","disabled":false,"info":"","env":[]},{"id":"d5bb5a6fbe8a8900","type":"http request","z":"99c8e0165e0d303e","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[{"keyType":"msg","keyValue":"payload","valueType":"other","valueValue":""}],"x":710,"y":100,"wires":[[]]},{"id":"f3351be463b175be","type":"function","z":"99c8e0165e0d303e","name":"function 1","func":"var value=msg.payload;\n\nif (value < 0) {\n value = 0;\n} else if (value > 100) {\n value = 100;\n}\n\n\nmsg.payload = \"http://192.168.0.77/?POWER=\"+value;\nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":300,"y":80,"wires":[["5317965d8acbf016"]]},{"id":"5317965d8acbf016","type":"change","z":"99c8e0165e0d303e","name":"","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":220,"wires":[["d5bb5a6fbe8a8900","efd318f8.965d28","e7032485600e2013"]]},{"id":"1ae1ff1136b1ce65","type":"debug","z":"99c8e0165e0d303e","name":"Increment","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":700,"y":380,"wires":[]},{"id":"90a44f2c9d4a8c4d","type":"debug","z":"99c8e0165e0d303e","name":"PU grid","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":420,"y":360,"wires":[]},{"id":"efd318f8.965d28","type":"debug","z":"99c8e0165e0d303e","name":"URL","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":730,"y":160,"wires":[]},{"id":"3215c48483a96014","type":"function","z":"99c8e0165e0d303e","name":"Calcul Sortie %","func":"var pu = Math.abs(msg.pu);\nvar pu_net = msg.pu;\nvar pourcentage;\nvar increment;\nvar count;\nvar Palier0 = 0;\nvar Palier1 = 10;\nvar Palier2 = 50;\nvar Palier3 = 100;\nvar Palier4 = 200;\nvar Palier5 = 350;\nvar Palier6 = 600;\nvar Palier7 = 900;\nvar etat = msg.dimmer; // Etat dimmer\n\nif (etat === \"on\") {\n\n if (context.get('count') === undefined) {\n context.set('count', 0);\n }\n\n if (pu >= Palier1 && pu < Palier2) {\n increment = 1;\n }\n else if (pu >= Palier2 && pu < Palier3) {\n increment = 1; \n }\n else if (pu >= Palier3 && pu < Palier4) {\n increment = 2; \n }\n else if (pu >= Palier4 && pu < Palier5) {\n increment = 3; \n }\n else if (pu >= Palier5 && pu < Palier6) {\n increment = 5;\n }\n else if (pu >= Palier6 && pu < Palier7) {\n increment = 6;\n }\n else if (pu >= Palier7) {\n increment = 7;\n }\n else {\n increment = 0;\n }\n\n if (pu_net < 0) {\n count = context.get('count') + increment;\n } else {\n count = context.get('count') - increment;\n }\n context.set('count', count);\n pourcentage = Math.trunc(Math.min(100, count));\n\n if (context.get('count') < 0) {\n context.set('count', 0);\n pourcentage = 0;\n }\n if (context.get('count') > 100) {\n context.set('count', 100);\n pourcentage = 100;\n }\n} else {\n pourcentage = 0;\n increment = 0;\n context.set('count', 0)\n}\n\n\nmsg.payload = \"http://192.168.0.77/?POWER=\" + pourcentage;\n\nvar msg2 = { payload: increment }\nvar msg3 = { payload: pourcentage }\nreturn [msg, msg2, msg3];","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":440,"y":420,"wires":[["5317965d8acbf016"],["1ae1ff1136b1ce65","46f7a8fd5e230c2f"],["d94c0ff96671f33a","bf0712cff0298b48"]]},{"id":"46f7a8fd5e230c2f","type":"ui_gauge","z":"99c8e0165e0d303e","name":"","group":"dedd34935ebbcdc1","order":1,"width":"3","height":"3","gtype":"gage","title":"Increment","label":"units","format":"{{value}}","min":0,"max":"20","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","diff":false,"className":"","x":700,"y":440,"wires":[]},{"id":"d94c0ff96671f33a","type":"ui_gauge","z":"99c8e0165e0d303e","name":"","group":"dedd34935ebbcdc1","order":2,"width":"3","height":"3","gtype":"gage","title":"Sortie V1","label":"units","format":"{{value}}","min":0,"max":"100","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","diff":false,"className":"","x":700,"y":480,"wires":[]},{"id":"8a52316c884dd04e","type":"modbus-read","z":"99c8e0165e0d303e","name":"Pu grid","topic":"Pu_grid","showStatusActivities":true,"logIOActivities":false,"showErrors":false,"showWarnings":true,"unitid":"100","dataType":"HoldingRegister","adr":"820","quantity":"1","rate":"2","rateUnit":"s","delayOnStart":false,"startDelayTime":"5","server":"af1b6fc455ed5ad2","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":true,"x":90,"y":200,"wires":[["d4c7e3e3.526538"],[]]},{"id":"d4c7e3e3.526538","type":"function","z":"99c8e0165e0d303e","name":"Convertion","func":"// Entrée : msg.payload (entier non signé)\n// Sortie : msg.payload (entier signé)\n\n// Récupérer la valeur de l'entier non signé\nvar unsignedInt = msg.payload;\n\n// Créer un tableau tampon (Buffer) pour stocker les données\nvar buffer = Buffer.allocUnsafe(2);\n\n// Écrire la valeur de l'entier non signé dans le tampon\nbuffer.writeUInt16BE(unsignedInt, 0);\n\n// Lire la valeur de l'entier signé depuis le tampon\nvar signedInt = buffer.readInt16BE(0);\n\n// Mettre à jour la valeur du message avec l'entier signé\nmsg.payload = signedInt;\n\n// Renvoyer le message modifié\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":130,"y":300,"wires":[["90a44f2c9d4a8c4d","af31ae510b0e868b","fe46843e5a1bd030","62c4bfac1802aab7"]]},{"id":"d485d8cc726be5c8","type":"ui_slider","z":"99c8e0165e0d303e","name":"","label":"Simul Sortie","tooltip":"","group":"378299f3e47d4d20","order":2,"width":0,"height":0,"passthru":true,"outs":"all","topic":"topic","topicType":"msg","min":"0","max":"100","step":1,"className":"","x":110,"y":80,"wires":[["f3351be463b175be"]]},{"id":"af31ae510b0e868b","type":"ui_chart","z":"99c8e0165e0d303e","name":"","group":"13956cf323d720cd","order":2,"width":0,"height":0,"label":"Pu Réseau","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":"5","removeOlderPoints":"","removeOlderUnit":"60","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":710,"y":280,"wires":[[]]},{"id":"e7032485600e2013","type":"ui_text","z":"99c8e0165e0d303e","group":"dedd34935ebbcdc1","order":4,"width":0,"height":0,"name":"","label":"Trame","format":"{{msg.payload}}","layout":"row-spread","className":"","x":690,"y":220,"wires":[]},{"id":"bf0712cff0298b48","type":"ui_chart","z":"99c8e0165e0d303e","name":"","group":"dedd34935ebbcdc1","order":3,"width":0,"height":0,"label":"Sortie GV1","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":"15","removeOlderPoints":"","removeOlderUnit":"60","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":710,"y":520,"wires":[[]]},{"id":"b746980fc02e1b13","type":"ui_slider","z":"99c8e0165e0d303e","name":"","label":"Simul Puissance","tooltip":"","group":"378299f3e47d4d20","order":1,"width":0,"height":0,"passthru":true,"outs":"all","topic":"topic","topicType":"msg","min":"-1000","max":"1000","step":1,"className":"","x":130,"y":140,"wires":[["3215c48483a96014"]]},{"id":"eb37db9b39905dbc","type":"function","z":"99c8e0165e0d303e","name":"essai","func":"var etat = msg.pu;\nvar msg1;\n\nif (etat === \"on\") {\n msg1 = msg.payload;\n } \n else{\n msg1=0;\n }\n \n\nmsg = { payload:etat};\n\nreturn [msg];","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":540,"wires":[["621b588ed3d71afe"]]},{"id":"fe46843e5a1bd030","type":"api-current-state","z":"99c8e0165e0d303e","name":"Etat Dimmer","server":"45bc8be7.a4f0a4","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"switch.dimmer_on_off_4630","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"dimmer","propertyType":"msg","value":"","valueType":"entityState"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":130,"y":360,"wires":[["be258b9d8eefcd93"]]},{"id":"be258b9d8eefcd93","type":"change","z":"99c8e0165e0d303e","name":"payload->Pu","rules":[{"t":"set","p":"pu","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":210,"y":420,"wires":[["eb37db9b39905dbc","ea6ab9ee1fa0e3f6","3215c48483a96014"]]},{"id":"621b588ed3d71afe","type":"debug","z":"99c8e0165e0d303e","name":"debug 5","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":700,"y":580,"wires":[]},{"id":"ea6ab9ee1fa0e3f6","type":"debug","z":"99c8e0165e0d303e","name":"Pu","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":470,"y":480,"wires":[]},{"id":"f531da7a37f7ebd6","type":"comment","z":"99c8e0165e0d303e","name":"Routeur PV","info":"","x":390,"y":40,"wires":[]},{"id":"62c4bfac1802aab7","type":"ui_gauge","z":"99c8e0165e0d303e","name":"","group":"13956cf323d720cd","order":1,"width":"3","height":"3","gtype":"gage","title":"Pu reseau","label":"units","format":"{{value}}","min":"-1000","max":"1000","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","diff":false,"className":"","x":710,"y":320,"wires":[]},{"id":"dedd34935ebbcdc1","type":"ui_group","name":"1","tab":"35ebc542aeecc309","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"af1b6fc455ed5ad2","type":"modbus-client","name":"Victron","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"failureLogEnabled":true,"tcpHost":"192.168.0.86","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"0x3A","unit_id":"1","commandDelay":"1","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true,"showWarnings":true,"showLogs":true},{"id":"378299f3e47d4d20","type":"ui_group","name":"4","tab":"35ebc542aeecc309","order":4,"disp":true,"width":"6","collapse":false,"className":""},{"id":"13956cf323d720cd","type":"ui_group","name":"2","tab":"35ebc542aeecc309","order":2,"disp":true,"width":"6","collapse":false,"className":""},{"id":"45bc8be7.a4f0a4","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true},{"id":"35ebc542aeecc309","type":"ui_tab","name":"Victron","icon":"dashboard","disabled":false,"hidden":false}]
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:36:"http://wellformedweb.org/CommentAPI/";a:1:{s:10:"commentRss";a:1:{i:0;a:5:{s:4:"data";s:58:"https://domo.rem81.com/2023/04/14/ha-routeur-solaire/feed/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:38:"http://purl.org/rss/1.0/modules/slash/";a:1:{s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:1:"9";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}i:2;a:6:{s:4:"data";s:100:"
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:5:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:24:"HA-ESP8266 sur Batterie.";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:59:"https://domo.rem81.com/2023/03/25/ha-esp8266-sur-batteries/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:68:"https://domo.rem81.com/2023/03/25/ha-esp8266-sur-batteries/#comments";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:7:"pubDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Sat, 25 Mar 2023 15:45:00 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"category";a:10:{i:0;a:5:{s:4:"data";s:9:"Domotique";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:1;a:5:{s:4:"data";s:15:"Faire soi-même";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:2;a:5:{s:4:"data";s:14:"Home Assistant";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:3;a:5:{s:4:"data";s:15:"Photovoltaïque";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:4;a:5:{s:4:"data";s:10:"Prototypes";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:5;a:5:{s:4:"data";s:5:"Eagle";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:6;a:5:{s:4:"data";s:7:"ESP8266";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:7;a:5:{s:4:"data";s:7:"ESPHOME";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:8;a:5:{s:4:"data";s:2:"HA";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:9;a:5:{s:4:"data";s:8:"wemos d1";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"guid";a:1:{i:0;a:5:{s:4:"data";s:30:"https://domo.rem81.com/?p=2516";s:7:"attribs";a:1:{s:0:"";a:1:{s:11:"isPermaLink";s:5:"false";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:184:"Intro Dans cet article je vous propose de partager mon expérience dans la mise en oeuvre d’un ESP8266 (ou Wemos D1) alimenté par une batterie et un panneau solaire. Le … ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:32:"http://purl.org/dc/elements/1.1/";a:1:{s:7:"creator";a:1:{i:0;a:5:{s:4:"data";s:5:"rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:40:"http://purl.org/rss/1.0/modules/content/";a:1:{s:7:"encoded";a:1:{i:0;a:5:{s:4:"data";s:21933:"
Dans cet article je vous propose de partager mon expérience dans la mise en oeuvre d’un ESP8266 (ou Wemos D1) alimenté par une batterie et un panneau solaire. Le but est de le rendre indépendant de toute source d’alimentation, la limite étant celle du Wi-Fi.
L’objectif de ce montage est de pouvoir relever des températures élevées dans un barbecue au gaz, c’est pourquoi j’ai utilisé un module thermocouple, bien évidemment vous pouvez l’adapter avec d’autres types de capteur, la bibliothèque ESPHome en contient un grand nombre.
Je l’ai également utilisé cet été pour mesurer la température des panneaux photovoltaïques installés sur le toit, plus de 70°C en plein soleil et en ce moment je surveille la température de mes plans potagés dans une petite serre.
Les articles nécessaires à la réalisation de ce montage sont facilement trouvables sur le Net, je vous donne des liens Ali Express, mais Amazon vous les propose également en plus cher.
Un panneau solaire 6V de 1 ou 2W, plus il est puissant, plus vite la batterie sera chargée, plus sa surface est importante. Vous en trouvez Ici par exemple

Un module de chargeur de batterie au Lithium, Type c/Micro/Mini USB 5V 1A 18650 TP4056, carte de charge avec Protection, double fonction 1A Li-ion. Ce chargeur protège votre batterie 18650 tout en délivrant une tension de 5V à partir du 3.7V de la batterie.
Vous en trouvez ici par exemple

Un module Wemos D1, vous en trouvez facilement sur Amazon ou Ali Express.

Un module 4 entrées analogiques ADS1115, vous en trouvez facilement sur Amazon ou Ali Express. Il n’est pas indispensable, je m’en sert pour remonter vers HA la tension délivrée par le panneau photovoltaïque. Vous en trouvez ici par exemple.

Une batterie 18650, 3000 mAh minimum, 4500mAh est plus courant.

Un support de batterie 18650. Vous en trouverez ici par exemple.

Un module thermocouple « max31855 » 0-800°C. Vous en trouverez ici par exemple

Un bouton poussoir de réinitialisation avec un contact normalement ouvert. Pas indispensable, mais j’en met systématiquement, cela évite d’avoir à ouvrir le boitier pour réinitialiser le Wemos. Vous en trouverez ici par exemple.

Une fois le matériel acheté, vous pouvez commencer à les raccorder entre eux via le schéma suivant. Ce schéma a été élaboré avec « Eagle de Autodesk ».


Le 5V+ est relié à la broche A0 du Wemos afin de mesurer sa tension d’alimentation.
Le +6V du panneau PV est relié à l’entrée A0 du module ADS1115.
Élaboré avec Eagle, vous pouvez sous traiter la fabrication de ce type de PCB à https://jlcpcb.com/ ça coûte que dalle, c’est du travail de pro, il faut pas être pressé et c’est quantité 5 minimum.


Et ça coute vraiment pas cher! 2€ pour 5 PCB.

Je mets à votre disposition en téléchargement le fichier Gerber qui permet de faire fabriquer le PCB.
J’ai mis le PCB dans une boite plastique d’électricité 100*100, on voit sur la photo qu’elle à vécue ainsi que le panneau mais ils tiennent le choc.


C’est sans surprise, le Wemos est codé avec ESphome. J’ai décrit le premier flashage d’un ESP dans cet article.
Rien d’exceptionnel si ce n’est la mise en veille de l’ESP et la mesure VCC
Il faut savoir que l’ESP se met en veille par logiciel, mais pour le sortir de sa torpeur, la broche D0 doit être reliée à la broche RST, d’ou la présence du cavalier, si vous l’enlevez, il ne se réveille pas.
Lorsque que le Wemos est en veille, il ne communique plus donc impossible de télécharger une mise à jour par exemple, c’est pourquoi par programme, je « bloque » sa mis en veille avec un « input_boolean.reveil_esp127_thermocouple » déclaré dans HA. Sur ON, la mise en veille est bloquée. Une fois le téléchargement de la mise à jour terminé vous le remettez sur OFF.
Vous pouvez déclarer l’input_boolean dans « ../config/helpers. ».

Tout est dit dans la documentation ESP, vous mesurez au max 3.3 V bien que ce soit 5V de relier à la broche A0.

Un exemple de la mesure de tension fluctuant avec le niveau de charge de la batterie:

Le panneau, bien que très bon marché, produit des que le jour se lève même par temps couvert:

Dans mon exemple, l’ESP se « réveille » pendant 60s (duree_reveil) toutes les 5mn (duree_sommeil). A adapter selon vos besoins dans « substitutions ».
substitutions:
device_name: esp127-thermocouple
adress_ip: "192.168.0.127"
friendly_name: esp127
duree_sommeil: "5min"
duree_reveil: "60s"
esphome:
name: ${device_name}
platform: ESP8266
board: d1_mini
on_boot:
then:
- script.execute: exec_deep_sleep
wifi:
networks:
- ssid: !secret wifi_esp
password: !secret mdpwifi_esp
priority: 2
- 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
deep_sleep:
sleep_duration: ${duree_sommeil}
id: control_deep_sleep
i2c:
sda: GPIO4 #D2
scl: GPIO5 #D1
scan: true
id: bus_a
logger:
api:
ota:
web_server:
port: 80
spi:
miso_pin: D5
clk_pin: D8 #ex D1
ads1115:
- address: 0x48
sensor:
- platform: ads1115
multiplexer: 'A0_GND'
gain: 6.144
name: "${friendly_name} U Panneau"
update_interval: 10s
- platform: max31855
name: "${friendly_name} Temperature"
cs_pin: D3
update_interval: 10s
accuracy_decimals: 2
filters:
- median:
window_size: 8
send_every: 4
send_first_at: 1
- platform: adc
pin: VCC
name: "${friendly_name} U Alim"
update_interval: 10s
binary_sensor:
- platform: homeassistant
entity_id: input_boolean.reveil_esp127_thermocouple
id: prevent_deep_sleep
#Etat de la connection
- platform: status
name: "${friendly_name} Status"
script:
- id: exec_deep_sleep
mode: queued
then:
- delay: ${duree_reveil}
- logger.log: 'execute script'
- if:
condition:
binary_sensor.is_on: prevent_deep_sleep
then:
- logger.log: 'Eviter la mise en sommeil par prevent_deep_sleep'
- deep_sleep.prevent: control_deep_sleep
else:
- logger.log: 'Autorise la mise en sommeil par deep_sleep_enter'
- deep_sleep.enter:
id: control_deep_sleep
sleep_duration: ${duree_sommeil}
- script.execute: exec_deep_sleep

type: entities
entities:
- entity: sensor.esp127_temperature
secondary_info: last-updated
- entity: sensor.esp127_u_alim
secondary_info: last-updated
- entity: sensor.esp127_u_panneau
secondary_info: last-updated
- entity: input_boolean.reveil_esp127_thermocouple
- entity: binary_sensor.esp127_status
secondary_info: last-updated
title: Esp127-thermocouple

type: history-graph
entities:
- entity: sensor.esp127_u_alim
name: Alim
- entity: sensor.esp127_u_panneau
name: Panneau
title: ESP127
hours_to_show: 12
Tuto tout simple qui, je l’espère, vous aidera à résoudre vos problèmes d’ESP Isolé à l’extérieur.
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:36:"http://wellformedweb.org/CommentAPI/";a:1:{s:10:"commentRss";a:1:{i:0;a:5:{s:4:"data";s:64:"https://domo.rem81.com/2023/03/25/ha-esp8266-sur-batteries/feed/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:38:"http://purl.org/rss/1.0/modules/slash/";a:1:{s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:1:"8";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}i:3;a:6:{s:4:"data";s:88:" ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:5:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:26:"HA-Platines Relais ESP8266";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:60:"https://domo.rem81.com/2023/01/09/ha-platine-relais-esp8266/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:68:"https://domo.rem81.com/2023/01/09/ha-platine-relais-esp8266/#respond";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:7:"pubDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Mon, 09 Jan 2023 14:27:29 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"category";a:6:{i:0;a:5:{s:4:"data";s:9:"Domotique";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:1;a:5:{s:4:"data";s:15:"Faire soi-même";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:2;a:5:{s:4:"data";s:14:"Home Assistant";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:3;a:5:{s:4:"data";s:7:"ESP8266";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:4;a:5:{s:4:"data";s:7:"ESPHOME";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:5;a:5:{s:4:"data";s:2:"HA";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"guid";a:1:{i:0;a:5:{s:4:"data";s:30:"https://domo.rem81.com/?p=2441";s:7:"attribs";a:1:{s:0:"";a:1:{s:11:"isPermaLink";s:5:"false";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:181:"Intro Je vous propose de découvrir la mise en oeuvre de platine relais à base ESP8266 équipée de 1 (ou plusieurs relais) sur ESPHOME. Liste des courses Un module relais … ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:32:"http://purl.org/dc/elements/1.1/";a:1:{s:7:"creator";a:1:{i:0;a:5:{s:4:"data";s:5:"rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:40:"http://purl.org/rss/1.0/modules/content/";a:1:{s:7:"encoded";a:1:{i:0;a:5:{s:4:"data";s:23316:"Je vous propose de découvrir la mise en oeuvre de platine relais à base ESP8266 équipée de 1 (ou plusieurs relais) sur ESPHOME.
Un module relais ESP8266 directement alimenté en 220 Vca ou en courant conctinu de 7 à 12 VCC ou en 5 VCC par prise USB acheté ici.
Ce module est très pratique puisqu’il suffit de le configurer, l’alimenter et le coupler à HA.

Les modules commandés sont livrés avec les broches à souder et un pont nécessaire à la première programmation. Peut être pourriez vous en trouver avec les broches déjà soudées. Si c’est le cas, merci de laisser le lien en commentaire.
Vous trouverez ci après une rapide présentation du module


Descriptif du Module
Descriptif des Broches surlignées en 7 (de gauche à droite):
Ces broches permettent d’étendre les possibilités de la carte.
Afin d’utiliser ce module avec HA, nous devons télécharger le programme ESP HOME via son port série. Le module que j’utilise est ce type de module., c’est un convertisseur USB<->Port série.

Vous devez le brancher à votre carte selon le mapping suivant (utilisation des câbles Dupont):


Le téléchargement est décrit dans mon article https://domo.rem81.com/2021/03/25/home-assistant_esp-home/
Une fois le premier flashage réalisée avec succés, vous devez débrancher le convertisseur, retirer le cavalier entre GND et GPIO00, puis alimenter votre module, vous avez le choix entre le 240 VCA, du courant continu 5VCC ou de 7 à 12 VCC.
Une fois ce code chargé, l’intégration validée dans HA, la communication est établie et la led GPIO10 est éteinte.
Je vous propose ci après un programme à télécharger, libre à vous de le modifier, dans ce programme j’ai configuré:
substitutions:
device_name: esp172-esp8266-1-relais-1
friendly_name: esp172
adress_ip: "192.168.0.172"
time_timezone: "Europe/Paris"
esphome:
name: ${device_name}
platform: ESP8266
board: d1_mini
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:
# Enable Home Assistant API
api:
ota:
web_server:
port: 80
# Configuration Dallas
dallas:
- pin: GPIO2
update_interval: 10s
# Utilisez la LED bleue de l'appareil comme LED d'état, qui clignotera s'il y a des avertissements (lent) ou des erreurs (rapide)
status_led:
pin:
number: GPIO16
inverted: true
binary_sensor:
# 3 Entrées logiques permettant de lire des contacts ou des BP
- platform: gpio
pin:
number: GPIO10
inverted: True
mode:
input: true
pullup: true
name: "${friendly_name}_bp1"
- platform: gpio
pin:
number: GPIO13
inverted: True
mode:
input: true
pullup: true
name: "${friendly_name}_bp2"
- platform: gpio
pin:
number: GPIO14
inverted: True
mode:
input: true
pullup: true
name: "${friendly_name}_bp3"
#Etat de la connection
- platform: status
name: "${friendly_name}_Status"
sensor:
# DS18B20 15/12/2021
- platform: dallas
address: 0xab0321117f919d28
name: "${friendly_name} Temperature"
id: temp
- platform: wifi_signal
name: "${friendly_name} WiFi Signal Sensor"
update_interval: 60s
- platform: uptime
name: "${friendly_name} Uptime Sensor"
update_interval: 60s
switch:
# Pilotage du relais
- platform: gpio
name: "${friendly_name} Relais"
pin: GPIO5
id: relay
- platform: restart
name: "${friendly_name} Restart"
Une fois la communication établie, vous avez accès à la page Web embarquée:

Vous pouvez tester votre relais
Vous avez également accès depuis l’intégration ESPHOME dans HA:

Exemple d’utilisation:
Comme décrit précédemment, j’ai choisi d’ajouter une sonde de température Dallas ds18b20.

Ces sondes communiquent avec le bus WireOne. Le cablage est simple:
Vous pouvez en mettre plusieurs sur un même GPIO. Il suffit de relier les raccorder en parallèle.
Pour cette mise en oeuvre, j’ai utilisé un connecteur à souder à plugger directement sur la carte. J’utilise le GPIO2 situé entre GND et 3.3V.


J’ai testé d’autres cartes, achetées ici. Perso, je préfére celle équipées d’une alimentation en courant alternatif, elles sont plus faciles à mettre en oeuvre.
Le principe de programmation est toujours le même, mais cependant elles ont quelques particularités:


Les relais doivent être associés au GPIO par des cavaliers, voir le code ci-dessous à ajouter dans les switch:
switch:
- platform: gpio
name: "${friendly_name} Relais1"
pin: GPIO4
id: relais1
- platform: gpio
name: "${friendly_name} Relais2"
pin: GPIO5
id: relais2

Attention lors de la première programmation, il faut mettre le cavalier du convertisseur sur le 3.3V et non 5V, sinon ça plante.
Comme pour la 2 relais, les relais doivent être associés au GPIO par des cavaliers, voir le code ci-dessous à ajouter dans les switch:
switch:
- platform: gpio
name: "${friendly_name} Relais1"
pin: GPIO16
id: relais1
- platform: gpio
name: "${friendly_name} Relais2"
pin: GPIO14
id: relais2
- platform: gpio
name: "${friendly_name} Relais3"
pin: GPIO12
id: relais3
- platform: gpio
name: "${friendly_name} Relais4"
pin: GPIO13
id: relais4
Dans cet article, il y a des éléments qui paraîtrons basiques ou évidents pour certain, j’en convient mais il s’adresse aux moins expérimentés qui souhaitent mettre un peu les mains dans le pâté en s’équipant de module presque prêts à l’emploi tout en offrant un maximum de possibilités pour quelques euros.
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:36:"http://wellformedweb.org/CommentAPI/";a:1:{s:10:"commentRss";a:1:{i:0;a:5:{s:4:"data";s:65:"https://domo.rem81.com/2023/01/09/ha-platine-relais-esp8266/feed/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:38:"http://purl.org/rss/1.0/modules/slash/";a:1:{s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:1:"0";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}i:4;a:6:{s:4:"data";s:94:" ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:5:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:31:"HA-Gestion Eau Chaude Sanitaire";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:66:"https://domo.rem81.com/2022/11/25/ha-gestion-eau-chaude-sanitaire/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:75:"https://domo.rem81.com/2022/11/25/ha-gestion-eau-chaude-sanitaire/#comments";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:7:"pubDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Fri, 25 Nov 2022 16:51:29 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"category";a:8:{i:0;a:5:{s:4:"data";s:9:"Domotique";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:1;a:5:{s:4:"data";s:15:"Faire soi-même";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:2;a:5:{s:4:"data";s:14:"Home Assistant";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:3;a:5:{s:4:"data";s:7:"ESPHOME";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:4;a:5:{s:4:"data";s:2:"HA";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:5;a:5:{s:4:"data";s:5:"Linky";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:6;a:5:{s:4:"data";s:8:"lovelace";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:7;a:5:{s:4:"data";s:10:"routeur pv";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"guid";a:1:{i:0;a:5:{s:4:"data";s:30:"https://domo.rem81.com/?p=2359";s:7:"attribs";a:1:{s:0:"";a:1:{s:11:"isPermaLink";s:5:"false";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:197:"Intro Lorsque la production d’Eau Chaude Sanitaire est comme chez moi produite par un ballon eau chaude électrique classique , elle peut être très énergivore et coûter un max si … ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:32:"http://purl.org/dc/elements/1.1/";a:1:{s:7:"creator";a:1:{i:0;a:5:{s:4:"data";s:5:"rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:40:"http://purl.org/rss/1.0/modules/content/";a:1:{s:7:"encoded";a:1:{i:0;a:5:{s:4:"data";s:26451:"Lorsque la production d’Eau Chaude Sanitaire est comme chez moi produite par un ballon eau chaude électrique classique , elle peut être très énergivore et coûter un max si elle n’est pas maîtrisée.
C’est pourquoi je tente de la réduire au minimum, pour ce faire, j’utilise au mieux le surplus de production générée par mon installation photovoltaïque décrite dans mon article https://domo.rem81.com/2022/11/13/pv-photovoltaique/ et bien entendu mon système domotique préféré Home Assistant.
Commençons par décrire les termes communément employés dans cet article:
Un RPV est un système électronique par lequel transite l’alimentation de votre BECS (on dit qu’il est raccordé en série). Ce système module la puissance du signal électrique transmise au BECS en fonction du surplus de puissance injecté dans le RPE. Des que le système détecte une injection supérieure à un seuil généralement paramétrable, il calcul la puissance du signal de sortie du RPV dans une fourchette Min/Max les deux étant aussi généralement paramétrable: Min = 0%, Max est fonction de la puissance du BECS et du RPV. De ce fait la consommation va augmenter jusqu’à ce le RPV calcul un soutirage dans le RPE, il adapte ainsi en permanence la puissance appliqué au BECS.
Vous trouverez dans cet article publié par l’association ‘P’TITWATT’ des explications bien plus compréhensible que la mienne.
Cet d’ailleurs ce routeur que j’utilise mais j’y reviendrai dans un article spécifique.
Comme je n’aime pas mélanger les sources électriques, j’ai modifié alimentation de mon BECS comme suit:

le disjoncteur Q23 protège électriquement le BECS, le disjoncteur Q28 protège électriquement le circuit de mesure tension du routeur et le circuit de commande des contacteurs. J’aurai également tout alimenter depuis le Q23 mais mon Q28 était disponible!.
Les contacteur PV et Réseau sont des contacteurs type chauffe-eau avec le mode Arret/Auto/Marche, pratique si la domotique est hors service.
Ils sont commandés par HA via un module Wago mais ce peut être bien entendu n’importe quel « switch » de puissance pilotés par HA.
Vous avez compris que le contacteur PV alimente le BECS via le routeur et que le contacteur « Réseau » l’alimente en direct depuis le réseau.
Si votre ballon est équipé d’un thermostat électromécanique comme le mien, il n’y a rien à faire et surtout il faut garder le thermostat opérationnel sous risque de le transformer en cocote minute si HA venait à déconner.
Si votre ballon est équipé d’un thermostat Electronique, c’est plus compliqué, il faudra dissocier l’alimentation électrique de l’électronique du thermostat, de l’alimentation électrique des résistances. La première devra toujours etre alimenté directement depuis le réseau, la deuxième pourra transiter par le RPV. Là encore il faut garder le thermostat opérationnel.
Dans ce cas c’est plus compliqué car vous ne pouvez pas l’alimenter électriquement directement via le RPV sans effectuer de modifications, vous risquez tout simplement de le cramer.
Malheureusement, je ne saurai pas vous aider sur ce coup, mais GOOGLE est votre ami, il vous apportera certainement la solution.
De mon point de vue il est intéressant de connaitre la température de l’eau à l’intérieur du BECS. Mon ballon n’étant pas équipé d’une sonde ni même d’un emplacement pour y loger une sonde, j’ai utilisé un ESP01 avec une sonde ds18b20. J’ai fait un trou de 8mm à mi-hauteur dans l’enveloppe extérieur du ballon et j’ai glissé ma sonde dans l’isolant au contact de la cuve métallique contenant l’eau chaude. J’ai étalonné la chaîne de mesure avec la température de l’eau chaude sortie robinet en jouant sur filters: – offset: 8.0 dans le code ESP, cela donne une bonne indication, et je ne suis pas au degré prêt.

Les sondes peuvent se mettre en parallèle, j’en ai prévu trois dans mon schéma. La led n’est pas obligatoire

Vous pouvez sous traiter la fabrication de ce type de PCB à https://jlcpcb.com/ ça coûte que dalle, c’est du travail de pro, faut pas etre pressé et c’est quantité 5 minimum, exemple en dessous pour ce PCB: 1.99+3.46€!!

substitutions:
device_name: esp126-temp-ecs
friendly_name: esp126
adress_ip: "192.168.0.126"
time_timezone: "Europe/Paris"
esphome:
name: ${device_name}
platform: ESP8266
board: esp01_1m
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
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
web_server:
port: 80
# Configuration Dalas
dallas:
- pin: GPIO0
#Etat de la connection
binary_sensor:
- platform: status
name: "${friendly_name} Status"
switch:
- platform: restart
name: "${friendly_name} Restart"
sensor:
- platform: dallas
address: 0xCA00AA2D00000328
name: "${friendly_name} temp_ecs"
filters:
- offset: 8.0
- platform: wifi_signal
name: "${friendly_name} WiFi Signal Sensor"
update_interval: 60s
- platform: uptime
name: "${friendly_name} Uptime Sensor"
update_interval: 60s
text_sensor:
# IP address #
- platform: wifi_info
ip_address:
name: "${friendly_name} IP address"
icon: "mdi:network-outline"
ssid:
name: "${friendly_name} Connected SSID"
bssid:
name: "${friendly_name} Connected BSSID"
Dans ce mode, je distingue le jour et la nuit, le jour est réservé à l’utilisation du routeur, la nuit, uniquement en mode secours, si l’eau n’est pas assez chaude.
La nuit, choix 1:
La nuit, choix 2:
Le jour, choix 3:
Le jour, choix 4:
Dans ce mode, je coupe les relais ECS_Réseau et ECS_PV.
Dans ce mode, je coupe le relais ECS_PV et j’active le relais ECS_Réseau, je force le chauffage via le réseau avec bien sur le thermostat électromécanique intégré au BECS en sécurité.
Afin d’éviter un chevauchement des relais PV et Réseau, j’ai créé trois scripts que je lance depuis les automatismes ou depuis le tableau de bord:
alias: 1_2_3 ECS Automatismes
description: ""
trigger:
- platform: state
entity_id:
- input_select.ecs_ssol
- platform: sun
event: sunrise
offset: 0
id: levee_soleil
- platform: sun
event: sunset
offset: 0
id: couche_soleil
- platform: state
entity_id:
- sensor.linky_ptec
from: HC..
to: HP..
id: HC-HP
- platform: state
entity_id:
- sensor.linky_ptec
from: HP..
to: HC..
id: HP-HC
- platform: numeric_state
entity_id: sensor.esp126_temp_ecs
id: t_bas
below: 40
- platform: numeric_state
entity_id: sensor.esp126_temp_ecs
above: 45
id: t_haut
- platform: state
entity_id:
- input_boolean.ecs_av_pv
from: "on"
to: "off"
id: arret_pv_routeur
- platform: state
entity_id:
- input_boolean.ecs_av_pv
from: "off"
to: "on"
id: avect_pv_routeur
condition: []
action:
- choose:
- conditions:
- condition: state
entity_id: input_select.ecs_ssol
state: Auto
- condition: sun
before: sunrise
after: sunset
- condition: numeric_state
entity_id: sensor.esp126_temp_ecs
below: 40
- condition: state
entity_id: sensor.linky_ptec
state: HC..
sequence:
- service: script.ecs_on
data: {}
- conditions:
- condition: state
entity_id: input_select.ecs_ssol
state: Auto
- condition: or
conditions:
- condition: trigger
id: HC-HP
- condition: numeric_state
entity_id: sensor.esp126_temp_ecs
above: 45
- condition: sun
before: sunrise
after: sunset
sequence:
- service: script.ecs_off_off
data: {}
- conditions:
- condition: state
entity_id: input_select.ecs_ssol
state: Auto
- condition: sun
before: sunset
after: sunrise
- condition: state
entity_id: input_boolean.ecs_av_pv
state: "on"
sequence:
- service: script.ecs_off
data: {}
- conditions:
- condition: trigger
id: arret_pv_routeur
- condition: state
entity_id: input_select.ecs_ssol
state: Auto
sequence:
- service: script.ecs_off_off
data: {}
- conditions:
- condition: state
entity_id: input_select.ecs_ssol
state: At Forcé
sequence:
- service: script.ecs_off_off
data: {}
- conditions:
- condition: state
entity_id: input_select.ecs_ssol
state: Ma Forcée
sequence:
- service: script.ecs_on
data: {}
default: []
mode: single

type: entities
entities:
- entities:
- entity: input_select.ecs_ssol
name: Mode
- entity: input_boolean.ecs_av_pv
name: Roteur PV
entity: input_select.ecs_ssol
icon: mdi:flash
name: Fonctionnement
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: sensor.ecocompteur_ecs
name: Pu
- entity: sensor.mp2_charge_batteries
name: Ch Bat
entity: sensor.ecocompteur_ecs
icon: mdi:flash
name: Puissance
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: sensor.energie_ecs_jour
name: Res+PV
- entity: sensor.energie_ecs_reseau_jour
name: Reseau
- entity: sensor.energie_ecs_pv_jour
name: PV
entity: sensor.energie_ecs_jour
icon: mdi:flash
name: Conso Jour
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: sensor.esp126_temp_ecs
name: T°
- entity: sensor.ecs_chauffage_ce_jour
name: Tps Ch
entity: sensor.energie_ecs_jour
icon: mdi:temperature-celsius
name: Temp
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: binary_sensor.ecs_chauffe
name: Chauffage
- entity: switch.cde_relais_ecs
name: Rel ECS
- entity: switch.cde_relais_ecs_router_pv
name: Rel PV
entity: switch.cde_relais_ecs
icon: mdi:water-boiler
name: Cde
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: switch.cde_relais_ecs
name: Relais ECS
- entity: switch.cde_relais_ecs_router_pv
name: Relais Routeur PV
- entity: script.ecs_reseau
- entity: script.ecs_pv
- entity: script.ecs_off
head:
label: Commandes
type: section
padding: 0
type: custom:fold-entity-row
how_header_toggle: false
show_header_toggle: false
####################################################
# #
# EAU CHAUDE SANITAIRE #
# #
####################################################
input_select:
ecs_ssol:
name: Ecs_SSol
icon: mdi:water-boiler
options:
- Auto
- At Forcé
- Ma Forcée
input_boolean:
ecs_av_pv:
name: Ecs PV(=1 avec Routeur PV)
sensor:
# Affichage du temps de fonctionnement ce jour
- platform: history_stats
name: ECS Chauffage ce jour
entity_id: binary_sensor.ecs_chauffe
state: 'on'
type: time
start: '{{ now().replace(hour=0).replace(minute=0).replace(second=0) }}'
end: '{{ now() }}'
template:
####################################
# Si puissance superieur à 500w = ECS en Marche
- binary_sensor:
- name: "ecs_chauffe"
unique_id: "ecs_chauffe"
device_class: heat
state: >-
{% set a=states('sensor.ecocompteur_ecs')|float(default=0) %}
{{ a > 500 }}
#
- sensor:
############################################ 21/12/2022
# sensor.ecocompteur_ecs:
# Si switch.cde_relais_ecs->
# template: sensor.puissance_ecs_reseau_w->
# template: sensor.puissance_ecs_reseau_kw
# Integration en kW: sensor.energie_ecs_reseau->
# utility_meter: energy_ecs_reseau_usage_daily->
# sensor.energy_ecs_reseau_usage_daily_hp
# sensor.energy_ecs_reseau_usage_daily_hc
# Si switch.cde_relais_ecs_router_pv->
# template: sensor.puissance_ecs_pv_w->
# template: sensor.puissance_ecs_pv_kw
# Integration en kW: sensor.energie_ecs_pv->
# utility_meter: energy_ecs_pv_usage_daily->
# sensor.energy_ecs_pv_usage_daily_hp
# sensor.energy_ecs_pv_usage_daily_hc
# Calcul puissance ECS si mode réseau
# L'integrale de rieumman et les utily_meter sont déclarés dans "/config/helpers"
- name: puissance_ecs_reseau_w
unique_id: "puissance_ecs_reseau_w"
device_class: "power"
state_class: "measurement"
unit_of_measurement: "W"
state: >-
{% set pu_ecs=states('sensor.ecocompteur_ecs')|float(default=0) %}
{% set rel_ecs=states('switch.cde_relais_ecs')%}
{% if (pu_ecs>0) and (rel_ecs=="on")%}
{{ pu_ecs }}
{%else%}
0
{%endif%}
- name: puissance_ecs_reseau_kw
unique_id: "puissance_ecs_reseau_kw"
device_class: "power"
state_class: "measurement"
unit_of_measurement: "kW"
state: >-
{% set p=states('sensor.puissance_ecs_reseau_w')|float(default=0) %}
{{ p/1000 }}
- name: "energie ecs reseau jour"
unique_id: "energie_ecs_reseau_jour"
state: >-
{% set p = states('sensor.energy_ecs_reseau_usage_daily_hp') | float(default=0) | round(2) %}
{% set o = states('sensor.energy_ecs_reseau_usage_daily_hc') | float(default=0) | round(2) %}
{{ (o + p) | round(2) }}
unit_of_measurement: "kWh"
device_class: "energy"
state_class: "total"
# Calcul puissance ECS si mode PV
- name: puissance_ecs_pv_w
unique_id: "puissance_ecs_pv_w"
device_class: "power"
state_class: "measurement"
unit_of_measurement: "W"
state: >-
{% set pu_ecs=states('sensor.ecocompteur_ecs')|float(default=0) %}
{% set rel_ecs=states('switch.cde_relais_ecs_router_pv')%}
{% if (pu_ecs>0) and (rel_ecs=="on")%}
{{ pu_ecs }}
{%else%}
0
{%endif%}
- name: puissance_ecs_pv_kw
unique_id: "puissance_ecs_pv_kw"
device_class: "power"
state_class: "measurement"
unit_of_measurement: "kW"
state: >-
{% set p=states('sensor.puissance_ecs_pv_w')|float(default=0) %}
{{ p/1000 }}
- name: "Energie ecs pv jour"
unique_id: "energie_ecs_pv_jour"
state: >-
{% set p = states('sensor.energy_ecs_pv_usage_daily_hp') | float(default=0) | round(2) %}
{% set o = states('sensor.energy_ecs_pv_usage_daily_hc') | float(default=0) | round(2) %}
{{ (o + p) | round(2) }}
unit_of_measurement: "kWh"
device_class: "energy"
state_class: "total"
# Cumul de Energie ECS Reseau et PV
- name: "Energie ECS Jour"
unique_id: "energie_ecs_jour"
state: >-
{% set p = states('sensor.energie_ecs_reseau_jour') | float(default=0) | round(2) %}
{% set o = states('sensor.energie_ecs_pv_jour') | float(default=0) | round(2) %}
{{ (o + p) | round(2) }}
unit_of_measurement: "kWh"
device_class: "energy"
state_class: "total"
###########################################################
# Puissance produite en surplus et injectée dans l'ECS en mode PV en W
- name: puissance_ecs_surplus_injectee_w
unique_id: "puissance_ecs_surplus_injectee_w"
device_class: "power"
state_class: "measurement"
unit_of_measurement: "W"
state: >-
{% set pu_ecs=states('sensor.ecocompteur_ecs')|float(default=0) %}
{% set prod=states('sensor.envoy_122103023124_current_power_production')|float(default=0) %}
{% set rel_ecs=states('switch.cde_relais_ecs_router_pv')%}
{% if (pu_ecs>0) and (prod>10) and (rel_ecs=="on")%}
{{ pu_ecs }}
{%else%}
0
{%endif%}
# Puissance produite en surplus et injectée dans l'ECS en mode PV en kW
- name: puissance_ecs_surplus_injectee
unique_id: "puissance_ecs_surplus_injectee"
device_class: "power"
state_class: "measurement"
unit_of_measurement: "kW"
state: >-
{% set a=states('sensor.puissance_ecs_surplus_injectee_w')|float(default=0) %}
{% if (a>0) %}
{{ a/1000 }}
{%else%}
0
{%endif%}
# Puissance disponible sans routeur ecs
# Utilisé dans esp141-affichage_pv
- name: puissance_dispo_sans ecs
unique_id: "puissance_dispo_sans_ecs"
device_class: "power"
state_class: "measurement"
unit_of_measurement: "W"
state: >-
{% set pu_ecs=states('sensor.ecocompteur_ecs')|float(default=0) %}
{% set prod=states('sensor.envoy_122103023124_current_power_production')|float(default=0) %}
{% set conso = states('sensor.envoy_122103023124_today_s_energy_consumption') | float(default=0) | round(2) %}
{% set rel_ecs=states('switch.cde_relais_ecs_router_pv')%}
{% if (prod>conso) and (pu_ecs>0) and (rel_ecs=="on")%}
{{ prod-conso+pu_ecs }}
{%else%}
0
{%endif%}
Ca peut paraître un peu compliqué pour certain, mais tout n’est pas à prendre, surtout si vous n’avez pas de batteries, dans ce cas il faut modifier l’automatisme
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:36:"http://wellformedweb.org/CommentAPI/";a:1:{s:10:"commentRss";a:1:{i:0;a:5:{s:4:"data";s:71:"https://domo.rem81.com/2022/11/25/ha-gestion-eau-chaude-sanitaire/feed/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:38:"http://purl.org/rss/1.0/modules/slash/";a:1:{s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:1:"8";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}i:5;a:6:{s:4:"data";s:88:" ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:5:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:17:"PV-Photovoltaique";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:52:"https://domo.rem81.com/2022/10/13/pv-photovoltaique/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:60:"https://domo.rem81.com/2022/10/13/pv-photovoltaique/#respond";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:7:"pubDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Thu, 13 Oct 2022 10:57:57 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"category";a:6:{i:0;a:5:{s:4:"data";s:14:"Home Assistant";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:1;a:5:{s:4:"data";s:15:"Photovoltaïque";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:2;a:5:{s:4:"data";s:2:"HA";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:3;a:5:{s:4:"data";s:14:"Micro Onduleur";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:4;a:5:{s:4:"data";s:25:"Panneaux Photovoltaîques";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:5;a:5:{s:4:"data";s:2:"PV";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"guid";a:1:{i:0;a:5:{s:4:"data";s:30:"https://domo.rem81.com/?p=2318";s:7:"attribs";a:1:{s:0:"";a:1:{s:11:"isPermaLink";s:5:"false";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:221:"Intro Je commence avec cet article une nouvelle série sur le Photovoltaïque. Après une description de mon installation, je continuerai vers une série d’articles décrivant mes solutions mises en oeuvre. … ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:32:"http://purl.org/dc/elements/1.1/";a:1:{s:7:"creator";a:1:{i:0;a:5:{s:4:"data";s:5:"rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:40:"http://purl.org/rss/1.0/modules/content/";a:1:{s:7:"encoded";a:1:{i:0;a:5:{s:4:"data";s:11425:"Je commence avec cet article une nouvelle série sur le Photovoltaïque. Après une description de mon installation, je continuerai vers une série d’articles décrivant mes solutions mises en oeuvre. Bien entendu HA est toujours de la partie.
Commençons par décrire les termes communement employés dans ce domaine:
Commencée en mai 2021, la première phase de mon installation comprend:
Schéma électrique du coffret.
Le matériel a été commandé chez Oscaro Power, à l’époque pas de problème de délai.
Détail du matériel utilisé.
Pourquoi des MO?
En premier lieu, la configuration de ma toiture fait que je dispose de 4 pans exposés plein Sud et Sud Ouest. Sur chaque pans je peux installé 6 PV max. Donc avec un onduleur centrale, il m’aurait fallu 2 puis 4 entrées MPPT (en prévision des extensions), la modularité des MO est précieuse dans ce cas.
En deux, par souci de simplicité, en effet la mise en oeuvre électrique est simplifiée au maximum:
En trois, pas de configuration compliquée, vous branchez, vous enclenchez les disjoncteurs et ça produit (si soleil, bien entendu), à ce stade la passerelle n’est pas obligatoire.
En quatre, la possibilité d’extension du système, j’ai ajouté par la suite six PV (voir ci-après)
J’ai choisi la Marque Enphase car la fiabilité de ses produits est mondialement reconnue, une garantie de 25 ans, et enfin il existe une intégration Envoy officielle Home Assistant.
Tous n’est pas tout rose dans cette solution, il y a également des points négatifs:
La législation oblige la déconnexion du réseau de votre installation Photovoltaïque et ce pour éviter de renvoyer du courant sur la réseau en cas de perte de celui ci et surtout si intervention des techniciens Enedis. Les onduleurs centraux répondant à la norme Française intègre cette fonctionalité, dans notre cas, c’est le relais Qrelais qui remplit ce rôle, donc vous ne pouvez et surtout ne devez pas en faire l’économie. C’est d’ailleurs le certificat de conformité de ce relais que vous devez fournir à Enedis lors de déclaration.
Remarque: La garantie de 25 ans ne s’applique que si le système est supervisé par une passerelle Metered. A ce propos, deux types de passerelle sont commercialisées:
Comme évoqué précédemment, j’ai installé en Août 2022, 6 PV de 395 Wc supplémentaires, sur un deuxième pan de la toiture, orienté différemment par rapport au premier, d’ou l’avantage des MO.
Installation identique à la précédente, mise à part:
J’ai donc acheté ce coup-ci les PV, les MO, un cable CA six MO, le systeme K2 et c’est tout. La passerelle Envoy, le coffret CA étaient compatibles.
Liste du matériel acheté:
Le câble CA de cette deuxième série est raccordé en parallèle sur le premier. Attention, mettre hors tension le coffret CA avant d’intervenir.
Vous remettez sous tension, attendre la synchronisation des MO et ça produit.
Voici une présentation simplifiée de mon installation.
Avec le mauvais temps qui arrive, je vais avoir plus de disponibilité pour écrire quelques articles.
Les prochains aborderont, l’intégration dans HA, les routeurs solaires, Etc..
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:36:"http://wellformedweb.org/CommentAPI/";a:1:{s:10:"commentRss";a:1:{i:0;a:5:{s:4:"data";s:57:"https://domo.rem81.com/2022/10/13/pv-photovoltaique/feed/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:38:"http://purl.org/rss/1.0/modules/slash/";a:1:{s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:1:"0";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}i:6;a:6:{s:4:"data";s:82:" ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:5:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:30:"HA-ESP HOME-Flashage WT01-ETH0";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:65:"https://domo.rem81.com/2022/09/06/ha-esp-home-flashage-wt01-eth0/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:74:"https://domo.rem81.com/2022/09/06/ha-esp-home-flashage-wt01-eth0/#comments";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:7:"pubDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Tue, 06 Sep 2022 07:55:06 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"category";a:4:{i:0;a:5:{s:4:"data";s:9:"Domotique";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:1;a:5:{s:4:"data";s:14:"Home Assistant";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:2;a:5:{s:4:"data";s:5:"esp32";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:3;a:5:{s:4:"data";s:2:"HA";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"guid";a:1:{i:0;a:5:{s:4:"data";s:30:"https://domo.rem81.com/?p=2260";s:7:"attribs";a:1:{s:0:"";a:1:{s:11:"isPermaLink";s:5:"false";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:217:"Intro J’utilise depuis longtemps des ESP32 ou ESP01 flashés avec ESP HOME. Ces petites bestioles sont très pratiques pour des petites conceptions DIY. Cependant celles-ci sont dépendantes du WIFI qui … ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:32:"http://purl.org/dc/elements/1.1/";a:1:{s:7:"creator";a:1:{i:0;a:5:{s:4:"data";s:5:"rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:40:"http://purl.org/rss/1.0/modules/content/";a:1:{s:7:"encoded";a:1:{i:0;a:5:{s:4:"data";s:19113:"J’utilise depuis longtemps des ESP32 ou ESP01 flashés avec ESP HOME. Ces petites bestioles sont très pratiques pour des petites conceptions DIY. Cependant celles-ci sont dépendantes du WIFI qui en terme de fiabilité et de disponibilité peut faire mieux.
Dernièrement j’ai utilisé un WT32-ETH01 qui permet de connecter l’ESP à un réseau ethernet câblé, pas en POE mais c’est déjà un premier pas vers la fiabilisation.

L’inconvénient, c’est qu’il n’embarque pas de port USB permettant de le flasher la première fois, il faut donc passer par un convertisseur USB/Port Série.
Autre inconvénient, le nom de pin utilisable est limité car beaucoup sont réservées au port Ethernet (en gris ci-dessous).

Il faut utiliser un convertisseur USB/Port série, perso j’utilise un FTDI232, le même que pour mes ESP01, je vous mets le lien vers Amazon ou Aliexpress mais Google peut vous aider: mot clef « FTDI232 ».
Il faut maintenant le raccorder au WT32.



Puis Il faut vous rendre sur ESPHOME et déclarer votre WT32.
Vous trouverez ci-après un code en exemple (mesure de niveau d’eau dans un puit).
J’utilise ce type de capteur à ultrason commandé sur Ali. Pas cher et efficace.

A vous de le personnaliser « device_name, adresse ip,..). Ne pas modifier la partie « Ethernet »

Voici le code.
substitutions:
device_name: esp144-test-wt32-eth01
adress_ip: "192.168.0.144"
friendly_name: esp144
time_timezone: "Europe/Paris"
esphome:
name: ${device_name}
platform: ESP32
board: esp-wrover-kit
# Enable logging
logger:
# Enable Home Assistant API
api:
web_server:
port: 80
ethernet:
type: LAN8720
mdc_pin: GPIO23
mdio_pin: GPIO18
clk_mode: GPIO0_IN
phy_addr: 1
power_pin: GPIO16
manual_ip:
static_ip: ${adress_ip}
gateway: 192.168.0.254
subnet: 255.255.255.0
sensor:
- platform: ultrasonic
trigger_pin: GPIO2
echo_pin: GPIO4
name: "niveau puit"
accuracy_decimals: 2
id: niveau_eau
update_interval: 60s
filters:
- lambda: return 3.5 - x;
- sliding_window_moving_average:
window_size: 5 # moyenne sur x lectures
send_every: 5 # envoi toutes les x lectures
send_first_at: 1 # envoi à la premiere lecture
# Calcul du niveau d'eau H total
# longueur du tube=2.3 m
# hauteur total puit=5.8 m
# d'ou 5.80-2.3=3.5
############### TEMPLATE ######################"
# Calcul volume eau
- platform: template
name: "volume_puit"
id: volume
icon: mdi:flash
unit_of_measurement: "m3"
accuracy_decimals: 2
lambda: |-
return (id(niveau_eau).state*0.6*0.6*3.14159);
#Etat de la connection
binary_sensor:
- platform: status
name: "${friendly_name} Status"
switch:
- platform: restart
name: "${friendly_name} Restart"
Apres avoir connecté votre FTDI232 à votre PC HA avec le cordon USB qui va bien, vous lancer « install »:

Dans mon cas je choisis l’option 3 « Plug into the computer running ESPHome Dashboard »:

Sélectionner le port USB correspondant à votre FDTI232, FT232R USB UART dans mon cas:

ESP HOME compile puis transfert vert le FTDI232:

Et voila c’est terminé.
Il suffit maintenant de débrancher le WT232, le connecter au réseau cablé et de l’alimenter en 5 ou 3.2 VCC.
Sur ESP HOME, si il est reconnu sur votre réseau, il est déclaré « ONLINE »:

Normalement HA doit vous le proposer comme une nouvelle intégration

Cliquer sur configurer

Cliquer sur « Soumettre »

Choisir une pièce, c’est facultatif mais recommandé.
Vous le retrouver dans les intégrations/appareils.

Une fois intégré dans HA, vous pouvez visualiser les logs ou la page WEB embarquée.

ou bien la page WEB embarquée

Si pas découvert automatiquement par HA, essayer de l’intégrer manuellement:

Cliquer sur « + Ajouter intégration« :
Chercher « ESPHOME », saisir l’adresse IP puis soumettre:

Cela devrait fonctionner, la cas échéant, vérifier votre adresse IP.
Une fois connecté à votre réseau, plus besoin d’utiliser le FTDI232, la mise à jour est à transférer comme d’habitude, via la « Wirelessly ».

J’en utilise un depuis quelque semaines et rien à signaler, il tourne comme une horloge.
N’hésitez par me faire part de vos commentaires.
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:36:"http://wellformedweb.org/CommentAPI/";a:1:{s:10:"commentRss";a:1:{i:0;a:5:{s:4:"data";s:70:"https://domo.rem81.com/2022/09/06/ha-esp-home-flashage-wt01-eth0/feed/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:38:"http://purl.org/rss/1.0/modules/slash/";a:1:{s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:1:"4";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}i:7;a:6:{s:4:"data";s:88:" ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:5:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:39:"HA-Modification statistiques long terme";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:74:"https://domo.rem81.com/2022/06/20/ha-modification-statistiques-long-terme/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:83:"https://domo.rem81.com/2022/06/20/ha-modification-statistiques-long-terme/#comments";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:7:"pubDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Mon, 20 Jun 2022 09:04:01 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"category";a:6:{i:0;a:5:{s:4:"data";s:9:"Domotique";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:1;a:5:{s:4:"data";s:14:"Home Assistant";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:2;a:5:{s:4:"data";s:2:"HA";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:3;a:5:{s:4:"data";s:5:"mysql";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:4;a:5:{s:4:"data";s:10:"phpmyadmin";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:5;a:5:{s:4:"data";s:3:"sql";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"guid";a:1:{i:0;a:5:{s:4:"data";s:30:"https://domo.rem81.com/?p=2193";s:7:"attribs";a:1:{s:0:"";a:1:{s:11:"isPermaLink";s:5:"false";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:214:"Intro J’ai récemment eu la désagréable surprise de constater une valeur anormalement élevée dans mon tableau « energy », en effet la conso totale jour HP était supérieure à 10000 kWh bien … ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:32:"http://purl.org/dc/elements/1.1/";a:1:{s:7:"creator";a:1:{i:0;a:5:{s:4:"data";s:5:"rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:40:"http://purl.org/rss/1.0/modules/content/";a:1:{s:7:"encoded";a:1:{i:0;a:5:{s:4:"data";s:14446:"J’ai récemment eu la désagréable surprise de constater une valeur anormalement élevée dans mon tableau « energy », en effet la conso totale jour HP était supérieure à 10000 kWh bien loin des valeurs habituelles.

Depuis la version 2022-04, HA offre la possibilité de modifier simplement les statistiques « longue durée ». Il faut vous rendre dans « outils de développement/statistiques ».
Vous cherchez votre entité corrompue avec la loupe

Vous cliquez sur l’icone de droite:

Vous sélectionnez la date, l’heure, vous cliquez sur la flèche correspondante à la valeur à rectifier:

Vous saisissez la nouvelle valeur et c’est terminé!
Merci HA, c’est quand même plus simple.
Méthode OBSOLETE
A ma connaissance, la seule méthode permettant de corriger les données est d’intervenir directement dans la base de données.
Pour rappel, les entités éligibles aux « statistiques au long terme » sont stockées dans des tables spécifiques indépendamment des statistiques « temps réels » purgées par défaut tous les 10 jours.
Toutes les heures, les entités sont calculées et stockées dans une table « statistics ». Dans cette table chaque entité est identifiée par un « id » que vous allez récupérerez dans la table « statistics-meta »
Dans mon exemple, je cherche le « sensor.energy_total_usage_dayly_hp », vous sélectionnez la table « statistics-meta » , onglet « rechercher », saisir le nom de votre sensor dans le champ « statistic_id », vous pouvez utilisez le signe % comme générique.

Exécuter (en bas à gauche).
Si pas d’erreur de saisie vous retrouverez l’ID de votre sensor.

Dans mon cas, je note ID=28
Dans la table « statistics » vous « recherchez » les enregistrements relatifs à votre id.
Dans le champ « metada-id » vous saisissez l' »id » de votre sensor, 28 dans mon cas.

Vous délimitez le champ de recherche avec la date de création en sélectionnant dans le champ « created », « between », vous saisissez vos dates min/max, ajuster l’heure.


Exécuter (en bas à gauche).
Vous devriez voir apparaître votre « anomalie » dans les colonnes « state » et « sum » 10103 et 14451 dans mon cas, ce sont ces valeurs qu’il faut rectifier.

Pour modifier c’est pas compliqué, vous cliquez sur « Editer » de la ligne concernée.
Vous mettez à jour « state » et/ou « sum » avec vos valeur et vous « exécuter ».
Remarque: Pour « state », inspirez vous des valeurs des lignes environnantes pour vous donner une idée de la consommation à l’instant T.

Remarque: pour « sum » vous additionner votre « state » à la « sum » de la ligne précédente.
Vous constaterez que les « sum » postérieures à cette erreur sont toutes créditées d’un surplus de consommation. Vous pouvez les modifier à la main, ligne par ligne, en soustrayant le surplus à la « sum ». Cela peut être long et fastidieux si comme moi vous avez mis trop de temps à réagir.
L’autre solution est d’exécuter une requête SQL.
Attention à ce que vous faites, prenez bien soi de vérifier votre requête avant de l’exécuter, sauvegarder votre base de données.
Ce que nous voulons, dans la table « statistics », c’est soustraire une valeur, par exemple 10101, pour le sensor dont l’ID=28, aux valeurs de la colonne « sum » et partir d’un certaine date et si sum>10000, la requête SQL est dans ce cas:
UPDATE statistics SET sum = sum - '10006.0' WHERE metadata_id = '29' AND created >= '2022-06-18 00:00:00.0' AND SUM>'10000';
Cette requête est à saisir dans l’onglet « SQL » après avoir sélectionner la table « statistics ».

Vous pouvez simuler la requête avant exécution, pratique pour s’assurer du résultat avant application définitive (pas de possibilité de retour en arrière!).
Si les résultats vous conviennent, vérifier notamment si le nombre de ligne concernée par la modification est cohérent, vous « exécuter ».
Visualiser le résultat de vos modifications dans le tableau « energy ».
Cette table est utiliser pour calculer les statistiques long terme, elle est purgée sur une période que vous avez défini dans votre configuration avec « purge_keep_days », le cas échéant c’est 10 jours par défaut.
Il faut donc également rectifier les « sum » et les « state » de cette table. Soit à la mano, soit avec une requête SQL du genre:
UPDATE statistics_short_term SET sum = sum - '10006.0' WHERE metadata_id = '28' AND created >= '2022-06-18 00:00:00.0' AND SUM>'10000';
UPDATE statistics_short_term SET state = state - '10006.0' WHERE metadata_id = '28' AND created >= '2022-06-18 00:00:00.0' AND state>'10000';
C’est exactement le même principe que la table « statistics »
Je ne vous cache pas que c’est un peu galère, notamment dans le calcul du « sum » qui est un cumul du « sum » précédent avec le « state « en cours, donc normalement le « sum » doit toujours croître, sinon vous retrouverez une conso négative.
PhpMyadmin est très puissant et permet de manipuler facilement les données, donc à utiliser avec prudence.
Si ce tuto n’est pas assez explicite, n’hésitez pas à me le faire remonter dans les commentaires.
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:36:"http://wellformedweb.org/CommentAPI/";a:1:{s:10:"commentRss";a:1:{i:0;a:5:{s:4:"data";s:79:"https://domo.rem81.com/2022/06/20/ha-modification-statistiques-long-terme/feed/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:38:"http://purl.org/rss/1.0/modules/slash/";a:1:{s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:1:"8";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}i:8;a:6:{s:4:"data";s:85:" ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:5:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:38:"HA-Compteur de service (utility meter)";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:71:"https://domo.rem81.com/2022/06/06/ha-compteur-de-service-utility-meter/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:80:"https://domo.rem81.com/2022/06/06/ha-compteur-de-service-utility-meter/#comments";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:7:"pubDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Mon, 06 Jun 2022 16:09:44 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"category";a:5:{i:0;a:5:{s:4:"data";s:9:"Domotique";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:1;a:5:{s:4:"data";s:14:"Home Assistant";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:2;a:5:{s:4:"data";s:2:"HA";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:3;a:5:{s:4:"data";s:3:"kWh";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:4;a:5:{s:4:"data";s:5:"Linky";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"guid";a:1:{i:0;a:5:{s:4:"data";s:30:"https://domo.rem81.com/?p=2098";s:7:"attribs";a:1:{s:0:"";a:1:{s:11:"isPermaLink";s:5:"false";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:252:"Intro Le comptage d’énergie est souvent évoqué sur les réseaux sociaux, qu’il s’agisse de kWh ou autres grandeurs physiques et semble être l’objet d’interrogations récurrentes. Récemment HA, dans sa version … ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:32:"http://purl.org/dc/elements/1.1/";a:1:{s:7:"creator";a:1:{i:0;a:5:{s:4:"data";s:5:"rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:40:"http://purl.org/rss/1.0/modules/content/";a:1:{s:7:"encoded";a:1:{i:0;a:5:{s:4:"data";s:20922:"Le comptage d’énergie est souvent évoqué sur les réseaux sociaux, qu’il s’agisse de kWh ou autres grandeurs physiques et semble être l’objet d’interrogations récurrentes.
Récemment HA, dans sa version 2022-04 a ajouté des intégrations directement configurables depuis l’interface utilisateur, simplifiant de fait leur déclaration, c’est ce que je vous invite à découvrir dans cet article. J’ai déjà abordé le sujet avec l’intégration « entrées threshold » dans cet article .
Un des avantages est qu’il n’est besoin de rebooter le système pour leur prise en compte.
Un des inconvénients, est qu’une fois créé et c’est regrettable, tous les paramètres ne sont pas modifiables et à ma connaissance la seul solution est de les supprimer puis de recréer une entité avec le même nom, de fait vous ne perdrez pas l’historique.
Comme pré requis il faut commencer par déclarer l’entité que vous souhaitez comptabiliser. En général nous nous intéressons au kWh mais c’est également valable pour des m3 d’eau ou de gaz.
Rappelons qu’un kilo watt heure correspond à une consommation de 1000 W ou 1 kW pendant 1 heure, il s’agit d’une énergie et non d’une puissance. Si votre capteur fournit uniquement une puissance en W ou kW, vous devez convertir la convertir en Wh ou kWh avec l’une des deux méthodes suivantes:
HA dispose d’une intégration « intégration par le méthode de Riemann » configurable depuis une interface utilisateur.
Pour cela vous allez dans « paramètres/appareils et service/entrées » puis « Ajouter un capteur d’intégrale de Riemann ».

Vous saisissez:
HA définit automatiquement les attributs de l’entité indispensable à sa classification (state_class, device_class,..)

Vous trouverez dans ce lien, un script python, qui d’après l’auteur calcule plus précisément les kWh,. J’ai testé, il fonctionne, mais plus compliqué à mettre en oeuvre, perso je ne cours pas après le kWh au 100 eme pret.
Votre entité en kWh (ou Wh) est maintenant créée, vous pouvez configurer votre compteur de service via une interface utilisateur.
Pour ce faire, allez dans « paramètres/appareils et service/entrées », puis ajouter « un compteur de services publics (eau, gaz, électricité…) ».

Vous saisissez:
Vous obtiendrez des informations complémentaires sur « utility meter » dans ce lien.
HA définit automatiquement les attributs de l’entité indispensable à sa classification (state_class, device_class,..)

A noter que vous devez déclarer autant de compteur que de cycles de remise à zéro (jour, semaine, mois année, ..) nécessaires.
Une fois créé, HA ajoute une entité par compteur, par ex « linky » et, si vous les avez déclaré, une entité supplémentaire par tarif , « linky_hc » et « linky_hp ».
Si vous avez un seul tarif, vous n’avez rien à faire de plus, votre compteur sera remis à zéro en fonction de votre unité de temps (jour, semaine,..).
Si vous avez un double tarif, vous devez indiquer au compteur quel tarif est en cours, pour ce faire vous pouvez utiliser un automatisme.
Les déclencheurs peuvent être des plages horaires ou encore mieux le tarif en cours dans votre linky par exemple.
Il faut créer un automatisme:
Les options « hc » et « hp » correspondent à celles que vous avez déclarées dans le compteur de service.
alias: 6_1_0 Energie Changement HP<->HC (Dupliquer)
description: ''
trigger:
- platform: time
id: tarif_hc
at: '01:00:00'
- platform: time
id: tarif_hp
at: '02:00:00'
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: tarif_hc
sequence:
- service: select.select_option
data:
option: hc
target:
entity_id:
- select.linky_energie_jour
- conditions:
- condition: trigger
id: tarif_hp
sequence:
- service: select.select_option
data:
option: hp
target:
entity_id:
- select.linky_energie_jour
default: []
mode: single
Si vous avez déclaré plusieurs compteurs avec les mêmes tarifs, vous les ajoutez les entités dans les « target: entity_id ».
alias: 6_1_0 Energie Changement HP<->HC (Dupliquer)
description: ''
trigger:
- platform: time
id: tarif_hc1
at: '01:00:00'
- platform: time
id: tarif_hp2
at: '02:00:00'
- platform: time
at: '05:00:00'
id: tarif_hc2
- platform: time
at: '06:00:00'
id: tarif_hp2
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: tarif_hc1
- condition: trigger
id: tarif_hc2
sequence:
- service: select.select_option
data:
option: hc
target:
entity_id:
- select.linky_energie_jour
- select.linky_energie_mois
- conditions:
- condition: trigger
id: tarif_hp1
- condition: trigger
id: tarif_hp2
sequence:
- service: select.select_option
data:
option: hp
target:
entity_id:
- select.linky_energie_jour
- select.linky_energie_mois
default: []
mode: single
Commencer par créer le deux « input_datetime » qui vont définir le début et la fin de la plage horaire des heures creuses.
Pour ce faire, allez dans « paramètres/appareils et service/entrées », puis ajouter « une date et/ou heure »:

Saisir
J’ai ainsi créé deux entités:

que l’on va pouvoir exploiter dans un automatisme:
Les options « hc » et « hp » correspondent à celles que vous avez déclarées dans le compteur de service.
Si vous avez déclaré plusieurs compteurs avec les mêmes tarifs, vous ajoutez les entités dans les « target: entity_id ».
alias: 6_1_0 Energie Changement HP<->HC
description: ''
trigger:
- platform: time
id: tarif_hc
at: input_datetime.debut_heure_creuse
- platform: time
id: tarif_hp
at: input_datetime.fin_heure_creuse
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: tarif_hc
sequence:
- service: select.select_option
data:
option: hc
target:
entity_id:
- select.linky_energie_jour
- conditions:
- condition: trigger
id: tarif_hp
sequence:
- service: select.select_option
data:
option: hp
target:
entity_id:
- select.linky_energie_jour
default: []
mode: single
L’automatisme est déclenché par une information délivrée par le Linky, qui, rappelons le, peux fonctionner sous 2 modes:
Les options « hc » et « hp » correspondent à celles que vous avez déclarées dans le compteur de service
Si vous avez déclaré plusieurs compteurs avec les mêmes tarifs, vous ajoutez les entités dans les « target: entity_id ».
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.linky_energie_jour
- conditions:
- condition: trigger
id: tarif_hp
sequence:
- service: select.select_option
data:
option: hp
target:
entity_id:
- select.linky_energie_jour
default: []
mode: single
Il faut commencer par créer deux inputs permettant des saisir le prix du kWh HP et HC
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
Puis utiliser trois templates pour le calcul: HP+HC, HP, HC.
template:
- sensor:
# Cout de l'Energie
- 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"
Exemple avec l’excellente intégration « mini-graph-card » disponible dans HACS.

type: custom:mini-graph-card
entities:
- entity: sensor.linky_energie_jour_hp
name: HP
show_state: true
- entity: sensor.linky_energie_jour_hc
name: HC
show_state: true
name: Conso Linky 7j
hours_to_show: 168
aggregate_func: max
group_by: date
show:
graph: bar
icon: mdi:flash
Vous trouverez d’autres exemples dans mon article https://domo.rem81.com/2022/01/12/ha-teleinformation-linky-mode-standard/ .
Tuto tout simple qui, je l’espère, vous aidera à définir vos compteurs.
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:36:"http://wellformedweb.org/CommentAPI/";a:1:{s:10:"commentRss";a:1:{i:0;a:5:{s:4:"data";s:76:"https://domo.rem81.com/2022/06/06/ha-compteur-de-service-utility-meter/feed/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:38:"http://purl.org/rss/1.0/modules/slash/";a:1:{s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:1:"9";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}i:9;a:6:{s:4:"data";s:91:" ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";s:5:"child";a:5:{s:0:"";a:7:{s:5:"title";a:1:{i:0;a:5:{s:4:"data";s:47:"HA-Mesure Qualité de l’air PM1.0-PM2.5-M10.0";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:78:"https://domo.rem81.com/2022/06/03/ha-mesure-qualite-de-lair-pm1-0-pm2-5-m10-0/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:87:"https://domo.rem81.com/2022/06/03/ha-mesure-qualite-de-lair-pm1-0-pm2-5-m10-0/#comments";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:7:"pubDate";a:1:{i:0;a:5:{s:4:"data";s:31:"Fri, 03 Jun 2022 06:00:59 +0000";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:8:"category";a:7:{i:0;a:5:{s:4:"data";s:9:"Domotique";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:1;a:5:{s:4:"data";s:15:"Faire soi-même";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:2;a:5:{s:4:"data";s:14:"Home Assistant";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:3;a:5:{s:4:"data";s:3:"CO2";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:4;a:5:{s:4:"data";s:7:"ESPHOME";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:5;a:5:{s:4:"data";s:2:"HA";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}i:6;a:5:{s:4:"data";s:5:"PM2.5";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:4:"guid";a:1:{i:0;a:5:{s:4:"data";s:29:"https://domo.rem81.com/?p=984";s:7:"attribs";a:1:{s:0:"";a:1:{s:11:"isPermaLink";s:5:"false";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:11:"description";a:1:{i:0;a:5:{s:4:"data";s:232:"Intro Dans un article précédent, j’abordais le détournement du boitier de mesure de qualité de l’air Vindriktning commercialisé par IKEA. Celui ci est équipé d’un capteur Pm2.5 pm1006 qui fonctionne … ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:32:"http://purl.org/dc/elements/1.1/";a:1:{s:7:"creator";a:1:{i:0;a:5:{s:4:"data";s:5:"rem81";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:40:"http://purl.org/rss/1.0/modules/content/";a:1:{s:7:"encoded";a:1:{i:0;a:5:{s:4:"data";s:29464:"Dans un article précédent, j’abordais le détournement du boitier de mesure de qualité de l’air Vindriktning commercialisé par IKEA. Celui ci est équipé d’un capteur Pm2.5 pm1006 qui fonctionne correctement mais la gamme de mesure se limite au PM2.5 et la précision semble t’il n’est pas au rendez vous.
En parcourant les sensors « Air Quality » de EspHome, j’ai découvert le PMS5003 qui propose lui une étendue de mesures bien supérieure pour un prix raisonnable. J’en ai profité pour y associer un MHZ-19B qui lui mesure le taux de CO2 plus un afficheur local et un bandeau de 8 leds.
L’ensemble est raccordé à un ESP32 Mini qui assure une puissance de traitement supérieure à un ESP8266.
Enfin j’ai intégré le tout sur un joli circuit imprimé dont j’ai sous traité la fabrication à https://jlcpcb.com/ pour un rapport qualité prix très attrayant.

Mesure fiable et en temps réel des concentrations de poussières PM2,5 ! Ce capteur utilise la diffusion laser pour rayonner les particules en suspension dans l’air, puis recueille la lumière diffusée pour obtenir la courbe de la variation de la lumière diffusée dans le temps. Le microprocesseur calcule le diamètre équivalent des particules et le nombre de particules de diamètre différent par unité de volume.
Concentrations de PM1,0, PM2,5 et PM10,0 dans les unités standard et environnementales
Particules par 0,1 L d’air, classées en bacs de 0,3 um, 0,5 um, 1,0 um, 2,5 um, 5,0 um et 10 um.
Plage de mesure : 0,3~1,0;1.0~2,5;2.5~10 μ m
Portée effective : 0~500 μ g/m³
Portée maximale : * ≥1000 μ g/m³
Résolution : 1 μ g/m³
Volume standard : 0.1L
Alimentation en courant continu : Typ:5.0 / Min:4.5 / Max : 5.5V
Courant actif : ≤100 mA
Courant de veille : ≤200 μ μ A
Plage de température de fonctionnement : -10~+60 ℃
Plage d’humidité de travail : 0~99%
Plage de température de stockage : -40~+80 ℃
Dimensions du module capteur : 50 × 38 × 21mm
Poids (câble et adaptateur inclus) : 42.2g
Fiche technique

Le capteur Co2 est un MH-Z19B qui mesure la teneur de CO2 sur une échelle de 400 à 10000 ppm et communique en UART.

J’ai choisi un ESP32 Mini, car l’ESP8266 est trop juste en puissance de calcul si on utilise l’intégration ESPHOME plus un afficheur plus un bandeau Led, j’ai galéré avec, je ne le recommande pas.
Vous en trouverez sans problème sur Amazon ou en chine

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.

Il n’est pas indispensable mais il permet de visualiser rapidement d’un simple coup d’œil le niveau de pollution.
Stick NeoPixel RGB 8 leds

j’utilise le logiciel Eagle d’Autodesk pour la création des circuits imprimé, puis je sous traite la fabrication chez https://jlcpcb.com/ pour un rapport qualité prix très attrayant et un rendu « professionnel »



Ca reste à faire, je cherche le boitier idéal!

J’ai raccordé un bouton poussoir me permettant ainsi de faire défiler différentes pages de mesure sur l’ecran Oled.


substitutions:
device_name: esp138-qualite-air
adress_ip: "192.168.0.138"
friendly_name: esp138
time_timezone: "Europe/Paris"
esphome:
name: ${device_name}
platform: ESP32
board: mhetesp32minikit
#board: wemos_d1_mini32
platformio_options:
lib_deps: NeoPixelBus@2.6.0
on_boot:
then:
- light.control:
id: rgb_led
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.1
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
# Led WS2812 RGB
light:
- platform: neopixelbus
num_leds: 8
pin: GPIO4 #gpio0
name: "RGB strip"
variant: ws2812
id: rgb_led
default_transition_length: 0s
i2c:
sda: GPIO21 #
scl: GPIO22 #
scan: True
id: bus_a
uart:
- id: uart_a
rx_pin: GPIO25 #
baud_rate: 9600
- id: uart_b
rx_pin: GPIO16 # GPIO16
tx_pin: GPIO17 # GPIO17
baud_rate: 9600
# debug:
# direction: BOTH
globals:
- id: bp_mode
type: int
initial_value: '1'
sensor:
- platform: pmsx003
uart_id: uart_a
type: PMSX003
pm_1_0:
name: "Concentration de particules <1.0µm"
id: pm1_0
accuracy_decimals: 0
filters:
- sliding_window_moving_average:
window_size: 15
send_every: 10
send_first_at: 1
pm_2_5:
name: "Concentration de particules <2.5µm"
id: pm2_5
accuracy_decimals: 0
filters:
- sliding_window_moving_average:
window_size: 15
send_every: 10
send_first_at: 1
on_value:
# de 0 à 7 / 8 leds
# Led 0
- if:
condition:
sensor.in_range:
id: pm2_5
below: 25
then:
- light.addressable_set:
id: rgb_led
range_from: 0
range_to: 0
red: 0%
green: 100%
blue: 0%
color_brightness: 100%
- light.addressable_set:
id: rgb_led
range_from: 1
range_to: 7
red: 0%
green: 0%
blue: 0%
color_brightness: 0%
# led 1
- if:
condition:
sensor.in_range:
id: pm2_5
above: 25
below: 35
then:
- light.addressable_set:
id: rgb_led
range_from: 0
range_to: 1
red: 0%
green: 100%
blue: 0%
color_brightness: 100%
- light.addressable_set:
id: rgb_led
range_from: 2
range_to: 7
red: 0%
green: 0%
blue: 0%
color_brightness: 0%
# Led 2
- if:
condition:
sensor.in_range:
id: pm2_5
above: 35
below: 45
then:
- light.addressable_set:
id: rgb_led
range_from: 0
range_to: 2
red: 0%
green: 100%
blue: 0%
color_brightness: 100%
- light.addressable_set:
id: rgb_led
range_from: 3
range_to: 7
red: 0%
green: 0%
blue: 0%
color_brightness: 0%
# led 3
- if:
condition:
sensor.in_range:
id: pm2_5
above: 45
below: 55
then:
- light.addressable_set:
id: rgb_led
range_from: 0
range_to: 3
red: 75%
green: 75%
blue: 0%
color_brightness: 100%
- light.addressable_set:
id: rgb_led
range_from: 4
range_to: 7
red: 0%
green: 0%
blue: 0%
color_brightness: 0%
# led 4
- if:
condition:
sensor.in_range:
id: pm2_5
above: 55
below: 65
then:
- light.addressable_set:
id: rgb_led
range_from: 0
range_to: 4
red: 75%
green: 75%
blue: 0%
color_brightness: 100%
- light.addressable_set:
id: rgb_led
range_from: 5
range_to: 7
red: 0%
green: 0%
blue: 0%
color_brightness: 0%
# led 5
- if:
condition:
sensor.in_range:
id: pm2_5
above: 65
below: 75
then:
- light.addressable_set:
id: rgb_led
range_from: 0
range_to: 5
red: 100%
green: 0%
blue: 0%
color_brightness: 100%
- light.addressable_set:
id: rgb_led
range_from: 6
range_to: 7
red: 0%
green: 0%
blue: 0%
color_brightness: 0%
# led 6
- if:
condition:
sensor.in_range:
id: pm2_5
above: 75
below: 85
then:
- light.addressable_set:
id: rgb_led
range_from: 0
range_to: 6
red: 100%
green: 0%
blue: 0%
color_brightness: 100%
- light.addressable_set:
id: rgb_led
range_from: 7
range_to: 7
red: 0%
green: 0%
blue: 0%
color_brightness: 0%
# Led 7
- if:
condition:
sensor.in_range:
id: pm2_5
above: 85
then:
- light.addressable_set:
id: rgb_led
range_from: 0
range_to: 7
red: 100%
green: 0%
blue: 0%
color_brightness: 100%
pm_10_0:
name: "Concentration de particules <10.0µm"
id: pm10_0
accuracy_decimals: 0
filters:
- sliding_window_moving_average:
window_size: 15
send_every: 10
send_first_at: 1
pm_0_3um:
name: "Nb de particules >0.3"
id: pm_03_um
unit_of_measurement: "ppd"
accuracy_decimals: 0
pm_0_5um:
name: "Nb de particules >0.5"
id: pm_05_um
unit_of_measurement: "ppd"
accuracy_decimals: 0
pm_1_0um:
name: "Nb de particules >1.0"
id: pm_10_um
unit_of_measurement: "ppd"
accuracy_decimals: 0
pm_2_5um:
name: "Nb de particules >2.5"
id: pm_25_um
unit_of_measurement: "ppd"
accuracy_decimals: 0
pm_5_0um:
name: "Nb de particules >5.0"
id: pm_50_um
unit_of_measurement: "ppd"
accuracy_decimals: 0
pm_10_0um:
name: "Nb de particules >10.0"
id: pm_100_um
unit_of_measurement: "ppd"
accuracy_decimals: 0
- platform: wifi_signal
name: "${friendly_name} WiFi Signal Sensor"
update_interval: 60s
- platform: uptime
name: "${friendly_name} Uptime Sensor"
update_interval: 60s
- platform: mhz19
uart_id: uart_b
id: mh_z19
co2:
name: "MH-Z19 CO2 Value"
id: co2
accuracy_decimals: 0
filters:
- sliding_window_moving_average:
window_size: 12 # moyenne sur 12 lecture
send_every: 6 # envoi toutes les 6 lectures
send_first_at: 1 # envoi à la premiere lecture
temperature:
name: "MH-Z19 Temperature"
id: temp
filters:
- sliding_window_moving_average:
window_size: 24
send_every: 12
send_first_at: 1
update_interval: 10s
automatic_baseline_calibration: false
# Il s'agit d'un modèle de capteur qui effectue une moyenne mobile de 30 minutes de PM2,5
# il supprime les valeurs aberrantes et de rendre le contrôle plus fluide
- platform: template
name: "Concentration de particules <2.5µm median"
id: pm2_5_median
icon: mdi:chemical-weapon
unit_of_measurement: µg/m³
lambda: |-
return id(pm2_5).state;
update_interval: 60s
filters:
- median:
window_size: 30
send_every: 30
send_first_at: 15
binary_sensor:
- platform: gpio
name: bp_mod
id: button
pin:
number: GPIO14 # GPIO 15TMS
inverted: true
mode:
input: true
pullup: true
on_click:
- min_length: 25ms
max_length: 500ms
then:
- lambda: |-
if (id(bp_mode) < 3) { id(bp_mode) += 1; }
else { id(bp_mode) = 1; }
- platform: gpio
name: bp_mod2
id: button2
pin:
number: GPIO13 # TCK
inverted: true
mode:
input: true
pullup: true
#Etat de la connection
- platform: status
name: "${friendly_name} Status"
interval:
- interval: 60s
then:
- switch.turn_on: val_mes
- delay: 10s
# - switch.turn_on: val_mes
- switch.turn_off: val_mes
- delay: 30s
switch:
- platform: gpio
pin:
number: GPIO27 #
id: val_mes
name: "${friendly_name} Validation mesure"
- platform: template
name: "Calibration zero Mh-Z19 CO2"
turn_on_action:
- mhz19.calibrate_zero: mh_z19
- switch.turn_off: co2_cal
id: co2_cal
- platform: restart
name: "${friendly_name} Restart"
# gestion afficheur
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
address: 0x3C
brightness: 100%
lambda: |-
if (id(bp_mode) == 1 )
{
it.printf(0,0,id(arial),"PM1.0=%.2f",id(pm1_0).state);
it.printf(0,15,id(arial),"PM2.5=%.2f",id(pm2_5).state);
it.printf(0,30,id(arial),"PM10.0=%.2f",id(pm10_0).state);
it.printf(0,45,id(arial),"CO2=%.0f",id(co2).state);
}
else if (id(bp_mode) == 2 )
{
it.printf(0,0,id(arial),"0.3UM=%.1f",id(pm_03_um).state);
it.printf(0,15,id(arial),"0.5UM=%.1f",id(pm_05_um).state);
it.printf(0,30,id(arial),"1.0UM=%.1f",id(pm_10_um).state);
it.printf(0,45,id(arial),"2.5UM=%.1f",id(pm_25_um).state);
}
else if (id(bp_mode) == 3 )
{
it.printf(0,0,id(arial),"5.0UM=%.1f",id(pm_50_um).state);
it.printf(0,15,id(arial),"10.0UM=%.1f",id(pm_100_um).state);
}

Un exemple minimaliste.

type: entities
entities:
- entity: sensor.concentration_de_particules_1_0um
- entity: sensor.concentration_de_particules_10_0um
- entity: sensor.concentration_de_particules_2_5um
- entity: sensor.concentration_de_particules_2_5um_median
- entity: sensor.mh_z19_co2_value
- entity: sensor.mh_z19_temperature
- entity: sensor.nb_de_particules_0_3
- entity: sensor.nb_de_particules_0_5
- entity: sensor.nb_de_particules_1_0
- entity: sensor.nb_de_particules_10_0
- entity: sensor.nb_de_particules_2_5
- entity: sensor.nb_de_particules_5_0
- entity: binary_sensor.bp_mod
- entity: binary_sensor.bp_mod2
- entity: automation.vmc_niv0_automatismes
title: esp138-qualite-air
Après quelques semaines d’expérience, les retours sont positifs, reste à valider la véracité des mesures, mais sans mesure étalon, on ne peut que faire confiance aux constructeurs.
J’ai remarqué que de temps en temps, la mesure de CO2 ne varie plus, j’active le switch « calibration zero mh-z19 ».
je l’utilise pour piloter ma VMC en cas de valeur PM2.5 ou de CO2 trop élévée.
";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:36:"http://wellformedweb.org/CommentAPI/";a:1:{s:10:"commentRss";a:1:{i:0;a:5:{s:4:"data";s:83:"https://domo.rem81.com/2022/06/03/ha-mesure-qualite-de-lair-pm1-0-pm2-5-m10-0/feed/";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:38:"http://purl.org/rss/1.0/modules/slash/";a:1:{s:8:"comments";a:1:{i:0;a:5:{s:4:"data";s:1:"2";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}}}s:27:"http://www.w3.org/2005/Atom";a:1:{s:4:"link";a:1:{i:0;a:5:{s:4:"data";s:0:"";s:7:"attribs";a:1:{s:0:"";a:3:{s:4:"href";s:28:"https://domo.rem81.com/feed/";s:3:"rel";s:4:"self";s:4:"type";s:19:"application/rss+xml";}}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}s:44:"http://purl.org/rss/1.0/modules/syndication/";a:2:{s:12:"updatePeriod";a:1:{i:0;a:5:{s:4:"data";s:9:" hourly ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}s:15:"updateFrequency";a:1:{i:0;a:5:{s:4:"data";s:4:" 1 ";s:7:"attribs";a:0:{}s:8:"xml_base";s:0:"";s:17:"xml_base_explicit";b:0;s:8:"xml_lang";s:0:"";}}}}}}}}}}}}s:4:"type";i:128;s:7:"headers";a:12:{s:6:"server";s:9:"openresty";s:4:"date";s:29:"Sat, 03 Feb 2024 16:54:02 GMT";s:12:"content-type";s:34:"application/rss+xml; charset=UTF-8";s:14:"content-length";s:5:"57255";s:12:"x-powered-by";s:10:"PHP/8.0.28";s:13:"last-modified";s:29:"Fri, 26 Jan 2024 10:26:27 GMT";s:4:"etag";s:39:""c3b2d72b112adbfb588eb3bd1ad9389d-gzip"";s:4:"link";s:57:"