fix(fw): EPEX spot price-forecast widget broken — chart doesn't render, shows a bare entry count #222
Labels
No labels
bug
enhancement
in-progress
needs-info
needs-triage
p0
ready-for-agent
ready-for-human
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/nixos#222
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The EPEX spot price-forecast widget on
fw's Home Assistant (added in #218 / closes #217) does not work: instead of a price-forecast chart it shows a single small number, and nothing that looks like a forecast. Root cause is two independent code-level defects, both confirmed from source (the fee/VAT math and the attribute mapping are not the problem — see "What is actually correct" below).Observed behaviour
Root cause
1.
apexcharts-cardis never loaded — HA is in storage mode,customLovelaceModulesonly auto-registers in yaml modeelectricity.nixinstalls the card declaratively:The NixOS module ships and serves the JS correctly —
www/nixos-lovelace-modules→apexcharts-card.jsis symlinked (home-assistant.nix:678-679), so/local/nixos-lovelace-modules/apexcharts-card.js?2.2.3is reachable — and it adds the resource tolovelace.resourcesinconfiguration.yaml(home-assistant.nix:146-151).But that config key is only honoured in yaml mode. The module says so explicitly:
fw's HA runs in the default storage (UI-managed) mode:
lovelace.modedefaults tostorageunlesslovelaceConfig/lovelaceConfigFileis set (home-assistant.nix:431-445), and a repo-wide grep confirms neither is set anywhere inhosts/orutils/. In storage mode HA ignores YAML-definedlovelace.resources— resources must be registered via the UI (Settings → Dashboards → Resources) or.storage/lovelace_resources.⇒ The
custom:apexcharts-cardelement is never registered, so a card oftype: custom:apexcharts-cardcannot render as a chart. This is the "does not look like a forecast" symptom.(Note: the sibling
lovelace-schedulercard inac.nixuses the same mechanism; if it renders today it was registered manually via the UI at some earlier point — the same one-time step apexcharts now needs.)2. The forecast sensor's state is an entry count, not a price
sensor.electricity_price_forecast(electricity.nix:54-72) puts the actual forecast in aforecastattribute and sets its state to the number of future intervals:So whenever this entity is shown as a plain value — an Entities/Sensor card, the sidebar, or an ApexCharts series that has no working
data_generator— you see a small integer (the count of remaining hourly/15-min slots), never a price. This is the "single digits instead of the price" symptom. The price series is only reachable through the card'sdata_generatorreadingentity.attributes.forecast, which cannot fire while defect #1 blocks the card from loading at all.3. Contributing / process: the chart YAML lives only in UI storage, never verified
The chart was pasted by hand into a storage-mode dashboard; the YAML is captured in the #218 PR description but is not in the repo, so it is not reproducible and was never reviewable. PR #218's own "post-merge verification" left "paste the card YAML onto a dashboard" and "confirm interval resolution" as unchecked human follow-ups — i.e. the widget was merged without ever being confirmed working end-to-end. A mis-pasted multi-line
data_generator:also silently breaks the forecast series.What is actually correct (do not "fix" these)
Verified against the deployed
epex_spot4.1.0 source (.../const.py,localization.py,sensor.py):start_time/end_time/price_per_kwhare correct for EUR (ATTR_PRICE_PER_KWH = "price_per_kwh"); this resolves the "open question" from #217.sensor.epex_spot_data_market_priceis already in €/kWh (uom_per_kwh), so(market + fees) × 1.20is dimensionally consistent — no 1000× unit error.sensor.electricity_priceare correct.data_generator: return entity.attributes.forecast.map(...).Not yet verified live
I was blocked from reading the running
fwHA instance (production SSH read requires explicit approval), so I could not confirm the exact on-screen manifestation — i.e. whether the user sees a "Custom element doesn't exist: apexcharts-card" error card (defect #1) or a bare entity showing the count (defect #2). Both are downstream of the same two root causes and the fix is the same. If you want live confirmation before/while fixing, check Developer Tools → States →sensor.electricity_price_forecast: its state should be an integer (the count) andforecastshould be a populated list of{start, price}; also note the interval resolution (hourly vs 15-min).Suggested fix (pick a direction during triage)
Defect #1 must be fixed for the chart to render; #2/#3 decide how robust and reproducible it is.
/local/nixos-lovelace-modules/apexcharts-card.js, type JavaScript Module). Persists in.storage/lovelace_resources. Fixes rendering; card stays in UI storage (still not reproducible).services.home-assistant.lovelaceConfig/ a yamldashboardsentry. This makescustomLovelaceModulesauto-register the resource and moves the card YAML into Nix (fixes #1 and #3 together). Trade-off: a yaml-mode dashboard is no longer UI-editable.data_generator.Acceptance criteria
apexcharts-cardresource is loaded (chart renders; no "Custom element doesn't exist" error).forecastattribute, not a bare number.sensor.electricity_price_forecastconfirmed in Developer Tools (state = count,forecast= populated list; interval resolution noted).fwpre-commit dry-build is green.References
hosts/fw/modules/home-assistant/electricity.nix:54-72(forecast sensor),:25-27(card install)nixos/modules/services/home-automation/home-assistant.nix— resources:146-151, mode default:431-445, yaml-mode-only note:322, www symlink:678-679mampfes/epex_spot4.1.0; keys in.../epex_spot/const.pyCorrection — real root cause found (not the resource, not a code defect)
Diagnosed live with the reporter. The deployed card turned out to be the apexcharts-card demo/example config — the stock template the UI card picker inserts, left unedited:
It ignores the sensor and plots
Math.random()*10+1— random integers 1–10. That random 1–10 data is the "single digits"; two random series is why it "doesn't look like a forecast." The real card YAML from this PR was never pasted in over the demo.This refutes Defect #1 (apexcharts resource not loaded in storage mode)
The resource is loaded from
configuration.yamlviacustomLovelaceModules— confirmed live two ways: (1) HA's Resources UI reports "Your resources are in YAML mode … manage them in configuration.yaml" (i.e. aResourceYAMLCollectionis active), and (2) the card type is selectable from the picker. So on this instance (HA 2026.5.4), a YAML-definedresources:block is honoured regardless of dashboard mode; the "storage mode ignores YAML resources" reasoning (and the module's:322note) does not apply here. Defect #2 (state is an entry count) is real but secondary — it only matters if a card shows the state bare.Actual root cause
The widget was merged with the demo card left in place — the "paste the card YAML onto a dashboard" post-merge step from this PR was never completed (the process gap flagged as the contributing factor is the actual cause).
Fix (applied via UI, no repo change)
Replace the card's YAML with the real config from the PR body (the
entity.attributes.forecast.map(...)version). The card config lives in.storagebecause the dashboard is UI-managed — that is expected and fine.Optional follow-up
Making the card reproducible in Nix requires a yaml-mode dashboard (
lovelaceConfig) — a deliberate, larger change. Track separately only if desired; otherwise this can be closed once the card is replaced.