From d37a11e803d93be6839e9772875c0b9a09b7f62c Mon Sep 17 00:00:00 2001 From: Patrick Schurig Date: Tue, 13 Oct 2026 10:21:18 +0200 Subject: [PATCH] =?UTF-8?q?docs(pr=C3=A9vision=20PV):=20=C2=A731.7=20?= =?UTF-8?q?=E2=80=94=20GTI=20observ=C3=A9,=20compl=C3=A9ter=20plut=C3=B4t?= =?UTF-8?q?=20qu'attendre,=20couverture=20attendue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- docs/DESIGN_PREVISION_PV.md | 63 +++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/docs/DESIGN_PREVISION_PV.md b/docs/DESIGN_PREVISION_PV.md index 145d630..336d148 100644 --- a/docs/DESIGN_PREVISION_PV.md +++ b/docs/DESIGN_PREVISION_PV.md @@ -1519,3 +1519,66 @@ déduire d'un écart prévu/mesuré serait précisément l'apprentissage qui n'a nouveau paramètre avec l'ancien `p`. La durée de cette fenêtre dépend du moment où le producteur recalcule après une reconfiguration — **non vérifié** ici. La refermer demande que le producteur publie ses paramètres **dans** la charge utile. + +### 31.7 Le GTI observé par satellite (2026-10-13, etm68) + +*État du code. Ajout au §31, rien n'y est réécrit. But : que T3 sépare l'erreur **météo** (GTI +prévu contre GTI observé) de l'erreur de **conversion** (GTI observé converti contre `measuredW`). +Aucune décision ne lit ces colonnes (§11) ; `valid` n'en dépend pas.* + +**Trois colonnes**, ajoutées en fin de table : + +| colonne | sens | NULL | +|---|---|---| +| `gtiObserved` | GTI observé du plan, W/m², moyen sur le pas | inconnu — jamais 0 par défaut ; un 0 **publié** (nuit) est écrit 0 | +| `gtiObservedSource` | code de la source : `openmeteo-satellite-state` | idem | +| `gtiObservedAt` | `observedGtiTime` **tel que publié** (epoch s, fin de l'heure moyennée) | idem | + +**Source** : les états `observedGti` / `observedGtiTime` du Thing plan openmeteo, lus **par leur +nom** à chaque cycle, comme `kwp`. `observedGtiTime == 0` (défaut) ou états absents ⇒ rien. + +**Le pas visé : `targetAt = observedGtiTime − 3600`.** Le `gti` prévu suit la convention du §14.3 : +l'élément `i` vaut pour `[t0 + i·step, t0 + (i+1)·step)`, une valeur est rattachée au **début** +du pas qu'elle moyenne. Open-Meteo horodate une moyenne horaire à la **fin** de son heure (la valeur +à `T` est la moyenne de `(T − 1 h, T]`). La même convention impose donc `T − 1 h`. Seul un pas +d'une heure reçoit l'observation : une heure observée ne se répartit pas sur quatre quarts d'heure. + +**Le retard — compléter, pas attendre.** L'observation arrive 1 à 3 h après la fin de l'heure (retard +du satellite), plus jusqu'à une heure de sondage : 1 à 4 h après l'écriture du pas (fin + 120 s). +Deux choix étaient possibles : + +- *retarder l'écriture du pas* d'une grâce bornée (~4 h). Écarté : un redémarrage perdrait 4 h de + lignes tenues en mémoire, et le retard réel n'a pas de borne sûre ; +- **compléter plus tard la ligne existante — retenu.** Un `UPDATE` ciblé, qui ne pose **que** les + trois colonnes `gtiObserved*`, et **seulement** si `gtiObserved IS NULL` (clé + `stepS = 3600`). + +C'est **l'unique exception** à « une ligne écrite n'est jamais réécrite » (§31.1). Une valeur écrite +n'est jamais remplacée, aucun autre champ n'est touché (ni `valid`, ni `writtenAt`, ni la mesure). +L'observation **ne crée jamais de ligne** : un pas sans ligne (écoulé avant le premier cycle) ne +reçoit rien. Si l'observation arrive pendant que le pas est encore en tampon, elle entre par +l'`INSERT`. L'`UPDATE` part sur le fil d'écriture, **après** le lot du même cycle, et attend un lot +retenu par un verrou. L'état étant relu à chaque cycle, une publication n'est envoyée qu'une fois ; +un redémarrage la renvoie, et le `IS NULL` la rend inoffensive. + +**Migration en place.** Une table de la forme **exacte** etm67 reçoit les trois colonnes par +`ALTER TABLE … ADD COLUMN` (nullables, sans défaut) dans une transaction. Ses lignes restent, et +les nouvelles cases valent NULL. Le mécanisme « forme inattendue ⇒ refaite » (§31.5) ne s'applique +qu'aux **autres** formes. Un échec de migration ne refait rien : l'enregistrement s'arrête jusqu'au +prochain démarrage, la table et ses lignes intactes. + +**Couverture attendue — incomplète par construction.** L'état ne porte que la **dernière** heure non +nulle, et openmeteo le rafraîchit toutes les ~3 600 ± 60 s. Si deux heures deviennent disponibles +entre deux sondages, la première n'est jamais publiée, et elle est perdue. Une simulation de ce +mécanisme sur un an (5 graines) donne : + +| retard du satellite | heures perdues | +|---|---| +| constant (1 h 30 ou 2 h) | 0,03 à 0,8 % | +| variable d'une heure à l'autre, entre 1 h 30 et 1 h 45 | 1 à 5 % | +| variable d'une heure à l'autre, entre 1 h et 2 h | 14 à 22 % | +| variable d'une heure à l'autre, entre 1 h et 3 h | 29 à 31 % | + +S'y ajoutent les sondages en échec (pas de nouvel essai avant l'heure suivante) et les +redémarrages. La vraie valeur dépend du rythme réel de mise à jour du produit satellite, qui n'est +pas mesuré ici. Elle se lira sur le banc : la part des lignes de jour dont `gtiObserved` est NULL. +**Rien n'est comblé côté `ems`** : la correction est de publier la série, ce sera openmeteo etm16.