HA-Intégrer et superviser un système Victron dans Home Assistant : Configuration MQTT, Modbus et Automatisation vers Node-RED

Intro

Dans cet article, je vous partage la configuration .yaml que j’ai mise en place dans Home Assistant pour superviser mon système Victron, composé d’un MultiPlus II, d’un MPPT 250/70, d’un SmartShunt, et de compteurs d’énergie (ET112). Cette configuration utilise les protocoles MQTT et Modbus pour récupérer et traiter les données, et inclut des capteurs personnalisés (via template) pour un affichage optimisé. En bonus, je vous présente deux automatisations (une pour envoyer des informations à Node-RED, une autre pour gérer la charge forcée en fonction de la couleur Tempo), ainsi que deux exemples de cartes Lovelace pour visualiser, contrôler et programmer ces données. Que vous souhaitiez suivre votre production solaire, l’état de vos batteries ou votre consommation, ce guide vous donnera une base solide pour intégrer un système Victron dans Home Assistant.

La configuration .yaml

Voici le fichier de configuration que j’ai ajouté à un fichier victron.yaml dans Home Assistant. Il est divisé en trois sections principales : mqtt, modbus, et template.

1. Section MQTT : Récupération des données via MQTT

Je commence par configurer des capteurs MQTT pour récupérer les données publiées par mon système Victron (via un broker MQTT, configuré séparément). Ces capteurs couvrent des métriques clés comme la tension des batteries, la puissance, l’état de charge (SOC), et les prévisions de production.

mqtt:
  sensor:
    # 1=Charger Only;2=Inverter Only;3=On;4=Off
    - name: "MP2 Mode Fonctionnement par MQTT"
      unique_id: "mp2_mode_fonctionnement_par_mqtt"
      state_topic: "mp2/multiplus2/mode"

    - name: "MP2 Tension Batteries par MQTT"
      unique_id: "mp2_tension_batteries_par_mqtt"
      state_topic: "mp2/batteries/tension"
      unit_of_measurement: 'V'
      device_class: voltage
      state_class: measurement

    - name: "MP2 Pu Batteries par MQTT"
      unique_id: "mp2_pu_batteries_par_mqtt"
      state_topic: "mp2/batteries/puissance"
      unit_of_measurement: 'W'
      device_class: power
      state_class: measurement

    - name: "MP2 Prod VRM MO MQTT"
      unique_id: "mp2_prod_vrm_mo_mqtt"
      state_topic: "mp2/prediction/prod_onduleur"
      unit_of_measurement: 'kW'
      device_class: power
      state_class: measurement

    - name: "MP2 Prod VRM MPPT1 MQTT"
      unique_id: "mp2_prod_vrm_mppt1_mqtt"
      state_topic: "mp2/prediction/prod_mppt1"
      unit_of_measurement: 'kW'
      device_class: power
      state_class: measurement

    - name: "MP2 Prod VRM TOTAL MQTT"
      unique_id: "mp2_prod_vrm_total_mqtt"
      state_topic: "mp2/prediction/prod_total"
      unit_of_measurement: 'kW'
      device_class: power
      state_class: measurement

    - name: "MP2 Pu Grid L1 AC MQTT"
      unique_id: "mp2_pu_grid_l1_mqtt"
      state_topic: "mp2/multiplus2/grid_l1_ac"
      unit_of_measurement: 'W'
      device_class: power
      state_class: measurement

    - name: "MP2 Conso Out1 MQTT"
      unique_id: "mp2_conso_ac_l1_mqtt"
      state_topic: "mp2/multiplus2/conso_out1"
      unit_of_measurement: 'W'
      device_class: power
      state_class: measurement

    - name: "MP2 Prod Totale MQTT"
      unique_id: "mp2_prod_totale_mqtt"
      state_topic: "mp2/multiplus2/prod_totale"
      unit_of_measurement: 'W'
      device_class: power
      state_class: measurement

    - name: "MP2 Cible SOC par MQTT"
      unique_id: "mp2_cible_soc_par_mqtt"
      state_topic: "mp2/batteries/cible_soc"
      unit_of_measurement: '%'
      device_class: battery
      state_class: measurement

    - name: "MP2 SOC theorique par JWT"
      unique_id: "mp2_soc_theorique_par_mqtt"
      state_topic: "mp2/batteries/soc_theorique"
      unit_of_measurement: '%'
      device_class: battery
      state_class: measurement

    - name: "MP2 SOC MQTT"
      unique_id: "mp2_soc_par_mqtt"
      state_topic: "mp2/batteries/soc"
      unit_of_measurement: '%'
      device_class: battery
      state_class: measurement

    - name: "MP2 SOC MINI MQTT"
      unique_id: "mp2_soc_mini_par_mqtt"
      state_topic: "mp2/multiplus2/soc_mini"
      unit_of_measurement: '%'
      device_class: battery
      state_class: measurement

    - name: "MP2 Intensité Batteries MQTT"
      unique_id: "mp2_intensite_batteries_mqtt"
      unit_of_measurement: "A"
      state_topic: "mp2/batteries/Courant"
      device_class: current
      state_class: measurement

