fix(strommix): SMARD as primary source — accuracy parity with audit
Deploy / verify (push) Successful in 45s
Deploy / deploy (push) Successful in 49s

Audit at 22:15 MESZ flagged the conventional sum (lignite + hard coal
+ gas + nuclear) as 19.1 GW in the widget vs 15.65 GW in reality. The
breakdown showed the gap was Energy-Charts' `Fossil gas` (6.9 GW)
which bundles natural gas + GuD + similar, while SMARD's `Erdgas`
filter 4069 (3.8 GW) tracks just natural gas the way the widget label
implies. SMARD is the canonical German grid feed; switching the
primary source resolves the discrepancy directly.

- New `lib/smard.ts` fetches the 11 relevant filter IDs in parallel:
  conventional (1223/4070/4069/1224), wind (4067/1225), solar (1226),
  hydro (1228), biomass (4066), other-conventional + pumped storage
  (1227/4071, surfaced separately), load (410). Two-step protocol
  (index.json → archive.json) handled inside; output is MW (MWh × 4)
  aligned to one common slot timestamp so every value on screen comes
  from the same point in time.
- Aggregator route uses SMARD for production + load, Energy-Charts
  only for cross-border saldo + day-ahead prices (where SMARD has no
  convenient single-call endpoint). `dataSource: "smard" |
  "energy-charts"` flag travels in the response so the widget can
  attribute the numbers and fall back gracefully when SMARD is down.
- StrommixBlock gets a "Werte prüfen" disclosure that lists every
  component (wind onshore + offshore, solar, the four conventional
  buckets, biomass, hydro, load) with its MW value and the slot
  timestamp + data source. Fact-check users can verify the addition
  themselves now without asking.

Verified live: SMARD @ 21:00 UTC = lignite 8484 + hard coal 3480 +
gas 3811 + nuclear 0 = 15.78 GW conventional. Matches the user's
ground-truth 15.65 GW within sampling noise.
This commit is contained in:
Peter Meier
2026-05-04 23:47:52 +02:00
parent f4e4abd978
commit 96cd9e9c57
5 changed files with 290 additions and 62 deletions
@@ -78,6 +78,12 @@
"content-copy": {
"body": "<path fill=\"currentColor\" d=\"M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12z\"/>"
},
"transmission-tower": {
"body": "<path fill=\"currentColor\" d=\"m8.28 5.45l-1.78-.9L7.76 2h8.47l1.27 2.55l-1.78.89L15 4H9zM18.62 8h-4.53l-.79-3h-2.6l-.79 3H5.38L4.1 10.55l1.79.89l.73-1.44h10.76l.72 1.45l1.79-.89zm-.85 14H15.7l-.24-.9L12 15.9l-3.47 5.2l-.23.9H6.23l2.89-11h2.07l-.36 1.35L12 14.1l1.16-1.75l-.35-1.35h2.07zm-6.37-7l-.9-1.35l-1.18 4.48zm3.28 3.12l-1.18-4.48l-.9 1.36z\"/>"
},
"cloud-off-outline": {
"body": "<path fill=\"currentColor\" d=\"M19.8 22.6L17.15 20H6.5q-2.3 0-3.9-1.6T1 14.5q0-1.92 1.19-3.42q1.19-1.51 3.06-1.93q.08-.2.15-.39q.1-.19.15-.41L1.4 4.2l1.4-1.4l18.4 18.4M6.5 18h8.65L7.1 9.95q-.05.28-.07.55q-.03.23-.03.5h-.5q-1.45 0-2.47 1.03Q3 13.05 3 14.5T4.03 17q1.02 1 2.47 1m15.1.75l-1.45-1.4q.43-.35.64-.81T21 15.5q0-1.05-.73-1.77q-.72-.73-1.77-.73H17v-2q0-2.07-1.46-3.54Q14.08 6 12 6q-.67 0-1.3.16q-.63.17-1.2.52L8.05 5.23q.88-.6 1.86-.92Q10.9 4 12 4q2.93 0 4.96 2.04Q19 8.07 19 11q1.73.2 2.86 1.5q1.14 1.28 1.14 3q0 1-.37 1.81q-.38.84-1.03 1.44m-6.77-6.72\"/>"
},
"play": {
"body": "<path fill=\"currentColor\" d=\"M8 5.14v14l11-7z\"/>"
},