Rapport de nuit envoye a 07:30 (total complet) + HANDOFF §76

Envoi decale 06:47 -> 07:30 : apres la fermeture de la fenetre HC (07:24)
l'import de la nuit est termine, donc le total est complet. A 06:47 le rapport
ratait l'import 06:47->07:24 meme apres le fix d'extrapolation (ec5f43e).
Proposition du proprietaire. HANDOFF §76 consigne le bug (extrapolation de la
derniere puissance sur la fenetre future), le fix et ce decalage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
This commit is contained in:
Tallagrand Thierry
2026-09-24 15:46:37 +02:00
parent ec5f43ecff
commit 41381fcdb9
2 changed files with 74 additions and 2 deletions

View File

@@ -7436,3 +7436,68 @@ SOC couvrent tout le parc (agregat Cerbo).
--- ---
*Document mis a jour le : 24/09/2026 — releve migre sur le Synology .17 (conteneur + tache boot root/sh), survie prouvee sur reboot + update DSM 7.4.1* *Document mis a jour le : 24/09/2026 — releve migre sur le Synology .17 (conteneur + tache boot root/sh), survie prouvee sur reboot + update DSM 7.4.1*
## 76. Session du 24/09/2026 — Le rapport de nuit extrapolait l'import sur les heures futures
### Le bug (signale par la session SPARK via les compteurs d'energie)
Rapport du 24/09 : « Au total 4,2 kilowattheures importes » pour la nuit, contre
**~1,6 kWh** vus par deux compteurs d'ENERGIE independants (le compteur EDF de
facturation `edf_general_ok_energie_totale` : 1,53 ; les compteurs AC-in Victron
`airtria_mpii_v1_energy_from_ac_in_1_to_*` : 1,60). Deux compteurs concordent :
c'est le 4,2 qui est faux.
### La cause — et ce n'etait PAS celle proposee d'abord
SPARK diagnostiquait une surestimation par la cadence d'echantillonnage
(`sum/60000` supposant 1 point/min alors qu'il y en aurait 2,7). **Faux, et
verifie en base** : le SQL ne sommait pas les points bruts, il construisait une
grille `generate_series` a la minute + derniere valeur connue, donc 1 point/min
par construction. Donnees d'ailleurs eparses : **130 points sur 961 minutes**.
Le 2,7 (= 4,2/1,53) etait une coincidence numerique, pas un mecanisme.
La vraie cause : **le rapport tourne a 06:47 mais sa fenetre va jusqu'a 10:00**.
Le `generate_series` remplit les ~3 h futures, et la derniere puissance connue
(le reseau qui importait encore a 06:47) est reportee sur 193 minutes fantomes.
Preuve : rejeu de l'ancienne methode tronquee a 06:47 -> **3,79 kWh**, cohcerent
avec le 4,2 ; la meme methode sur la fenetre COMPLETE (donnees presentes cet
apres-midi) redonne **1,60**. Elle n'etait donc fausse QUE parce qu'elle tournait
avant la cloture de sa propre fenetre.
⚠️ Lecon de methode : cette cause ne se trouve qu'en REJOUANT la requete sur les
donnees, pas en raisonnant sur un ratio. J'ai rejoue plutot que de croire le
diagnostic du ratio sur parole — c'est ce qui a evite de « corriger » la mauvaise
chose.
### Le correctif (deploye 24/09, `ec5f43e`)
`tools/rapport-nuit.mjs` : integration **ponderee par l'intervalle reel** entre
points (`lead(ts)`, cap 300 s pour qu'un trou n'extrapole rien ; aucun point
apres le dernier echantillon donc aucune extrapolation) **et fenetre plafonnee a
`now()`**. Applique aux QUATRE grandeurs integrees (importe, injecte, voiture,
batterie_chargee) qui partageaient la formule. Verifie : **1,60 kWh** sur fenetre
complete (= les compteurs), **1,19** en simulation 06:47 (import reel jusque-la).
⚠️ **Option ecartee** : lire le delta d'un compteur d'ENERGIE cumule (le plus
robuste en principe) est **inapplicable ici** — ces compteurs
(`edf_general_ok_energie_totale`, AC-in Victron) ne sont PAS dans la table
PostgreSQL `mesure` (seul `sensor.victron_grid_power_l1` y est) ; SPARK les lisait
direct sur HA (recorder SQLite). Si un jour on veut la methode compteur, il faut
d'abord ajouter ces entites a l'historisation.
⚠️ **Portee** : tous les rapports depuis le 08/09 surestimaient ces kWh (ils
tournent toujours avant 10 h). Le RESTE du rapport (SOC, heures de fermeture,
vehicule, injection) etait juste — ces faits ne sont pas integres.
### Decalage de l'heure d'envoi 06:47 -> 07:30 (proposition du proprietaire)
Le fix stoppe la SURestimation, mais a 06:47 le rapport reste INCOMPLET : il rate
l'import 06:47->07:24. Raisonnement du proprietaire : la fenetre HC ferme a 07:24,
et si l'ajustement de la cible du matin fait son travail il n'y a **pas** d'autre
fermeture EDF ensuite — donc un rapport apres 07:24 capture l'import COMPLET de la
nuit. `RAPPORT_HEURE/MINUTE` passe a **07:30** (`historise-evcs.mjs`).
Reserve consignee : les jours ou la cible du matin est trop basse, l'hysteresis
peut refermer EDF apres 07:24 (cas plein tarif §39) et un rapport a 07:30 le
raterait. C'est l'exception ; 07:30 est strictement meilleur que 06:47 (toujours
incomplet). La fenetre de calcul restant plafonnee a `now()`, l'heure d'envoi peut
etre avancee/reculee sans risque de fantome.
---
*Document mis a jour le : 24/09/2026 — rapport de nuit : integration ponderee + fenetre plafonnee (fin de l'extrapolation), envoi decale a 07:30 pour un total complet*

View File

@@ -964,8 +964,15 @@ async function ecrireSession(sql, client, st) {
// table `evenement`, qui est de toute facon la trace que l'on veut garder. // table `evenement`, qui est de toute facon la trace que l'on veut garder.
// Redemarrer le conteneur ne renvoie donc pas le rapport. // Redemarrer le conteneur ne renvoie donc pas le rapport.
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
const RAPPORT_HEURE = 6; // 07:30, apres la fermeture de la fenetre HC (07:24) : l'import de la nuit est
const RAPPORT_MINUTE = 47; // alors termine, donc le total du rapport est COMPLET. A 06:47 il manquait
// l'import 06:47->07:24 (proposition du proprietaire, 24/09). Reserve connue :
// si la cible du matin est trop basse, l'hysteresis peut refermer EDF apres
// 07:24 (cas plein tarif §39) et ce rapport le raterait — l'exception, pas la
// regle. La fenetre de calcul est de toute facon plafonnee a now() (voir
// rapport-nuit.mjs), donc avancer/reculer cette heure reste sur.
const RAPPORT_HEURE = 7;
const RAPPORT_MINUTE = 30;
async function envoyerRapportDuMatin(sql, client) { async function envoyerRapportDuMatin(sql, client) {
if (!client) return 0; if (!client) return 0;