Doc: MANUEL_COMPLET à jour (helpers advisor/véhicules, §11.5 P9, GRAFCET G1bis + Fix E/F, §11.7 advisor, méthode R2) + MEMORY refresh

This commit is contained in:
Tallagrand Thierry
2026-08-09 09:34:48 +02:00
parent 0419c741de
commit 970ff83f68
2 changed files with 152 additions and 29 deletions

View File

@@ -1,6 +1,7 @@
# Manuel Utilisateur - Système EVCS Solaire
> Document généré le 17/07/2026
> Document généré le 17/07/2026 — dernière mise à jour le 09/08/2026
> (fixes anti-rebond A→F, câblage advisor cible SOC, P9 départ, véhicules VW/JEEP)
> Projet: n8n / Home Assistant / EVCS Solaire sans injection réseau
---
@@ -180,13 +181,32 @@
| Entity ID | Type | Description |
|---|---|---|
| `input_select.victron_evcs_strategy` | select | Stratégie (auto_solar_plus, force_grid_now, etc.) |
| `input_select.victron_evcs_vehicle` | select | **Véhicule branché : VW ou JEEP** (09/08/2026, à sélectionner au branchement) |
| `input_number.victron_evcs_required_energy_kwh` | number | Énergie demandée (kWh) |
| `input_boolean.victron_evcs_departure_priority_enabled` | boolean | Priorité départ |
| `input_datetime.victron_evcs_departure_time` | datetime | Heure de départ |
| `input_boolean.victron_evcs_allow_grid_hc_night` | boolean | Réseau HC nuit |
| `input_datetime.victron_evcs_departure_time` | datetime | Heure de départ **VW** (~08:50) |
| `input_datetime.victron_evcs_departure_time_jeep` | datetime | Heure de départ **JEEP** (~06:30) |
| `input_boolean.victron_evcs_allow_grid_departure_urgent` | boolean | **P9 : réseau avant départ hors HC** (fenêtre 120 min) |
| `input_boolean.victron_evcs_allow_grid_hc_night` | boolean | Réseau HC nuit (P7) |
| `input_boolean.victron_evcs_allow_grid_hc_midday` | boolean | Réseau HC midi |
| `input_boolean.victron_evcs_surplus_auto_enabled` | boolean | Contrôleur surplus actif |
Package : `/mnt/ARCH3/docker/HA/packages/victron_evcs_vehicles.yaml` (sélecteur,
départ JEEP, toggle P9). NB : `input_select.victron_evcs_target_vehicle`
(None/Jeep/Zero) est un ancien helper UI non câblé — ne pas l'utiliser.
### 6.1bis Conseiller IA (advisor)
| Entity ID | Type | Description |
|---|---|---|
| `input_boolean.evcs_advisor_enabled` | boolean | Kill-switch : l'advisor tourne (15 min) et écrit ses recommandations |
| `input_boolean.evcs_advisor_apply_night_target` | boolean | **CÂBLAGE RÉEL** : la cible SOC matin suit l'advisor (bornes 22-90, statut ok, fraîcheur ≤ 120 min) |
| `input_number.evcs_advisor_night_target_soc` | number | Cible SOC matin recommandée |
| `input_text.evcs_advisor_strategy` / `_reason` / `_status` / `_divergence` / `_last_run` / `_model` | text | Détail des recommandations (cartes + historique) |
| `input_number.evcs_advisor_agree_count` / `_diverge_count` | number | Compteurs accord/divergence vs réel |
Package : `/mnt/ARCH3/docker/HA/packages/evcs_advisor_shadow.yaml`.
### 6.2 État système
| Entity ID | Type | Description |
@@ -322,29 +342,48 @@ En mode `auto_solar_plus` ou `force_charge_now`, le profil `outside_window` ne b
- Forecast solaire fort
- Maison consommation faible
### 11.5 Logique Heure de départ (Night EVCS)
### 11.5 Logique Heure de départ (Night EVCS + P9)
#### Objectif
S'assurer que le véhicule est chargé avant l'heure de départ prévue.
#### Deux véhicules (09/08/2026)
Le sélecteur `input_select.victron_evcs_vehicle` choisit l'heure de départ
effective — **à positionner au branchement** (la borne ne détecte pas qui est
branché) :
| Véhicule | Heure départ (helper) | Particularité |
|---|---|---|
| **VW** (défaut) | `victron_evcs_departure_time` (~08:50) | Ne publie pas franchement "charged" → fin de charge via VDF |
| **JEEP** | `victron_evcs_departure_time_jeep` (~06:30) | "Charged" franc (statut 3) ; départ DANS la fenêtre HC → logique nuit |
#### Comportement
| Scénario | Action |
|---|---|
| Heure départ proche + batteries suffisantes | Charge solaire prioritaire |
| Heure départ proche + batteries insuffisantes | grid_forced (HC) si disponible |
| Heure départ proche + pas de HC | grid_forced (plein tarif) |
| Départ pendant la fenêtre HC (JEEP 06:30) | Logique nuit : P7 + recovery urgent avant départ |
| Départ après la fenêtre HC (VW 08:50) + charge finie | Rien (veille collante) |
| Départ ≤ 120 min, hors HC, charge NON finie, **toggle P9 ON** | `grid_hc_allowed` → EDF ON → charge jusqu'à fin (VDF/statut) → `departure_done_idle` collant → EDF coupé immédiatement |
| Toggle P9 OFF | Comportement historique (attente solaire) |
P9 ne s'impose jamais sur `solar_only` (solaire réel prioritaire) ni sur
`stop` / `force_*`. Pendant P9 le helper takeover est tenu ON (ACM maintient
la batterie, l'hystérésis maintient EDF).
#### Paramètres
- **batteryHardFloorPct** : Plancher dur batterie (ex: 22%)
- **batteryMorningTargetPct** : Objectif SOC matin selon forecast
- Forecast fort (> 15 kWh) : 40%
- Forecast moyen (8-15 kWh) : 50%
- Forecast faible (< 8 kWh) : 75%
- **batteryMorningTargetPct** : Objectif SOC matin
- Règles forecast (fort/moyen/faible) — valeurs helpers ;
- **OU la recommandation de l'advisor** si le toggle
`evcs_advisor_apply_night_target` est ON (bornes [max(22, hard floor), 90],
statut `ok`, fraîcheur ≤ 120 min ; trace `(ADVISOR)` dans la raison) —
câblage réel du 09/08/2026, HANDOFF §20.
- **gridTakeoverTriggerPct** : Seuil de basculement réseau
- **batteryRecoveryUrgent** : Si temps restant < temps de charge nécessaire
(utilise l'heure de départ du véhicule sélectionné)
- **P9_DEPARTURE_LEAD_MIN** : 120 min (constante WINDOWS_SOURCEV2)
### 11.6 Cycle nuit HC complet — GRAFCET (P7 + P8 + fixes 08/08/2026)
### 11.6 Cycle nuit HC complet — GRAFCET (P7 + P8 + fixes 08-09/08/2026)
Deux automates coordonnés via les helpers HA (`night_grid_takeover_needed`,
`victron_evcs_surplus_state`) :
@@ -361,46 +400,87 @@ X1 SESSION NUIT ACTIVE — capture startSOC/startAt (une seule fois, Fix B)
X2 TAKEOVER: helper ON → G2 force EDF ON ; ACM tient la batterie (~2 A)
│ t3: EDF ON confirmé (gridAvailable)
X3 CHARGE VE: start 6 A → step-up (plafond 20 A / boost 28 A)
│ t4: fin de charge = VDF no-demand OU statut EVCS brut 3 "charged" (Fix D)
│ t4: fin de charge = VDF no-demand OU statut EVCS brut 3 "charged"
│ + puissance ≤ 300 W (Fix D+E)
X4 CHARGE TERMINÉE (collant): vehicleChargeCompleted, sourceMode='blocked'
│ ⚑ Fix F : cet état est réécrit à CHAQUE cycle AU-DESSUS des gardes
│ (hard stop batterie, source-lost...) → il survit aux micro-charges
│ du véhicule et ne peut plus être écrasé.
│
├─ t5a: SOC < cible matin
├─ t5a: SOC < cible matin (cible = règles forecast OU advisor si câblé)
│ X5a RECOVERY BATTERIE: takeover ON (EDF ON), ACM recharge → cible
│ │ t6: SOC ≥ cible
│ ▼
└─ t5b: SOC ≥ cible matin
X5b RECOVERY DONE (collant, Fix A): état 'night_recovery_done_idle'
│ takeover OFF définitif → G2 coupe EDF (turn_off_recovered)
│ takeover OFF définitif → G2 coupe EDF IMMÉDIATEMENT (cut E2)
│ ré-engagement UNIQUEMENT si SOC ≤ cible − 2 (bande anti-rebond)
│ t7: débranchement OU fin de fenêtre (07:24)
X6 CLÔTURE: clear session → retour X0 (profil jour)
G1bis — P9 : DÉPART IMMINENT HORS HC (09/08/2026)
─────────────────────────────────────────────────
Z0 JOUR, hors fenêtre HC
│ w1: toggle P9 ON ET véhicule branché ET départ (véhicule sélectionné)
│ dans ≤ 120 min ET charge non terminée
Z1 RÉSEAU PRÉ-DÉPART: sourceMode='grid_hc_allowed' (bypass garde SOC 35),
│ takeover helper ON (ACM + hystérésis), EDF ON, charge du véhicule.
│ NB: solar_only réel reste prioritaire ; stop/force* restent maîtres.
│ w2: fin de charge (VDF vehicle_full_or_paused OU statut 3)
Z2 'departure_done_idle' (COLLANT, réécrit chaque cycle comme Fix F)
│ takeover OFF → G2 coupe EDF immédiatement (cut E2 étendu)
│ w3: heure de départ passée OU débranchement
Z0 retour au jour normal
G2 — HYSTÉRÉSIS EDF (seuils ON ≤ 20 % | OFF ≥ 30 % | min_on 25 | cooldown 15)
──────────────────────────────────────────────────────────────────────────────
Y0 EDF OFF (observe_only)
│ u1: override EVCS (takeover/force_grid/grid_forced) sans no-demand
│ u1: override EVCS (takeover/force_grid/grid_forced/grid_hc_allowed)
│ sans no-demand sémantique
│ u2: SOC ≤ seuil ON (bypass cooldown)
Y1 EDF ON + latch
│ v1: override disparu ET min_on écoulé ET SOC ≥ seuil OFF → turn_off_recovered
│ v2: force_grid + voiture pleine → coupure immédiate
│ v3: véhicule débranché + SOC ≥ seuil OFF → coupure immédiate
│ (turn_off_vehicle_unplugged, bypass min_on — Fix C 08/08/2026)
│ (turn_off_vehicle_unplugged, bypass min_on — Fix C)
│ v4: es ∈ {night_recovery_done_idle, departure_done_idle} + SOC ≥ seuil OFF
│ → coupure immédiate (turn_off_recovery_done, bypass min_on — E2+P9)
└─▶ retour Y0 (cooldown 15 min)
```
États surplus « fin de nuit » (aucun ne doit matcher les patterns no-demand
États surplus « fin de charge » (aucun ne doit matcher les patterns no-demand
de G2 — full_or_paused / not_requesting_power / charge_complete / no_demand) :
- `night_session_done_idle` : charge finie, recovery batterie possible (EDF
maintenu si SOC < cible)
- `night_recovery_done_idle` : charge finie ET batterie à la cible → EDF
relâché définitivement (anti-rebond)
- `departure_done_idle` : charge finie pendant la fenêtre départ P9 (jour)
→ EDF relâché définitivement
#### Incident de référence (nuit 07-08/08/2026)
SOC bloqué pile à la cible (35 %) = point dégénéré (engage `soc ≤ 35`,
release `soc > 35`) → rebond EDF ON/OFF période ~10 min + flapping ACM 2-4 s,
et EDF maintenu 25 min après débranchement. Corrigé par Fix A (flag collant +
bande 2 pts), Fix B (snapshot relit startSOC/startAt), Fix C (coupure au
débranchement), Fix D (statut charged = fin de charge immédiate).
#### Incidents de référence
- **Nuit 07-08/08 (JEEP)** : SOC bloqué pile à la cible = point dégénéré →
rebond EDF ~10 min + flapping ACM ; EDF maintenu 25 min après débranchement.
→ Fix A (collant + bande 2 pts), B (snapshot startSOC/At), C (coupure au
débranchement), D (statut charged).
- **Nuit 08-09/08 (JEEP)** : statut 3 pendant la session armée → branches
source-lost zombies, état collant jamais écrit, statut retombe à l'ouverture
du relais → re-P7 ~30 min. → Fix E (latch en session active) + E2 (coupure
immédiate recovery done).
- **Matin 09/08 (VW pleine rebranchée)** : micro-charges du véhicule sur
batterie → hard stop ÉCRASAIT l'état collant → re-P7. → Fix F (mémoire
prioritaire sur les gardes, réécrite chaque cycle).
### 11.7 Conseiller IA — mode ombre et câblages réels
- Workflow `EVCS Advisor Shadow V1` (15 min) : snapshot HA compact → LLM local
(qwen3-vl / qwen3.6-35b sur la Spark, fallback cloud) → validation stricte →
helpers `evcs_advisor_*` + logbook. N'écrit RIEN d'autre (testé).
- **Câblage réel n°1 (09/08/2026)** : cible SOC matin
(`evcs_advisor_apply_night_target`, cf. §11.5). Garde-fous : statut ok,
fraîcheur ≤ 120 min, bornes, fallback règles, rollback toggle.
- Suivi : carte « Conseiller IA (ombre) » (accords/divergences), historique
des entités `evcs_advisor_*`, logbook « EVCS Advisor », executions n8n.
- Prochains candidats (après observation) : stratégie, plafond courant.
---
@@ -439,7 +519,30 @@ débranchement), Fix D (statut charged = fin de charge immédiate).
## 13. Méthode de travail
### 13.1 Lecture d'un workflow n8n
### 13.1 Source de vérité et déploiement (R2, 07/08/2026)
Le code des nodes du workflow EVCS V2.6 vit dans **`src/nodes/*.js`**
(+ `HA_SNAPSHOT_TEMPLATE.json.tpl`). Le JSON `workflows/*.json` est un
artefact reconstruit au push.
```
éditer src/nodes/<NODE>.js
node tools/n8n-push.mjs workflows/evcs-surplus-controller-v2.6.json
→ build src→JSON → node --check → GOLDEN 33 scénarios (bloquant)
→ backup serveur → PUT
git commit && git push
```
- **JAMAIS** d'édition du JSON ou de l'UI n8n (écrasée au prochain push).
- Tests : `node tests/golden/run.mjs` (33 scénarios figés, exécute le JSON
**buildé** → toujours `node tools/n8n-build.mjs` avant un run manuel).
- Évolution voulue du comportement → mettre à jour
`tests/golden/scenarios.mjs` dans le même commit.
- Workflow hystérésis (`7iIlu7LLTW7TZA8o`) : fichier local
`workflows/victron-grid-hysteresis-v1.json`, patches rejouables dans
`tools/patch-*.mjs`, push via `n8n-push.mjs` (backup auto).
### 13.2 Lecture d'un workflow n8n (hors EVCS V2.6)
1. Utiliser `n8n-mcp_get_workflow` avec l'ID
2. Le fichier est écrit dans `~/.local/share/opencode/tool-output/tool_*`
@@ -450,14 +553,14 @@ débranchement), Fix D (statut charged = fin de charge immédiate).
sed -n 'DEBUT,FINp' <fichier>
```
### 13.2 Modification
### 13.3 Modification
1. **TOUJOURS** backup avant modification
2. Une seule modification à la fois
3. Vérifier avec dry-run
4. Valider en production
### 13.3 Interdiction
### 13.4 Interdiction
- **JAMAIS** de curl/wget direct vers HA/n8n/Victron
- **JAMAIS** d'IP/URL/token inventés
@@ -469,10 +572,10 @@ débranchement), Fix D (statut charged = fin de charge immédiate).
- [ ] Tableau détaillé des fonctionnalités (entrées/sorties/conditions)
- [ ] Documentation EDF Urgence (créé par FABLE)
- [ ] Liste des incidents récurrents
- [x] Liste des incidents récurrents → §11.6 (incidents de référence) + HANDOFF §17-21
- [ ] Procédures de dépannage
- [ ] Glossaire des termes techniques
---
*Document généré automatiquement le 17/07/2026*
*Document généré le 17/07/2026 — mis à jour le 09/08/2026 (HANDOFF §17-21 : fixes A→F, advisor, P9, véhicules)*