feat: session 09/07 — P1-P5 déployés (hystérésis robuste, anti-créneaux nuit, provocation PV, maintien SOC takeover, plafond EDF ON) + backups n8n/lovelace + HANDOFF à jour
This commit is contained in:
52
AGENT.md
Normal file
52
AGENT.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
EVCS Workflow Analysis
|
||||||
|
|
||||||
|
## Workflow Mechanism Analysis
|
||||||
|
|
||||||
|
### Energy Context Monitoring
|
||||||
|
- Tracks battery SOC, PV power, house load, grid power, and EVCS current
|
||||||
|
- Monitors vehicle connection status
|
||||||
|
- Continuously evaluates energy balance
|
||||||
|
|
||||||
|
### Decision Logic
|
||||||
|
- Primary decision: "stop_not_connected" when vehicle is not connected
|
||||||
|
- Secondary decisions based on energy context (night_hc, day_hc)
|
||||||
|
- Source authorization: "Bloqué" (Blocked) when conditions aren't met
|
||||||
|
|
||||||
|
### Control Flow
|
||||||
|
- Surplus controller active but only manages surplus when vehicle is connected
|
||||||
|
- Grid power used when solar is unavailable and house needs must be met
|
||||||
|
- Manual mode allows override of automated decisions
|
||||||
|
|
||||||
|
### State Transitions
|
||||||
|
- Vehicle connection status triggers different control paths
|
||||||
|
- Energy context changes trigger different strategies
|
||||||
|
- User interventions (manual mode) can override automated decisions
|
||||||
|
|
||||||
|
## Situational Framework
|
||||||
|
|
||||||
|
| Situation | Vehicle Status | Solar Power | House Load | Grid Power | EVCS Current | Decision Logic |
|
||||||
|
Control Action |
|
||||||
|
|---------|----------------|------------|-----------|------------|--------------|----------------|------------
|
||||||
|
----|
|
||||||
|
| No Vehicle, No Solar | Disconnected | 0 W | 696 W | ON | 0 A | stop_not_connected | Grid powers house |
|
||||||
|
| No Vehicle, Solar | Disconnected | 683 W | 696 W | OFF | 0 A | stop_not_connected | Solar powers house |
|
||||||
|
| Vehicle Connected, No Solar | Connected | 0 W | 696 W | ON | 0 A | auto_solar_plus | Grid powers house,
|
||||||
|
EVCS idle |
|
||||||
|
| Vehicle Connected, Solar | Connected | 683 W | 696 W | OFF | 0 A | auto_solar_plus | Solar powers house,
|
||||||
|
EVCS idle |
|
||||||
|
| Vehicle Connected, High Demand | Connected | 0 W | 1000 W | ON | 7 A | auto_solar_plus | Grid powers house,
|
||||||
|
EVCS charges |
|
||||||
|
| Manual Override | Any | Any | Any | Any | Any | Stop | Manual control |
|
||||||
|
|
||||||
|
## Key Insights
|
||||||
|
1. The system prioritizes grid power for house needs when solar is unavailable
|
||||||
|
2. The "stop_not_connected" logic prevents EV charging but doesn't manage grid power
|
||||||
|
3. The surplus controller only activates when vehicle is connected and there's surplus energy
|
||||||
|
4. Manual mode allows complete override of automated decisions
|
||||||
|
|
||||||
|
## Recommendations
|
||||||
|
1. Create a rule to disable grid power when no vehicle is connected and solar is unavailable
|
||||||
|
2. Implement a "low energy" mode that prioritizes battery charging over grid power
|
||||||
|
3. Add a "maintenance" mode that allows manual control of all systems
|
||||||
|
4. Create a monitoring dashboard to track energy flows in real-time
|
||||||
|
|
||||||
347
HANDOFF.md
347
HANDOFF.md
@@ -1,207 +1,198 @@
|
|||||||
# HANDOFF.md — EVCS Outside-Window Solar Charging Block
|
# HANDOFF.md — EVCS / Grid Hysteresis — État au 09/07/2026
|
||||||
|
|
||||||
## 1. Contexte Projet
|
## 1. Contexte Projet
|
||||||
|
|
||||||
- **Installation** : Victron ESS sans injection réseau. Batterie 17,5 kWh.
|
- **Installation** : Victron ESS **sans injection réseau**. Batterie 17,5 kWh utile.
|
||||||
- **Workflow actif** : `HA Snapshot EVCS Surplus Controller V2.6` (n8n)
|
- **Workflows n8n actifs** :
|
||||||
- **Code source** : `/mnt/projects/EVCS/EVCS/decoupesurplus/` (architecture modulaire V2)
|
- `HA Snapshot EVCS Surplus Controller V2.6` (id `ATswvGfG4KJUls0K`) — pilote la borne EVCS (30 s)
|
||||||
- **Fichiers critiques** :
|
- `Victron - Battery / Grid Hysteresis Fix V1` (id `7iIlu7LLTW7TZA8o`) — pilote le switch EDF (1 min)
|
||||||
- `WINDOWS/WINDOW_SOURCEV2.js` — Détermine `profile` et `sourceMode`
|
- **Accès** :
|
||||||
- `BATTERY/BATTERY_CLOUD_LOCKS.js` — Calcule `cloudDebt`, `cloudToleranceOk`
|
- HA : `http://10.10.10.17:8123` — jeton dans `jeton_EVCS.txt` (⚠️ en clair, à révoquer si dépôt partagé)
|
||||||
- `snapshot.js` — Récupération des helpers HA
|
- n8n : `https://n8n.airtria.pro` — clé API dans `~/.config/opencode/opencode.json` (mcp.n8n-mcp)
|
||||||
- `modified/EVCS_V2.5_PATCHED.json` — Export n8n de référence (avant upgrade V2.6)
|
- **MCP opencode** (option 1 déployée) : 5 serveurs distants dans `~/.config/opencode/opencode.json`
|
||||||
|
(`ha-get-state`, `ha-set-helper`, `grid-set-state`, `victron-set-charge-limits`, `pv-get-forecast`)
|
||||||
|
→ endpoints SSE `https://n8n.airtria.pro/mcp/<path>/sse`.
|
||||||
|
Les 4 outils paramétrés utilisent `$fromAI(...)` (corrigé le 09/07).
|
||||||
|
⚠️ **Endpoints MCP n8n sans authentification** — à sécuriser (Bearer sur les nodes MCP Server Trigger).
|
||||||
|
- **Fichiers de référence locaux** :
|
||||||
|
- `WINDOWS/WINDOW_SOURCEV2.js`, `BATTERY/BATTERY_CLOUD_LOCKS.js`, `HYSTERESIS/COMPUTE.js` — copies de lecture (le code qui fait foi est dans n8n)
|
||||||
|
- `modified/GRID_HYSTERESIS_backup_20260709-*.json` — rollback avant P1
|
||||||
|
- `modified/EVCS_V2.6_backup_20260709-*.json` — rollbacks avant P2 puis P3 (2 fichiers)
|
||||||
|
|
||||||
## 2. Architecture Data-Flow
|
## 2. Architecture Data-Flow
|
||||||
|
|
||||||
```
|
```
|
||||||
Schedule Trigger (30s)
|
EVCS V2.6 (30s) :
|
||||||
→ HA Snapshot (template)
|
HA Snapshot (template) → INPUT_PARSE → WINDOWS_SOURCEV2
|
||||||
→ INPUT_PARSE
|
→ BATTERY_CLOUD_LOCKS → DECISION_ENGINEV2 → HA_SERVICE_CALLS_OUTPUT
|
||||||
→ WINDOWS_SOURCEV2 ← C'EST ICI QUE LE BLOCAGE SE PRODUIT
|
→ Build Actions → Execute HA Service
|
||||||
→ BATTERY_CLOUD_LOCKS
|
|
||||||
→ DECISION_ENGINEV2
|
Grid Hysteresis (1min) :
|
||||||
→ HA_SERVICE_CALLS_OUTPUT
|
HA Snapshot → Compute Grid Hysteresis → Build Actions → Execute HA Service
|
||||||
→ Execute HA Service
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. Problème Observé
|
Communication inter-workflows via helpers HA :
|
||||||
|
`input_text.victron_evcs_source_mode` (labels FR), `input_boolean.victron_evcs_night_grid_takeover_needed`,
|
||||||
|
`input_text.victron_evcs_surplus_state`, `input_select.victron_evcs_strategy`.
|
||||||
|
|
||||||
### Symptôme
|
## 3. Patchs déployés le 09/07/2026 (session opencode)
|
||||||
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
|
### P1 — Grid Hysteresis (déployé, vérifié)
|
||||||
```
|
1. **Entité fantôme corrigée** : le snapshot lisait `input_select.victron_evcs_user_strategy`
|
||||||
Stratégie : auto_solar_plus
|
(inexistante → toujours `unknown`). Corrigé en `input_select.victron_evcs_strategy`.
|
||||||
Profil : outside_window
|
Conséquence avant fix : les overrides `force_grid_now`/`force_charge_now` et la coupure
|
||||||
Source : Bloqué
|
« voiture pleine » ne fonctionnaient JAMAIS dans l'hystérésis.
|
||||||
SOC : 91 %
|
2. **Switch EDF `unavailable`** : nouvel état `switch_unavailable` = aucun ordre, aucun timestamp,
|
||||||
Cloud Debt: 1.66 kWh
|
réévaluation complète au retour du switch. Avant : spam `turn_on` chaque minute + rallumage
|
||||||
PV Power : ~800 W (aligné sur charge maison, pas d'injection)
|
aveugle à la reconnexion (incident du 08-09/07 : disjoncteur physique coupé par l'utilisateur,
|
||||||
Decision : stop_hard | battery_current_hard_stop
|
EDF rallumé à 00:41 au retour, batterie chargée sur réseau à SOC 48 %).
|
||||||
```
|
3. **`last_on_at`** : réécrit uniquement sur vraie transition (latch OFF→ON), plus à chaque retry.
|
||||||
|
Avant : `hold_on_min_runtime` pouvait durer éternellement.
|
||||||
|
4. **Bug latent corrigé** : le bloc `turn_off_force_grid_vehicle_full` (V2.5) était écrasé par la
|
||||||
|
chaîne principale (code mort). Flag `forcedCut` ajouté.
|
||||||
|
|
||||||
**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`.
|
### P2 — EVCS V2.6 : continuité takeover nuit / anti-créneaux (déployé, vérifié en réel)
|
||||||
|
- Le snapshot relit `night_takeover_prev` (= helper takeover du cycle précédent).
|
||||||
|
- `nightTakeoverLatched` dans `WINDOWS_SOURCEV2` **et** `BATTERY_CLOUD_LOCKS` :
|
||||||
|
une fois le réseau HC engagé en session nuit, on y reste jusqu'à fin de session
|
||||||
|
(fenêtre/débranchement) ou SOC ≥ 90 (`NIGHT_TAKEOVER_RELEASE_SOC_PCT`).
|
||||||
|
- Supprime le cycle « château fort » : batterie→jeep→seuil 20 %→EDF ON→30 %→EDF OFF→batterie...
|
||||||
|
- Vérifié en production dans la nuit du 09/07 : takeover engagé à SOC 35 %, EDF resté ON,
|
||||||
|
Jeep en charge continue (`hold_min_run`).
|
||||||
|
|
||||||
## 4. Root Cause Analysis
|
### P3 — EVCS V2.6 : provocation PV batteries pleines (déployé, dry-run complet)
|
||||||
|
- Problème (ancien sujet de ce HANDOFF) : sans injection, batteries pleines ⇒ MPPT bridé à la
|
||||||
|
conso maison ⇒ aucun seuil PV observable ; en plus `forecastBufferKwh` (10,5 kWh véhicule
|
||||||
|
soustraits) toujours ≤ 0 l'après-midi, et `cloudDebt` en deadlock (batterie pleine = courant
|
||||||
|
nul = dette jamais remboursée). Sonde afternoon inopérante (`probe_enabled = off` + seuil PV 1000 W).
|
||||||
|
- Fix : `pvProvocationEligible = SOC ≥ 90 && batterie non déchargée` → `solar_potential`
|
||||||
|
(intégré à `isHighBatteryForPotential`, donc actif sur les 4 profils jour). Gardes aval intactes.
|
||||||
|
- **Attention réglage** : `soc_start_min` (HA) = 94 ⇒ plancher de démarrage hors fenêtre.
|
||||||
|
Le déclenchement pratique est donc SOC ≥ 94 %. Baisser ce helper à 90 pour aligner.
|
||||||
|
|
||||||
### 4.1. Définition de outside_window
|
### P4 — Maintien SOC adapté au forecast pendant le takeover nuit (déployé 09/07 après-midi)
|
||||||
`outside_window` = tout horaire **hors** des 4 fenêtres configurées :
|
- **Découverte clé** : `Victron - Auto Charge Manager V1.2` (id `cTeeHy4ePiVeELLh`) est le
|
||||||
- `night_hc` : 23:00 → 06:00
|
propriétaire des limites DVCC (`MaxChargeCurrent`/`MaxChargeVoltage` via MQTT,
|
||||||
- `morning_solar` : 07:30 → 11:00
|
feedback : `sensor.victron_max_charge_current_setting`). Son mode « nuit idle » laissait
|
||||||
- `midday_hc_or_solar` : 12:24 → 14:24
|
30 A de charge batterie dès que EDF était ON → batterie rechargée à fond pendant un takeover.
|
||||||
- `evening_high_soc` : 17:00 → 20:30
|
- **ACM patché** : nouvelle branche prioritaire `evcs_takeover_hold` / `evcs_takeover_recover` :
|
||||||
|
si `night_grid_takeover_needed` ON + EDF ON → SOC < cible-1 : recharge 30 A ; sinon **maintien
|
||||||
|
2 A / 50.1 V** (maison + VE sur HC, batterie en pause). Cible lue depuis
|
||||||
|
`input_number.victron_evcs_night_target_soc` (écrite par le workflow EVCS : forecast fort→35 %,
|
||||||
|
moyen→55 %, faible→85 % — donc été ~35, hiver ~85 comme demandé).
|
||||||
|
- **EVCS patché** : avant minuit (20h→8h), la cible matin utilise
|
||||||
|
`max(today_remaining, tomorrow_kwh)` (sinon today_remaining≈0 à 23h → cible 85 % à tort en été).
|
||||||
|
Ajout `tomorrow_kwh` au snapshot + `parsed.tomorrowKwh`.
|
||||||
|
- Dry-runs : 8 scénarios ACM + 2 scénarios cible EVCS validés (voir session 09/07).
|
||||||
|
|
||||||
Donc `outside_window` couvre : **11:00→12:24, 14:24→17:00, 20:30→23:00**.
|
### Autres réalisations du 09/07 (après-midi)
|
||||||
|
- **Borne fantôme résolue** : firmware EVCS 2.05 → **2.08** (session repartie de zéro,
|
||||||
|
détection véhicule correcte). Les 19 kWh affichés étaient un cumul de session non réinitialisé.
|
||||||
|
- **Dashboard « EDF Urgence »** créé via API HA (sidebar) : scripts `script.edf_urgence_off`
|
||||||
|
(hystérésis OFF + latch OFF + stratégie stop + switch OFF — rien ne rallume),
|
||||||
|
`script.edf_force_on`, `script.edf_rendre_la_main` + cartes d'état et « pourquoi ».
|
||||||
|
- **Incident Synology** : NAS éteint dans la nuit (cause à chercher dans les logs DSM) →
|
||||||
|
n8n + HA morts → EDF resté ON toute la nuit, batterie chargée à 96 % sur réseau.
|
||||||
|
⚠️ SPOF structurel : tout le contrôle vit sur le Synology.
|
||||||
|
|
||||||
### 4.2. Logique du sourceMode en outside_window (WINDOW_SOURCEV2.js, L454-468)
|
### P5 — Plafond courant EVCS configurable quand EDF est ON (déployé 09/07 soir)
|
||||||
|
- Le plafond 20 A venait de `cfg.evcsDedicatedMaxW` (4900−300 W / 230 V) codé en dur dans INPUT_PARSE.
|
||||||
|
- Nouveau helper **`input_number.evcs_plafond_courant_edf_on`** (6–32 A, défaut 20) : quand
|
||||||
|
**AC-IN est physiquement présent** (`acin1_available`, pas juste le switch), le plafond = helper ;
|
||||||
|
hors réseau, retour au plafond câblé ~20 A. Dry-run 5 scénarios OK (dont disjoncteur coupé).
|
||||||
|
- Subtilité : `victron_evcs_current_max_auto_a` (22) plafonne EN PLUS les modes auto ;
|
||||||
|
en force_grid/force_charge seul le nouveau helper compte.
|
||||||
|
- **Boutons dashboards** (EVCS Master = fichier YAML `/mnt/ARCH3/docker/HA/dashboards/evcs_master.yaml`
|
||||||
|
édité via NFS ; EDF Urgence = API) : carte « Plafonds courant EVCS » + boutons
|
||||||
|
**⚡ BOOST EDF 28A** (`script.evcs_boost_edf` : plafonds 28/28 + force_grid_now + consigne 28)
|
||||||
|
et **Retour normal** (`script.evcs_boost_off` : 20/22 + auto_solar_plus).
|
||||||
|
- Sémantique clarifiée : « Courant demandé » = « Consigne envoyée » = `number.victron_evcs_set_current_command`
|
||||||
|
(réécrit toutes les 30 s par le workflow) ; « Consigne lue » = readback borne. En force_charge_now,
|
||||||
|
PV ≥ 700 W ⇒ source « Solaire » ⇒ gardes nuages/batterie freinent : pour une grosse charge, force_grid_now.
|
||||||
|
|
||||||
```javascript
|
### Maintenance du 09/07 soir (analyse des messages d'erreurs)
|
||||||
else if (profile === 'outside_window') {
|
- **W-105 borne** (surcharge) : survenu en charge 20 A sur onduleur seul (disjoncteur EDF coupé).
|
||||||
if (strongSolarSignal) {
|
Déjà couvert : gardes vebus_overload + P5 (plafond retombe à 20 A si AC-IN absent).
|
||||||
sourceMode = 'solar_only';
|
- **`saveDataErrorExecution: all`** activé sur les 8 workflows critiques (diagnostic des
|
||||||
} else if (isHighBatteryForPotential && potentialAllowed) {
|
prochaines erreurs avec données des nodes ; Water Heater V2.3 avait erré 4× le 09/07 20:20-20:35,
|
||||||
sourceMode = 'solar_potential';
|
cause inconnue faute de données, rétabli seul).
|
||||||
} else {
|
- **Garage Thermal** : la prise `switch.clim_hygro_socket_1` est débranchée volontairement par
|
||||||
sourceMode = 'blocked'; // ← TOMBE ICI
|
moments → l'appel au switch est maintenant conditionné à sa disponibilité (`execute: switchAvailable`).
|
||||||
}
|
Plus de warnings « missing entity » toutes les 10 min. Backup `modified/GARAGE_backup_*`.
|
||||||
}
|
- **Templates MQTT durcis** (33 occurrences, `configuration.yaml` + `packages/victron_vebus_mqtt.yaml`) :
|
||||||
```
|
garde `value_json is defined` → plus d'erreurs `value_json is undefined` aux reconnexions MQTT.
|
||||||
|
Backups `SAVE_CONFIG/*.bak.20260709-234800`, `check_config` valid, `mqtt.reload` fait.
|
||||||
|
⚠️ Après un `mqtt.reload`, les sensors restent `unknown` jusqu'à republication Venus :
|
||||||
|
publier `R/c0619ab34ac5/keepalive` (payload vide) force la republication complète.
|
||||||
|
|
||||||
Pour sortir de `blocked`, il faut **obligatoirement** l'un des deux :
|
## 4. Root Cause de l'incident « EDF ON à 48 % sans charge Jeep » (nuit 08→09/07)
|
||||||
|
|
||||||
#### A. strongSolarSignal (L343-352)
|
Chaîne complète reconstituée via l'historique HA :
|
||||||
```javascript
|
1. Borne fantôme au matin du 08/07 (« véhicule en charge » sans véhicule) + `force_grid_now`
|
||||||
const strongSolarSignal =
|
de la veille ⇒ EDF maintenu ON (la coupure voiture-pleine était du code mort, cf. P1.1/P1.4).
|
||||||
(parsed.pvPowerW > 0 && parsed.pvPowerW >= effectivePvStartMinW) ||
|
2. L'utilisateur coupe le **disjoncteur physique** ⇒ switch `unavailable` pendant ~5 h.
|
||||||
parsed.pvPowerAvg10mW >= params.pvHoldMinW ||
|
3. Le workflow reste coincé en `hold_on_min_runtime` (P1.3) en spammant `turn_on` (P1.2).
|
||||||
(departurePriorityActive && parsed.pvPowerAvg10mW >= params.pvHoldMinW);
|
4. 00:40:54 : le switch revient ⇒ 00:41:03 EDF ON sans cause actuelle ⇒ Multiplus charge la
|
||||||
```
|
batterie sur réseau (2980 W) ⇒ coupé à 01:06 (min_on 25 min, SOC ≥ 30).
|
||||||
- `pvStartMinW` défaut = **1800 W**
|
Tous les maillons sont corrigés par P1.
|
||||||
- `pvHoldMinW` défaut = **1200 W**
|
|
||||||
|
|
||||||
**Pourquoi c'est faux chez l'utilisateur** :
|
## 5. Sémantique utile (pour ne pas re-chercher)
|
||||||
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)
|
- **Latch** (`input_boolean.victron_grid_hysteresis_latch`) : « c'est l'automate qui a allumé EDF
|
||||||
```javascript
|
et il défend cet état ». Reprise en main manuelle : stratégie `stop` + hystérésis OFF + latch OFF.
|
||||||
const isHighBatteryForPotential =
|
- **Fenêtres EVCS (helpers HA, corrigées/vérifiées le 09/07)** : `night_hc` **01:24→07:24** (HC réelles),
|
||||||
parsed.soc >= 85 &&
|
`morning_solar` 07:30→11:00, `midday_hc_or_solar` **12:24→14:24** (HC réelles),
|
||||||
forecastBufferKwh > 0 &&
|
`evening_high_soc` 17:00→20:30, sinon `outside_window`.
|
||||||
cloudDebtOkForPotential && // ← BLOQUÉ ICI
|
L'Auto Charge Manager utilisait des fenêtres codées en dur légèrement fausses
|
||||||
batteryOkForPotential;
|
(01:30-07:15 / 12:25-14:25) — alignées sur 01:24-07:24 / 12:24-14:24 le 09/07.
|
||||||
```
|
- **Seuils hystérésis réseau (HA, valeurs réelles)** : ON ≤ 20 %, OFF ≥ 30 %, min_on 25 min.
|
||||||
|
- **Cibles nuit** : hard floor 22 % ; cible matin selon forecast : ≥18 kWh→35 %, ≥10→55 %, sinon 85 %.
|
||||||
|
`nightSessionActive = fenêtre nuit && véhicule branché` (⚠️ pas besoin de charge active).
|
||||||
|
- **Statut borne 6** = branchée en attente de démarrage (« Inconnu (6) » sur le dashboard).
|
||||||
|
- **Labels FR** dans `source_mode` : `Réseau forcé`, `Réseau HC autorisé`, `Assistance batterie nuit`,
|
||||||
|
`Bloqué`, `Solaire`, `Potentiel solaire` — l'hystérésis matche ces labels.
|
||||||
|
|
||||||
**Pourquoi c'est faux chez l'utilisateur** :
|
## 6. Méthode de travail validée (à réutiliser)
|
||||||
```javascript
|
|
||||||
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 %.
|
1. Backup : `GET /api/v1/workflows/<id>` → `modified/*_backup_<stamp>.json`.
|
||||||
|
2. Patch des `jsCode` par remplacement exact (script node), `node --check` sur chaque node.
|
||||||
|
3. **Dry-run local de la chaîne complète** : snapshot réel via `POST /api/template` HA,
|
||||||
|
exécution séquentielle des 5 nodes avec shim `$input`, horloge simulable en surchargeant
|
||||||
|
`global.Date` (voir session du 09/07).
|
||||||
|
4. `PUT /api/v1/workflows/<id>` (⚠️ filtrer `settings` : seuls
|
||||||
|
`executionOrder/timezone/save*/executionTimeout/errorWorkflow` sont acceptés).
|
||||||
|
5. Vérification live : helpers HA 40-70 s après.
|
||||||
|
|
||||||
### 4.3. Pourquoi le cloud debt est à 1.66 kWh
|
## 7. Backlog / Point du 10/07 au réveil
|
||||||
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.
|
1. **Vérifier la nuit de test P2+P4** (fenêtre HC 01:24→07:24, forecast fort → cible 35 %) :
|
||||||
|
- takeover engagé quand SOC ≤ 35 → EDF ON **continu** (pas de créneaux) ;
|
||||||
|
- `input_text.victron_charge_mode` = `evcs_takeover_recover` puis **`evcs_takeover_hold`** ;
|
||||||
|
- `sensor.victron_max_charge_current_setting` = **2** pendant le hold (batterie tenue ~35 %) ;
|
||||||
|
- 07:24 : fin de fenêtre → EDF coupé (`turn_off_recovered`), ACM repasse en profil jour.
|
||||||
|
Historique utile : `switch.edf_general_ok_switch`, `sensor.victron_battery_soc`,
|
||||||
|
`input_text.victron_charge_mode` entre 01:00 et 08:00.
|
||||||
|
2. **Cause de l'extinction du Synology** (DSM → Centre des journaux) + réflexion SPOF :
|
||||||
|
le fail-safe physique actuel est « EDF ON + charge batterie » quand le NAS meurt.
|
||||||
|
3. Baisser `input_number.victron_evcs_soc_start_min` 94 → 90 (aligner avec P3) si souhaité.
|
||||||
|
4. **Sécuriser** : auth Bearer sur les 5 MCP Server Triggers n8n + révoquer/déplacer le jeton HA.
|
||||||
|
5. **À investiguer** : « conditions de démarrage nuit batterie non réunies » quand la batterie
|
||||||
|
suffit pour la nuit (conditions de départ `battery_assist_night`).
|
||||||
|
6. Optionnel : brancher un keepalive/republish Venus automatique après `mqtt.reload`
|
||||||
|
(cf. note maintenance §3).
|
||||||
|
|
||||||
### 4.4. Absence de probe en outside_window
|
## 8. Historique des sessions
|
||||||
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
|
- **12/06/2026** : analyse blocage outside_window, déploiement afternoon_probe (V2.6),
|
||||||
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.
|
fix clignotement EDF (`edf_general_ok_on` conditionné au sourceMode).
|
||||||
|
- **09/07/2026 (nuit)** : incident EDF nocturne analysé (root cause complète), MCP option 1 en place,
|
||||||
### 4.6. Priorité départ
|
P1 (hystérésis robuste + entité stratégie), P2 (anti-créneaux nuit), P3 (provocation PV).
|
||||||
`departurePriorityActive` s'active seulement si :
|
- **09/07/2026 (journée/soir)** : incident Synology (NAS éteint → EDF ON toute la nuit, batterie 96 %),
|
||||||
- `departurePriorityEnabled = ON`
|
firmware borne 2.08 (fantôme résolu), dashboard EDF Urgence + boost 28 A, P4 (maintien SOC
|
||||||
- `minutesUntilDeparture <= 240 min`
|
au forecast pendant takeover, via Auto Charge Manager), P5 (plafond EDF ON configurable),
|
||||||
- Véhicule branché
|
fenêtres HC corrigées (01:24-07:24 / 12:24-14:24), maintenance erreurs (save error executions,
|
||||||
|
prise garage conditionnelle, 33 templates MQTT durcis).
|
||||||
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*
|
*Document mis à jour le : 09/07/2026 (~23:55) — session opencode avec accès HA (REST+WS+NFS) + n8n (API+MCP)*
|
||||||
*Session terminée : afternoon_probe déployé + bug EDF corrigé + stabilité confirmée*
|
*État live à la clôture : SOC 65 % ↘, Jeep branchée, fenêtre HC à 01:24, nuit de validation P2+P4 en cours*
|
||||||
*Prochaine action : Observer le comportement en afternoon et ajuster les seuils des helpers si nécessaire*
|
|
||||||
|
|||||||
1
modified/AUTO_CHARGE_backup_20260709-150754.json
Normal file
1
modified/AUTO_CHARGE_backup_20260709-150754.json
Normal file
File diff suppressed because one or more lines are too long
1
modified/AUTO_CHARGE_backup_20260709-181838.json
Normal file
1
modified/AUTO_CHARGE_backup_20260709-181838.json
Normal file
File diff suppressed because one or more lines are too long
1
modified/EVCS_V2.6_backup_20260709-030818.json
Normal file
1
modified/EVCS_V2.6_backup_20260709-030818.json
Normal file
File diff suppressed because one or more lines are too long
1
modified/EVCS_V2.6_backup_20260709-031751.json
Normal file
1
modified/EVCS_V2.6_backup_20260709-031751.json
Normal file
File diff suppressed because one or more lines are too long
1
modified/EVCS_V2.6_backup_20260709-151000.json
Normal file
1
modified/EVCS_V2.6_backup_20260709-151000.json
Normal file
File diff suppressed because one or more lines are too long
1
modified/EVCS_V2.6_backup_20260709-200557.json
Normal file
1
modified/EVCS_V2.6_backup_20260709-200557.json
Normal file
File diff suppressed because one or more lines are too long
1
modified/GARAGE_backup_20260709-234608.json
Normal file
1
modified/GARAGE_backup_20260709-234608.json
Normal file
File diff suppressed because one or more lines are too long
1
modified/GRID_HYSTERESIS_backup_20260709-025916.json
Normal file
1
modified/GRID_HYSTERESIS_backup_20260709-025916.json
Normal file
File diff suppressed because one or more lines are too long
696
modified/lovelace_evcs-master_backup_2026-07-09T18-17-33.json
Normal file
696
modified/lovelace_evcs-master_backup_2026-07-09T18-17-33.json
Normal file
@@ -0,0 +1,696 @@
|
|||||||
|
{
|
||||||
|
"views": [
|
||||||
|
{
|
||||||
|
"title": "EVCS Master",
|
||||||
|
"path": "default_view",
|
||||||
|
"icon": "mdi:car-electric",
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "vertical-stack",
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-title-card",
|
||||||
|
"title": "EVCS Master",
|
||||||
|
"subtitle": "Vue borne / session / stratégie / énergie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "conditional",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"entity": "binary_sensor.victron_evcs_vehicle_connected",
|
||||||
|
"state": "off"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"card": {
|
||||||
|
"type": "markdown",
|
||||||
|
"content": "## ℹ️ Véhicule non détecté\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "conditional",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"entity": "binary_sensor.victron_evcs_vehicle_connected",
|
||||||
|
"state": "on"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "switch.victron_evcs_charging",
|
||||||
|
"state": "off"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"card": {
|
||||||
|
"type": "markdown",
|
||||||
|
"content": "## ⚠️ Véhicule connecté mais charge inactive\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "conditional",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"entity": "switch.victron_evcs_charging",
|
||||||
|
"state": "on"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"card": {
|
||||||
|
"type": "markdown",
|
||||||
|
"content": "## ✅ Charge EVCS active\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:layout-card",
|
||||||
|
"layout_type": "grid",
|
||||||
|
"layout": {
|
||||||
|
"grid-template-columns": "repeat(auto-fit, minmax(380px, 1fr))",
|
||||||
|
"grid-gap": "16px",
|
||||||
|
"margin": 0
|
||||||
|
},
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "custom:vertical-stack-in-card",
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-title-card",
|
||||||
|
"title": "État borne",
|
||||||
|
"subtitle": "Statut global"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-template-card",
|
||||||
|
"entity": "sensor.victron_evcs_statut_fr",
|
||||||
|
"primary": "EVCS",
|
||||||
|
"secondary": "{{ states('sensor.victron_evcs_statut_fr') }} • Mode {{ states('sensor.victron_evcs_mode_fr') }} • {{ states('sensor.victron_evcs_current') | float(0) | round(1) }} A\n",
|
||||||
|
"multiline_secondary": true,
|
||||||
|
"icon": "mdi:ev-station",
|
||||||
|
"icon_color": "{% if is_state('switch.victron_evcs_charging', 'on') %}\n green\n{% elif is_state('binary_sensor.victron_evcs_vehicle_connected', 'on') %}\n blue\n{% else %}\n grey\n{% endif %}\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "entities",
|
||||||
|
"show_header_toggle": false,
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_statut_fr",
|
||||||
|
"name": "Statut FR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_mode_fr",
|
||||||
|
"name": "Mode FR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_status_raw",
|
||||||
|
"name": "Statut brut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_mode_raw",
|
||||||
|
"name": "Mode brut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "binary_sensor.victron_evcs_device_connected",
|
||||||
|
"name": "EVCS détecté"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "binary_sensor.victron_evcs_vehicle_connected",
|
||||||
|
"name": "Véhicule connecté"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_charging_time",
|
||||||
|
"name": "Durée charge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_boolean.victron_evcs_surplus_auto_enabled",
|
||||||
|
"name": "Contrôleur surplus actif"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:vertical-stack-in-card",
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-title-card",
|
||||||
|
"title": "Session",
|
||||||
|
"subtitle": "Courant / puissance / énergie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:gauge-card-pro",
|
||||||
|
"entity": "sensor.victron_evcs_current",
|
||||||
|
"header": "Courant EVCS",
|
||||||
|
"min": 0,
|
||||||
|
"max": 32,
|
||||||
|
"needle": true,
|
||||||
|
"segments": [
|
||||||
|
{
|
||||||
|
"from": 0,
|
||||||
|
"color": "#43a047"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": 6,
|
||||||
|
"color": "#fdd835"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": 16,
|
||||||
|
"color": "#fb8c00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": 24,
|
||||||
|
"color": "#e53935"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-template-card",
|
||||||
|
"primary": "Session en cours",
|
||||||
|
"secondary": "{{ states('sensor.victron_evcs_ac_power') | float(0) | round(0) }} W • {{ states('sensor.victron_evcs_current') | float(0) | round(1) }} A • Consigne {{ states('sensor.victron_evcs_set_current') | float(0) | round(1) }} A • {{ states('sensor.victron_evcs_charging_time') }}\n",
|
||||||
|
"multiline_secondary": true,
|
||||||
|
"icon": "mdi:flash",
|
||||||
|
"icon_color": "amber"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "entities",
|
||||||
|
"show_header_toggle": false,
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_ac_power",
|
||||||
|
"name": "Puissance EVCS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_l1_power",
|
||||||
|
"name": "Puissance L1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_current",
|
||||||
|
"name": "Courant réel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_set_current",
|
||||||
|
"name": "Consigne lue"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "number.victron_evcs_set_current_command",
|
||||||
|
"name": "Consigne envoyée"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_charging_time",
|
||||||
|
"name": "Durée charge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_l1_energy_forward",
|
||||||
|
"name": "Énergie session"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:vertical-stack-in-card",
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-title-card",
|
||||||
|
"title": "Stratégie & décision",
|
||||||
|
"subtitle": "Mode utilisateur / logique n8n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-template-card",
|
||||||
|
"primary": "Mode utilisateur",
|
||||||
|
"secondary": "Stratégie : {{ states('input_select.victron_evcs_strategy') }} • Profil : {{ states('input_text.victron_evcs_operating_mode') }} • Décision : {{ states('input_text.victron_evcs_surplus_current_decision') }} • Source : {{ states('input_text.victron_evcs_source_mode') }}\n",
|
||||||
|
"multiline_secondary": true,
|
||||||
|
"icon": "mdi:strategy",
|
||||||
|
"icon_color": "{% if is_state('input_select.victron_evcs_strategy', 'force_grid_now') %}\n red\n{% elif is_state('input_select.victron_evcs_strategy', 'force_charge_now') %}\n orange\n{% elif is_state('input_select.victron_evcs_strategy', 'auto_solar_plus') %}\n green\n{% elif is_state('input_select.victron_evcs_strategy', 'auto_solar') %}\n teal\n{% else %}\n grey\n{% endif %}\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-template-card",
|
||||||
|
"primary": "Besoin véhicule",
|
||||||
|
"secondary": "Véhicule : {{ states('input_select.victron_evcs_target_vehicle') }} • {{ states('input_number.victron_evcs_required_energy_kwh') | float(0) | round(1) }} kWh • Départ : {{ states('input_datetime.victron_evcs_departure_time') }}\n",
|
||||||
|
"multiline_secondary": true,
|
||||||
|
"icon": "mdi:calendar-clock",
|
||||||
|
"icon_color": "cyan"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "entities",
|
||||||
|
"title": "Paramètres utilisateur",
|
||||||
|
"show_header_toggle": false,
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity": "input_select.victron_evcs_target_vehicle",
|
||||||
|
"name": "Véhicule cible"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_number.victron_evcs_required_energy_kwh",
|
||||||
|
"name": "Énergie demandée"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_boolean.victron_evcs_departure_priority_enabled",
|
||||||
|
"name": "Priorité départ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_datetime.victron_evcs_departure_time",
|
||||||
|
"name": "Heure départ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_select.victron_evcs_strategy",
|
||||||
|
"name": "Stratégie EVCS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_boolean.victron_evcs_allow_grid_hc_night",
|
||||||
|
"name": "Réseau HC nuit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_boolean.victron_evcs_allow_grid_hc_midday",
|
||||||
|
"name": "Réseau HC midi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_boolean.victron_evcs_surplus_auto_enabled",
|
||||||
|
"name": "Contrôleur surplus actif"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "entities",
|
||||||
|
"title": "Décision contrôleur",
|
||||||
|
"show_header_toggle": false,
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity": "input_text.victron_evcs_operating_mode",
|
||||||
|
"name": "Profil actif"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_text.victron_evcs_surplus_state",
|
||||||
|
"name": "État interne"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_text.victron_evcs_surplus_current_decision",
|
||||||
|
"name": "Décision logique"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_text.victron_evcs_source_mode",
|
||||||
|
"name": "Source autorisée"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_text.victron_evcs_surplus_reason",
|
||||||
|
"name": "Raison courte"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_text.victron_evcs_last_block_reason",
|
||||||
|
"name": "Dernier blocage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_datetime.victron_evcs_blocked_until",
|
||||||
|
"name": "Bloqué jusqu'à"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:vertical-stack-in-card",
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-title-card",
|
||||||
|
"title": "Contexte énergie",
|
||||||
|
"subtitle": "Batterie / PV / maison / réseau"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-template-card",
|
||||||
|
"primary": "Contexte instantané",
|
||||||
|
"secondary": "SOC {{ states('sensor.victron_battery_soc') | float(0) | round(1) }} % • PV {{ states('sensor.victron_pv_power_system') | float(0) | round(0) }} W • Maison {{ states('sensor.victron_consumption_power_l1') | float(0) | round(0) }} W • Grid {{ states('sensor.victron_grid_power_l1') | float(0) | round(0) }} W\n",
|
||||||
|
"multiline_secondary": true,
|
||||||
|
"icon": "mdi:home-lightning-bolt",
|
||||||
|
"icon_color": "{% set pv = states('sensor.victron_pv_power_system') | float(0) %} {% if pv < 300 %} grey {% elif pv < 1500 %} yellow {% else %} green {% endif %}\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "entities",
|
||||||
|
"show_header_toggle": false,
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_battery_soc",
|
||||||
|
"name": "SOC batterie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_battery_current",
|
||||||
|
"name": "Courant batterie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_pv_power_system",
|
||||||
|
"name": "Puissance PV"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_consumption_power_l1",
|
||||||
|
"name": "Charges maison"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_grid_power_l1",
|
||||||
|
"name": "Puissance réseau"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "switch.edf_general_ok_switch",
|
||||||
|
"name": "Réseau EDF"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:vertical-stack-in-card",
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-title-card",
|
||||||
|
"title": "Actions rapides",
|
||||||
|
"subtitle": "Contrôle direct EVCS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "grid",
|
||||||
|
"columns": 2,
|
||||||
|
"square": false,
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "custom:button-card",
|
||||||
|
"entity": "switch.victron_evcs_charging",
|
||||||
|
"name": "Charge",
|
||||||
|
"icon": "mdi:ev-station",
|
||||||
|
"show_state": true,
|
||||||
|
"state_display": "[[[\n if (!entity) return 'Inconnu';\n if (entity.state === 'on') return 'ON';\n if (entity.state === 'off') return 'OFF';\n return entity.state;\n]]]\n",
|
||||||
|
"tap_action": {
|
||||||
|
"action": "toggle"
|
||||||
|
},
|
||||||
|
"hold_action": {
|
||||||
|
"action": "more-info"
|
||||||
|
},
|
||||||
|
"styles": {
|
||||||
|
"card": [
|
||||||
|
{
|
||||||
|
"border-radius": "18px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"padding": "12px"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"font-size": "15px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font-weight": 600
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
{
|
||||||
|
"font-size": "12px"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
{
|
||||||
|
"value": "on",
|
||||||
|
"color": "#43a047"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "off",
|
||||||
|
"color": "#757575"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:button-card",
|
||||||
|
"entity": "input_boolean.victron_evcs_surplus_auto_enabled",
|
||||||
|
"name": "Contrôleur surplus",
|
||||||
|
"icon": "mdi:robot",
|
||||||
|
"show_state": true,
|
||||||
|
"tap_action": {
|
||||||
|
"action": "toggle"
|
||||||
|
},
|
||||||
|
"hold_action": {
|
||||||
|
"action": "more-info"
|
||||||
|
},
|
||||||
|
"styles": {
|
||||||
|
"card": [
|
||||||
|
{
|
||||||
|
"border-radius": "18px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"padding": "12px"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"font-size": "15px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font-weight": 600
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
{
|
||||||
|
"font-size": "12px"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
{
|
||||||
|
"value": "on",
|
||||||
|
"color": "#26a69a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "off",
|
||||||
|
"color": "#757575"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:button-card",
|
||||||
|
"entity": "binary_sensor.victron_evcs_vehicle_connected",
|
||||||
|
"name": "Véhicule",
|
||||||
|
"icon": "mdi:car-electric",
|
||||||
|
"show_state": true,
|
||||||
|
"tap_action": {
|
||||||
|
"action": "more-info"
|
||||||
|
},
|
||||||
|
"styles": {
|
||||||
|
"card": [
|
||||||
|
{
|
||||||
|
"border-radius": "18px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"padding": "12px"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"font-size": "15px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font-weight": 600
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
{
|
||||||
|
"font-size": "12px"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
{
|
||||||
|
"value": "on",
|
||||||
|
"color": "#1e88e5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "off",
|
||||||
|
"color": "#757575"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:button-card",
|
||||||
|
"entity": "number.victron_evcs_set_current_command",
|
||||||
|
"name": "Courant demandé",
|
||||||
|
"icon": "mdi:current-ac",
|
||||||
|
"show_state": true,
|
||||||
|
"tap_action": {
|
||||||
|
"action": "more-info"
|
||||||
|
},
|
||||||
|
"hold_action": {
|
||||||
|
"action": "more-info"
|
||||||
|
},
|
||||||
|
"styles": {
|
||||||
|
"card": [
|
||||||
|
{
|
||||||
|
"border-radius": "18px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"padding": "12px"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"font-size": "15px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font-weight": 600
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
{
|
||||||
|
"font-size": "12px"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "entities",
|
||||||
|
"title": "Commandes manuelles",
|
||||||
|
"show_header_toggle": false,
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity": "switch.victron_evcs_charging",
|
||||||
|
"name": "Start / Stop charge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "number.victron_evcs_set_current_command",
|
||||||
|
"name": "Courant demandé"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_boolean.victron_evcs_charge_permission_now",
|
||||||
|
"name": "Permission charge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_boolean.victron_evcs_control_latch",
|
||||||
|
"name": "Latch contrôle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "switch.victron_evcs_auto_start",
|
||||||
|
"name": "Auto Start borne (diagnostic)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:vertical-stack-in-card",
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-title-card",
|
||||||
|
"title": "Diagnostic",
|
||||||
|
"subtitle": "Identité / version / brut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "entities",
|
||||||
|
"show_header_toggle": false,
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_product_name",
|
||||||
|
"name": "Produit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_custom_name",
|
||||||
|
"name": "Nom borne"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_serial",
|
||||||
|
"name": "Numéro de série"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_firmware_version",
|
||||||
|
"name": "Firmware"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_connected_raw",
|
||||||
|
"name": "Connected brut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_status_raw",
|
||||||
|
"name": "Statut brut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_mode_raw",
|
||||||
|
"name": "Mode brut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "switch.victron_evcs_auto_start",
|
||||||
|
"name": "Auto Start borne"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_datetime.victron_evcs_last_start_at",
|
||||||
|
"name": "Dernier start"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_datetime.victron_evcs_last_stop_at",
|
||||||
|
"name": "Dernier stop"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_datetime.victron_evcs_last_current_change_at",
|
||||||
|
"name": "Dernier changement courant"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_datetime.victron_evcs_probe_started_at",
|
||||||
|
"name": "Début probe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_datetime.victron_evcs_cloud_debt_started_at",
|
||||||
|
"name": "Début cloud debt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_number.victron_evcs_cloud_debt_kwh",
|
||||||
|
"name": "Cloud debt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "input_text.victron_evcs_control_last_signature",
|
||||||
|
"name": "Signature"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:vertical-stack-in-card",
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"type": "custom:mushroom-title-card",
|
||||||
|
"title": "Historique EVCS",
|
||||||
|
"subtitle": "12 dernières heures"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom:apexcharts-card",
|
||||||
|
"graph_span": "12h",
|
||||||
|
"header": {
|
||||||
|
"show": true,
|
||||||
|
"title": "Session EVCS",
|
||||||
|
"show_states": false
|
||||||
|
},
|
||||||
|
"series": [
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_current",
|
||||||
|
"name": "Courant EVCS",
|
||||||
|
"color": "#42a5f5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_set_current",
|
||||||
|
"name": "Consigne lue",
|
||||||
|
"color": "#ffca28"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_evcs_ac_power",
|
||||||
|
"name": "Puissance EVCS",
|
||||||
|
"color": "#66bb6a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_pv_power_system",
|
||||||
|
"name": "PV",
|
||||||
|
"color": "#fdd835"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entity": "sensor.victron_grid_power_l1",
|
||||||
|
"name": "Réseau",
|
||||||
|
"color": "#ef5350"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user