Chantier : le bilan lit la courbe horaire au lieu de l'enveloppe

RESOURCE_ESTIMATE consomme desormais la courbe horaire publiee par le workflow
de prevision : forme et magnitude d'un seul tenant, sur 6 jours, avec les trois
plans reels et sans censure. Plus de repartition au prorata, plus de
renormalisation — le noeud se simplifie.

L'enveloppe est retrogradee en repli, utilisee seulement si la courbe est
absente ou vieille de plus d'une heure, le champ `mode` disant laquelle a
servi. Elle garde un role de repere de vraisemblance mais n'ecrete PLUS la
prevision : etant minoree l'apres-midi, elle tronquerait a tort une prevision
correcte.

Piege corrige au passage : le nouveau champ `source` entrait en collision avec
l'objet `source` deja present dans la sortie et etait silencieusement ecrase.
Renomme en `mode`.

Suite portee a 35 scenarios (courbe fraiche lue telle quelle, courbe perimee
basculant en repli).

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-25 02:37:41 +02:00
parent 26fb9f72ea
commit c35c39cb83
6 changed files with 124 additions and 21 deletions

View File

@@ -59,6 +59,7 @@ const SUMMARIZE = {
}),
RESOURCE_ESTIMATE: o => ({
usable: o.usable,
mode: o.mode,
todayExpected: o.todayExpectedRemainingKwh,
tomorrowExpected: o.tomorrowExpectedKwh,
shapeConfidenceBelow: o.source.shapeConfidence != null && o.source.shapeConfidence < 0.5,

View File

@@ -126,6 +126,47 @@ export const resourceScenarios = [
todayExpected: 30,
},
},
{
node: 'RESOURCE_ESTIMATE',
id: 'ressource-courbe-horaire',
label: 'Courbe horaire fraîche : lue telle quelle, sans répartition ni renormalisation',
snapshot: {
nowMs: Date.parse('2026-08-25T09:30:00+02:00'),
forecast_today_remaining_kwh: '999',
forecast_tomorrow_kwh: '999',
forecast_updated: '25/08 09:30',
// Relevé réel du 25/08 : 43,6 kWh sur la journée.
forecast_today_csv: '0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.07,0.63,1.60,3.50,6.50,7.90,7.00,4.60,3.30,2.70,2.20,1.70,1.10,0.60,0.10,0.00,0.00',
forecast_tomorrow_csv: '0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.09,0.77,1.60,2.27,2.81,3.63,4.24,3.52,2.95,2.59,2.21,1.69,1.08,0.47,0.05,0.00,0.00',
envelope_kwh: envelope.envelope_kwh,
censorship_rate: envelope.censorship_rate,
},
expect: {
usable: true,
mode: 'courbe_horaire_api',
// Reste de la journée à partir de 09 h : lu dans la courbe, pas recalculé.
todayExpected: 42.8,
},
},
{
node: 'RESOURCE_ESTIMATE',
id: 'ressource-courbe-perimee',
label: 'Courbe vieille de plus d\'une heure : repli sur l\'enveloppe, signalé',
snapshot: {
nowMs: Date.parse('2026-08-25T12:30:00+02:00'),
forecast_today_remaining_kwh: '15.9',
forecast_tomorrow_kwh: '29.1',
forecast_updated: '25/08 09:30',
forecast_today_csv: '0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.07,0.63,1.60,3.50,6.50,7.90,7.00,4.60,3.30,2.70,2.20,1.70,1.10,0.60,0.10,0.00,0.00',
envelope_kwh: envelope.envelope_kwh,
censorship_rate: envelope.censorship_rate,
},
expect: {
usable: true,
mode: 'repli_enveloppe',
todayExpected: 15.9,
},
},
{
node: 'RESOURCE_ESTIMATE',
id: 'ressource-sans-enveloppe',