2. Section MODBUS : Communication directe avec les appareils Victron

Ensuite, j’utilise le protocole Modbus pour communiquer directement avec mon Cerbo GX (adresse IP 192.168.0.86, port 502). Cette section récupère des données brutes des différents appareils Victron, comme le MultiPlus II, le MPPT, le SmartShunt, et les compteurs ET112.

modbus:
  - name: cerbo
    host: 192.168.0.86
    type: tcp
    port: 502
    switches:
      - name: "MP2 cde"
        slave: 227
        address: 33
        command_on: 3
        command_off: 4
        verify:
          input_type: holding
          address: 33
          state_on: 3
          state_off: 4

    sensors:
      # Compteur Photovoltaïque ET112-1 - GRID METER
      - name: "MP2 Energy Total Energy from net"
        unique_id: "mp2_total_energy_from_net"
        data_type: uint32
        slave: 31
        address: 2634
        scale: 0.01
        unit_of_measurement: "kWh"
        device_class: "energy"
        state_class: "total"

      - name: "MP2 Energy Total Energy to net"
        unique_id: "mp2_total_energy_to_net"
        data_type: uint32
        slave: 31
        address: 2636
        scale: 0.01
        unit_of_measurement: "kWh"
        device_class: "energy"
        state_class: "total"

      # Compteur Photovoltaïque ET112-2 - PVMETER
      - name: "MP2 Tension PV"
        unique_id: "mp2_tension_pv"
        data_type: uint16
        unit_of_measurement: "V"
        slave: 32
        address: 1027
        scale: 0.1
        device_class: voltage
        state_class: measurement

      - name: "MP2 Intensité PV"
        unique_id: "mp2_intensite_pv"
        data_type: int16
        unit_of_measurement: "A"
        slave: 32
        address: 1028
        scale: 0.1
        device_class: current
        state_class: measurement

      - name: "MP2 Puissance Production PV"
        unique_id: "mp2_puissance_production_pv"
        data_type: uint16
        unit_of_measurement: "W"
        slave: 32
        address: 1029
        scale: 1
        device_class: power
        state_class: measurement

      - name: "MP2 Energy Produite PV"
        unique_id: "mp2_energy_produite_pv"
        data_type: uint32
        slave: 32
        address: 1046
        scale: 0.01
        unit_of_measurement: "kWh"
        device_class: "energy"
        state_class: "total"

      # MPPT 250/70
      - name: "MP2 MPPT1 Tension PV"
        unique_id: "mp2_mppt1_tension_pv"
        data_type: uint16
        unit_of_measurement: "V"
        slave: 226
        address: 776
        scale: 0.01
        precision: 2
        device_class: voltage
        state_class: measurement

      - name: "MP2 MPPT1 Intensité PV"
        unique_id: "mp2_mppt1_intensite_pv"
        data_type: int16
        unit_of_measurement: "A"
        slave: 226
        address: 777
        scale: 0.1
        precision: 2
        device_class: current
        state_class: measurement

      - name: "MP2 MPPT1 Puissance Production PV"
        unique_id: "mp2_mppt1_puissance_production_pv"
        data_type: uint16
        unit_of_measurement: "W"
        slave: 226
        address: 789
        scale: 0.1
        device_class: power
        state_class: measurement

      # MultiPlus II
      - name: "MP2 PC AC Couplet on L1"
        unique_id: "mp2_pv_ac_coupled_on_l1"
        data_type: uint16
        unit_of_measurement: "W"
        slave: 100
        address: 811
        scale: 1
        device_class: power
        state_class: measurement

      - name: "MP2 Conso AC L1"
        unique_id: "mp2_conso_ac_l1"
        data_type: uint16
        unit_of_measurement: "W"
        slave: 100
        address: 817
        scale: 1
        device_class: power
        state_class: measurement

      - name: "MP2 Grid L1"
        unique_id: "mp2_grid_l1"
        data_type: int16
        unit_of_measurement: "W"
        slave: 100
        address: 820
        scale: 1
        device_class: power
        state_class: measurement

      - name: "MP2 Source Puissance"
        unique_id: "mp2_source_puissance"
        data_type: int16
        slave: 100
        address: 826
        scale: 1

      - name: "MP2 Tension Batteries"
        unique_id: "mp2_tension_batteries"
        data_type: uint16
        unit_of_measurement: "V"
        slave: 100
        address: 840
        scale: 0.1
        precision: 2
        device_class: voltage
        state_class: measurement

      - name: "MP2 Intensité Batteries"
        unique_id: "mp2_intensite_batteries"
        data_type: int16
        unit_of_measurement: "A"
        slave: 100
        address: 841
        scale: 0.1
        precision: 2
        device_class: current
        state_class: measurement

      - name: "MP2 Puissance Batteries"
        unique_id: "mp2_puissance_batteries"
        data_type: int16
        unit_of_measurement: "W"
        slave: 100
        address: 842
        scale: 1
        device_class: power
        state_class: measurement

      - name: "MP2 Status Batteries"
        unique_id: "mp2_status_batteries"
        data_type: int16
        slave: 100
        address: 844
        scale: 1

      - name: "MP2 Puissance PV"
        unique_id: "mp2_puissance_pv"
        data_type: uint16
        unit_of_measurement: "W"
        slave: 100
        address: 850
        scale: 1
        device_class: power
        state_class: measurement

      - name: "MP2 Puissance reseau DC"
        unique_id: "mp2_puissance_reseau_dc"
        data_type: int16
        unit_of_measurement: "W"
        slave: 100
        address: 860
        scale: 1
        device_class: power
        state_class: measurement

      - name: 'MP2 P Max alim System'
        unique_id: 'mp2_p_max_alim_system'
        unit_of_measurement: "W"
        device_class: power
        state_class: measurement
        slave: 100
        address: 2700
        data_type: int16

      - name: 'MP2 ESS Puissance Decharge Max'
        unique_id: 'mp2_ess_puissance_decharge_maximum'
        unit_of_measurement: "W"
        device_class: power
        state_class: measurement
        data_type: uint16
        slave: 100
        address: 2704
        scale: 10

      # SmartShunt
      - name: "MP2 SS Tension Batteries"
        unique_id: "mp2_ss_tension_batteries"
        data_type: uint16
        unit_of_measurement: "V"
        slave: 223
        address: 259
        scale: 0.01
        device_class: voltage
        state_class: measurement

      - name: "MP2 SS Tension Start Batteries"
        unique_id: "mp2_ss_tension_start_batteries"
        data_type: uint16
        unit_of_measurement: "V"
        slave: 223
        address: 260
        scale: 0.01
        device_class: voltage
        state_class: measurement

      - name: "MP2 SS Intensité Batteries"
        unique_id: "mp2_ss_intensite_batteries"
        data_type: int16
        unit_of_measurement: "A"
        slave: 223
        address: 261
        scale: 0.1
        device_class: current
        state_class: measurement

      - name: "MP2 SS Conso Ah Batteries"
        unique_id: "mp2_ss_conso_ah_batteries"
        data_type: int16
        unit_of_measurement: "Ah"
        slave: 223
        address: 265
        scale: 0.1
        state_class: measurement

      - name: "MP2 Temps depuis derniere pleine batteries"
        unique_id: "mp2_temps_depuis_derniere_batteries_pleines"
        data_type: uint16
        unit_of_measurement: "s"
        slave: 223
        address: 289
        scale: 100
        device_class: duration
        state_class: measurement

      - name: "MP2 Energy décharge batteries"
        unique_id: "mp2_energy_decharge_batteries"
        data_type: uint16
        slave: 223
        address: 301
        scale: 0.1
        unit_of_measurement: "kWh"
        device_class: "energy"
        state_class: "total"

      - name: "MP2 Energy charge batteries"
        unique_id: "mp2_energy_charge_batteries"
        data_type: uint16
        slave: 223
        address: 302
        scale: 0.1
        unit_of_measurement: "kWh"
        device_class: "energy"
        state_class: "total"

      - name: "MP2 Temps restant batteries"
        unique_id: "mp2_temps_restant_batteries"
        data_type: uint16
        unit_of_measurement: "s"
        slave: 223
        address: 303
        scale: 100
        device_class: duration
        state_class: measurement

      # MultiPlus II (suite)
      - name: "MP2 Tension Entrée L1"
        unique_id: "mp2_tension_entree_l1"
        data_type: uint16
        unit_of_measurement: "V"
        slave: 227
        address: 3
        scale: 0.1
        device_class: voltage
        state_class: measurement

      - name: "MP2 Intensité Entrée L1"
        unique_id: "mp2_intensite_entree_l1"
        data_type: int16
        unit_of_measurement: "A"
        slave: 227
        address: 6
        scale: 0.1
        device_class: current
        state_class: measurement

      - name: "MP2 Fréquence Entrée L1"
        unique_id: "mp2_frequence_entree_l1"
        data_type: int16
        unit_of_measurement: "Hz"
        slave: 227
        address: 9
        scale: 0.01
        device_class: frequency
        state_class: measurement

      - name: "MP2 Tension Sortie L1"
        unique_id: "mp2_tension_sortie_l1"
        data_type: uint16
        unit_of_measurement: "V"
        slave: 227
        address: 15
        scale: 0.1
        device_class: voltage
        state_class: measurement

      - name: "MP2 Intensité Sortie L1"
        unique_id: "mp2_intensite_sortie_l1"
        data_type: int16
        unit_of_measurement: "A"
        slave: 227
        address: 18
        scale: 0.1
        device_class: current
        state_class: measurement

      - name: "MP2 Fréquence Sortie"
        unique_id: "mp2_frequence_sortie"
        data_type: int16
        unit_of_measurement: "Hz"
        slave: 227
        address: 21
        scale: 0.01
        device_class: frequency
        state_class: measurement

      - name: "MP2 Puissance Sortie 1"
        unique_id: "mp2_puissance_sortie_1"
        data_type: int16
        unit_of_measurement: "W"
        slave: 227
        address: 23
        scale: 10
        device_class: power
        state_class: measurement

      - name: "MP2 Status bus VE"
        unique_id: "mp2_status_bus_ve"
        slave: 227
        address: 31
        data_type: uint16
        scale: 1

      - name: "MP2 Mode ESS"
        unique_id: mp2_mode_ess
        slave: 227
        address: 33
        data_type: uint16
        scale: 1

      - name: 'Mp2 Alarme perte réseau'
        unique_id: mp2_alarme_perte_reseau
        data_type: uint16
        slave: 227
        address: 64
        scale: 1

