Boost sur batterie : force_charge_now donne d'abord le budget batterie (au-dessus du requis prudent), puis EDF ; script, fin automatique, bouton
This commit is contained in:
@@ -2443,5 +2443,13 @@ batterie a 32 A et JEEP (branchee 13:01, 52 %) qui ne demarre pas. SOC 47 % a 12
|
|||||||
- Golden 149 -> **153** (fixture REELLE `tests/golden/fixtures/jeep-1410-1257.json` : sans niveau = latch historique ; 51 % = pas cru ; collant leve ; temoin 97 % = plein), mutation « regle coupee » -> 2 echecs. Verifie en reel : 13:13:00 `start_min_current`, borne « Charge en cours », 6 A / 1,08 kW.
|
- Golden 149 -> **153** (fixture REELLE `tests/golden/fixtures/jeep-1410-1257.json` : sans niveau = latch historique ; 51 % = pas cru ; collant leve ; temoin 97 % = plein), mutation « regle coupee » -> 2 echecs. Verifie en reel : 13:13:00 `start_min_current`, borne « Charge en cours », 6 A / 1,08 kW.
|
||||||
- ⚠️ Si la voiture refuse vraiment la charge (limite reglee dans la voiture), le controleur retentera au lieu de se mettre en veille : a surveiller. VW sans saisie de niveau : non couverte.
|
- ⚠️ Si la voiture refuse vraiment la charge (limite reglee dans la voiture), le controleur retentera au lieu de se mettre en veille : a surveiller. VW sans saisie de niveau : non couverte.
|
||||||
|
|
||||||
|
### 14/10 soir — Boost EDF d'une Volvo invitee, et ce qu'il a coute
|
||||||
|
- Volvo XC90 T8 (HYBRIDE rechargeable, ~70 km electriques, batterie ~18 kWh au compteur, chargeur embarque **3,7 kW** ; le proprietaire l'a d'abord crue electrique : « 30 km » sans icone = l'ESSENCE). Branchee 20:03 a 0 %, boost EDF 20:09 -> 22:01 : **6,45 kWh** (25 km). Etiquetee INVITE par le concierge (22:56).
|
||||||
|
- Achats EDF en HP 20:09-22:01 : **11,47 kWh** = voiture 6,35 + **batterie maison 2,81** (+30 A a SOC 86 %) + maison ~2,3. Nuit sans EDF ensuite (89 -> 60 % a 09:00).
|
||||||
|
- **A (deploye 15/10 12:51, `52c1703`)** : la part voiture de la consigne reseau suivait le plafond de borne (28 A = 6,4 kW) alors que la voiture plafonnait a 3,7 kW : les 2,7 kW de trop rechargeaient la batterie en HP. Voiture plafonnee (puissance < consigne - 2 A) -> part = puissance reelle (+ le pas de marge existant). Rejeu 20:40 : 7 304 -> **4 795 W** ; temoin voiture qui suit : 6 458 W inchange.
|
||||||
|
- **B (deploye 15/10 12:58)** : `force_charge_now` = **boost sur batterie** : budget = (SOC - requis prudent du bilan) x capacite, FIGE au demarrage avec l'index du compteur (`input_text.victron_evcs_boost_budget`), batterie d'abord (chemin `battery_assist_night`, libelle « Boost batterie »), EDF (`grid_forced`, `gridAllowedBySoc`) quand le budget est atteint ; bilan absent/perime -> budget 0 -> EDF. Paquet `evcs_boost_batterie.yaml` (helper, `script.evcs_boost_batterie`, automatisation de fin : debranchement 1 min ou `evcs_force_grid_max_minutes` -> BOOST OFF), bouton sur EVCS Master (Pilotage). Golden **159/159** (fixture reelle `volvo-1410-2040.json`), mutations : budget ignore -> 1, EDF refuse -> 2 ; `force-charge-nuit` change VOLONTAIREMENT (sans bilan : EDF au lieu de la batterie a l'aveugle). diagnostics 95/95 (« Boost batterie » -> en_charge_batterie).
|
||||||
|
- ⚠️ Rejeu du 14/10 20:40 : requis prudent **82,2 %** pour SOC 87 -> budget **1,44 kWh** seulement ; ma premiere analyse (« ~9 kWh, la batterie etait la bonne source ») utilisait le requis du matin (56 %) : fausse. Le gain reel du soir aurait ete ~1,4 kWh + les 2,8 kWh de batterie (corriges par A).
|
||||||
|
- ⚠️ Les gardes de courant par bande de SOC restent en place sur le chemin batterie : debit possiblement bride.
|
||||||
|
|
||||||
---
|
---
|
||||||
*Document mis a jour le : 14/10/2026 (~00:10) — disjoncteur EDF 100A (identifiants repris), revue (EDF absent, voiture payee par la batterie, interventions, kWh sur la puissance), piles (hysteresis + acquittement), frontal web .17 en cours ; 13/10/2026 (~06:30) — nuit du 12-13/10 : disjoncteur EDF qui n'executait pas la fermeture (alerte edf_ne_ferme_pas, envoyee a toute heure), charge HC manuelle reparee et utilisee a 40 % ; 13/10 : certificats HTTPS du .50 renouveles (via le .17) + alerte d'expiration ; 12/10 : VW payee par la batterie (temps mini + tolerance nuage bornes par le bilan), niveaux estimes par l'autonomie ; 10/10/2026 (~16:00) — conseiller relecteur de la journee (revue calculee + pistes) ; nuit : voiture qui profite d'EDF ferme pour la batterie, nuit qui prepare le soir les jours annonces faibles ; 08/10/2026 (~00:15) — jour faible : charge maximale en HC de midi (bilan 100 %, ACM plafond + solaire) ; 07/10/2026 (~22:45) — reprise de 16 h verifiee, EDF en HP a 18:03, bilan : reprise du soir et prevision recalee sur la matinee ; bilan HC de midi, reprise du soir apres coupure en pleine chauffe, mesure ECS sur 10 min ; recharge reseau HC : courant calcule (12 kVA) et consigne non tenue ; HC de midi : AUTO ne chauffe pas (BOOST), alerte v2, Jeep (contact, relecture, zone), recharge batterie bridee a 30 A par l'ACM ; jour faible = EDF les deux fenetres HC pour le chauffe-eau, alerte BOOST, Victron Mobile refait ; 1re decision jour faible en reel, mesure ECS reparee, douches 06:00/20:00, Grafana chauffe-eau, tableaux ECS ; chauffe-eau en HC de nuit les jours faibles (decision du bilan, workflow ECS sous controle du depot, VRM, V2.3 desactive) ; garde batterie reseau : voiture bridee a 6 A au lieu d'un arret ; garde-fou concierge 2 h ; allers-retours brefs de la borne retrouves dans l'historique HA (echange VW -> JEEP de 20 s), production 14,5 kWh contre 22 prevus, defaut garde batterie en mode reseau a trancher ; voiture a midi : la batterie n'est plus comptee comme du solaire (EDF automatique les jours de depart si le surplus ne couvre pas) ; nuit 05->06 : JEEP chargee sur EDF en complete (6,32 kWh), budget 0 du a la prevision, Windy/ECMWF contre VRM, a comparer ce soir ; concierge aligne sur la preuve fin de trajet ; a verifier : nuit 05->06 et mardi faible, comparaison VRM/Forecast.Solar ; JEEP identifiee aussi par sa fin de trajet, prevision de la nuit 05->06 ; identification JEEP reussie en reel, correction humaine qui prime (refus supprime), session du 04/10 coupee ; EVCS Master en quatre onglets ; Jeep lue par Uconnect et identifiee seule, capacite JEEP 10 kWh, concierge variante (a) ; releve par photo (SPARK), hass-uconnect en attente ; ecart semaine/week-end mesure (pas de profil week-end la nuit) ; nuit du budget : budget borne au plancher prudent, sans EDF = voiture bloquee meme EDF ferme (batterie seule) ; Energie : sauts corriges ; tableau Energie complete (Sud/Ouest, batterie par integration, borne ; aucun redemarrage HA) ; kilometrage des vehicules (km/kWh, capacite, releves de reference, agent cable 15/15) ; a verifier le 04/10 au matin : nuit du budget JEEP ; concierge : vehicule non confirme demande, heure de saisie ; Grafana vehicules en tableau ; Grafana vehicules : ZERO et Invite ajoutes, session 16:46 reetiquetee ZERO ; prevision SOC 10 h ~35 % ; concierge fiable : niveau note par le script, une ligne, dedoublonnage, simulation par drapeau ; agent : message incompris = question, bourse sur demande explicite (banc final 6/6) ; a verifier : nuit du samedi 03 au dimanche 04/10 (budget < besoin JEEP), cron orange-cloture lundi 05/10 apres 17:40, comparaison VRM / Forecast.Solar lundi 05/10*
|
*Document mis a jour le : 14/10/2026 (~00:10) — disjoncteur EDF 100A (identifiants repris), revue (EDF absent, voiture payee par la batterie, interventions, kWh sur la puissance), piles (hysteresis + acquittement), frontal web .17 en cours ; 13/10/2026 (~06:30) — nuit du 12-13/10 : disjoncteur EDF qui n'executait pas la fermeture (alerte edf_ne_ferme_pas, envoyee a toute heure), charge HC manuelle reparee et utilisee a 40 % ; 13/10 : certificats HTTPS du .50 renouveles (via le .17) + alerte d'expiration ; 12/10 : VW payee par la batterie (temps mini + tolerance nuage bornes par le bilan), niveaux estimes par l'autonomie ; 10/10/2026 (~16:00) — conseiller relecteur de la journee (revue calculee + pistes) ; nuit : voiture qui profite d'EDF ferme pour la batterie, nuit qui prepare le soir les jours annonces faibles ; 08/10/2026 (~00:15) — jour faible : charge maximale en HC de midi (bilan 100 %, ACM plafond + solaire) ; 07/10/2026 (~22:45) — reprise de 16 h verifiee, EDF en HP a 18:03, bilan : reprise du soir et prevision recalee sur la matinee ; bilan HC de midi, reprise du soir apres coupure en pleine chauffe, mesure ECS sur 10 min ; recharge reseau HC : courant calcule (12 kVA) et consigne non tenue ; HC de midi : AUTO ne chauffe pas (BOOST), alerte v2, Jeep (contact, relecture, zone), recharge batterie bridee a 30 A par l'ACM ; jour faible = EDF les deux fenetres HC pour le chauffe-eau, alerte BOOST, Victron Mobile refait ; 1re decision jour faible en reel, mesure ECS reparee, douches 06:00/20:00, Grafana chauffe-eau, tableaux ECS ; chauffe-eau en HC de nuit les jours faibles (decision du bilan, workflow ECS sous controle du depot, VRM, V2.3 desactive) ; garde batterie reseau : voiture bridee a 6 A au lieu d'un arret ; garde-fou concierge 2 h ; allers-retours brefs de la borne retrouves dans l'historique HA (echange VW -> JEEP de 20 s), production 14,5 kWh contre 22 prevus, defaut garde batterie en mode reseau a trancher ; voiture a midi : la batterie n'est plus comptee comme du solaire (EDF automatique les jours de depart si le surplus ne couvre pas) ; nuit 05->06 : JEEP chargee sur EDF en complete (6,32 kWh), budget 0 du a la prevision, Windy/ECMWF contre VRM, a comparer ce soir ; concierge aligne sur la preuve fin de trajet ; a verifier : nuit 05->06 et mardi faible, comparaison VRM/Forecast.Solar ; JEEP identifiee aussi par sa fin de trajet, prevision de la nuit 05->06 ; identification JEEP reussie en reel, correction humaine qui prime (refus supprime), session du 04/10 coupee ; EVCS Master en quatre onglets ; Jeep lue par Uconnect et identifiee seule, capacite JEEP 10 kWh, concierge variante (a) ; releve par photo (SPARK), hass-uconnect en attente ; ecart semaine/week-end mesure (pas de profil week-end la nuit) ; nuit du budget : budget borne au plancher prudent, sans EDF = voiture bloquee meme EDF ferme (batterie seule) ; Energie : sauts corriges ; tableau Energie complete (Sud/Ouest, batterie par integration, borne ; aucun redemarrage HA) ; kilometrage des vehicules (km/kWh, capacite, releves de reference, agent cable 15/15) ; a verifier le 04/10 au matin : nuit du budget JEEP ; concierge : vehicule non confirme demande, heure de saisie ; Grafana vehicules en tableau ; Grafana vehicules : ZERO et Invite ajoutes, session 16:46 reetiquetee ZERO ; prevision SOC 10 h ~35 % ; concierge fiable : niveau note par le script, une ligne, dedoublonnage, simulation par drapeau ; agent : message incompris = question, bourse sur demande explicite (banc final 6/6) ; a verifier : nuit du samedi 03 au dimanche 04/10 (budget < besoin JEEP), cron orange-cloture lundi 05/10 apres 17:40, comparaison VRM / Forecast.Solar lundi 05/10*
|
||||||
|
|||||||
@@ -267,6 +267,11 @@ embarques) ; la Megane a pris **6 360 W a 28 A** le 11/09. La colonne
|
|||||||
| 3 600 a 3 800 W | VW ou JEEP a pleine consigne — **indiscernables entre elles** |
|
| 3 600 a 3 800 W | VW ou JEEP a pleine consigne — **indiscernables entre elles** |
|
||||||
| > 4 000 W | vehicule INVITE, ni VW ni JEEP |
|
| > 4 000 W | vehicule INVITE, ni VW ni JEEP |
|
||||||
|
|
||||||
|
Volvo **XC90 T8** d'un invite (14/10/2026) : HYBRIDE rechargeable (~70 km
|
||||||
|
electriques, ~18 kWh au compteur pour une charge complete), chargeur embarque
|
||||||
|
**3,7 kW** - elle plafonne comme la VW et la JEEP, donc PAS discernable a la
|
||||||
|
puissance. Au tableau de bord, « 30 km » sans icone = autonomie ESSENCE.
|
||||||
|
|
||||||
La doctrine « les vehicules sont indiscernables » ne vaut donc QUE pour la VW
|
La doctrine « les vehicules sont indiscernables » ne vaut donc QUE pour la VW
|
||||||
et la JEEP l'une par rapport a l'autre. Toute question posee au proprietaire
|
et la JEEP l'une par rapport a l'autre. Toute question posee au proprietaire
|
||||||
sur l'identite d'un vehicule doit offrir une reponse « aucune des deux », sans
|
sur l'identite d'un vehicule doit offrir une reponse « aucune des deux », sans
|
||||||
|
|||||||
74
packages/evcs_boost_batterie.yaml
Normal file
74
packages/evcs_boost_batterie.yaml
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# =====================================================================
|
||||||
|
# BOOST SUR BATTERIE (15/10/2026, decision du proprietaire)
|
||||||
|
# Le 14/10 au soir, le boost EDF de la Volvo d'un invite a achete 11,5 kWh en
|
||||||
|
# heures pleines. « EVCS BOOST BATTERIE » passe en force_charge_now : le
|
||||||
|
# controleur donne d'abord a la voiture l'energie de la batterie AU-DESSUS du
|
||||||
|
# SOC requis prudent du bilan (budget fige au demarrage dans
|
||||||
|
# input_text.victron_evcs_boost_budget = « budget|index du compteur »), puis
|
||||||
|
# EDF prend le relais. Bilan absent ou perime : EDF tout de suite.
|
||||||
|
# Fin : debranchement (1 min) ou duree maximale du reseau force
|
||||||
|
# (input_number.evcs_force_grid_max_minutes) -> EVCS BOOST OFF.
|
||||||
|
# Retour arriere : supprimer ce fichier, recharger scripts / automatisations /
|
||||||
|
# input_text (aucun redemarrage).
|
||||||
|
# =====================================================================
|
||||||
|
input_text:
|
||||||
|
victron_evcs_boost_budget:
|
||||||
|
name: EVCS - Budget batterie du boost (fige)
|
||||||
|
max: 40
|
||||||
|
icon: mdi:battery-lock
|
||||||
|
|
||||||
|
script:
|
||||||
|
evcs_boost_batterie:
|
||||||
|
alias: EVCS BOOST BATTERIE (batterie d'abord, puis EDF)
|
||||||
|
icon: mdi:battery-charging-high
|
||||||
|
mode: restart
|
||||||
|
sequence:
|
||||||
|
- action: input_number.set_value
|
||||||
|
target:
|
||||||
|
entity_id: input_number.evcs_plafond_courant_edf_on
|
||||||
|
data:
|
||||||
|
value: 28
|
||||||
|
- action: input_number.set_value
|
||||||
|
target:
|
||||||
|
entity_id: input_number.victron_evcs_current_max_auto_a
|
||||||
|
data:
|
||||||
|
value: 28
|
||||||
|
- action: input_select.select_option
|
||||||
|
target:
|
||||||
|
entity_id: input_select.victron_evcs_strategy
|
||||||
|
data:
|
||||||
|
option: force_charge_now
|
||||||
|
|
||||||
|
automation:
|
||||||
|
- id: evcs_boost_batterie_fin
|
||||||
|
alias: "EVCS — fin du boost batterie"
|
||||||
|
description: >
|
||||||
|
Le boost (force_charge_now) s'arrete au debranchement ou apres la duree
|
||||||
|
maximale du reseau force ; EVCS BOOST OFF remet plafonds et strategie.
|
||||||
|
mode: single
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: binary_sensor.victron_evcs_vehicle_connected
|
||||||
|
to: "off"
|
||||||
|
for: "00:01:00"
|
||||||
|
- platform: time_pattern
|
||||||
|
minutes: "/1"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_select.victron_evcs_strategy
|
||||||
|
state: force_charge_now
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{% set s = states.input_select.victron_evcs_strategy %}
|
||||||
|
{% set duree = (as_timestamp(now()) - as_timestamp(s.last_changed)) / 60 %}
|
||||||
|
{% set plafond = states('input_number.evcs_force_grid_max_minutes') | float(180) %}
|
||||||
|
{{ is_state('binary_sensor.victron_evcs_vehicle_connected', 'off') or duree > plafond }}
|
||||||
|
action:
|
||||||
|
- action: script.evcs_boost_off
|
||||||
|
- action: logbook.log
|
||||||
|
data:
|
||||||
|
name: EVCS
|
||||||
|
message: >
|
||||||
|
Boost batterie termine ({{ 'voiture debranchee' if is_state('binary_sensor.victron_evcs_vehicle_connected', 'off') else 'duree maximale' }}),
|
||||||
|
budget {{ states('input_text.victron_evcs_boost_budget') }}, SOC {{ states('sensor.victron_battery_soc') | round(0) }} %.
|
||||||
|
entity_id: input_select.victron_evcs_strategy
|
||||||
@@ -409,7 +409,11 @@ const batteryRecoveryUrgent = !!nightPrev.batteryRecoveryUrgent;
|
|||||||
const batteryRecoveryAllowedNow = !!nightPrev.batteryRecoveryAllowedNow;
|
const batteryRecoveryAllowedNow = !!nightPrev.batteryRecoveryAllowedNow;
|
||||||
const batteryTargetReached = !!nightPrev.batteryTargetReached;
|
const batteryTargetReached = !!nightPrev.batteryTargetReached;
|
||||||
|
|
||||||
const batteryAssistAllowed = !!nightPrev.batteryAssistAllowed;
|
// Boost sur batterie (15/10/2026) : force_charge_now dans son budget emprunte
|
||||||
|
// le chemin batterie de la nuit, hors session de nuit. Le plancher (SOC requis
|
||||||
|
// prudent) et le budget au compteur sont juges dans WINDOWS_SOURCEV2.
|
||||||
|
const boostBatteryAvailable = !!nightPrev.boostBatteryAvailable;
|
||||||
|
const batteryAssistAllowed = !!nightPrev.batteryAssistAllowed || boostBatteryAvailable;
|
||||||
const nightGridTakeoverNeeded = !!nightPrev.nightGridTakeoverNeeded;
|
const nightGridTakeoverNeeded = !!nightPrev.nightGridTakeoverNeeded;
|
||||||
const nightTakeoverLatched = !!nightPrev.nightTakeoverLatched;
|
const nightTakeoverLatched = !!nightPrev.nightTakeoverLatched;
|
||||||
const vehicleChargeCompleted = !!nightPrev.vehicleChargeCompleted;
|
const vehicleChargeCompleted = !!nightPrev.vehicleChargeCompleted;
|
||||||
@@ -836,6 +840,8 @@ const solarHoldOk =
|
|||||||
// au-dessus de 35 %.
|
// au-dessus de 35 %.
|
||||||
const gridAllowedBySoc =
|
const gridAllowedBySoc =
|
||||||
strategy.forceGridRequested ||
|
strategy.forceGridRequested ||
|
||||||
|
// Boost (15/10) : budget batterie epuise ou nul -> EDF, quel que soit le SOC.
|
||||||
|
(strategy.forceChargeRequested && !!nightPrev.boostActive) ||
|
||||||
context.profile === 'night_hc' ||
|
context.profile === 'night_hc' ||
|
||||||
departureUrgentActive ||
|
departureUrgentActive ||
|
||||||
(context.profile === 'midday_hc_or_solar' && nightGridSessionCommitted) ||
|
(context.profile === 'midday_hc_or_solar' && nightGridSessionCommitted) ||
|
||||||
@@ -882,10 +888,11 @@ const nightBatterySurplusFloorPct = Number.isFinite(nightPrev.nightBatterySurplu
|
|||||||
const batteryAssistNightStartOk =
|
const batteryAssistNightStartOk =
|
||||||
context.sourceMode === 'battery_assist_night' &&
|
context.sourceMode === 'battery_assist_night' &&
|
||||||
commonSafetyStartOk &&
|
commonSafetyStartOk &&
|
||||||
nightSessionActive &&
|
(nightSessionActive || boostBatteryAvailable) &&
|
||||||
batteryAssistAllowed &&
|
batteryAssistAllowed &&
|
||||||
parsed.soc > batteryHardFloorPct &&
|
parsed.soc > batteryHardFloorPct &&
|
||||||
(
|
(
|
||||||
|
boostBatteryAvailable ||
|
||||||
nightBatterySurplusAvailable
|
nightBatterySurplusAvailable
|
||||||
? parsed.soc > nightBatterySurplusFloorPct
|
? parsed.soc > nightBatterySurplusFloorPct
|
||||||
: (
|
: (
|
||||||
@@ -897,11 +904,12 @@ const batteryAssistNightStartOk =
|
|||||||
const batteryAssistNightHoldOk =
|
const batteryAssistNightHoldOk =
|
||||||
context.sourceMode === 'battery_assist_night' &&
|
context.sourceMode === 'battery_assist_night' &&
|
||||||
commonSafetyHoldOk &&
|
commonSafetyHoldOk &&
|
||||||
nightSessionActive &&
|
(nightSessionActive || boostBatteryAvailable) &&
|
||||||
batteryAssistAllowed &&
|
batteryAssistAllowed &&
|
||||||
parsed.soc > batteryHardFloorPct &&
|
parsed.soc > batteryHardFloorPct &&
|
||||||
parsed.batteryCurrentA >= batteryDischargeHardDynamicA &&
|
parsed.batteryCurrentA >= batteryDischargeHardDynamicA &&
|
||||||
(
|
(
|
||||||
|
boostBatteryAvailable ||
|
||||||
nightBatterySurplusAvailable
|
nightBatterySurplusAvailable
|
||||||
? parsed.soc > nightBatterySurplusFloorPct
|
? parsed.soc > nightBatterySurplusFloorPct
|
||||||
: parsed.soc > gridTakeoverTriggerPct
|
: parsed.soc > gridTakeoverTriggerPct
|
||||||
@@ -1175,6 +1183,12 @@ return [{
|
|||||||
nightBudgetDeliveredKwh: nightPrev.nightBudgetDeliveredKwh ?? null,
|
nightBudgetDeliveredKwh: nightPrev.nightBudgetDeliveredKwh ?? null,
|
||||||
nightBudgetReached: !!nightPrev.nightBudgetReached,
|
nightBudgetReached: !!nightPrev.nightBudgetReached,
|
||||||
nightBudgetToWrite: nightPrev.nightBudgetToWrite ?? null,
|
nightBudgetToWrite: nightPrev.nightBudgetToWrite ?? null,
|
||||||
|
boostActive: !!nightPrev.boostActive,
|
||||||
|
boostBatteryAvailable,
|
||||||
|
boostFloorPct: nightPrev.boostFloorPct ?? null,
|
||||||
|
boostBudgetKwh: nightPrev.boostBudgetKwh ?? null,
|
||||||
|
boostDeliveredKwh: nightPrev.boostDeliveredKwh ?? null,
|
||||||
|
boostBudgetToWrite: nightPrev.boostBudgetToWrite ?? null,
|
||||||
nightChargeMode: nightPrev.nightChargeMode || 'sans_edf',
|
nightChargeMode: nightPrev.nightChargeMode || 'sans_edf',
|
||||||
nightCarWaitsNoGrid: !!nightPrev.nightCarWaitsNoGrid,
|
nightCarWaitsNoGrid: !!nightPrev.nightCarWaitsNoGrid,
|
||||||
nightBatteryGridOnly: !!nightPrev.nightBatteryGridOnly,
|
nightBatteryGridOnly: !!nightPrev.nightBatteryGridOnly,
|
||||||
|
|||||||
@@ -155,6 +155,12 @@ pushAction(
|
|||||||
!!calls.helper_night_budget?.execute
|
!!calls.helper_night_budget?.execute
|
||||||
);
|
);
|
||||||
|
|
||||||
|
pushAction(
|
||||||
|
'helper_boost_budget',
|
||||||
|
calls.helper_boost_budget,
|
||||||
|
!!calls.helper_boost_budget?.execute
|
||||||
|
);
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// DEMANDE RÉSEAU EDF SI SOURCE GRID
|
// DEMANDE RÉSEAU EDF SI SOURCE GRID
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|||||||
@@ -790,6 +790,7 @@ const sourceModeLabel =
|
|||||||
context.sourceMode === 'hybrid_probe' ? 'Probe hybride' :
|
context.sourceMode === 'hybrid_probe' ? 'Probe hybride' :
|
||||||
context.sourceMode === 'grid_hc_allowed' ? 'Réseau HC autorisé' :
|
context.sourceMode === 'grid_hc_allowed' ? 'Réseau HC autorisé' :
|
||||||
context.sourceMode === 'grid_forced' ? 'Réseau forcé' :
|
context.sourceMode === 'grid_forced' ? 'Réseau forcé' :
|
||||||
|
context.sourceMode === 'battery_assist_night' && night.boostBatteryAvailable ? 'Boost batterie' :
|
||||||
context.sourceMode === 'battery_assist_night' ? 'Assistance batterie nuit' :
|
context.sourceMode === 'battery_assist_night' ? 'Assistance batterie nuit' :
|
||||||
context.sourceMode;
|
context.sourceMode;
|
||||||
|
|
||||||
@@ -1439,6 +1440,17 @@ return [{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Boost sur batterie (15/10) : fige au premier cycle, efface a la sortie.
|
||||||
|
helper_boost_budget: {
|
||||||
|
execute: night.boostBudgetToWrite !== null && night.boostBudgetToWrite !== undefined,
|
||||||
|
domain: 'input_text',
|
||||||
|
service: 'set_value',
|
||||||
|
data: {
|
||||||
|
entity_id: 'input_text.victron_evcs_boost_budget',
|
||||||
|
value: night.boostBudgetToWrite ?? ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
helper_night_session_start_at: {
|
helper_night_session_start_at: {
|
||||||
execute: decision.setNightSessionStart || decision.clearNightSessionStart,
|
execute: decision.setNightSessionStart || decision.clearNightSessionStart,
|
||||||
domain: 'input_text',
|
domain: 'input_text',
|
||||||
|
|||||||
@@ -171,6 +171,7 @@
|
|||||||
"night_charge_mode": states("input_select.victron_evcs_night_charge_mode"),
|
"night_charge_mode": states("input_select.victron_evcs_night_charge_mode"),
|
||||||
"balance_night_vehicle_budget_kwh": states("input_number.evcs_balance_night_vehicle_budget_kwh"),
|
"balance_night_vehicle_budget_kwh": states("input_number.evcs_balance_night_vehicle_budget_kwh"),
|
||||||
"night_budget_prev": states("input_text.victron_evcs_night_budget"),
|
"night_budget_prev": states("input_text.victron_evcs_night_budget"),
|
||||||
|
"boost_budget_prev": states("input_text.victron_evcs_boost_budget"),
|
||||||
"evcs_total_energy_kwh": states("sensor.evcs_hq2239dnt7p_total_energy"),
|
"evcs_total_energy_kwh": states("sensor.evcs_hq2239dnt7p_total_energy"),
|
||||||
"balance_required_soc": states("input_number.evcs_balance_required_soc"),
|
"balance_required_soc": states("input_number.evcs_balance_required_soc"),
|
||||||
"balance_energy_to_cover_kwh": states("input_number.evcs_balance_energy_to_cover_kwh"),
|
"balance_energy_to_cover_kwh": states("input_number.evcs_balance_energy_to_cover_kwh"),
|
||||||
|
|||||||
@@ -535,6 +535,9 @@ const params = {
|
|||||||
nightChargeMode: low(input.night_charge_mode || 'sans_edf') === 'complete' ? 'complete' : 'sans_edf',
|
nightChargeMode: low(input.night_charge_mode || 'sans_edf') === 'complete' ? 'complete' : 'sans_edf',
|
||||||
balanceNightVehicleBudgetKwh: num(input.balance_night_vehicle_budget_kwh, NaN),
|
balanceNightVehicleBudgetKwh: num(input.balance_night_vehicle_budget_kwh, NaN),
|
||||||
nightBudgetPrevRaw: cleanText(input.night_budget_prev),
|
nightBudgetPrevRaw: cleanText(input.night_budget_prev),
|
||||||
|
// Boost sur batterie (15/10/2026) : « budget|index » fige au premier cycle de
|
||||||
|
// force_charge_now, efface a sa sortie (meme forme que le budget de nuit).
|
||||||
|
boostBudgetPrevRaw: cleanText(input.boost_budget_prev),
|
||||||
evcsTotalEnergyKwh: num(input.evcs_total_energy_kwh, NaN),
|
evcsTotalEnergyKwh: num(input.evcs_total_energy_kwh, NaN),
|
||||||
balanceEnergyToCoverKwh: num(input.balance_energy_to_cover_kwh, NaN),
|
balanceEnergyToCoverKwh: num(input.balance_energy_to_cover_kwh, NaN),
|
||||||
// ⚠️ NE PAS CONFONDRE LES DEUX GRANDEURS DU BILAN.
|
// ⚠️ NE PAS CONFONDRE LES DEUX GRANDEURS DU BILAN.
|
||||||
|
|||||||
@@ -687,6 +687,53 @@ const nightBudgetReached =
|
|||||||
nightBudgetDeliveredKwh >= nightBudget.budgetKwh - 0.05;
|
nightBudgetDeliveredKwh >= nightBudget.budgetKwh - 0.05;
|
||||||
const nightChargeComplete = params.nightChargeMode === 'complete';
|
const nightChargeComplete = params.nightChargeMode === 'complete';
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// BOOST SUR BATTERIE (15/10/2026, decision du proprietaire)
|
||||||
|
// =====================================================
|
||||||
|
// Le 14/10 au soir, boost EDF pour la Volvo d'un invite : 11,5 kWh achetes en
|
||||||
|
// heures pleines (voiture 6,35, batterie maison 2,81, maison ~2,3) alors que la
|
||||||
|
// batterie etait a 86 % pour 56 % requis et que la nuit est passee sans EDF.
|
||||||
|
// `force_charge_now` (« charge maintenant ») donne desormais d'abord a la
|
||||||
|
// voiture l'energie de la batterie AU-DESSUS du SOC requis prudent du bilan
|
||||||
|
// (meme plancher que P12 et que la tolerance nuage du 12/10), puis EDF.
|
||||||
|
// Budget FIGE au premier cycle avec l'index du compteur de la borne, dans
|
||||||
|
// input_text.victron_evcs_boost_budget (« budget|index »), efface a la sortie ;
|
||||||
|
// arret au COMPTEUR (monotone, pas d'oscillateur). Bilan absent ou perime :
|
||||||
|
// budget 0, EDF tout de suite (jamais la batterie a l'aveugle). Les gardes de
|
||||||
|
// courant batterie restent en place (elles peuvent brider le debit).
|
||||||
|
const boostBudgetPrev = (() => {
|
||||||
|
const m = String(params.boostBudgetPrevRaw || '').match(/^\s*([\d.]+)\|([\d.]+)\s*$/);
|
||||||
|
return m ? { budgetKwh: Number(m[1]), refKwh: Number(m[2]) } : null;
|
||||||
|
})();
|
||||||
|
const boostActive = forceChargeRequested && parsed.evcsVehicleConnected && !isStopMode;
|
||||||
|
const boostFloorPct = Math.max(
|
||||||
|
batteryHardFloorPct,
|
||||||
|
balanceMorningTargetApplied && Number.isFinite(params.balanceRequiredSocPrudentPct)
|
||||||
|
? params.balanceRequiredSocPrudentPct
|
||||||
|
: Infinity,
|
||||||
|
);
|
||||||
|
const boostCaptureOk = boostActive && !boostBudgetPrev && Number.isFinite(params.evcsTotalEnergyKwh);
|
||||||
|
const boostBudget = !boostActive
|
||||||
|
? null
|
||||||
|
: boostBudgetPrev || (boostCaptureOk
|
||||||
|
? {
|
||||||
|
budgetKwh: Number.isFinite(boostFloorPct)
|
||||||
|
? Math.max(0, ((parsed.soc - boostFloorPct) / 100) * cfg.batteryUsableCapacityKwh)
|
||||||
|
: 0,
|
||||||
|
refKwh: params.evcsTotalEnergyKwh,
|
||||||
|
}
|
||||||
|
: null);
|
||||||
|
const boostBudgetToWrite = boostActive
|
||||||
|
? (boostCaptureOk ? `${Math.round(boostBudget.budgetKwh * 100) / 100}|${boostBudget.refKwh}` : null)
|
||||||
|
: (boostBudgetPrev ? '' : null);
|
||||||
|
const boostDeliveredKwh = boostBudget && Number.isFinite(params.evcsTotalEnergyKwh)
|
||||||
|
? Math.max(0, params.evcsTotalEnergyKwh - boostBudget.refKwh)
|
||||||
|
: null;
|
||||||
|
const boostBatteryAvailable =
|
||||||
|
boostActive && !!boostBudget && boostDeliveredKwh !== null &&
|
||||||
|
boostDeliveredKwh < boostBudget.budgetKwh - 0.05 &&
|
||||||
|
parsed.soc > boostFloorPct;
|
||||||
|
|
||||||
// Le verrou ne vaut QUE pendant la session de nuit (01/10/2026). Ecrit sous la
|
// Le verrou ne vaut QUE pendant la session de nuit (01/10/2026). Ecrit sous la
|
||||||
// forme `prev || …`, il restait vrai pour toujours une fois pose ; invisible
|
// forme `prev || …`, il restait vrai pour toujours une fois pose ; invisible
|
||||||
// tant que son ecriture n'atteignait pas HA (jamais relayee du 15/09 au 01/10).
|
// tant que son ecriture n'atteignait pas HA (jamais relayee du 15/09 au 01/10).
|
||||||
@@ -1038,6 +1085,15 @@ else if (forceChargeRequested) {
|
|||||||
sourceMode = 'solar_only';
|
sourceMode = 'solar_only';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boost sur batterie (15/10) : la batterie dans son budget, puis EDF.
|
||||||
|
else if (boostBatteryAvailable) {
|
||||||
|
sourceMode = 'battery_assist_night';
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (boostActive) {
|
||||||
|
sourceMode = 'grid_forced';
|
||||||
|
}
|
||||||
|
|
||||||
else if (nightSessionActive && batteryAssistAllowed) {
|
else if (nightSessionActive && batteryAssistAllowed) {
|
||||||
sourceMode = 'battery_assist_night';
|
sourceMode = 'battery_assist_night';
|
||||||
}
|
}
|
||||||
@@ -1319,6 +1375,12 @@ return [{
|
|||||||
nightBudgetDeliveredKwh,
|
nightBudgetDeliveredKwh,
|
||||||
nightBudgetReached,
|
nightBudgetReached,
|
||||||
nightBudgetToWrite,
|
nightBudgetToWrite,
|
||||||
|
boostActive,
|
||||||
|
boostBatteryAvailable,
|
||||||
|
boostFloorPct: Number.isFinite(boostFloorPct) ? boostFloorPct : null,
|
||||||
|
boostBudgetKwh: boostBudget ? boostBudget.budgetKwh : null,
|
||||||
|
boostDeliveredKwh,
|
||||||
|
boostBudgetToWrite,
|
||||||
nightChargeMode: params.nightChargeMode,
|
nightChargeMode: params.nightChargeMode,
|
||||||
nightCarWaitsNoGrid,
|
nightCarWaitsNoGrid,
|
||||||
nightBatteryGridOnly,
|
nightBatteryGridOnly,
|
||||||
|
|||||||
@@ -144,6 +144,8 @@ function summarize(out) {
|
|||||||
nightBatteryDoneService: calls.helper_night_battery_done?.execute ? calls.helper_night_battery_done.service : null,
|
nightBatteryDoneService: calls.helper_night_battery_done?.execute ? calls.helper_night_battery_done.service : null,
|
||||||
// Budget voiture de la nuit (30/09) : valeur ecrite ce cycle, null sinon.
|
// Budget voiture de la nuit (30/09) : valeur ecrite ce cycle, null sinon.
|
||||||
nightBudgetWrite: calls.helper_night_budget?.execute ? calls.helper_night_budget.data.value : null,
|
nightBudgetWrite: calls.helper_night_budget?.execute ? calls.helper_night_budget.data.value : null,
|
||||||
|
// Boost sur batterie (15/10) : budget ecrit ce cycle, null sinon.
|
||||||
|
boostBudgetWrite: calls.helper_boost_budget?.execute ? calls.helper_boost_budget.data.value : null,
|
||||||
// Consigne de puissance reseau ecrite ce cycle (null = aucune ecriture).
|
// Consigne de puissance reseau ecrite ce cycle (null = aucune ecriture).
|
||||||
gridSetpointW: calls.grid_power_setpoint?.execute
|
gridSetpointW: calls.grid_power_setpoint?.execute
|
||||||
? calls.grid_power_setpoint.data.value
|
? calls.grid_power_setpoint.data.value
|
||||||
|
|||||||
@@ -1849,21 +1849,23 @@ export const scenarios = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'force-charge-nuit',
|
id: 'force-charge-nuit',
|
||||||
label: 'force_charge_now la nuit (toggle HC ON) → démarrage manuel local (non-régression P7)',
|
label: 'force_charge_now la nuit, bilan absent → budget batterie 0 → EDF tout de suite (boost du 15/10)',
|
||||||
time: NIGHT,
|
time: NIGHT,
|
||||||
overrides: {
|
overrides: {
|
||||||
...VEHICLE_NIGHT, victron_evcs_strategy: 'force_charge_now',
|
...VEHICLE_NIGHT, victron_evcs_strategy: 'force_charge_now',
|
||||||
soc_percent: '60', allow_grid_hc_night: 'on',
|
soc_percent: '60', allow_grid_hc_night: 'on',
|
||||||
},
|
},
|
||||||
|
// Avant le 15/10 : 'solar_potential' / start_manual_local (la batterie a
|
||||||
|
// l'aveugle). Desormais, sans bilan exploitable, le boost ne prend JAMAIS la
|
||||||
|
// batterie : il demande EDF (ici en HC de nuit).
|
||||||
expect: {
|
expect: {
|
||||||
profile: 'night_hc',
|
profile: 'night_hc',
|
||||||
sourceMode: 'solar_potential',
|
sourceMode: 'grid_forced',
|
||||||
state: 'start_manual_local_min_current',
|
state: 'night_wait_grid_takeover',
|
||||||
decision: 'start',
|
decision: 'hold',
|
||||||
desiredCharging: true,
|
desiredCharging: false,
|
||||||
currentA: 6,
|
|
||||||
takeoverNeeded: true,
|
takeoverNeeded: true,
|
||||||
edfOnAction: false,
|
edfOnAction: true,
|
||||||
takeoverHelperService: 'turn_on',
|
takeoverHelperService: 'turn_on',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -3651,4 +3653,32 @@ export const scenarios = [
|
|||||||
// Identique a l'ancien code (6458 W).
|
// Identique a l'ancien code (6458 W).
|
||||||
expect: { gridSetpointW: 6458 },
|
expect: { gridSetpointW: 6458 },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'boost-batterie-1410-dans-le-budget',
|
||||||
|
label: '14/10 20:40 rejoue en force_charge_now — SOC 87, requis prudent 82,2 : la batterie d abord (budget 1,44 kWh fige)',
|
||||||
|
time: '2026-10-14T20:40:00+02:00',
|
||||||
|
overrides: { ...VOLVO_1410, victron_evcs_strategy: 'force_charge_now', boost_budget_prev: '' },
|
||||||
|
expect: { sourceMode: 'battery_assist_night', desiredCharging: true, boostBudgetWrite: '1.44|4144' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'boost-batterie-1410-budget-atteint-edf',
|
||||||
|
label: 'meme soiree, budget 1,44 kWh deja donne au compteur : EDF prend le relais',
|
||||||
|
time: '2026-10-14T20:40:00+02:00',
|
||||||
|
overrides: { ...VOLVO_1410, victron_evcs_strategy: 'force_charge_now', boost_budget_prev: '1.44|4142.5' },
|
||||||
|
expect: { sourceMode: 'grid_forced', state: 'charging_hold_grid', desiredCharging: true, boostBudgetWrite: null },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'boost-batterie-bilan-perime-edf',
|
||||||
|
label: 'boost, bilan perime (2 h) : budget 0, EDF tout de suite, jamais la batterie a l aveugle',
|
||||||
|
time: '2026-10-14T20:40:00+02:00',
|
||||||
|
overrides: { ...VOLVO_1410, victron_evcs_strategy: 'force_charge_now', boost_budget_prev: '', balance_last_run: '14/10 18:35' },
|
||||||
|
expect: { sourceMode: 'grid_forced', state: 'charging_hold_grid', desiredCharging: true, boostBudgetWrite: '0|4144' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'boost-batterie-efface-a-la-sortie',
|
||||||
|
label: 'sortie du boost (retour auto_solar_plus) : le budget fige est efface',
|
||||||
|
time: '2026-10-14T20:40:00+02:00',
|
||||||
|
overrides: { ...VOLVO_1410, victron_evcs_strategy: 'auto_solar_plus', boost_budget_prev: '1.44|4144' },
|
||||||
|
expect: { boostBudgetWrite: '' },
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -226,6 +226,8 @@ export const ORIGINE_PAR_SOURCE = {
|
|||||||
'Potentiel solaire': 'en_charge_solaire',
|
'Potentiel solaire': 'en_charge_solaire',
|
||||||
'Probe hybride': 'en_charge_sonde',
|
'Probe hybride': 'en_charge_sonde',
|
||||||
'Assistance batterie nuit': 'en_charge_batterie',
|
'Assistance batterie nuit': 'en_charge_batterie',
|
||||||
|
// 15/10/2026 : force_charge_now dans son budget batterie.
|
||||||
|
'Boost batterie': 'en_charge_batterie',
|
||||||
'Réseau HC autorisé': 'en_charge_reseau',
|
'Réseau HC autorisé': 'en_charge_reseau',
|
||||||
'Réseau forcé': 'en_charge_reseau',
|
'Réseau forcé': 'en_charge_reseau',
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user