diff --git a/CLAUDE.md b/CLAUDE.md index 7078cfa..aa9f30b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -87,11 +87,34 @@ PV + échéance → ChargingModeEcoWithTargetTime + targetPercentage + Min+PV + échéance → ChargingModeEcoMinWithTargetTime + targetPercentage + endDateTime ``` -> ⚠️ **`minCurrent` n'existe nulle part.** Le mode `ChargingModeEcoWithMinCurrent` est bien -> dans l'énumération, mais `ChargingInfo` ne porte **aucun champ** de courant minimum. Soit -> il est fixé ailleurs (paramètre du Thing borne), soit il manque côté plugin. **Ne pas -> proposer de réglage de courant minimum tant que ce n'est pas tranché** — un champ qui ne -> part nulle part est pire que pas de champ. +> ⚠️ **`minCurrent` n'existe nulle part dans `ChargingInfo`** — et c'est normal : ce n'est +> pas un réglage. **Tranché le 2026-09-07.** Le plancher est une limite MATÉRIELLE, et elle +> est déjà sur la box, dans la classe du Thing borne : +> +> ```jsonc +> // Integrations.GetThingClasses, classe "trydan" +> { "name": "maxChargingCurrent", "minValue": 6, "maxValue": 32, "unit": "UnitAmpere" } +> { "name": "phaseCount", "minValue": 1, "maxValue": 3 } // état courant sur .75 : 3 +> ``` +> +> `6 A × 3 phases × 230 V = 4 140 W`. Donc **ne jamais proposer de saisir un courant +> minimum** — la règle tient, mais pour une meilleure raison qu'avant : une limite matérielle +> se lit sur le matériel, elle ne se demande pas à l'utilisateur. +> +> 🔴 **Et le mode ne fait rien pour l'instant.** Sémantique voulue (Patrick, 2026-09-07) : +> Min+PV charge **toujours** au minimum de la borne, acheté au réseau s'il le faut, **et +> ajoute le surplus par-dessus** — 400 W d'injection sur un plancher de 4 140 W donnent +> 4 540 W. Mesuré sur `.75` : la borne ne reçoit **qu'un niveau `comfort`**, aucun niveau +> `eco`, et la décision est `SURPLUS_INSUFFICIENT`. `ChargingModeEcoWithMinCurrent` se +> comporte donc **exactement** comme `ChargingModeEco`. +> +> Le mécanisme existe pourtant déjà : c'est `ECO_FLOOR_GRID`, ce que le chauffe-eau fait dans +> la même trame. Demande portée au moteur (`BRIEF_plugin_depuis_maquettes.md`, 2026-09-07). +> +> ⚠️ **Les deux modes sont indiscernables tant que le surplus reste sous le plancher** — à +> l'œil comme à la sonde. Sur `.75` le 2026-09-06, **zéro** quart d'heure sur 97 n'atteint +> 4 140 W (meilleur : 2 214 W). C'est ce qui a permis de croire le mode implémenté : deux +> modes qui rendent le même rien ne se distinguent par aucune observation. --- diff --git a/docs/BRIEF_plugin_depuis_maquettes.md b/docs/BRIEF_plugin_depuis_maquettes.md index 0f9dcf0..0a9498b 100644 --- a/docs/BRIEF_plugin_depuis_maquettes.md +++ b/docs/BRIEF_plugin_depuis_maquettes.md @@ -2,6 +2,88 @@ --- +## 2026-09-07 — `ChargingModeEcoWithMinCurrent` ne sert aucun plancher : le « Min » ne fait rien + +**Ce que le mode doit faire, spécifié par Patrick aujourd'hui** : Min+PV charge **toujours** +au minimum de la borne, acheté au réseau s'il le faut, **et ajoute le surplus par-dessus**. +Avec 400 W d'injection, une borne dont le minimum vaut 4 140 W doit charger à **4 540 W**. + +**Ce qu'il fait sur `.75`** : rien. Mesuré ce matin, voiture branchée et borne joignable — + +```jsonc +// GetChargingInfos +{ "evChargerId": "4d1adafd-…", "chargingMode": "ChargingModeEcoWithMinCurrent", + "chargingState": "ChargingStateIdle" } + +// GetLoadTelemetry, la borne +{ "loadId": "{4d1adafd-…}", "allocatedW": 0, "available": true, + "mechanism": { "kind": "evcharger", "chargingEnabled": false, "currentA": 6, + "phaseCount": 3, "pluggedIn": true }, + "decision": { "code": "SURPLUS_INSUFFICIENT", "level": "comfort", + "params": { "budgetW": -3 } }, + "levels": [ { "level": "comfort", "targetW": 0, "decision": {…} } ] } +``` + +**Un seul niveau `comfort`, aucun niveau `eco`.** La borne est arbitrée sur le surplus seul : +`ChargingModeEcoWithMinCurrent` se comporte donc **exactement** comme `ChargingModeEco`. Le +mode existe dans l'énumération, il traverse la frontière RPC, il est persisté — et il ne +change aucune décision. + +### Le mécanisme existe déjà, il n'est simplement pas câblé sur la borne + +Le chauffe-eau, dans la même trame, fait précisément ce qui est demandé : + +```jsonc +{ "level": "eco", "targetW": 1071.6, + "decision": { "code": "ECO_FLOOR_GRID", "params": { "gridW": 1072, "regime": "measured", … } }, + "counts": { "draw.committedW": 1071.6 } } +``` + +Un plancher servi, acheté au réseau, compté dans `draw.committedW`, avec le surplus +distribué au-dessus par le niveau `comfort`. **C'est le même objet.** La demande est donc : +donner à une borne en `…WithMinCurrent` (et en `…EcoMinWithTargetTime`) un niveau `eco` +dont la cible est le minimum de la borne. + +### Et le plancher n'a besoin d'AUCUN champ de contrat + +`minCurrent` n'existe nulle part dans `ChargingInfo`, et c'est noté depuis longtemps chez +moi comme un blocage. **Ce n'en est pas un** : la valeur est déjà sur la box, dans la classe +du Thing. + +```jsonc +// Integrations.GetThingClasses, classe "trydan" +{ "name": "maxChargingCurrent", "type": "Double", "minValue": 6, "maxValue": 32, + "unit": "UnitAmpere" } +{ "name": "phaseCount", "minValue": 1, "maxValue": 3 } // état courant : 3 +``` + +`6 A × 3 phases × 230 V = 4 140 W`, exactement le nombre attendu par Patrick. Le moteur +peut donc dériver le plancher de `maxChargingCurrent.minValue × phaseCount` sans qu'aucun +champ nouveau ne traverse la frontière, et sans que l'app ait à saisir quoi que ce soit — +ce qui est le bon partage : une limite matérielle se lit sur le matériel. + +### Pourquoi ça se voit maintenant et pas avant + +Parce que sur ce banc le surplus n'atteint **jamais** le plancher, donc le mode PV et le mode +Min+PV rendent le même résultat visible — rien. Sur les 97 quarts d'heure du 2026-09-06, +**zéro** dépasse 4 140 W ; le meilleur fait 2 214 W. Tant que le « Min » n'est pas servi, les +deux modes sont indiscernables **à l'œil comme à la sonde**, et c'est ce qui a permis de +croire le mode implémenté. + +> Conséquence pour la borne, côté client : elle affiche « désactivé ». Ce n'est pas une +> panne — `optimizerSuspended: true`, le HEMS a pris la main sur l'optimiseur interne V2C et +> la laisse à `chargingEnabled: false`. L'utilisateur voit donc le HEMS éteindre sa borne +> dans le mode censé garantir une charge minimale. + +### Une piste séparée, à trancher par vous + +La borne simulée expose `desiredPhaseCount`, la V2C non. En monophasé le plancher tomberait à +**1 380 W**, et les 2 214 W du 6 septembre auraient suffi. Si la bascule de phases est +pilotable sur la Trydan, elle change la réponse pour toutes les installations à petit +surplus — mais c'est un autre lot, et je ne l'ouvre pas. + +--- + ## 2026-09-06 — état du banc laissé en place pour le week-end **Rien écrit par l'app.** L'obligation était déjà posée quand j'ai regardé, et déjà à la