3. Section TEMPLATE : Capteurs personnalisés pour un affichage optimisé

Enfin, j’utilise des capteurs template pour transformer les données brutes en informations plus lisibles et utiles. Par exemple, je convertis des codes numériques en texte (comme le mode de fonctionnement ou l’état des batteries) et je calcule des métriques comme le temps restant avant que les batteries n’atteignent leur SOC minimum.

    template:
      - sensor:
          # Alarme Perte Réseau
          - name: "MP2 Alarme Perte Reseau Affichage"
            unique_id: 'mp2_alarme_perte_reseau_affichage'
            state: >-
              {% set st = states('sensor.mp2_alarme_perte_reseau') | int(default=0) %}
              {% for num, text in [(0,'Normal'),(2, 'Perte Reseau')] %}
                  {% if st == num %}
                    {{ text }}
                  {%endif%}
              {% endfor %}
    
          # Mode de fonctionnement
          - name: "MP2 Mode Fonctionnement Texte"
            unique_id: "mp2_mode_fonctionnement_texte"
            state: >-
              {% set st = states('sensor.mp2_mode_fonctionnement_par_mqtt') | int(default=0) %}
              {% for num, text in [(0,'Défaut'),(1, 'Chargeur Seul'), (2, 'Convertisseur Seul'),(3, 'Normal'),(4, 'Arret')] %}
                  {% if st == num %}
                    {{ text }}
                  {%endif%}
              {% endfor %}
    
          # Charge AC
          - name: MP2_ac_loads
            unique_id: "mp2_ac_loads"
            device_class: "power"
            state_class: "measurement"
            unit_of_measurement: "W"
            state: >-
              {% set l1=states('sensor.mp2_conso_ac_l1')|int(default=0)%}
              {% set out1=states('sensor.mp2_puissance_sortie_1')|int(default=0)%}
              {{ l1-out1 }}
    
          # Statut bus VE
          - name: "Mp2 Affichage Status Bus VE"
            unique_id: "mp2_affichage_status_bus_ve"
            state: >-
              {% set st = states('sensor.mp2_status_bus_ve') | int(default=0) %}
              {% for num, text in [(0, 'Off'), (1, 'Low power'),(2, 'Defaut'),(3, 'Bulk'),(4, 'Absorption'),(5, 'Float'),(6, 'Stockage'),(7, 'Equalize'),(8, 'Traverse'),(9, 'Inverser'),(10, 'Power Assist'),(11, 'Power Supply'),(252, 'PControl externe')] %}
                  {% if st == num %}
                    {{ text }}
                  {%endif%}
              {% endfor %}
    
          # Statut charge batteries
          - name: "Mp2 Affichage Status Charge Batteries"
            unique_id: "mp2_affichage_status_charge_batteries"
            state: >-
              {% set st = states('sensor.mp2_status_batteries') | int(default=0) %}
              {% for num, text in [(0, 'Off'), (1, 'Charge'),(2, 'DeCharge')] %}
                  {% if st == num %}
                    {{ text }}
                  {%endif%}
              {% endfor %}
    
          # Puissance de charge/décharge
          - name: "MP2 Pu charge batterie"
            unique_id: "mp2_pu_charge_batterie"
            device_class: "power"
            state_class: "measurement"
            unit_of_measurement: "W"
            state: >-
              {{ max(0, states('sensor.mp2_pu_batteries_par_mqtt') | float(default=0)) }}
    
          - name: "MP2 Pu decharge batterie"
            unique_id: "mp2_pu_decharge_batterie"
            device_class: "power"
            state_class: "measurement"
            unit_of_measurement: "W"
            state: >-
              {{ max(0, 0 - states('sensor.mp2_pu_batteries_par_mqtt') | float(default=0)) }}
    
          # Puissance injectée/soutirée
          - name: "MP2 Pu Grid Mqtt Soutirée"
            unique_id: "mp2_pu_grid_l1_mqtt_soutiree"
            device_class: "power"
            state_class: "measurement"
            unit_of_measurement: "W"
            state: >-
              {{ max(0, states('sensor.mp2_pu_grid_l1_ac_mppt') | float(default=0)) }}
    
          - name: "MP2 Pu Grid Mqtt Injectée"
            unique_id: "mp2_pu_grid_l1_mqtt_injectee"
            device_class: "power"
            state_class: "measurement"
            unit_of_measurement: "W"
            state: >-
              {{ max(0, 0 - states('sensor.mp2_pu_grid_l1_ac_mppt') | float(default=0)) }}
    
          # Temps restant et durée depuis dernière charge
          - name: "MP2 affichage Autonomie Restante Batteries"
            unique_id: mp2_affichage_autonomie_restante_batteries
            state: >-
              {{ states('sensor.mp2_temps_restant_batteries')|int(default=0)|timestamp_custom('%H:%M:%S', false) }}
    
          - name: "MP2 affichage Temps Depuis Derniere Charge"
            unique_id: mp2_affichage_temps_depuis_derniere_charge
            state: >-
              {{ states('sensor.mp2_temps_depuis_derniere_pleine_batteries')|int(default=0)|timestamp_custom('%H:%M:%S', false) }}
    
          # Temps restant jusqu’au SOC minimum
          - name: "MP2 Temps Restant Batteries Mini SOC"
            unique_id: "mp2_temps_restant_batteries_mini_soc"
            unit_of_measurement: "h"
            device_class: "duration"
            icon: mdi:sort-clock-ascending
            state: >-
              {% set battery_current = states('sensor.mp2_intensite_batteries')|float %}
              {% set battery_soc = states('sensor.mp2_soc_mqtt')|float %}
              {% set loads_current = states('sensor.mp2_conso_out1_mqtt')|float/states('sensor.mp2_tension_batteries_par_mqtt')|float %}
              {% set battery_min_soc = states('sensor.mp2_soc_mini_mqtt')|float %}
              {% set battery_max_capacity = 300 %}
              {% if (battery_soc-battery_min_soc) < 0 %}
                {{ 0 }}
              {% else %}
                {{ ((((battery_soc-battery_min_soc)*battery_max_capacity)/100)/loads_current | float ) | round(2) }}
              {% endif %}

    Automatisations

    Envoi des informations de Home Assistant vers Node-RED

    Pour aller plus loin dans l’intégration entre Home Assistant et Node-RED, j’ai créé une automatisation qui envoie des informations clés de Home Assistant vers Node-RED via MQTT. Cela permet à Node-RED de prendre des décisions basées sur l’état de mon système, par exemple pour ajuster dynamiquement la charge des batteries ou le mode de fonctionnement du MultiPlus II. Voici l’automatisation que j’ai mise en place.

    Code de l’automatisation

    Cette automatisation, nommée « Recopie Etat HA vers NR MP2 », est déclenchée soit toutes les heures, soit lorsqu’un des capteurs ou entrées surveillés change d’état. Elle publie ensuite les valeurs correspondantes sur des topics MQTT que Node-RED peut écouter.

    alias: Recopie Etat HA vers NR MP2
    description: Lien entre HA et le Node-RED du MP2
    mode: single
    triggers:
      - id: mn
        hours: /1
        trigger: time_pattern
      - entity_id:
          - input_boolean.mp2_valid_ess_charge_prog_1
          - input_boolean.forcage_charge_pgm_mp2_100
          - input_number.mp2_niveau_forcage_cp1
          - sensor.linky_ptec
        trigger: state
    conditions: []
    actions:
      - action: mqtt.publish
        metadata: {}
        data:
          evaluate_payload: false
          qos: "0"
          retain: false
          topic: ha/mp2/cp/validcp
          payload: "\"{{ states('input_boolean.mp2_valid_ess_charge_prog_1') }}\""
      - action: mqtt.publish
        metadata: {}
        data:
          evaluate_payload: false
          qos: "0"
          retain: false
          topic: ha/mp2/cp/forcage100
          payload: "\"{{ states('input_boolean.forcage_charge_pgm_mp2_100') }}\""
      - action: mqtt.publish
        metadata: {}
        data:
          evaluate_payload: false
          qos: "0"
          retain: false
          topic: ha/mp2/cp/niveauforcagecp1
          payload: "\"{{ states('input_number.mp2_niveau_forcage_cp1') }}\""
      - action: mqtt.publish
        metadata: {}
        data:
          evaluate_payload: false
          qos: "0"
          retain: false
          topic: ha/mp2/cp/hc
          payload: "\"{{ states('sensor.linky_ptec') }}\""

    Explications de l’automatisation

    1. Déclencheurs :
      • Toutes les heures (time_pattern: hours: /1) : Cela garantit que Node-RED reçoit les informations même si aucun changement d’état n’a lieu.
      • Changement d’état (trigger: state) : L’automatisation se déclenche dès qu’un des capteurs ou entrées suivants change :
        • input_boolean.mp2_valid_ess_charge_prog_1 : Indique si le programme de charge ESS est valide.
        • input_boolean.forcage_charge_pgm_mp2_100 : Indique si un forçage de charge à 100 % est activé.
        • input_number.mp2_niveau_forcage_cp1 : Niveau de forçage pour le programme de charge.
        • sensor.linky_ptec : Période tarifaire en cours (par exemple, Heures Creuses ou Heures Pleines, via l’intégration Linky).
    2. Actions :
      • L’automatisation publie les valeurs des entités sur des topics MQTT spécifiques :
        • ha/mp2/cp/validcp : État du programme de charge ESS.
        • ha/mp2/cp/forcage100 : État du forçage à 100 %.
        • ha/mp2/cp/niveauforcagecp1 : Niveau de forçage.
        • ha/mp2/cp/hc : Période tarifaire (HC/HP).
      • Les messages sont envoyés avec un QoS de 0 (pas de garantie de livraison) et sans rétention (retain: false), pour éviter d’encombrer le broker MQTT.

    Utilité de cette automatisation

    Cette automatisation permet à Node-RED de recevoir des informations en temps réel (ou toutes les heures) sur l’état de mon système dans Home Assistant. Par exemple :

    • Node-RED peut ajuster le SOC cible du MultiPlus II en fonction des heures creuses (sensor.linky_ptec).
    • Si un forçage de charge à 100 % est activé (input_boolean.forcage_charge_pgm_mp2_100), Node-RED peut déclencher une logique spécifique, comme désactiver d’autres automatisations.
    • Le niveau de forçage (input_number.mp2_niveau_forcage_cp1) peut être utilisé pour moduler la charge des batteries.

    Dans mon cas, Node-RED utilise ces données pour optimiser la gestion de la charge des batteries en fonction des tarifs électriques et des prévisions de production solaire (comme vu dans mes articles précédents sur Node-RED et Victron).

    Activation de la charge forcée en cas de Tempo Rouge

    Pour optimiser encore davantage la gestion de la charge de mes batteries, j’ai ajouté une automatisation qui active ou désactive les programmations de charge forcée en fonction de la couleur Tempo du lendemain, détectée via le capteur sensor.rte_tempo_prochaine_couleur. Cette automatisation s’assure que la charge forcée (définie dans la carte custom:scheduler-card présentée plus loin) est activée uniquement les jours précédant une journée Tempo rouge, où les tarifs électriques sont plus élevés.

    Code de l’automatisation

    Cette automatisation, nommée « Activation Forcage Charge Programmée 1 si tempo Rouge », est déclenchée par un changement d’état du capteur sensor.rte_tempo_prochaine_couleur. Elle active les programmations de charge forcée si la couleur passe à « Rouge », et les désactive si la couleur n’est plus « Rouge ».

    alias: Activation Forcage Charge Programmée 1 si tempo Rouge
    description: ""
    triggers:
      - trigger: state
        entity_id:
          - sensor.rte_tempo_prochaine_couleur
        to: Rouge
        id: vers_rouge
      - trigger: state
        entity_id:
          - sensor.rte_tempo_prochaine_couleur
        id: sortie_rouge
        from: Rouge
    conditions: []
    actions:
      - choose:
          - conditions:
              - condition: trigger
                id:
                  - vers_rouge
            sequence:
              - action: switch.turn_on
                target:
                  entity_id:
                    - switch.schedule_e7a1a2
                    - switch.schedule_6aebea
                data: {}
          - conditions:
              - condition: trigger
                id:
                  - sortie_rouge
            sequence:
              - action: switch.turn_off
                target:
                  entity_id:
                    - switch.schedule_e7a1a2
                    - switch.schedule_6aebea
                data: {}
    mode: single

    Explications de l’automatisation

    1. Déclencheurs :
      • Passage à Tempo Rouge (id: vers_rouge) : L’automatisation se déclenche lorsque sensor.rte_tempo_prochaine_couleur passe à l’état « Rouge », indiquant que le lendemain sera une journée Tempo rouge.
      • Sortie de Tempo Rouge (id: sortie_rouge) : L’automatisation se déclenche lorsque sensor.rte_tempo_prochaine_couleur quitte l’état « Rouge », indiquant que le lendemain ne sera plus une journée Tempo rouge.
    2. Actions :
      • Si passage à Tempo Rouge : L’action switch.turn_on active deux interrupteurs :
        • switch.schedule_e7a1a2 : Correspond à l’interrupteur de la programmation définie dans la carte custom:scheduler-card (présentée plus loin).
        • switch.schedule_6aebea : Un autre interrupteur de programmation, potentiellement pour une autre période ou un autre scénario de charge.
      • Si sortie de Tempo Rouge : L’action switch.turn_off désactive les mêmes interrupteurs, suspendant ainsi les programmations de charge forcée.
    3. Mode : mode: single garantit que l’automatisation ne s’exécute qu’une seule fois par déclencheur, évitant des exécutions multiples en cas de changements rapides d’état.

    Utilité de cette automatisation

    Cette automatisation est un complément essentiel à la carte custom:scheduler-card présentée plus haut, qui programme la charge forcée pendant les heures creuses (22h00 à 6h00). En activant les programmations uniquement les jours précédant une journée Tempo rouge, je m’assure que ma batterie est chargée à 100 % (ou au niveau défini dans input_number.mp2_niveau_forcage_cp1) pour affronter les tarifs élevés du lendemain. Si le lendemain n’est pas une journée Tempo rouge, les programmations sont désactivées pour éviter une charge inutile, optimisant ainsi l’utilisation de l’énergie solaire et réduisant les coûts.

    Visualisation dans Home Assistant :

    Exemple de carte Lovelace

    Pour rendre toutes ces données et contrôles facilement accessibles, j’ai créé une carte dans Home Assistant en utilisant l’interface Lovelace. Cette carte regroupe les informations clés et les entrées utilisateur liées à mon MultiPlus II (MP2) et à mes automatisations Node-RED. Voici le code YAML de la carte que j’utilise :

    type: entities
    entities:
      - entity: input_boolean.mp2_valid_ess_charge_prog_1
        secondary_info: last-changed
      - entity: sensor.mp2_prod_vrm_total_mqtt
        secondary_info: last-updated
      - entity: sensor.mp2_soc_mqtt
        secondary_info: last-updated
      - entity: sensor.mp2_cible_soc_par_mqtt
        secondary_info: last-updated
      - entity: input_number.mp2_memoire_estimation_production_jour
        secondary_info: last-updated
      - entity: sensor.mp2_total_energie_produite_jour
      - entity: input_boolean.forcage_charge_pgm_mp2_100
      - entity: input_number.mp2_niveau_forcage_cp1
    title: Automatismes MP2 NodeRed
    show_header_toggle: false
    state_color: true

    Explications de la carte

    • Type de carte : J’utilise une carte de type entities, qui permet d’afficher une liste d’entités avec leurs états et des options de contrôle.
    • Entités affichées :
      • input_boolean.mp2_valid_ess_charge_prog_1 : Un interrupteur pour activer/désactiver le programme de charge ESS, avec l’heure de la dernière modification (last-changed).
      • sensor.mp2_prod_vrm_total_mqtt : La production totale prévue (via VRM), mise à jour avec l’heure de la dernière actualisation (last-updated).
      • sensor.mp2_soc_mqtt : L’état de charge (SOC) actuel des batteries.
      • sensor.mp2_cible_soc_par_mqtt : Le SOC cible défini pour les batteries.
      • input_number.mp2_memoire_estimation_production_jour : Une entrée numérique pour mémoriser l’estimation de production journalière.
      • sensor.mp2_total_energie_produite_jour : L’énergie totale produite dans la journée (non défini dans la configuration précédente, mais ajouté ici pour le suivi).
      • input_boolean.forcage_charge_pgm_mp2_100 : Un interrupteur pour forcer la charge des batteries à 100 %.
      • input_number.mp2_niveau_forcage_cp1 : Une entrée numérique pour définir le niveau de forçage de la charge.
    • Options :
      • title: Automatismes MP2 NodeRed : Le titre de la carte, qui reflète son objectif.
      • show_header_toggle: false : Désactive l’interrupteur global dans l’en-tête de la carte.
      • state_color: true : Active la coloration des états (par exemple, les interrupteurs s’affichent en vert lorsqu’ils sont activés).

    Pourquoi cette carte ?

    Cette carte me permet de visualiser rapidement les informations essentielles (SOC, production, énergie produite) et de contrôler les paramètres de charge (forçage, niveau de forçage) directement depuis mon tableau de bord. Les indications last-changed et last-updated sont utiles pour vérifier la fraîcheur des données et des actions. C’est un complément parfait à la configuration et à l’automatisation décrites plus haut, car elle rend l’ensemble interactif et visuel.

    Gestion de la charge programmée : Une carte pour les heures creuses

    En complément de la carte précédente, j’utilise une autre carte personnalisée, basée sur le composant custom:scheduler-card, pour programmer et valider la charge forcée de mes batteries à un niveau de SOC défini dans input_number.mp2_niveau_forcage_cp1 (souvent 100 %). Cette programmation est configurée pour se déclencher pendant les heures creuses, de 22h00 à 6h00, afin de commencer une journée Tempo rouge avec une batterie pleinement chargée. Voici le code YAML de cette carte :

    type: custom:scheduler-card
    discover_existing: false
    display_options:
      icon: mdi:radiator
      primary_info:
        - <b>{entity} / {name}</b>
        - "<b>Next</b> : {relative-time} | <b>Action</b> : {action}"
        - additional-tasks
      secondary_info:
        - "{days} {time}"
    include:
      - input_boolean.forcage_charge_pgm_mp2_100
    title: Forcage CP1
    how_header_toggle: false
    style: |
      ha-card {
        border: solid 2px var(--primary-color);
      }
    show_header_toggle: true
    exclude: []

    Explications de la carte

    • Type de carte : J’utilise custom:scheduler-card, un composant personnalisé qui permet de programmer des actions dans Home Assistant (il faut l’installer via HACS ou manuellement si ce n’est pas déjà fait).
    • Objectif : Cette carte gère l’activation de input_boolean.forcage_charge_pgm_mp2_100 pour forcer la charge des batteries à un niveau de SOC défini dans input_number.mp2_niveau_forcage_cp1 (souvent 100 %). La programmation est configurée pour les heures creuses (22h00 à 6h00), ce qui me permet d’optimiser la charge avant une journée Tempo rouge, où les tarifs électriques sont plus élevés.
    • Options :
      • discover_existing: false : Désactive la découverte automatique des programmations existantes, pour un contrôle manuel.
      • display_options : Personnalise l’affichage de la carte :
        • icon: mdi:radiator : Utilise une icône de radiateur pour représenter la charge.
        • primary_info : Affiche le nom de l’entité, l’heure de la prochaine action, et les tâches supplémentaires.
        • secondary_info : Montre les jours et l’heure de la programmation (par exemple, « Tous les jours 22:00 »).
      • include: input_boolean.forcage_charge_pgm_mp2_100 : Seule cette entité est incluse dans la programmation.
      • title: Forcage CP1 : Le titre de la carte, qui indique qu’elle concerne le forçage de la charge programmée (CP1).
      • style : Ajoute une bordure colorée autour de la carte, en utilisant la couleur principale du thème Home Assistant.
      • show_header_toggle: true : Affiche un interrupteur dans l’en-tête pour activer/désactiver rapidement la programmation.

    Pourquoi cette carte ?

    Cette carte est essentielle pour gérer automatiquement la charge de mes batteries pendant les heures creuses, en anticipant les journées Tempo rouge où l’électricité est plus chère. En programmant le forçage de la charge à 100 % entre 22h00 et 6h00, je m’assure que ma batterie est prête à alimenter ma maison dès le matin, réduisant ainsi ma dépendance au réseau pendant les heures coûteuses. La visualisation claire de la prochaine action et des horaires me permet de vérifier facilement que tout est bien configuré.

    Ce que cette configuration m’apporte

    Grâce à cette configuration, à l’automatisation, et à la visualisation via Lovelace, j’ai une vue complète et détaillée de mon système Victron dans Home Assistant :

    • Production solaire : Je peux suivre la production de mes panneaux (via le MPPT et le compteur PV) et l’énergie totale produite.
    • Batteries : Je surveille le SOC, la tension, le courant, la puissance de charge/décharge, et même le temps restant avant d’atteindre le SOC minimum.
    • Réseau : Je vois l’énergie injectée ou soutirée du réseau, ainsi que la consommation AC.
    • Supervision et contrôle : Les capteurs template me permettent d’afficher des informations claires (par exemple, « Charge » au lieu d’un simple 1) et de calculer des métriques utiles comme l’autonomie restante. L’automatisation vers Node-RED ajoute une couche de contrôle dynamique, en permettant à Node-RED de réagir aux changements dans Home Assistant. L’automatisation pour les jours Tempo rouge garantit que la charge forcée est activée uniquement quand c’est nécessaire, optimisant les coûts. Enfin, les cartes Lovelace me donnent un accès rapide et visuel à toutes ces données, avec la possibilité de programmer des actions comme la charge forcée pendant les heures creuses.

    Ces données sont ensuite utilisées dans des tableaux de bord Home Assistant (comme ceux montrés ci-dessus) et dans Node-RED pour des automatisations, comme ajuster le SOC cible en fonction des prévisions solaires ou des tarifs électriques.

    Prérequis pour reproduire ce projet

    • Un système Victron avec un Cerbo GX (ou équivalent) connecté à votre réseau.
    • L’intégration MQTT configurée dans Home Assistant, avec un broker MQTT actif.
    • L’intégration Modbus activée dans Home Assistant (via modbus dans configuration.yaml).
    • Les capteurs MQTT doivent être publiés par un autre système (par exemple, un script ou Node-RED, comme mentionné dans mes articles précédents).
    • Node-RED installé et configuré pour écouter les topics MQTT publiés par l’automatisation.
    • Les entités comme input_boolean.mp2_valid_ess_charge_prog_1, input_boolean.forcage_charge_pgm_mp2_100, input_number.mp2_niveau_forcage_cp1, et sensor.linky_ptec doivent être créées dans Home Assistant (via des helpers ou des intégrations comme Linky).
    • Pour l’automatisation Tempo, l’intégration RTE Tempo doit être configurée pour fournir le capteur sensor.rte_tempo_prochaine_couleur.
    • Les interrupteurs switch.schedule_e7a1a2 et switch.schedule_6aebea doivent exister et être associés aux programmations de la carte custom:scheduler-card.
    • Une compréhension de base des registres Modbus (les adresses utilisées ici sont spécifiques aux appareils Victron).
    • Pour les cartes Lovelace, assurez-vous que toutes les entités listées existent dans votre configuration Home Assistant.
    • Pour la carte custom:scheduler-card, vous devez installer ce composant personnalisé via HACS ou manuellement.

    Conclusion

    Si vous avez un système Victron, cette configuration est une excellente base pour l’intégrer dans Home Assistant, interagir avec Node-RED, et visualiser vos données dans un tableau de bord Lovelace. Vous pouvez l’adapter à vos appareils (en ajustant les adresses Modbus ou les topics MQTT) et personnaliser les capteurs template, les automatisations, et les cartes selon vos besoins. Ce projet m’a permis de mieux comprendre et optimiser mon installation photovoltaïque, et j’espère qu’il vous inspirera ! N’hésitez pas à partager vos propres configurations ou questions en commentaire.

    Liste des publications en lien avec cet article:

    Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *