2 Commits

Author SHA1 Message Date
Patrick Schurig
f1547f674a fix(énergie): grouper par période CIVILE, soutiré en bleu, second graphe d'énergie
TROIS DEMANDES DE PATRICK.

1. Le soutiré passe du rouge au BLEU. Avec l'orange partagé sur les deux barres,
   le rouge rendait l'image trop chaude — et le bleu est déjà la couleur de la
   maison partout ailleurs. Il ne reste d'orange que le bloc partagé, celui qui
   doit se voir.

2. Second graphe en vue barres : « Où est passée la consommation » — une barre
   empilée par période, une couleur par charge déclarée, plus le reste du foyer
   qui ferme la barre à la consommation totale.

   L'énergie vient du compteur cumulé de chaque appareil (`totalConsumption`),
   jamais d'une intégration de la puissance — intégrer supposerait la puissance
   constante entre deux échantillons. Vérifié à la sonde avant d'écrire : ECS
   80,8 kWh et PAC 43,1 kWh sur la fenêtre, avec des deltas journaliers réels.

   Une charge dont le compteur n'a pas bougé donne 0 kWh, qui est une MESURE.
   Une charge dont le cumul manque à une borne n'a PAS de part. Les deux se
   ressemblent à l'écran et ne disent pas la même chose. Et un compteur qui
   recule est une remise à zéro, pas une consommation négative : la part est
   refusée plutôt que rendue absurde.

🔴 3. LE « 6/9 » EN DOUBLE N'ÉTAIT PAS UN DÉFAUT DE L'APP. C'est la trace de
   notre propre bascule de fuseau du 2026-09-06 : la frontière de journée de la
   box a glissé d'une heure, et l'historique porte deux échantillons pour le
   06/09 — 00:00 et 01:00. Le graphe affichait fidèlement une « journée » d'une
   heure à côté de journées entières.

   La couture est PERMANENTE : elle est dans les données passées, pas dans une
   requête. Tout écran qui compare des périodes doit grouper par période civile,
   jamais par indices consécutifs. Aucune énergie n'est perdue — la tranche
   d'une heure est absorbée dans sa journée.

Et une étiquette d'axe illisible : fl_chart en pose une à `min` en plus de
celles de l'intervalle, et les deux se superposaient — « 20:4500 ». Deux heures
imprimées l'une sur l'autre ne se lisent ni l'une ni l'autre.

358 tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GKM8FDNHZWogAsjjfB8pSw
2026-09-09 08:52:54 +02:00
Patrick Schurig
9c19791e9a feat(énergie): les deux graphes — flux corrigé, et l'empilement par consommateur
Maquette validée par Patrick (couleurs comprises). Deux graphes, et trois
défauts d'affichage trouvés en chemin — dont deux à l'écran seulement.

GRAPHE 1 — les trois « on ne voit pas » avaient trois causes.

  production : publiée NÉGATIVE (−103 W). La magnitude est prise AU RENDU, pas
  au transport : le champ reste brut (§7.1), et `.abs()` est licite sur une
  production, dont le signe ne porte aucune information — contrairement au
  réseau, où le signe dit le sens (d'où gridImportW/gridExportW là-bas).

  autoconsommation : `production − export` clampé à 0, donc TOUJOURS zéro avec
  une production négative. Même racine, corrigée par la même magnitude.

  SOC : correctement absent — aucune batterie sur l'installation. Ce qui
  manquait, c'était de le DIRE ; c'est maintenant une note sous le graphe.

  ⚠️ Et un deuxième empêchement, vu seulement à l'écran : le signe réparé, la
  production restait invisible SOUS l'autoconsommation. Tant que rien n'est
  exporté les deux sont égales au pixel près, et la verte était tracée par
  dessus. L'autoconso passe en pointillé — des tirets sur la bande ambre disent
  « tout est consommé sur place », leur décrochage dit l'export. Deux courbes
  qui coïncident doivent pouvoir se VOIR coïncider.

  ⚠️ Ce correctif en créait un autre : le SOC était aussi vert pointillé. Sur
  une installation AVEC batterie les deux auraient été indiscernables — collision
  qu'aucun banc sans batterie ne pouvait montrer. Le SOC passe en indigo.

GRAPHE 2 — qui consomme, empilé.

  `Energy.GetThingPowerLogs`, et la liste des appareils vient de GetLoadConfig :
  chaque charge déclarée porte son `meterThingId`, son label et son domaine —
  vérifié renseigné sur les quatre charges de .75. Rien n'est deviné d'un nom
  d'appareil.

  Un appareil demandé sans réponse sort dans `sansHistorique` et est NOMMÉ sous
  le graphe, jamais tracé à zéro : la V2C ne déclare pas `smartmeter`, donc elle
  n'a pas de passé — ce qui n'est pas « elle n'a rien tiré ».

  Le RESTE du foyer est licite ici, contrairement au Sankey qui l'avait fait
  interdire : chaque part est un compteur dédié et le total est le compteur du
  foyer, donc la soustraction ne porte que du mesuré. Et un reste NÉGATIF n'est
  pas raboté — c'est la preuve qu'un sous-compteur n'est pas dans le périmètre
  du total, et l'écraser effacerait la seule chose qui le dise.

  🔴 Le signe des sous-compteurs n'est PAS vérifié : les trois lisent 0 W à tous
  les pas, donc aucun échantillon non nul n'existe. Le compteur PV publie en
  négatif — rien n'autorise à supposer. La valeur est transportée brute et
  `signeIndetermine` le dit à l'écran.

Couleurs par consommateur ajoutées au thème (pac ambre, ecs sarcelle, ev
indigo) : distinctes des couleurs de FLUX, qui disent d'où vient l'énergie, là
où celles-ci disent qui la prend.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GKM8FDNHZWogAsjjfB8pSw
2026-09-08 10:25:16 +02:00