diff --git a/docs/mockups/configurer_mecanismes_mockup.html b/docs/mockups/configurer_mecanismes_mockup.html index 729de82..7fb7e15 100644 --- a/docs/mockups/configurer_mecanismes_mockup.html +++ b/docs/mockups/configurer_mecanismes_mockup.html @@ -207,15 +207,75 @@ .pill.load{background:rgba(53,201,138,.12);color:var(--green);border:1px solid rgba(53,201,138,.3)} .pill.ev{background:rgba(157,140,224,.12);color:var(--violet);border:1px solid rgba(157,140,224,.32)} .pill.ac{background:rgba(49,163,221,.12);color:var(--blue);border:1px solid rgba(49,163,221,.32)} + .pill.bat{background:rgba(254,193,19,.1);color:var(--yellow);border:1px solid rgba(254,193,19,.32)} + + /* ── batterie ───────────────────────────────────────────────────────── */ + .newf{font-size:10.5px;color:#ff9d6b;background:rgba(255,157,107,.1);border:1px solid rgba(255,157,107,.34); + border-radius:20px;padding:2px 8px;font-weight:600;float:right;margin-top:-2px} + .perm{display:flex;align-items:center;gap:10px;background:var(--card2);border:1px solid var(--line); + border-radius:11px;padding:10px 11px;margin-bottom:7px} + .perm .ic{width:24px;height:24px;border-radius:7px;display:grid;place-items:center;font-size:13px;flex:none; + background:rgba(255,255,255,.06)} + .perm .nm{flex:1;min-width:0} + .perm .nm b{display:block;font-family:'Poppins';font-weight:600;font-size:12.5px} + .perm .nm span{font-size:10.2px;color:var(--muted2)} + .src{display:flex;gap:5px;flex:none} + .sbtn{font-size:10px;font-family:'Poppins';font-weight:600;border-radius:7px;padding:5px 8px; + border:1px solid var(--line2);background:var(--panel);color:var(--muted2);cursor:pointer} + .sbtn.on{border-color:var(--green);color:var(--green);background:rgba(53,201,138,.1)} + .sbtn.no{border-color:rgba(224,122,122,.4);color:var(--red);background:rgba(224,122,122,.08)} + + .tl{margin-top:10px;background:var(--card2);border:1px solid var(--line);border-radius:11px;padding:12px 12px 10px} + .tl .bar{position:relative;height:26px;border-radius:7px;overflow:hidden; + background:linear-gradient(90deg,#0f3242 0%,#123c4f 34%,#16506a 50%,#123c4f 66%,#0f3242 100%)} + .tl .seg1{position:absolute;left:56%;right:14%;top:0;bottom:0;background:rgba(53,201,138,.28)} + .tl .pnr{position:absolute;left:56%;top:-4px;bottom:-4px;width:2px;background:var(--red)} + .tl .pnr::after{content:"";position:absolute;top:-3px;left:-3px;width:8px;height:8px;border-radius:50%; + background:var(--red)} + .tl .peak{position:absolute;left:86%;top:0;bottom:0;width:2px;background:var(--yellow);opacity:.8} + .tl .ax{display:flex;justify-content:space-between;margin-top:6px;font-size:9.5px;color:var(--muted2)} + .tl .lg{margin-top:9px;font-size:10.5px;color:var(--muted2);line-height:1.55} + .tl .lg em{font-style:normal;color:var(--red);font-weight:600} + .tl .lg u{text-decoration:none;color:var(--yellow);font-weight:600} + + .boost{border:1px solid rgba(157,140,224,.35);background:rgba(157,140,224,.07);border-radius:13px;padding:13px} + .boost .t{display:flex;align-items:center;gap:9px;margin-bottom:8px} + .boost .t b{font-family:'Poppins';font-weight:600;font-size:13px;flex:1} + .boost .t u{text-decoration:none;font-size:16px} + .boost .end{margin-top:9px;border-top:1px dashed rgba(157,140,224,.3);padding-top:9px; + font-size:10.6px;color:var(--muted2);line-height:1.55} + .boost .end b{color:var(--violet)} + .gauge{display:flex;align-items:center;gap:9px;margin:9px 0 2px} + .gauge .tr{flex:1;height:7px;border-radius:20px;background:rgba(255,255,255,.09);overflow:hidden} + .gauge .fl{height:100%;width:64%;background:var(--yellow)} + .gauge b{font-family:'Poppins';font-weight:700;font-size:13px} + .ask{margin-top:12px;border:1px solid rgba(224,122,122,.3);background:rgba(224,122,122,.06); + border-radius:11px;padding:11px 12px;font-size:11px;color:var(--muted);line-height:1.55} + .ask b{color:var(--red);display:block;font-family:'Poppins';font-size:11.5px;margin-bottom:5px} + .ask ol{margin:6px 0 0;padding-left:16px} .ask li{margin-bottom:6px} + .wide{max-width:824px;width:824px} + .wide h3{font-family:'Poppins';font-weight:600;font-size:13px;margin:0 0 7px;color:var(--txt)} + .mot{display:flex;gap:10px;margin:10px 0 4px;flex-wrap:wrap} + .mot .m{flex:1;min-width:230px;background:var(--card2);border:1px solid var(--line);border-radius:11px;padding:11px} + .mot .m b{display:block;font-family:'Poppins';font-weight:600;font-size:12px;margin-bottom:5px;color:var(--blue)} + .mot .m span{font-size:10.6px;color:var(--muted2);line-height:1.5;display:block}
-

Six écrans, trois contrats — et ils ne se ressemblent pas

+

Sept écrans, quatre contrats — et ils ne se ressemblent pas

Le bouton Configurer ne peut pas être un formulaire unique. SG-Ready est une LoadConfig comme le routeur de relais ; la borne de recharge et les zones de climatisation n'en sont pas du tout — elles vivent sur d'autres namespaces, avec d'autres champs et d'autres tiers.

+

Ajout du 2026-08-27 — la batterie, septième écran. Elle devient une charge du waterfall, donc + son bouton Configurer ouvre un écran de mécanisme comme les autres. Rien de ce qui suit + n'existe côté box : ni BatteryAdapter, ni entrée LoadConfig pour le + stockage, ni prévision PV. Cette colonne est un brief pour le moteur, comme les six autres + l'ont été — et les seuls leviers réels de .75 sont les cinq actions de la classe + SunSpec Storage : enableCharging, enableDischarging, + chargingRate, dischargingRate, gridCharging, plus l'état + controlHealthy. Tout le reste est à créer.

Deux écarts relevés en introspectant .75 (plugin 1.15.2+etm15) : ① le ChargingInfo réellement déployé ne porte ni mode, ni minCurrent, ni targetSoc, ni endTime — les noms écrits dans CLAUDE.md ne sont pas @@ -996,6 +1056,247 @@

+ + +
+
+
‹

Configurer · Batterie

+
+ +
+ + +
+ +
+ +
+
Position1 = servi en premier
+
1
+
+
Défaut : la batterie en premier. Ce n'est pas un choix de conception, + c'est la reproduction du comportement actuel — aujourd'hui l'onduleur charge avant que le HEMS + ne serve quoi que ce soit. Une mise à jour ne change jamais l'arbitrage sans geste. La + nouveauté n'est pas l'ordre, c'est qu'il devient réglable : glisser « Eau chaude » au-dessus + suffit alors à obtenir « ECS d'abord, batterie ensuite ».
+
+ +
+ +
50 % · 10 kWh · 0 WHolding
+
batteryLevel · capacity · + currentPower · storageStatus — publiés par le Thing, jamais + recalculés ici.
+
+ + +
+ + +
+
🚿
+
Eau chauderang 2 · relay-router
+
SolaireBatterie
+
+
+
🔥
+
PAC bancrang 3 · sg-ready
+
SolaireBatterie
+
+
+
🚗
+
Simulated wallboxrang 4 · evcharger
+
SolaireBatterie
+
+ +
Ce n'est pas une question de rang, c'est une question de SOURCE. + « Bloquer la décharge pendant la recharge nocturne du véhicule » ne se dit pas avec un ordre de + priorité : la nuit, il n'y a pas de surplus à répartir, il y a une batterie qu'on ne veut pas + vider dans la voiture. La formulation juste est donc quelles charges ont le droit d'être + servies par la batterie, et elle se règle charge par charge.

+ Le contrat porte déjà Source { Solar, GridSource } — il manque le troisième terme, + et le droit de le refuser par charge.
+
+ + +
+ +
+
Viser 100 % juste avant la pointeau lieu de plafonner dès midi
+
+
+
+
Prête à2 à 3 h avant la pointe du soir
+
16:30
+
+ +
+
+
06:0012:0018:0022:00
+
+ ┃ point de non-retour — 13:20
+ Avant : la charge attend, le pic PV va à l'ECS et à la voiture.
+ Après : on charge de tout ce qui reste, prévision ou pas — une prévision qui se trompe + ne doit jamais coûter une batterie vide. ┃ pointe du soir +
+
+ +
Ce que ça gagne : le pic PV de midi est libéré pour l'ECS et le + véhicule, le vieillissement calendaire baisse (moins de temps passé à 100 %), et + aucun kWh n'est sacrifié — la même énergie est stockée, plus tard.
+
+ + +
+ +
+
Remonter le plancher après une nuit trop bassefaçon « Battery Life »
+
+
+
À reprendre pour la bonne raison, pas par mimétisme. + Victron a conçu Battery Life pour du plomb : une batterie plomb laissée + partiellement déchargée se sulfate, d'où un plancher qui remonte tant qu'une recharge complète + n'a pas eu lieu. Sur du LFP, le problème traité n'existe quasiment pas — pas de + sulfatation, et un séjour à SOC bas n'abîme rien.

+ Si ce mécanisme est repris, ce sera pour un autre motif à nommer explicitement (garder une + réserve de secours, lisser l'autonomie sur plusieurs jours gris). Le copier tel quel + importerait une contrainte de chimie que cette installation n'a pas.
+
+ + +
+ +
+
+
Cible d'énergieen kWh, pas en %
+
6 kWh
+
+
+
Terminé àheure de fin
+
06:00
+
+
Ni prix, ni Tempo, ni marché de gros ici. Cet écran pose le mécanisme : + soutirer au réseau une quantité donnée avant une heure donnée. Ce qui décide qu'il faut + le faire reste dehors — le jour où une source tarifaire existera, elle remplacera le doigt de + l'utilisateur sans que ce bloc ne change.
+
+ +
Annuler
Enregistrer
+
+
+
Batterie — une charge, enfin
+
+ à créer — BatteryAdapter · LoadConfig
+ Rien de cet écran n'existe. Le stockage n'a aucune entrée GetLoadConfig, et + enableCharging / chargingRate / enableDischarging ont + zéro occurrence dans energyplugin/. Le levier matériel, lui, est déclaré : la + classe SunSpec Storage de .75 publie ces cinq actions. + +
+
+ + +
+
+
☰

Tableau de bord

⋯
+
+ +
+ +
64 %
6,4 / 10 kWh
+ +
+
⚡Vider dans le véhicule
+
+ Pleine puissance, tout de suite. C'est le seul cas où la batterie est une source et + non une charge — d'où sa place ici, sur un geste immédiat, et non dans les réglages. +
+
+
S'arrête àcible sur la batterie maison
+
20 %
+
+
+
Ou au bout dedurée maximale
+
45 min
+
+
Il doit finir tout seul. Cible atteinte, durée écoulée, ou véhicule + débranché — jamais « jusqu'à annulation ». Un transfert sans fin vide une maison + pendant que personne ne regarde, et l'écran qui l'a lancé n'est plus là pour le dire.
+
+
+ +
+
+
Boost — hors Configurer
+
+ geste immédiat, pas un réglage
+ Un réglage décrit une intention durable ; ceci est une action ponctuelle avec un effet immédiat et + visible. La mettre dans « Configurer » la rendrait introuvable au moment où on la veut, et + persistante alors qu'elle ne doit pas l'être. + +
+
+ + +
+
+

Un seul motif, pas trois écrans voisins

+

+ Trois fonctionnalités demandées à des moments différents ont exactement la même forme. Si la + maquette le montre comme un motif unique, le moteur peut l'implémenter une fois au lieu de trois — + et l'écran peut le présenter une fois au lieu de trois.

+
+
Charge différéecible : 100 % de la batterie
échéance : 2–3 h avant + la pointe
non-retour : au-delà, on charge de tout
+
Charge depuis le réseaucible : 6 kWh soutirés
échéance : 06:00
+ non-retour : au-delà, pleine puissance
+
Échéance véhicule (LM-1009)cible : énergie livrée
échéance : heure + de départ
non-retour : au-delà, on passe au réseau
+
+

+ Une cible, une échéance, un point de non-retour. Le point de non-retour est la partie qui se + perd si on ne la nomme pas : c'est lui qui garantit qu'une prévision fausse ne coûte rien, et c'est + lui qu'un écran doit montrer — pas la prévision elle-même, qui n'engage personne.

+ +
+ Trois questions pour le moteur — à trancher, pas à deviner +
    +
  1. Bloquer demande un INTERDIT ACTIF, pas une allocation à zéro. La batterie agit + d'elle-même : l'onduleur charge sans qu'on le lui demande. Ne rien lui allouer ne l'empêche donc + de rien — il faut lui dire enableCharging = false. C'est une différence de nature + avec toutes les autres charges du waterfall, où « 0 W alloué » suffit à ce qu'il ne se passe + rien.
  2. +
  3. Cet interdit doit EXPIRER. Un HEMS qui tombe après avoir posé + enableCharging = false laisse une batterie inerte, sans que rien ne le signale et + sans que personne ne sache pourquoi. Il faut un bail à durée limitée, renouvelé tant que + l'arbitre vit — l'état sûr d'un stockage, c'est « il fait ce qu'il ferait sans nous », pas + « il reste sur le dernier ordre reçu ».
  4. +
  5. controlHealthy == false doit SORTIR la batterie de l'arbitrage, comme + available == false sort une charge en défaut. L'état existe déjà sur la classe. Une + batterie qu'on croit piloter et qui ne répond plus fausse le budget en silence, exactement comme + le faisait le double commandeur des bornes avant 3g-2.
  6. +
+
+
+
+