The Summary cards labelled `metered_import` / `metered_export` as "(kWh)", but
both fields are monetary totals (Σ import_cost / Σ export_revenue). Today's
page therefore showed "Import 1.339 kWh" when the meter had actually imported
4.188 kWh — the 1.339 was EUR. Cross-checked against the DSMR cumulative
registers and Home Assistant: our energy figures were correct all along, only
the label was wrong.
summarize() now also aggregates the metered energy, reusing the already-fetched
non-degraded rows so no extra query is issued:
metered_import_kwh = Σ (d1_kwh + d2_kwh)
metered_export_kwh = Σ (r1_kwh + r2_kwh)
The Import/Export cards show kWh as the headline figure and keep the monetary
equivalent as a sub-line, so the split between energy cost and standing
charges/credits behind total_payable stays visible.
The `_kwh` suffix is now the only thing separating energy from money in this
payload, so the docstrings on both summarize() and SummaryResponse call that
out explicitly.
app/integrations/expose.py reads only the money keys, so the HA outbound
sensors are unaffected by the additive fields.
- routes/api/energy.py + schemas/energy.py: GET prices (tibber points or manual
tariff, buy/sell consistent with the pricing strategies), GET costs (time
window + limit, ascending), GET costs/summary (summarize passthrough), GET
dsmr/latest, POST costs/recompute (idempotent, <=366d guard, CSRF), POST
tibber/test (three-state, token never echoed, CSRF).
- main.py registers router; OpenAPI re-exported; tests for all endpoints.