# Expiration du reseau force — le contournement manuel a desormais une fin # # LE DEFAUT, constate le 17/09/2026. `force_grid_now` pose a la main a 12:58 # pendant les heures creuses de midi (12:24-14:24) a ferme le contacteur et # lance une charge batterie a 7,7 kW. Rien dans le systeme ne l'arrete : # # - WINDOWS_SOURCEV2 : `else if (forceGridRequested) sourceMode='grid_forced'` # est evalue AVANT tout test de profil. La fenetre HC n'entre pas dans le # calcul. # - Hysteresis : `evcsExplicitGridRequest` inclut la strategie, et l'override # ne tombe que sur un motif « pas de demande » — or `vehicle_not_connected` # n'en fait pas partie. Le depart du vehicule ne libere donc rien. # - Les deux coupures immediates existantes sont bloquees par cet override. # # Consequence : a 14:24 la fenetre economique se ferme et l'import continue AU # PLEIN TARIF, indefiniment, jusqu'a ce qu'un humain soit devant l'ecran. # # LA REGLE, et pourquoi elle est formulee ainsi. Un contournement manuel n'est # pas illegitime — le proprietaire ferme deliberement le contacteur pour # charger en heures creuses, ou pour proteger le parc pendant une pointe. Ce # qui manque n'est pas une interdiction, c'est une ECHEANCE. Deux sorties, et # aucune ne repose sur un seuil invente : # # 1. FENETRE ECONOMIQUE. Si le reseau force a ete engage PENDANT une fenetre # d'heures creuses, il expire a la sortie de cette fenetre. On n'achete # pas au plein tarif ce qu'on avait decide d'acheter au tarif creux. # ⚠️ La condition porte sur l'instant d'ENGAGEMENT, pas seulement sur # l'heure courante : engage HORS heures creuses — pour proteger le parc un # soir de cuisson, cf. la regle « fermer EDF pour proteger le materiel » — # il ne doit PAS etre annule a la minute suivante. C'est la difference # entre une echeance et une interdiction. # 2. PLAFOND DE DUREE. Au-dela de `evcs_force_grid_max_minutes`, quelle que # soit la raison. Filet pour le cas engage hors fenetre et oublie. # # Les bornes des fenetres sont LUES dans les helpers qui font foi # (`victron_evcs_hc_*`), jamais recopiees : elles ont deja change une fois # (01:30 -> 01:24 le 09/07/2026) et une copie divergerait en silence. # # ⚠️ AUCUN `initial:` DANS CE FICHIER. Declarer `initial:` DESACTIVE la # restauration d'etat : le helper reprend cette valeur a CHAQUE demarrage de # Home Assistant. Le 06/09/2026, cinq reglages manuels du projet se # reinitialisaient ainsi en silence, dont deux toggles de cablage. input_boolean: evcs_expiration_force_grid_enabled: name: "EVCS — expiration du réseau forcé" icon: mdi:timer-sand input_number: evcs_force_grid_max_minutes: name: "EVCS — durée maximale du réseau forcé" min: 15 max: 720 step: 15 unit_of_measurement: min mode: box icon: mdi:timer-alert-outline input_text: # Trace lisible du dernier declenchement. Un helper `input_text` accepte 100 # caracteres par defaut et REJETTE EN SILENCE au-dela — le 08/09/2026 une # panne de 4 h 45 n'a laisse aucune trace pour cette raison. 255 ici. evcs_force_grid_last_expiry: name: "EVCS — dernière expiration du réseau forcé" max: 255 icon: mdi:history automation: - id: evcs_expiration_reseau_force alias: "EVCS — le réseau forcé expire tout seul" description: > Repasse la stratégie en auto_solar_plus quand le réseau forcé a perdu sa raison d'être : sortie de la fenêtre d'heures creuses dans laquelle il a été engagé, ou dépassement de la durée maximale. mode: single trigger: - platform: time_pattern minutes: "/1" condition: - condition: state entity_id: input_select.victron_evcs_strategy state: force_grid_now - condition: state entity_id: input_boolean.evcs_expiration_force_grid_enabled state: "on" - condition: template value_template: > {% set s = states.input_select.victron_evcs_strategy %} {% set ns = states('input_datetime.victron_evcs_hc_night_start').split(':') %} {% set ne = states('input_datetime.victron_evcs_hc_night_stop').split(':') %} {% set ms = states('input_datetime.victron_evcs_hc_midday_start').split(':') %} {% set me = states('input_datetime.victron_evcs_hc_midday_stop').split(':') %} {% set n1 = ns[0]|int * 60 + ns[1]|int %} {% set n2 = ne[0]|int * 60 + ne[1]|int %} {% set m1 = ms[0]|int * 60 + ms[1]|int %} {% set m2 = me[0]|int * 60 + me[1]|int %} {% set eng = s.last_changed | as_local %} {% set em = eng.hour * 60 + eng.minute %} {% set hm = now().hour * 60 + now().minute %} {% set d = namespace(eng=false, now=false) %} {% if n1 <= n2 %} {% set d.eng = (em >= n1 and em < n2) %} {% set d.now = (hm >= n1 and hm < n2) %} {% else %} {% set d.eng = (em >= n1 or em < n2) %} {% set d.now = (hm >= n1 or hm < n2) %} {% endif %} {% if em >= m1 and em < m2 %}{% set d.eng = true %}{% endif %} {% if hm >= m1 and hm < m2 %}{% set d.now = true %}{% endif %} {% set duree = (as_timestamp(now()) - as_timestamp(s.last_changed)) / 60 %} {% set plafond = states('input_number.evcs_force_grid_max_minutes') | float(180) %} {{ (d.eng and not d.now) or (duree > plafond) }} action: - variables: motif: > {% set s = states.input_select.victron_evcs_strategy %} {% set duree = ((as_timestamp(now()) - as_timestamp(s.last_changed)) / 60) | round(0) %} {% set plafond = states('input_number.evcs_force_grid_max_minutes') | float(180) %} {% if duree > plafond %}durée maximale de {{ plafond | round(0) }} min dépassée {% else %}sortie de la fenêtre d'heures creuses{% endif %} - service: input_select.select_option target: entity_id: input_select.victron_evcs_strategy data: option: auto_solar_plus - service: input_text.set_value target: entity_id: input_text.evcs_force_grid_last_expiry data: value: > {{ now().strftime('%d/%m %H:%M') }} — retour auto_solar_plus ({{ motif }}), SOC {{ states('sensor.victron_battery_soc') | round(0) }} % - service: logbook.log data: name: EVCS message: > Réseau forcé expiré ({{ motif }}) — retour à auto_solar_plus. SOC {{ states('sensor.victron_battery_soc') | round(0) }} %. entity_id: input_select.victron_evcs_strategy - service: persistent_notification.create data: title: EVCS — réseau forcé expiré message: > La stratégie est repassée en **auto_solar_plus** : {{ motif }}. SOC {{ states('sensor.victron_battery_soc') | round(0) }} %. notification_id: evcs_force_grid_expire