Chantier etapes 5b et 5c : recalcul quotidien des profils et fenetre de deficit suivante

5c — BALANCE ne repondait qu'a "combien jusqu'a ce que le solaire prenne le
relais". A 15 h la reponse est zero : exacte mais inutile, le deficit qui
approche etant celui de la nuit. Ajout de la prochaine traversee deficitaire
(heure de debut, energie, SOC a atteindre avant). Ce SOC n'est PAS ecrete a
100 % : au-dela, meme une batterie pleine ne passe pas, et le manque est
publie comme storage_shortfall_kwh — c'est le chiffre du dimensionnement.

5b — Workflow "EVCS Energy Profiles Daily V1" (N6UaB4ZozsbRPrFb), actif,
03:30 : lit /api/history/period sur 30 jours glissants et republie les quatre
CSV (conso p50 et p80, enveloppe de production, taux de censure).
CONSUMPTION_PROFILE devient DAILY_PROFILES et sait desormais decoder la
reponse brute de l'API en plus des series deja pretes.

Piege trouve : sans end_time, /api/history/period ne renvoie qu'UNE journee,
silencieusement. Mes premieres mesures "sur 3 jours" n'en couvraient qu'une.

Validation croisee : profils calcules depuis l'API REST (etats bruts, 11 j)
contre profils calcules depuis les statistiques long terme (28 j) — 0,20 kWh/h
d'ecart absolu moyen, par deux chemins de donnees independants.

BUILD_HA_CALLS_PROFILES refuse d'ecraser les profils en place si l'historique
ne couvre pas les 24 heures. Meme garantie de perimetre que le bilan.
Suite a 27 scenarios.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
This commit is contained in:
Tallagrand Thierry
2026-08-24 15:58:10 +02:00
parent e36f050a42
commit 6dc5ea25cb
14 changed files with 668 additions and 22 deletions

View File

@@ -79,3 +79,32 @@ export const shadowScenarios = [
},
},
];
// --- BUILD_HA_CALLS_PROFILES (workflow quotidien) ------------------------
const PROFILES_OK = {
complete: true,
days: 28,
csv: { p50: '1,'.repeat(23) + '1', p80: '2,'.repeat(23) + '2',
envelope: '3,'.repeat(23) + '3', censorshipRate: '0,'.repeat(23) + '0' },
totals: { typicalDailyKwh: 31.9, prudentDailyKwh: 42.8 },
production: { demonstratedDailyKwh: 74.4, censoredDayHours: 8 },
quality: { hoursUsed: 639, pvHoursUsed: 620, countersReset: 0, unreliableHours: [] },
};
export const profilesShadowScenarios = [
{
node: 'BUILD_HA_CALLS_PROFILES',
id: 'profils-perimetre-respecte',
label: 'Publication des profils : périmètre evcs_balance_* respecté',
snapshot: PROFILES_OK,
expect: { outOfScope: '', callCount: 6, hasLogbook: true },
},
{
node: 'BUILD_HA_CALLS_PROFILES',
id: 'profils-historique-insuffisant',
label: 'Historique trop court : les profils en place ne sont PAS écrasés',
snapshot: { ...PROFILES_OK, complete: false, days: 2,
quality: { ...PROFILES_OK.quality, unreliableHours: [3, 4, 5] } },
expect: { outOfScope: '', wroteProfiles: false },
},
];