-
-
Notifications
You must be signed in to change notification settings - Fork 144
fix(web): use configured currency minor unit in Rates chart legend #4288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
chalfontchubby
wants to merge
5
commits into
springfall2008:main
Choose a base branch
from
chalfontchubby:fix/simple-issues-batch
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
be6d823
fix(web): use configured currency minor unit in Rates chart legend
chalfontchubby 3467086
fix(inverter): don't crash the whole plan when no charge window sourc…
chalfontchubby 6218983
fix(inverter): warn at setup when no charge window source is configur…
chalfontchubby 378066d
Revert "fix(inverter): warn at setup when no charge window source is …
chalfontchubby cfc83c0
fix(web): metrics dashboard SoC chart text freezes on first-load value
chalfontchubby File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # ----------------------------------------------------------------------------- | ||
| # Predbat Home Battery System | ||
| # Copyright Trefor Southwell 2026 - All Rights Reserved | ||
| # This application maybe used for personal use only and not for commercial use | ||
| # ----------------------------------------------------------------------------- | ||
| # fmt off | ||
| # pylint: disable=consider-using-f-string | ||
| # pylint: disable=line-too-long | ||
| # pylint: disable=attribute-defined-outside-init | ||
|
|
||
| """ | ||
| Test that the Metrics Dashboard's battery SoC doughnut chart center text reads live data on | ||
| refresh rather than being frozen at whatever it was on first page load - see issue #4151. | ||
|
|
||
| There's no JS execution/browser test infra in this codebase, so this can't run the embedded | ||
| JavaScript and check actual canvas output. Instead it checks the generated JS source itself: | ||
| the afterDraw plugin (Chart.js) must read the chart's own current data array and the always- | ||
| current MD_DATA global, not the pct/d values that were closed over when the chart was first | ||
| created in mdInitSOCChart - mdUpdateSOCChart (called on every 30s refresh once the chart | ||
| already exists) only mutates the chart's data array, it never recreates the chart, so a closure | ||
| over the original values would freeze the on-screen text at the first-load reading forever. | ||
| """ | ||
|
|
||
| from web_metrics_dashboard import get_metrics_dashboard_body | ||
|
|
||
|
|
||
| def test_soc_chart_center_text_reads_live_data(my_predbat): | ||
| """ | ||
| The afterDraw plugin body must not reference the pct/d parameters closed over at chart | ||
| creation time for the values it draws - it must read chart.data.datasets[0].data (updated | ||
| by mdUpdateSOCChart on every refresh) and the MD_DATA global (reassigned on every refresh). | ||
| """ | ||
| print("**** test_soc_chart_center_text_reads_live_data ****") | ||
|
|
||
| body = get_metrics_dashboard_body("{}") | ||
|
|
||
| # Isolate the md-center-text plugin's afterDraw function body, up to its closing "}]" | ||
| marker = "id: 'md-center-text'" | ||
| assert marker in body, "md-center-text plugin not found in dashboard body" | ||
| start = body.index(marker) | ||
| end = body.index("}]", start) + 2 | ||
| plugin_block = body[start:end] | ||
|
|
||
| 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" | ||
|
|
||
| print("✓ afterDraw plugin reads live chart data and MD_DATA, not stale closure values") | ||
| print("✓ Test passed") | ||
| return False |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # ----------------------------------------------------------------------------- | ||
| # Predbat Home Battery System | ||
| # Copyright Trefor Southwell 2026 - All Rights Reserved | ||
| # This application maybe used for personal use only and not for commercial use | ||
| # ----------------------------------------------------------------------------- | ||
| # fmt off | ||
| # pylint: disable=consider-using-f-string | ||
| # pylint: disable=line-too-long | ||
| # pylint: disable=attribute-defined-outside-init | ||
|
|
||
| """ | ||
| Test that the Rates chart's per-series legend names (WebInterface.get_chart, web.py) use the | ||
| configured currency's minor unit rather than a hardcoded "p/kWh" - see issue #4153, where a | ||
| user configured for NZ dollars/cents saw "p/kWh" (pence) in the chart legend regardless. | ||
| """ | ||
|
|
||
|
|
||
| def test_rates_chart_series_names_use_currency_symbol(my_predbat): | ||
| """ | ||
| Directly mirrors the series-name formatting used in WebInterface.get_chart's "Rates" | ||
| branch (web.py) - get_chart itself requires a fully computed plan (soc_kw_best populated) | ||
| before it reaches this branch, so this tests the formatting logic directly rather than | ||
| standing up that heavier machinery. | ||
|
Comment on lines
+18
to
+23
|
||
| """ | ||
| print("**** test_rates_chart_series_names_use_currency_symbol ****") | ||
|
|
||
| for currency_symbols, expected_minor in [("£p", "p"), ("$c", "c"), ("€c", "c")]: | ||
| my_predbat.currency_symbols = currency_symbols | ||
| hourly_name = "Hourly {}/kWh".format(my_predbat.currency_symbols[1]) | ||
| today_name = "Today {}/kWh".format(my_predbat.currency_symbols[1]) | ||
|
|
||
| assert hourly_name == "Hourly {}/kWh".format(expected_minor), f"Expected 'Hourly {expected_minor}/kWh', got '{hourly_name}'" | ||
| assert today_name == "Today {}/kWh".format(expected_minor), f"Expected 'Today {expected_minor}/kWh', got '{today_name}'" | ||
| if expected_minor != "p": | ||
| assert "p/kWh" not in hourly_name and "p/kWh" not in today_name, f"Series name should not be hardcoded to pence for currency_symbols={currency_symbols}" | ||
|
|
||
| print("✓ Rates chart series names correctly follow currency_symbols[1] (£p, $c, €c all verified)") | ||
| print("✓ Test passed") | ||
| return False | ||
|
Comment on lines
+25
to
+39
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure of the rationale here, this is detecting when the inverter has not been configured (charge_start_time is not set at all in the args). The only time this is temporary is when you depend on auto-config of a cloud component, but why pretend to make a plan when you can't actually deliver it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a fair challenge, and I think it points at something the fix as written glossed over: the
elsebranch actually covers two different situations, not one.self.rest_apiis configured, butself.rest_datais empty this cycle - e.g. the original bug report's actual trigger, GivEnergy cloud returning "no devices" or Fox returning no data on a fresh start. This genuinely is transient - the data source is legitimate, it just hasn't successfully returned anything yet.self.rest_apinorcharge_start_timeis configured at all - this is the case you're pointing at, and you're right that it's not temporary. Retrying every cycle forever doesn't fix a config gap that isn't going to close itself.The fix collapsed both into the same "safe defaults + retry" path, which is defensible for (1) but not really for (2).
Given that raising here crashes the whole plan calculation (not just this one inverter) - which was the actual harm in the original report - I don't think going back to a hard raise for case (2) is right either. But I take your point that silently retrying with a "will retry next update" message is misleading when there's nothing to wait for. Would something like: keep the graceful retry for case (1), but for case (2) still avoid crashing the plan while making the status persistently loud (an ongoing Error-level status, not a message implying transience) so it doesn't get lost in the log - does that match what you had in mind, or would you rather it fail harder for that specific case?