fix(strommix): per-field fallback to Energy-Charts when SMARD value missing
The widget rendered "Keine gültigen Live-Werte" the moment SMARD's load filter (id 410) lagged behind the production filters by even one slot — the aggregator coalesced "filter unavailable" with "filter returned 0" and the percent calculation refused to divide by zero. Three changes: 1. SmardSnapshot.values now uses `number | null` so callers can tell "filter genuinely missing" apart from "filter reported zero" (e.g. solar at night, decommissioned nuclear). 2. Aggregator pulls Energy-Charts (CMS strommix_de) in parallel and uses it as a per-field fallback for any SMARD null. New `dataSource: "smard+energy-charts"` flag travels in the response so the attribution stays honest. Pure SMARD when everything resolves; pure Energy-Charts when SMARD is entirely down; the hybrid label for the common case where only load drops out. 3. Widget renders the production breakdown + context row + price row even when the percentage is unavailable, with a clear "Lastwert von SMARD gerade nicht verfügbar" hint instead of going blank.
This commit is contained in:
+8
-4
@@ -116,8 +116,12 @@ export type SmardSnapshot = {
|
||||
* set, so every value is from a slot that all filters have reported.
|
||||
* Unix seconds (not ms). */
|
||||
measuredAtUnix: number;
|
||||
/** Average MW for each filter at the aligned slot. Missing filters → 0. */
|
||||
values: Record<SmardFilter, number>;
|
||||
/** Average MW for each filter at the aligned slot. `null` means the
|
||||
* filter could not be resolved (404, all-null series, fetch error)
|
||||
* — distinguished from a genuine zero so callers can choose a
|
||||
* fallback source per-field instead of ignoring real zeroes
|
||||
* (e.g. solar at night, nuclear in DE). */
|
||||
values: Record<SmardFilter, number | null>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -174,9 +178,9 @@ export async function fetchSmardSnapshot(
|
||||
})
|
||||
);
|
||||
|
||||
const values = {} as Record<SmardFilter, number>;
|
||||
const values = {} as Record<SmardFilter, number | null>;
|
||||
for (const key of Object.keys(SMARD_FILTERS) as SmardFilter[]) {
|
||||
values[key] = 0;
|
||||
values[key] = null;
|
||||
}
|
||||
for (const [key, mwh] of aligned) {
|
||||
if (mwh != null) {
|
||||
|
||||
Reference in New Issue
Block a user