fix(heatpump-dhw-loading): dedupe scrape-residue series (broken scatter, 8x stat) #276

Merged
k.renner merged 1 commits from claude-bot/dash-heatpump-dhw-loading into master 2026-07-17 11:19:50 +00:00
Member

Before

before

After

after

Review report

This dashboard is conceptually sound — it was built after the open3e migration, uses the current entity names, and the panel design (scatter of loading power vs. outside temp, period average, two supporting time series) genuinely answers the question in the title. It had ONE real bug, and it was severe enough to break rendering:

  1. [critical] Duplicate scrape-residue series break all four panels. ✅ FIXED — every target queried the raw metric (homeassistant_sensor_power_w{entity="sensor.vitocal_dhw_loading_power"} / homeassistant_sensor_temperature_celsius{entity="sensor.vitocal_250_a_vitocal_outside_temperature"}). Over the default 90d window each of those returns ~12 series: two scrape jobs (home-assistant via proxy:8124 and home-assistant-bgp via :8123 — the duplicate-scrape bug fixed 2026-07-16) × six pod lifetimes. Consequences visible in the BEFORE shot:

    • Scatter panel: the join-by-Time transformation got 24 identically-named fields and rendered no points at all.
    • "Ø Ladeleistung" stat: eight conflicting values (290 W … 2.95 kW) instead of one.
    • Both time series: rainbow duplicates of one logical series.

    Fix: wrapped all five targets in max by (entity) (…). Values of the overlapping duplicate jobs were near-identical (e.g. 1059 W vs 1060 W at the same instant), so max is lossless. Stat panel now shows a single Ø of 968 W and the scatter renders a proper point cloud. Note the residue will keep polluting 90d windows until mid-October, so the defensive aggregation is warranted even though only one job scrapes today.

  2. [info, no change] sensor.vitocal_dhw_loading_power is currently unavailable in HA — that is by design (template sensor only exists during an active DHW loading; the metric drops out of Prometheus otherwise, verified empirically). The stat's range-query mean therefore averages only over loading periods, which matches the panel title. instant: true would be wrong here — no change made.

  3. [info, no change] Data only starts ~2026-07-03. Both entities are new since the ViCare→open3e migration, so the 90d window is mostly empty on the left. Expected; it fills up over time, and the now-90d default matches the "builds up with every loading" intent.

  4. [minor, not fixed] Scatter shows a row of 0 W points at 26–32 °C. These are real samples (compressor pauses/ramp within an active loading window), so I left them in — filtering them out would hide real behaviour. If you prefer a cleaner correlation view, I can add > 0 to the scatter target only. ❓ QUESTION — want that?

Units (W / °C), axis labels, legend naming, thresholds and layout are all sane; no other changes needed.

Verification

  • sensor.vitocal_250_a_vitocal_outside_temperature: live in Prometheus (20.5 °C at check time), single series today.
  • sensor.vitocal_dhw_loading_power: exists in HA (state unavailable, device_class power, unit W); count_over_time(...[90d]) confirms ~3.4k samples spread over 12 duplicate series; last_over_time values 0–2951 W are plausible for a Vitocal 250-A DHW load.
  • max by (entity) (…) verified against live Prometheus: collapses to exactly 1 series per entity, range query 07-01→07-17 returns plausible values (0–2831 W).
  • AFTER screenshot rendered via temp preview uid heatpump-dhw-loading-preview (deleted again afterwards).
## Before ![before](https://gitea.renner.uno/attachments/623ae0fe-997b-49fc-8b81-4b5da28dc9e5) ## After ![after](https://gitea.renner.uno/attachments/3f4cd29d-9363-4c50-aee2-6bd66ba96083) ## Review report This dashboard is conceptually sound — it was built after the open3e migration, uses the current entity names, and the panel design (scatter of loading power vs. outside temp, period average, two supporting time series) genuinely answers the question in the title. It had ONE real bug, and it was severe enough to break rendering: 1. **[critical] Duplicate scrape-residue series break all four panels.** ✅ FIXED — every target queried the raw metric (`homeassistant_sensor_power_w{entity="sensor.vitocal_dhw_loading_power"}` / `homeassistant_sensor_temperature_celsius{entity="sensor.vitocal_250_a_vitocal_outside_temperature"}`). Over the default 90d window each of those returns ~12 series: two scrape jobs (`home-assistant` via proxy:8124 and `home-assistant-bgp` via :8123 — the duplicate-scrape bug fixed 2026-07-16) × six pod lifetimes. Consequences visible in the BEFORE shot: - Scatter panel: the join-by-Time transformation got 24 identically-named fields and rendered **no points at all**. - "Ø Ladeleistung" stat: **eight** conflicting values (290 W … 2.95 kW) instead of one. - Both time series: rainbow duplicates of one logical series. Fix: wrapped all five targets in `max by (entity) (…)`. Values of the overlapping duplicate jobs were near-identical (e.g. 1059 W vs 1060 W at the same instant), so `max` is lossless. Stat panel now shows a single Ø of 968 W and the scatter renders a proper point cloud. Note the residue will keep polluting 90d windows until mid-October, so the defensive aggregation is warranted even though only one job scrapes today. 2. **[info, no change] `sensor.vitocal_dhw_loading_power` is currently `unavailable` in HA — that is by design** (template sensor only exists during an active DHW loading; the metric drops out of Prometheus otherwise, verified empirically). The stat's range-query mean therefore averages only over loading periods, which matches the panel title. `instant: true` would be wrong here — no change made. 3. **[info, no change] Data only starts ~2026-07-03.** Both entities are new since the ViCare→open3e migration, so the 90d window is mostly empty on the left. Expected; it fills up over time, and the `now-90d` default matches the "builds up with every loading" intent. 4. **[minor, not fixed] Scatter shows a row of 0 W points** at 26–32 °C. These are real samples (compressor pauses/ramp within an active loading window), so I left them in — filtering them out would hide real behaviour. If you prefer a cleaner correlation view, I can add `> 0` to the scatter target only. ❓ QUESTION — want that? Units (W / °C), axis labels, legend naming, thresholds and layout are all sane; no other changes needed. ## Verification - `sensor.vitocal_250_a_vitocal_outside_temperature`: live in Prometheus (20.5 °C at check time), single series today. - `sensor.vitocal_dhw_loading_power`: exists in HA (state `unavailable`, device_class power, unit W); `count_over_time(...[90d])` confirms ~3.4k samples spread over 12 duplicate series; `last_over_time` values 0–2951 W are plausible for a Vitocal 250-A DHW load. - `max by (entity) (…)` verified against live Prometheus: collapses to exactly 1 series per entity, range query 07-01→07-17 returns plausible values (0–2831 W). - AFTER screenshot rendered via temp preview uid `heatpump-dhw-loading-preview` (deleted again afterwards).
claude-bot added 1 commit 2026-07-16 22:22:28 +00:00
All four panels queried raw HA metrics that still carry ~12 duplicate
series per entity in the 90d window (two scrape jobs x six pod
lifetimes; the duplicate-scrape bug was fixed 2026-07-16 but the
residue stays in range queries until it ages out). This broke the
scatter join (no points rendered), made the stat panel show 8
conflicting averages, and drew rainbow duplicates in both time series.

Wrapping every target in max by (entity) (...) collapses the residue
to one series per entity; values between the duplicate jobs were
near-identical, so max is lossless.
k.renner merged commit 5cdec44ed6 into master 2026-07-17 11:19:50 +00:00
Sign in to join this conversation.