Files
EVCS/HANDOFF.md
2026-06-13 00:03:22 +02:00

9.7 KiB

HANDOFF.md — EVCS Outside-Window Solar Charging Block

1. Contexte Projet

  • Installation : Victron ESS sans injection réseau. Batterie 17,5 kWh.
  • Workflow actif : HA Snapshot EVCS Surplus Controller V2.6 (n8n)
  • Code source : /mnt/projects/EVCS/EVCS/decoupesurplus/ (architecture modulaire V2)
  • Fichiers critiques :
    • WINDOWS/WINDOW_SOURCEV2.js — Détermine profile et sourceMode
    • BATTERY/BATTERY_CLOUD_LOCKS.js — Calcule cloudDebt, cloudToleranceOk
    • snapshot.js — Récupération des helpers HA
    • modified/EVCS_V2.5_PATCHED.json — Export n8n de référence (avant upgrade V2.6)

2. Architecture Data-Flow

Schedule Trigger (30s)
  → HA Snapshot (template)
  → INPUT_PARSE
  → WINDOWS_SOURCEV2  ← C'EST ICI QUE LE BLOCAGE SE PRODUIT
  → BATTERY_CLOUD_LOCKS
  → DECISION_ENGINEV2
  → HA_SERVICE_CALLS_OUTPUT
  → Execute HA Service

3. Problème Observé

Symptôme

L'après-midi, avec un fort ensoleillement et un SOC élevé (> 85 %), l'EVCS reste en :

  • Profil : outside_window
  • Décision : stop_hard ou hold / blocked
  • Source : Bloqué
  • Action utilisateur requise : Forcer manuellement force_charge_now

Capture d'état typique

