Home Assistant - Zendure automation MQTT and QCELLs YAML alias: __Zendure_New_Automation v4 description: "" triggers:   - trigger: time_pattern     seconds: /30 conditions: [] actions:   - sequence: []   - alias: HP ou HC ?     choose:       - conditions:           - condition: state             entity_id: sensor.linky_current_price             state:               - HEURE PLEINE         sequence:           - alias: Etat de QCELLS             choose:               - conditions:                   - condition: state                     entity_id: sensor.qcells_etat                     state:                       - Standby                 sequence:                   - alias: >-                       Si il est à -10% (vide) alors on compense si nécessaire                       avec SF2400                     choose:                       - conditions:                           - condition: and                             conditions:                               - type: is_battery_level                                 condition: device                                 device_id: afda895cc1812b99521eb78710326b89                                 entity_id: f25a2fe7b99ed232a00fd0c82cb205e2                                 domain: sensor                                 below: 11                               - condition: numeric_state                                 entity_id: sensor.te31njn8n387601_l3_p                                 above: 50                         sequence:                           - sequence:                               - if:                                   - condition: device                                     device_id: a9bed78637a3d4199888177480ba0f4b                                     domain: select                                     entity_id: faa8306ea0f42cc0b510209a0e408c8e                                     type: selected_option                                     option: Input mode                                 then:                                   - device_id: a9bed78637a3d4199888177480ba0f4b                                     domain: select                                     entity_id: faa8306ea0f42cc0b510209a0e408c8e                                     type: select_option                                     option: Output mode                                 alias: >-                                   SF2400 - Changement d'état IN to Out si                                   necessaire                               - action: number.set_value                                 target:                                   entity_id: number.eeb4aep1p032084_outputlimit                                 data:                                   value: >                                     {% set current =                                     states('sensor.te31njn8n387601_l3_p') |                                     float(0) %} {% set output =                                     states('number.eeb4aep1p032084_outputlimit')                                     | float(0) %}                                     {% if -50 <= current <= 50 %}                                       {{ output | round(0) }}                                     {% else %}                                       {% set delta = 0.7 * current %}                                       {% set cible = output + delta %}                                       {% set result = cible - 50 if cible > 0 else cible %}                                       {{ [result, 900] | min | round(0) }}                                     {% endif %}                           - sequence:                               - if:                                   - condition: device                                     device_id: a9bed78637a3d4199888177480ba0f4b                                     domain: select                                     entity_id: faa8306ea0f42cc0b510209a0e408c8e                                     type: selected_option                                     option: Input mode                                 then:                                   - device_id: a9bed78637a3d4199888177480ba0f4b                                     domain: select                                     entity_id: faa8306ea0f42cc0b510209a0e408c8e                                     type: select_option                                     option: Output mode                                 alias: >-                                   SF2400 - Changement d'état IN to Out si                                   necessaire                               - action: number.set_value                                 target:                                   entity_id: number.eeb4aep1p032084_outputlimit                                 data:                                   value: >                                     {% set current =                                     states('sensor.te31njn8n387601_l3_p') |                                     float(0) %} {% set output =                                     states('number.eeb4aep1p032084_outputlimit')                                     | float(0) %}                                     {% if -50 <= current <= 50 %}                                       {{ output | round(0) }}                                     {% else %}                                       {% set delta = 0.7 * current %}                                       {% set cible = output + delta %}                                       {% set result = cible - 50 if cible > 0 else cible %}                                       {{ [result, 900] | min | round(0) }}                                     {% endif %}                             enabled: false                         alias: Si 3CT > 50W, on compense avec xW pour arriver à 50W                       - conditions:                           - condition: numeric_state                             entity_id: sensor.te31njn8n387601_l3_p                             below: -200                           - type: is_battery_level                             condition: device                             device_id: afda895cc1812b99521eb78710326b89                             entity_id: f25a2fe7b99ed232a00fd0c82cb205e2                             domain: sensor                             above: 90                             alias: QCELLs > 90%                         sequence:                           - alias: >-                               On demarre la charge de SF2400 avec 0.3 de ce                               qu'on inject en trop                             sequence:                               - device_id: a9bed78637a3d4199888177480ba0f4b                                 domain: select                                 entity_id: faa8306ea0f42cc0b510209a0e408c8e                                 type: select_option                                 option: Input mode                               - device_id: a9bed78637a3d4199888177480ba0f4b                                 domain: number                                 entity_id: f2984ee0e6ebcf40e208c5a0d56b90d8                                 type: set_value                                 value: 0                               - action: number.set_value                                 target:                                   entity_id: number.eeb4aep1p032084_inputlimit                                 data:                                   value: >                                     {% set current =                                     states('sensor.te31njn8n387601_l3_p') |                                     float(0) %} {% set input =                                     states('number.eeb4aep1p032084_inputlimit')                                     | float(0) %}                                     {% if -50 <= current <= 50 %}                                       {{ input | round(0) }}                                     {% else %}                                       {% set current = current * -1 %}                                       {% set delta = 0.3 * current %}                                       {% set cible = input + delta %}                                       {% set result = cible - 50 if cible > 0 else cible %}                                       {{ [result, 900] | min | round(0) }}                                     {% endif %}                               - device_id: a9bed78637a3d4199888177480ba0f4b                                 domain: number                                 entity_id: 446540682f8a0142e01a5f8a2272926d                                 type: set_value                                 value: 200                                 enabled: false                         alias: QCELLs full                 alias: QCELLS en Standby               - conditions:                   - condition: state                     entity_id: sensor.qcells_etat                     state:                       - En charge                 sequence:                   - alias: Si surplus de production                     choose:                       - conditions:                           - condition: and                             conditions:                               - condition: numeric_state                                 entity_id: sensor.qcells_inverter_production_2                                 below: 20                               - type: is_power                                 condition: device                                 device_id: 181b299767530862f68a9d7f84c40146                                 entity_id: 04b888d40622ee63c389a1da5046b77f                                 domain: sensor                                 below: -50                         sequence:                           - alias: Faut-il lancer la charge du SF2400 ?                             choose:                               - conditions:                                   - condition: device                                     device_id: a9bed78637a3d4199888177480ba0f4b                                     domain: select                                     entity_id: faa8306ea0f42cc0b510209a0e408c8e                                     type: selected_option                                     option: Output mode                                 sequence:                                   - target:                                       entity_id: number.eeb4aep1p032084_outputlimit                                     data:                                       value: >                                         {% set current =                                         states('sensor.te31njn8n387601_l3_p') |                                         float %} {% set output =                                         states('number.eeb4aep1p032084_outputlimit')                                         | float %}                                         {% if -50 <= current <= 50 %}                                           {{ output | round(0) }}                                         {% else %}                                           {% set surplus = current * -1 %}                                           {% set delta = 0.7 * surplus %}                                           {{ (output - delta) | round(0) }}                                         {% endif %}                                     action: number.set_value                                 alias: >-                                   SF2400 est-il en output, auquel ca il faut                                   réduire son injection                               - conditions: []                                 sequence:                                   - sequence:                                       - alias: >-                                           SF2400 - Changement d'état OUT to IN si                                           necessaire                                         if:                                           - condition: device                                             device_id: a9bed78637a3d4199888177480ba0f4b                                             domain: select                                             entity_id: faa8306ea0f42cc0b510209a0e408c8e                                             type: selected_option                                             option: Output mode                                         then:                                           - device_id: a9bed78637a3d4199888177480ba0f4b                                             domain: select                                             entity_id: faa8306ea0f42cc0b510209a0e408c8e                                             type: select_option                                             option: Input mode                                       - target:                                           entity_id: number.eeb4aep1p032084_inputlimit                                         data:                                           value: >                                             {% set current =                                             states('sensor.te31njn8n387601_l3_p') |                                             float %} {% set input =                                             states('number.eeb4aep1p032084_inputlimit')                                             | float %}                                             {% if -50 <= current <= 50 %}                                               {{ input | round(0) }}                                             {% else %}                                               {% set surplus = current * -1 %}                                               {% set delta = 0.7 * surplus %}                                               {{ (input + delta) | round(0) }}                                             {% endif %}                                         action: number.set_value                         alias: 3CT negatif < -50W vérification sur QCELLS inject                       - conditions:                           - condition: or                             conditions:                               - condition: and                                 conditions:                                   - condition: numeric_state                                     entity_id: sensor.qcells_inverter_production_2                                     below: 10                                   - condition: device                                     device_id: a9bed78637a3d4199888177480ba0f4b                                     domain: select                                     entity_id: faa8306ea0f42cc0b510209a0e408c8e                                     type: selected_option                                     option: Output mode                               - condition: and                                 conditions:                                   - condition: numeric_state                                     entity_id: sensor.qcells_inverter_production_2                                     below: sensor.qcells_production_solaire                                 enabled: false                         sequence:                           - target:                               entity_id: number.eeb4aep1p032084_outputlimit                             data:                               value: >                                 {% set current =                                 states('sensor.te31njn8n387601_l3_p') | float                                 %}  {% set output =                                 states('number.eeb4aep1p032084_outputlimit') |                                 float %} {% set qcell =                                 states('sensor.qcells_inverter_production_2') |                                 float %}                                 {% if qcell <= 10 %}                                   {{ output | round(0) }}                                 {% else %}                                   {% set surplus = current * -1 %}                                   {% set delta = 0.1 * output %}                                   {{ (output - delta) | round(0) }}                                 {% endif %}                             action: number.set_value                 alias: QCELLS en Charge               - conditions:                   - condition: state                     entity_id: sensor.qcells_etat                     state:                       - En décharge                 sequence:                   - choose:                       - conditions:                           - alias: >-                               QCELLs à plus de 90%, on réduit la charge de                               SF2400 si en charge                             condition: and                             conditions:                               - condition: and                                 conditions: []                               - condition: numeric_state                                 entity_id: sensor.qcells_batterie_level                                 above: 90                               - condition: device                                 device_id: a9bed78637a3d4199888177480ba0f4b                                 domain: select                                 entity_id: faa8306ea0f42cc0b510209a0e408c8e                                 type: selected_option                                 option: Input mode                         sequence:                           - action: number.set_value                             target:                               entity_id: number.eeb4aep1p032084_inputlimit                             data:                               value: >                                 {% set current =                                 states('sensor.te31njn8n387601_l3_p') | float(0)                                 %}                                  {% set input =                                 states('number.eeb4aep1p032084_inputlimit') |                                 float(0) %}                                 {% if -50 <= current <= 50 %}                                   {{ input | round(0) }}                                 {% else %}                                   {% set delta = 0.7 * current * -1 %}                                   {% set cible = input - delta %}                                   {% set result = cible - 50 if cible > 0 else cible %}                                   {{ [result, 900] | min | round(0) }}                                 {% endif %}                       - conditions:                           - condition: numeric_state                             entity_id: sensor.te31njn8n387601_l3_p                             above: 50                           - type: is_power                             condition: device                             device_id: afda895cc1812b99521eb78710326b89                             entity_id: ef2eee2418adb0259f2f29dbd7ed8206                             domain: sensor                             above: 1900                         sequence:                           - sequence:                               - if:                                   - condition: device                                     device_id: a9bed78637a3d4199888177480ba0f4b                                     domain: select                                     entity_id: faa8306ea0f42cc0b510209a0e408c8e                                     type: selected_option                                     option: Input mode                                 then:                                   - device_id: a9bed78637a3d4199888177480ba0f4b                                     domain: select                                     entity_id: faa8306ea0f42cc0b510209a0e408c8e                                     type: select_option                                     option: Output mode                                 alias: >-                                   SF2400 - Changement d'état IN to Out si                                   necessaire                               - action: number.set_value                                 target:                                   entity_id: number.eeb4aep1p032084_outputlimit                                 data:                                   value: >                                     {% set current =                                     states('sensor.te31njn8n387601_l3_p') |                                     float(0) %} {% set output =                                     states('number.eeb4aep1p032084_outputlimit')                                     | float(0) %}                                     {% if -50 <= current <= 50 %}                                       {{ output | round(0) }}                                     {% else %}                                       {% set delta = 0.7 * current %}                                       {% set cible = output + delta %}                                       {% set result = cible - 50 if cible > 0 else cible %}                                       {{ [result, 900] | min | round(0) }}                                     {% endif %}                         alias: >-                           Qcells en Décharge mais on tire toujours de l'EDF, on                           compense avec SF2400                       - conditions:                           - type: is_power                             condition: device                             device_id: a9bed78637a3d4199888177480ba0f4b                             entity_id: b220a07315cd6e8c253e8c771528fd3e                             domain: sensor                             above: 50                         sequence:                           - sequence:                               - action: number.set_value                                 target:                                   entity_id: number.eeb4aep1p032084_outputlimit                                 data:                                   value: >                                     {% set current =                                     states('sensor.te31njn8n387601_l3_p') |                                     float(0) %}                                      {% set output =                                     states('number.eeb4aep1p032084_outputlimit')                                     | float(0) %}                                     {% set delta = 0.3 * output %}                                     {% set cible = output - delta %}                                     {% set result = cible - 50 if cible > 0 else                                     cible %}                                     {% if -50 <= result <= 50 %}                                       {{ output | round(0) }}                                     {% else %}                                       {{ [result, 900] | min | round(0) }}                                     {% endif %}                         alias: QCELLs est en Decharge mais SF aussi, on reduit SF                 alias: QCELLS en Decharge         alias: Si HP       - conditions:           - condition: state             entity_id: sensor.linky_current_price             state:               - HEURE CREUSE         sequence:           - alias: Faut-il lancer la charge du SF2400 ?             choose:               - conditions:                   - condition: state                     entity_id: sensor.qcells_etat                     state:                       - En décharge                 sequence:                   - sequence:                       - target:                           entity_id: number.eeb4aep1p032084_inputlimit                         data:                           value: "0"                         action: number.set_value                 alias: >-                   QCELLs est en Décharge alors mettre le SF2400 en input mais à                   0W !               - conditions:                   - condition: and                     conditions:                       - condition: state                         entity_id: sensor.qcells_etat                         state:                           - Standby                         alias: Si Qcells est Standby                       - condition: numeric_state                         entity_id: sensor.qcells_batterie_level                         below: 11                         alias: Si QCells < 11%                       - type: is_battery_level                         condition: device                         device_id: a9bed78637a3d4199888177480ba0f4b                         entity_id: 23f1ec717c4dcf6732d11bfaac92d296                         domain: sensor                         below: 35                         alias: Si SF2400 < 35%                 sequence:                   - sequence:                       - alias: SF2400 - Changement d'état OUT to IN si necessaire                         if:                           - condition: device                             device_id: a9bed78637a3d4199888177480ba0f4b                             domain: select                             entity_id: faa8306ea0f42cc0b510209a0e408c8e                             type: selected_option                             option: Output mode                         then:                           - device_id: a9bed78637a3d4199888177480ba0f4b                             domain: select                             entity_id: faa8306ea0f42cc0b510209a0e408c8e                             type: select_option                             option: Input mode                       - target:                           entity_id: number.eeb4aep1p032084_inputlimit                         data:                           value: "900"                         action: number.set_value                       - if:                           - condition: numeric_state                             entity_id: number.eeb4aep1p032084_inputlimit                             below: 800                         then:                           - device_id: a9bed78637a3d4199888177480ba0f4b                             domain: number                             entity_id: 446540682f8a0142e01a5f8a2272926d                             type: set_value                             value: 900                 alias: Charge SF2400 Si Qcells vide et SF2400 <35%               - conditions:                   - type: is_battery_level                     condition: device                     device_id: a9bed78637a3d4199888177480ba0f4b                     entity_id: 23f1ec717c4dcf6732d11bfaac92d296                     domain: sensor                     above: 89                 sequence:                   - sequence:                       - alias: SF2400 - Changement d'état IN to OUT si necessaire                         if:                           - condition: device                             device_id: a9bed78637a3d4199888177480ba0f4b                             domain: select                             entity_id: faa8306ea0f42cc0b510209a0e408c8e                             type: selected_option                             option: Input mode                         then:                           - device_id: a9bed78637a3d4199888177480ba0f4b                             domain: select                             entity_id: faa8306ea0f42cc0b510209a0e408c8e                             type: select_option                             option: Output mode                       - target:                           entity_id: number.eeb4aep1p032084_outputlimit                         data:                           value: "300"                         action: number.set_value                 alias: SF2400 est à >=90%               - conditions:                   - condition: and                     conditions:                       - condition: device                         device_id: a9bed78637a3d4199888177480ba0f4b                         domain: select                         entity_id: faa8306ea0f42cc0b510209a0e408c8e                         type: selected_option                         option: Output mode                         alias: "SF2400 Mode : output"                       - type: is_battery_level                         condition: device                         device_id: a9bed78637a3d4199888177480ba0f4b                         entity_id: 23f1ec717c4dcf6732d11bfaac92d296                         domain: sensor                         below: 41                         alias: SF2400 Bat <=41%                     alias: SF2400 <=41% et AC Output                 sequence:                   - sequence:                       - target:                           entity_id: number.eeb4aep1p032084_outputlimit                         data:                           value: "0"                         action: number.set_value                         alias: "SF2400 Stop decharge : Output 0W"                     alias: Stop decharge SF2400                 alias: SF2400 est à <=40% et si il etait en décharge, on stop         alias: Si HC mode: single Présentation Le but de ce process est le suivant : Pouvoir coupler à la fois le système Zendure sans HEMS, un système QCells, et optimiser les cycles ! Eviter de donner le surplus à EDF au maximum possible. Je vais essayer d'expliquer en détail ce que j'ai souhaité faire... Mon installation : - Solution QCells G1 avec 5.5kw en batterie et 2400Wc (installation toiture historique) - Solution Zendure SolarFlow 800 avec 2 x 500Wc (Installation toiture Veranda) - Solution Zendure SolarFlow 800 avec 2x 450Wc (Installation toiture Abris Bois) - Solution Zendure SolarFlow 2400 Pro avec 4 x 450Wc (Future installation toiture Garage) Pourquoi une si "grosse installation" ? Habitant dans le sud (Aix en Provence), il est parfois nécessaire en été de se rafraichir... la climatisation de la maison (5 clims) et la piscine peuvent vite devenir un gouffre ! De même l'hiver, il est pas rare de devoir chauffer un peu ! Quand j'ai emménagé dans la maison, la première période (Aout 2023 - Aout 2024) a été un test, pas de clim et pas d'optimisation de la piscine Résultat : 7.428kWh de consommés (HP 4.293kWh / HC 3.135kWh) : 1849€ TTC pour l'année, soit 154€ mensuel... L'année suivante Aout 2024 - Aout 2025), 7.286kWh ( HP 3.942kWh / HC 3.344kWh) : 1772€ pour l'année, soit 148€ mensuel... Cette seconde année a été marqué par le fait que j'ai optimisé un peu la piscine (variateur de pompe), qu'on a installé la Clim dans la maison, mais surtout que j'ai ajoutée un kit SF800, ce qui nous a pas réduis la conso, mais a rendu la maison plus confortable ! Bref c'était pas foufou... Enfin cette troisième année Aout 2025 - Aout 2026, même si elle n'est pas fini, a été l'occasion de refaire un abris à bois et donc d'installer un second kit SF800 en guise de toiture en novembre 2025 ! Et à partir de ce moment, c'est devenu intéressant, on a tiré un peu moins d'EDF sur l'hiver, mais surtout, j'arrivais à charger le QCells a plus de 50%, ce qui était une bonne chose car avant ce n'était pas possible. Depuis fin février et l'ajout d'une batterie AB2000, avec les beaux jours, cela c'est confirmé c'était intéressant. Enfin depuis avril, les jours ensoleillés, le QCells se charge à plus de 80% et de temps à autre, je donne quelques kWh à EDF gratuitement. L'idée était donc d'éviter de trop donner tout en essayer d'optimiser encore... Ainsi depuis début mai, j'ai ajouter un kit SF2400 Pro avec 4 x 450Wc. A ce jour, je suis à 4.425kWh (HP 1.192 / HC 2.513kWh) Voici le tableau sur ces 3 an :   2023 - 2024 2024 - 2025 2025 - 2026   HP HC HP HC HP HC juillet   142 128 274 294 248 299 aout 375 257 399 309 284 285 septembre 331 227 286 223 171 184 octobre   548 274 296 267 246 280 novembre   566 309 470 358 322 329 décembre   768 513 589 392 426 443 janvier   529 350 432 283 230 326 février   195 209 348 283 127 277 mars   185 182 265 219 53 211 avril   113 106 196 190 53 178 mai   299 319 153 228     juin   242 261 234 298       4293 3135 3942 3344 2160 2812   7428 7286 4972 Il fallait donc un petit chef d'orchestre pour gerer tout ca, HEMS n'etant pas capable d'avoir une vision d'ensemble et surtout de s'adapter au cas particulier. Ainsi est né cet automatisme sous HA...   Fonctionnement Ce script se base sur plusieurs éléments et tourne toute les 30 secondes. Dans mon cas, les heures creuses sont de 20h50 à 4h50. Dans un premier temps il vérifie si on est en heure pleine ou en heure creuse. Si on est en HC, il va avoir 4 options : Soit le QCells est en décharge => Dans ce cas le SF2400 va bloquer sa charge forcée. Soit le QCells est vide et le SF2400 a moins de 35% => On passe le SF2400 en mode "input" avec une charge forcée à 900W => Objectif le charger en HC quand l'EDF est moins cher pour venir le décharger en heure pleine Soit le SF2400 est à plus de 90% chargé => le SF2400 s'est chargé avec les PV ou le surplus au cours de la journée => on injecte 300W en HC pour "gommer" un peu la conso. Soit le SF2400 est en dessous de 40% (ou passe en dessous) => on stop sa décharge => on garde le reste pour les heures pleine. Maintenant les HP ! Je me base en priorité sur l'état de mon QCells ! Il peut avoir 3 etats : Standby, en Charge, en Décharge StandBy : c'est quand il est complètement vide ou complètement chargé en Charge : il se charge avec le surplus de ses PV qu'il n'injecte pas en Décharge : il balance ce que les PV produisent + sa batterie si nécessaire, dans la limite des 3500W Il surveille ce que je tire d'EDF et compense de façon autonome et non pilotable ! J'ai pas le chois c'est comme ca... Donc en StandBy : Je demande au SF2400 de venir compenser uniquement si le QCells est vide. En Décharge, 3 options : - QCells est à plus de 90% alors je réduis ma charge sur le SF2400. - QCells est en décharge mais on tire encore de l'EDF, alors SF2400 vient aider le QCells - QCells est en décharge mais aussi SF2400, alors on va essayer d'adapter l'injection de SF2400 pour toujours privilégier une décharge de QCells En Charge, 2 options : - QCells se charge mais SF2400 injecte, alors on réduit l'injection de SF2400 au maximum - QCells se charge mais on injecte encore vers EDF, on vient forcer la charge de SF2400 avec le surplus. Ce qu'il va manquer maintenant c'est de limiter l'injection vers EDF si tout est full. Au plus fort, il peut arriver d'envoyer 3000W vers EDF ce qui n'est pas supposer arriver...