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:"

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, 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.

Mise à Jour:

Liste des courses:

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.

Principe de fonctionnement

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.

La Partie Matérielle

Schéma Electronique:

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.

Modification du refroidissement du triac

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.

La partie logicielle:

Capteur JSY-MK-194T

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:

JSY-MK-194TTélécharger

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

Codage ESP

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

Paramètres:

Vous pouvez régler:

Vous pouvez piloter:

Grandeurs physiques:

Vous retrouverez:

Automatisation:

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

Affichage Local:

Localement j’affiche:

Résultats:

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.

Liens vers des routeurs à monter soi-même:

Bien entendu cette liste est non exhaustive, si vous avez d’autres liens, n’hésiter pas à me les transmettre, je les ajouterai.

Conclusion

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:"

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.

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.

Présentation du PVROUTEUR de Cyril.

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.

Ma solution.

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%.

La partie matériel:

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.

La partie logiciel:

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.

Code Node red.

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 ».

Algorithme de régulation.

J’ai fait simple, le principe retenu est le suivant:

PalierPu (W)Incrément
Palier 000
Palier 1101
Palier 2501
Palier 31002
Palier 42003
Palier 53004
Palier 66006
Palier 79007
Tableau des paliers programmés dans NR

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.

Courbes de résultat:

A compléter quand j’aurai d’autres courbes significatives à montrer.

Vue HA:

Solution alternative.

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.

Liens vers des routeurs à monter soi-même:

Bien entendu cette liste est non exhaustive, si vous avez d’autres liens, n’hésiter pas à me les transmettre, je les ajouterai.

Conclusion:

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.

Annexe:

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:"

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 but est de le rendre indépendant de toute source d’alimentation, la limite étant celle du Wi-Fi.

Partie matérielle

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.

Liste des courses

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.

Schéma électronique

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.

Circuit Imprimé

É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.

CAMOutputsTélécharger

Mise en oeuvre

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.

Partie Logicielle

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

Mise en veille de l’ESP:

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. ».

Mesure VCC

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:

Code YAML

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

Quelques vues d’exemple:

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

Conclusion:

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:"

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 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.

Présentation du Module

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.

Utilisation du module

Premier flashage du module:

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.

Programme ESPHOME

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.

Autres cartes:

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:

Un relais mais pas d’alim Courant Alternatif.

Deux relais mais pas d’alim Courant Alternatif.

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

Quatre relais avec alim Courant Alternatif.

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

Conclusion

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:"

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 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.

Terminologie:

Commençons par décrire les termes communément employés dans cet article:

Solution proposée

Mis en oeuvre d’un routeur photovoltaïque.

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.

Modifications électriques du tableau principal

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.

Modification électrique du ballon

Thermostat électromécanique

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.

Thermostat électronique

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.

Ballon Thermodynamique

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.

Mesure de température de l’eau

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.

Schéma Electronique

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

Exemple de circuit imprimé conçu 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, faut pas etre pressé et c’est quantité 5 minimum, exemple en dessous pour ce PCB: 1.99+3.46€!!

Code de l’ESP01

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"

Automatismes

Cahier des charges:

Mode Automatique:

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:

Mode Arrêt Forcé:

Dans ce mode, je coupe les relais ECS_Réseau et ECS_PV.

Mode Marche Forcé:

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é.

Script gestion relais

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:

Code de l’automatisme:

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

Tableau de bord:

Exemple de carte

Code de la carte

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

Déclaration de entités:

####################################################
#                                                  #
#              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%}



Conclusion:

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:"

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. Bien entendu HA est toujours de la partie.

Terminologie

Commençons par décrire les termes communement employés dans ce domaine:

Descriptif de mon installation

Commencée en mai 2021, la première phase de mon installation comprend:

Schéma électrique du coffret.

M_CAQM1-coffret-AC-Mono-1-Qrelais_1WilandTélécharger

Le matériel a été commandé chez Oscaro Power, à l’époque pas de problème de délai.

Détail du matériel utilisé.

2021-001294-2Télécharger

Choix des micro onduleurs

Points positifs:

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.

Points négatifs:

Tous n’est pas tout rose dans cette solution, il y a également des points négatifs:

Remarques sur les MO:

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:

Extension Août 2022

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é:

2022-007478Télécharger

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.

Conclusion

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:"

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 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).

Premier Flashage

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é.

Exploitation

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 »:

Intégration dans HA

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.

Mise à Jour

Une fois connecté à votre réseau, plus besoin d’utiliser le FTDI232, la mise à jour est à transférer comme d’habitude, via la « Wirelessly ».

Conclusion

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:"

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 loin des valeurs habituelles.

Méthodologie apres 2022-04

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.

Modifications des données avant 2022-04

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.

Prè requis pour ce tuto

Avertissements

Mode opératoire

Recherche de l’ID de l’entité concerné

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

Modification de la table « statistics »

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.

Requete SQL:

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 ».

Modification de la table « statistics_short_term »

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 »

Conclusion

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:"

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 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.

Conversion de la puissance en énergie

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:

Methode de Riemann

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,..)

Autre méthode de calcul

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.

Configuration des compteurs de service.

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.

Exploitation des compteurs

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.

Selon une plage horaire fixe

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 ».

Selon plusieurs plages horaires fixes

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

Selon une plage horaire paramétrable

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

Avec l’information HP/HC du Linky

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

Calcul du cout de l’énergie

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"

Tableau de bord

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/ .

Conclusion

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:"

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 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.

Descriptif matériel

Capteur de particules PMS 5003

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

pms5003-english-v2.3Télécharger

Capteur de Co2

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

ESP32 Mini

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.

Afficheur Oled

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.

Bandeau led

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

Mise en oeuvre

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 »

Schéma Electronique

Circuit imprimé

Mise en boitier

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

Logiciel

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

Code ESP Home

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

      

Affichage Local

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

Conclusion

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:"; rel=https://api.w.org/";s:4:"vary";s:15:"Accept-Encoding";s:16:"content-encoding";s:4:"gzip";s:25:"strict-transport-security";s:25:"max-age=63072000; preload";s:11:"x-served-by";s:14:"domo.rem81.com";}s:5:"build";s:14:"20231030185604";s:5:"mtime";i:1706979242;s:3:"md5";s:32:"d6a21b576455c2037a395c3180b02cce";}