Stratégie : auto_solar_plus
Profil    : outside_window
Source    : Bloqué
SOC       : 91 %
Cloud Debt: 1.66 kWh
PV Power  : ~800 W (aligné sur charge maison, pas d'injection)
Decision  : stop_hard | battery_current_hard_stop

Note contextuelle importante : L'utilisateur a attendu ~45 min sans succès, puis a volontairement passé en force_charge_now pour charger sa moto électrique. Ce forçage a fait tirer sur les batteries à cause des nuages, augmentant encore le cloud_debt.

4. Root Cause Analysis

4.1. Définition de outside_window

outside_window = tout horaire hors des 4 fenêtres configurées :

  • night_hc : 23:00 → 06:00
  • morning_solar : 07:30 → 11:00
  • midday_hc_or_solar : 12:24 → 14:24
  • evening_high_soc : 17:00 → 20:30

Donc outside_window couvre : 11:00→12:24, 14:24→17:00, 20:30→23:00.

4.2. Logique du sourceMode en outside_window (WINDOW_SOURCEV2.js, L454-468)

else if (profile === 'outside_window') {
  if (strongSolarSignal) {
    sourceMode = 'solar_only';
  } else if (isHighBatteryForPotential && potentialAllowed) {
    sourceMode = 'solar_potential';
  } else {
    sourceMode = 'blocked';   // ← TOMBE ICI
  }
}

Pour sortir de blocked, il faut obligatoirement l'un des deux :

A. strongSolarSignal (L343-352)

const strongSolarSignal =
  (parsed.pvPowerW > 0 && parsed.pvPowerW >= effectivePvStartMinW) ||
  parsed.pvPowerAvg10mW >= params.pvHoldMinW ||
  (departurePriorityActive && parsed.pvPowerAvg10mW >= params.pvHoldMinW);
  • pvStartMinW défaut = 1800 W
  • pvHoldMinW défaut = 1200 W

Pourquoi c'est faux chez l'utilisateur : Comme il n'injecte pas, quand SOC > 85 % et charge maison = 800 W, le MPPT régule les PV à ~800 W. Ni pvPowerW, ni pvPowerAvg10mW ne dépassent les seuils.

B. isHighBatteryForPotential (L335-339)

const isHighBatteryForPotential =
  parsed.soc >= 85 &&
  forecastBufferKwh > 0 &&
  cloudDebtOkForPotential &&     // ← BLOQUÉ ICI
  batteryOkForPotential;

Pourquoi c'est faux chez l'utilisateur :

const cloudDebtOkForPotential = params.cloudDebtPrevKwh <= params.cloudDebtMaxKwh;
// cloudDebtPrevKwh = 1.66 kWh
// cloudDebtMaxKwh  = 1.2 kWh (défaut)
// → cloudDebtOkForPotential = FALSE

Donc isHighBatteryForPotential est FORCÉMENT FALSE, même avec SOC 91 %.

4.3. Pourquoi le cloud debt est à 1.66 kWh

Le cloud_debt s'accumule quand :

  • Session EVCS active
  • sourceMode n'est PAS grid_hc_allowed (donc solaire ou batterie)
  • batteryCurrentA < -neutralBand (batterie qui décharge)

Sur une journée nuageuse avec intermittences, l'EVCS a démarré/stoppé plusieurs fois. Pendant les passages nuageux, la batterie a complété la puissance manquante → accumulation de dette. Cette dette ne se rembourse que quand batteryCurrentA > 0 (batterie en charge). Or, si le système bloque l'EVCS, il n'y a pas de passage à batteryCurrentA > 0 pendant la charge EVCS, donc la dette reste bloquée haute.

4.4. Absence de probe en outside_window

Les probes (morningProbeEligible, middayProbeEligible) sont strictement limitées aux profiles morning_solar et midday_hc_or_solar (WINDOW_SOURCEV2.js L317-330). Il n'existe aucun mécanisme de sonde en outside_window pour tester si le PV peut supporter une charge à 6 A.

4.5. Réseau HC midi / nuit

Les toggles allow_grid_hc_night et allow_grid_hc_midday ne concernent QUE les fenêtres night_hc et midday_hc_or_solar. Ils sont totalement ignorés en outside_window. Ce n'est donc PAS une solution.

4.6. Priorité départ

departurePriorityActive s'active seulement si :

  • departurePriorityEnabled = ON
  • minutesUntilDeparture <= 240 min
  • Véhicule branché

Effet : facilite strongSolarSignal en baissant la barre si pvPowerAvg10mW >= pvHoldMinW. Mais ne résout pas le blocage cloudDebt.

5. Résumé des Verrous

Verrou Condition État actuel Impact
Seuil PV instantané pvPowerW >= 1800 W ~800 W strongSolarSignal = false
Seuil PV moyenne pvPowerAvg10mW >= 1200 W Souvent < 1200 W strongSolarSignal = false
Cloud Debt cloudDebt <= 1.2 kWh 1.66 kWh isHighBatteryForPotential = false
Probe absente Seulement morning / midday N/A en afternoon Aucun test de démarrage
Réseau HC Ignoré hors fenêtre N/A Pas de fallback grid

6. Options de Correction Envisagées

Option A — Relâcher cloudDebtOkForPotential en outside_window

Dans WINDOW_SOURCEV2.js, ignorer la condition cloudDebtOkForPotential pour le calcul de isHighBatteryForPotential quand profile === 'outside_window'.

Avantage : Simple, 1 ligne. Risque : Peut entraîner une décharge excessive de la batterie si le PV baisse brutalement.

Option B — Ajouter une afternoon_probe en outside_window (RECOMMANDÉ)

Créer une logique de sonde (probe) active en outside_window lorsque auto_solar_plus est sélectionné. Démarrage à 6 A pendant 3 min, puis évaluation.

Avantage : Fidèle à la philosophie du système (ne charge que si le PV confirme). Risque : Nécessite modification de BATTERY_CLOUD_LOCKS.js + DECISION_ENGINEV2.js.

Option C — Ajouter une fenêtre afternoon_solar

Étendre la logique des fenêtres pour inclure une plage 14:24→17:00 (ou configurable) avec des seuils PV adaptés.

Avantage : Résout définitivement le "trou" de l'après-midi. Risque : Change la sémantique utilisateur des fenêtres.

Option D — Abaisser pvStartMinW / pvHoldMinW dynamiquement

En outside_window + auto_solar_plus, baisser les seuils si soc >= 90 et forecastBufferKwh > 0.

Avantage : Adaptatif. Risque : Peut causer des démarrages/stops fréquents si le PV est instable.

7. Prochaines Étapes Recommandées

  1. Décider quelle Option (A, B, C ou D) correspond au comportement souhaité.
  2. Vérifier la valeur exacte de cloud_debt_max_kwh dans HA (input_number.victron_cloud_debt_max_kwh ou équivalent).
  3. Implémenter le patch dans le fichier cible :
    • Si Option A : WINDOWS/WINDOW_SOURCEV2.js
    • Si Option B : WINDOWS/WINDOW_SOURCEV2.js + BATTERY_CLOUD_LOCKS.js + DECISION_ENGINEV2.js
    • Si Option C : WINDOWS/WINDOW_SOURCEV2.js + INPUT_PARSE.js
    • Si Option D : WINDOWS/WINDOW_SOURCEV2.js
  4. Tester en mode "dry-run" (logique uniquement, pas d'appels HA).
  5. Redéployer via export/import du workflow n8n.

8. Paramètres Clés à Vérifier dans Home Assistant

Paramètre HA Entité typique Valeur défaut Valeur actuelle ?
pv_start_min_w input_number.victron_pv_start_min_w 1800 W ?
pv_hold_min_w input_number.victron_pv_hold_min_w 1200 W ?
cloud_debt_max_kwh input_number.victron_cloud_debt_max_kwh 1.2 kWh ?
battery_neutral_band_a input_number.victron_battery_neutral_band_a 3 A ?
allow_grid_hc_midday input_boolean.victron_allow_grid_hc_midday OFF ON (actif)
allow_grid_hc_night input_boolean.victron_allow_grid_hc_night OFF ON (actif)

9. Bugs corrigés lors du déploiement V2.6

Bug 1 — Clignotement EDF (edf_general_ok_switch)

  • Symptôme : Le switch EDF clignotait ON/OFF toutes les 30s depuis la mise à jour manuelle du workflow V2.6
  • Cause : Dans le nœud Build EVCS Surplus Controller V2.0 Actions, l'appel edf_general_ok_on avait la condition true (toujours actif) au lieu d'être conditionné au sourceMode
  • Fix : Remplacé true par context.sourceMode === 'grid_hc_allowed' || context.sourceMode === 'grid_forced'
  • Note : Il a fallu aussi ajouter const context = root.context || {}; en haut du nœud Build car context n'était pas importé
  • Validation : Désactivation de V2.6 → arrêt du clignotement. Réactivation Grid Hysteresis seul → stable. Réactivation V2.6 corrigé → stable.

10. Notes de Version

  • Workflow mis à jour de V2.5 → V2.6 par l'utilisateur via l'interface n8n.
  • La feature afternoon_probe y est désormais active.
  • Le fichier modified/EVCS_V2.5_PATCHED.json reste l'export de référence pour rollback.

Document créé le : 12/06/2026 | Mis à jour : 12/06/2026 Session terminée : afternoon_probe déployé + bug EDF corrigé + stabilité confirmée Prochaine action : Observer le comportement en afternoon et ajuster les seuils des helpers si nécessaire