diff --git a/CLAUDE.md b/CLAUDE.md index 4b6881f..72014ad 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -420,6 +420,30 @@ entiers **déjà en pourcentage** (ne pas confondre `reservePercent` = 40 avec --- +## Échéances — l'heure saisie n'est pas l'heure du client + +`needs.dailyDeadline` est une chaîne `"HH:MM"` **sans fuseau**, et la box l'interprète dans **le +sien**. Mesuré le 2026-09-04 : `.75` est en `Europe/London`, donc une échéance « 12:00 » vaut +**13:00 sur une horloge française**. Le moteur a failli imputer l'écart à un décalage d'heure +d'été qui n'existe pas. + +Le fuseau franchit la frontière RPC, et l'app peut donc être honnête sans rien supposer : + +```dart +System.GetTime -> {"automaticTime": true, "time": 1788500953, "timeZone": "Europe/London"} +``` + +**Règle d'écran : ne jamais présenter une échéance comme locale sans dire quelle horloge la box a +lue.** Afficher le fuseau de la box à côté du champ, et signaler la divergence avec celui de +l'appareil quand il y en a une. `remainingS` de la télémétrie permet de le vérifier après coup — +18 719 s à 06:48 heure box donnent bien 12:00 heure box, pas 12:00 heure client. + +Vaut aussi pour **toute fenêtre tarifaire** à venir. Un lot moteur est ouvert pour trancher d'où +vient le fuseau et ce qu'il fait quand il diverge ; d'ici là, l'app **dit** l'horloge au lieu de +la choisir. + +--- + ## Règles de modification - Tout nouvel écran → valider maquette avec Patrick avant de coder - Tout nouvel appel RPC → vérifier dans `INTERFACE.md` que la méthode existe diff --git a/docs/BRIEF_plugin_depuis_maquettes.md b/docs/BRIEF_plugin_depuis_maquettes.md index e37d0a5..aa523ac 100644 --- a/docs/BRIEF_plugin_depuis_maquettes.md +++ b/docs/BRIEF_plugin_depuis_maquettes.md @@ -2,6 +2,53 @@ --- +## 2026-09-04 (suite) — la baisse, mesurée en lecture seule, et le fuseau qui la datait mal + +Banc laissé tel quel — l'obligation est la vôtre, je n'ai rien écrit. + +### Le critère positif est atteint, et deux invariants tiennent avec lui + +| cycle | livré | reste | gridW | restS | +|---|---|---|---|---| +| 05:48Z | 575,0 | 2 425 | **466** | 18 719 | +| 05:49Z | 600,0 | 2 400 | **463** | 18 659 | + +`deliveredWh` monte de **25 Wh/min**, soit 1 500 W — exactement ce que le compteur ECS annonce. +`remainingWh` descend d'autant, et `gridW` **baisse**. Ce n'est plus l'absence de mur, c'est la +décroissance. + +Deux vérifications qui ne coûtent rien et que l'écran fera à chaque trame : + +- **`deliveredWh + remainingWh == targetWh`** — 3 000,0000000000364 puis 2 999,999583 pour une + cible de 3 000. L'identité que vous aviez épinglée tient sur données réelles, et **c'est ici + qu'elle mord** : sous `measured`, elle n'est plus le corollaire trivial qu'elle est sous + `unmeasurable`. +- **`gridW == remainingWh / remainingS`** — 466 == 466, puis 463 == 463. La loi d'étalement est + donc vérifiable **de l'extérieur**, sans lire le code. Un écart futur serait un défaut, pas une + approximation. + +Et `purchasedWh` 183 → 191 pour 575 → 600 Wh livrés : le plancher acheté reste le tiers du +consommé. La paire diverge, et c'est la divergence qui informe — le second usage, exercé. + +### Le fuseau : l'app peut être honnête aujourd'hui, sans attendre votre arbitrage + +`remainingS` le confirme de notre côté : 18 719 s à 06:48 heure box mènent à **12:00 heure box**, +pas 12:00 heure client. Et le fuseau **franchit déjà la frontière RPC** : + +```jsonc +System.GetTime -> {"automaticTime": true, "time": 1788500953, "timeZone": "Europe/London"} +``` + +L'écran n'a donc pas besoin de la décision pour cesser de mentir : il **dira** l'horloge au lieu +de la choisir — fuseau de la box affiché à côté du champ d'échéance, divergence signalée quand +celui de l'appareil diffère. C'est écrit dans `CLAUDE.md` et dans la maquette. + +Ce que votre lot doit trancher reste entier, et c'est autre chose : **d'où vient le fuseau** et ce +qui se passe quand il diverge. Nous ne présumons pas de la réponse — nous rendons seulement +impossible qu'un installateur lise « 12:00 » comme son 12:00. + +--- + ## 2026-09-04 — `+etm52` : la contradiction est levée, mesurée Obligation déclarée puis retirée (`chauffe-eau`, 4 000 Wh avant 12:00, sept cycles, restauration diff --git a/docs/mockups/deux_passes_eco_confort_mockup.html b/docs/mockups/deux_passes_eco_confort_mockup.html index 0471a85..dfc4c85 100644 --- a/docs/mockups/deux_passes_eco_confort_mockup.html +++ b/docs/mockups/deux_passes_eco_confort_mockup.html @@ -281,7 +281,8 @@ ÉCO
Plancher servi — 1 400 W achetés au réseau - 2,1 kWh livrés sur les 3,0 dus avant 07:00 MESURÉ + 2,1 kWh livrés sur les 3,0 dus avant 07:00 (heure box) + MESURÉ
@@ -424,6 +425,12 @@ setpointW, currentA), qui existe déjà aujourd'hui.
  • Et il ne se répartit pas non plus. L'écart appartient à la charge, pas à un niveau : l'adaptateur arrondit une consigne unique, il ne sait pas de quel besoin elle venait.
  • +
  • L'heure d'une échéance est celle de la BOX, pas celle du client : + dailyDeadline est un "HH:MM" sans fuseau, interprété dans celui de + la box. Mesuré le 2026-09-04 — .75 est en Europe/London, donc + « 12:00 » vaut 13:00 sur une horloge française. Le fuseau se lit par + System.GetTime : l'écran l'affiche à côté du champ et signale la divergence, + plutôt que de choisir une horloge à la place de l'installateur.
  • Sous unmeasurable, le plancher ne peut pas se refermer — mesuré le 2026-09-01 sur quatre cycles : remainingWh figé à 4 000, remainingS qui descend, gridW qui monte 755 → 767. Ce n'est pas un cas limite, c'est la