Skip to content

fix(web): metrics dashboard SoC chart text freezes on first-load value#4308

Open
chalfontchubby wants to merge 2 commits into
springfall2008:mainfrom
chalfontchubby:fix/metrics-soc-chart-refresh
Open

fix(web): metrics dashboard SoC chart text freezes on first-load value#4308
chalfontchubby wants to merge 2 commits into
springfall2008:mainfrom
chalfontchubby:fix/metrics-soc-chart-refresh

Conversation

@chalfontchubby

Copy link
Copy Markdown
Collaborator

Summary

Fixes #4151. The battery SoC doughnut chart's center text (percentage and kWh figures) is drawn by a Chart.js afterDraw plugin registered once in mdInitSOCChart. That plugin closed over the pct/d values from the moment the chart was first created. On each 30s refresh, mdUpdateSOCChart only mutates the existing chart's data array and calls .update() - it never recreates the chart (mdRenderAll only calls mdInitSOCChart again if mdSocChart doesn't exist yet) - so the doughnut ring's fill proportion updated correctly but the on-screen number text stayed frozen at the first-load reading, while every other card on the page (Health, Cost, API, Solar) re-renders fresh from the latest data on every refresh.

Split out from #4288, which originally bundled this with two unrelated fixes.

Changes

  • apps/predbat/web_metrics_dashboard.py: the afterDraw plugin now reads chart.data.datasets[0].data[0] for the percentage (already correctly updated by mdUpdateSOCChart) and the MD_DATA global for the kWh figures (already correctly reassigned on every refresh), instead of the stale closed-over values.
  • apps/predbat/tests/test_metrics_dashboard_soc_refresh.py: no JS execution/browser test infra exists in this codebase, so this checks the generated JS source itself reads from chart.data/MD_DATA rather than the closure parameters, to catch a regression back to the same bug shape.

Test plan

  • ./run_all --test metrics_dashboard_soc_refresh - new test passes
  • ./run_all --quick - full quick suite passes (611 tests, 0 failures)
  • ./run_pre_commit - clean (ruff, black, cspell, markdownlint)

🤖 Implemented with Claude Code, disclosed per repo convention.

The battery SoC doughnut chart's center text (percentage and kWh figures)
is drawn by a Chart.js afterDraw plugin registered once in mdInitSOCChart.
That plugin closed over the pct/d values from the moment the chart was
first created. On each 30s refresh, mdUpdateSOCChart only mutates the
existing chart's data array and calls .update() - it never recreates the
chart (mdRenderAll only calls mdInitSOCChart again if mdSocChart doesn't
exist yet) - so the doughnut ring's fill proportion updated correctly but
the on-screen number text stayed frozen at the first-load reading, while
every other card on the page (Health, Cost, API, Solar) re-renders fresh
from the latest data on every refresh. Fixes springfall2008#4151.

The afterDraw plugin now reads chart.data.datasets[0].data[0] for the
percentage (already correctly updated by mdUpdateSOCChart) and the
MD_DATA global for the kWh figures (already correctly reassigned on every
refresh), instead of the stale closed-over values.

No JS execution/browser test infra exists in this codebase, so this can't
run the embedded JavaScript and check actual canvas output. Added a
structural test instead, checking the generated JS source itself reads
from chart.data/MD_DATA rather than the closure parameters, to catch a
regression back to the same bug shape.

🤖 Implemented with Claude Code, disclosed per repo convention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes the Metrics Dashboard battery SoC doughnut chart center text not updating on periodic refresh by removing stale closure-captured values in the Chart.js afterDraw plugin and instead reading live values from the chart dataset and current MD_DATA. Adds a regression test that inspects the generated JS source to ensure the live-data reads are present, and wires the test into the unit test runner.

Changes:

  • Update the Chart.js afterDraw plugin to read the live percentage from chart.data.datasets[0].data[0] and kWh figures from MD_DATA.
  • Add a unit test that validates the generated dashboard JS references live data sources (rather than closure variables).
  • Register the new test in apps/predbat/unit_test.py.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
apps/predbat/web_metrics_dashboard.py Updates the SoC chart center-text drawing logic to read live values on refresh.
apps/predbat/unit_test.py Registers the new metrics-dashboard SoC refresh regression test.
apps/predbat/tests/test_metrics_dashboard_soc_refresh.py Adds a source-based regression test to prevent reintroducing the stale-closure bug shape.

Comment on lines +44 to +45
assert "chart.data.datasets[0].data[0]" in plugin_block, "afterDraw should read the live percentage from the chart's own current data, not a closed-over value"
assert "MD_DATA.battery_soc_kwh" in plugin_block, "afterDraw should read the live kWh figure from the MD_DATA global, not a closed-over value"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — added assertions that the pre-fix stale-closure reads (mdFmt(pct,, d.battery_soc_kwh, d.battery_max_kwh) are gone from the plugin block, not just that the new reads are present. Verified it actually catches a partial revert: temporarily reintroduced just the pct half of the original bug and confirmed the new assertion fails where the old test wouldn't have.

…the new reads present

Copilot review on springfall2008#4308: the test only checked the new live-data reads
(chart.data.datasets[0].data[0], MD_DATA.battery_soc_kwh) were present,
not that the old closed-over reads (pct, d.battery_soc_kwh/battery_max_kwh)
were actually removed - a partial revert of either half would still
pass. Verified by temporarily reintroducing just the pct half of the
original bug: the new assertion catches it, the old test wouldn't have.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Metrics battery SoC does not update when page left displayed

2 participants