feat(annual): warn when a solar kWp figure looks like Watts was entered - #4860
Open
springfall2008 wants to merge 2 commits into
Open
feat(annual): warn when a solar kWp figure looks like Watts was entered#4860springfall2008 wants to merge 2 commits into
springfall2008 wants to merge 2 commits into
Conversation
Co-Authored-By: Claude Code <noreply@anthropic.com>
- config_warnings no longer 500s the annual page on an unconvertible (huge integer) kWp; validate_config now rejects such figures with an actionable AnnualConfigError instead of a bare OverflowError - quoted numeric kWp strings (hand-edited YAML) now warn; NaN/inf are rejected by validation instead of slipping past every bound - the live JS hint thresholds per array rather than the total, matching the server's per-array kWp-only rule and giving the right conversion - render_form normalises dict-form solar instead of crashing; warning names the form's 1-based array label; solar shape unwrap shared - annual_cli surfaces config_warnings so headless runs are not silent Co-Authored-By: Claude Code <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The behavior change is intentionally non-blocking, consistently surfaced across web/CLI, and is backed by targeted tests; remaining feedback is limited to minor docstring wording/grammar.
Pull request overview
Adds a non-blocking “sanity warning” when an annual solar array kWp value looks implausibly large (likely Wp entered into a kWp field), and surfaces that warning consistently in the annual web form (server-rendered banner + live client-side hint) and the annual CLI.
Changes:
- Introduce
SOLAR_KWP_SOFT_LIMITandconfig_warnings()to emit soft warnings for suspicious solarkwpvalues while still accepting them as-is. - Wire warnings into the annual web UI rendering, plus inject the server limit into the JS so the client-side hint and server warning can’t drift.
- Add CLI warning output and extend unit tests to cover boundary cases, indexing, dict-form solar normalization, and numeric edge cases (NaN/inf/overflow).
File summaries
| File | Description |
|---|---|
| apps/predbat/web_annual.py | Renders non-blocking config warnings above the form and adds a live per-array hint in the “Total kWp” note; normalizes dict-form solar to a list for rendering. |
| apps/predbat/annual.py | Adds SOLAR_KWP_SOFT_LIMIT, improves numeric validation (finite check + overflow handling), and introduces config_warnings() plus helpers. |
| apps/predbat/annual_cli.py | Logs config_warnings() output so headless runs also surface likely config mistakes. |
| apps/predbat/tests/test_web_annual.py | Adds coverage for warning rendering, dict-form solar rendering, JS limit injection, and html_annual() wiring. |
| apps/predbat/tests/test_annual_config.py | Adds coverage for NaN/inf rejection and comprehensive config_warnings() behavior (threshold, indexing, junk tolerance, dict-form). |
Review details
Suppressed comments (1)
apps/predbat/annual.py:515
- Minor grammar issue in the _numeric_or_none() docstring: “a value validation will reject has” reads as a broken phrase.
Mirrors _require_number()'s coercion (numeric strings like the quoted figures a
hand-edited YAML or a stored form round-trip can carry are accepted) but instead
of raising, anything unusable returns None for the caller to skip: this is a
warning pass, and a value validation will reject has its own AnnualConfigError.
"""
- Files reviewed: 5/5 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+492
to
+498
| def _solar_entries(raw): | ||
| """Return solar entries as a list, or None when the value is neither a mapping nor a list of them. | ||
|
|
||
| validate_config accepts a single array as a bare mapping (the wrapped YAML form | ||
| ``solar: {kwp: ...}``) as well as a list; every reader of this field wants the | ||
| same normalisation, so it lives here rather than being re-derived per caller. | ||
| """ |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
This is an automated draft PR generated from issue #4858 — a maintainer should review it before merging.
Fixes #4858
Summary
Adds a soft, non-blocking warning when a solar array's peak power exceeds 100 kWp (
SOLAR_KWP_SOFT_LIMITinannual.py), the size at which a figure entered in the kWp field is more likely Watts typed by mistake — "6000" meaning 6,000 Wp — than a real array. The value is still accepted and modelled exactly as typed, since genuine >100 kWp commercial installations exist; the warning just questions it.Two surfaces, one threshold:
config_warnings()inannual.py(paired with, but separate from,validate_config()) renders an indexed warning above the form whenever the config is re-rendered after save, run, array add/remove or reset — e.g.annual.solar[0]: peak power 6000 kWp is far larger than a typical home array. If you entered Watts (Wp) rather than kWp, that is 6 kWp.Testing
run_all --test annual_configand--test web_annual_form(plustools/triage_test.shfor both): all pass, including new cases covering the limit boundary (100 no / 101 yes), multi-array indexing, panels-mode exemption, junk-input tolerance, form rendering with/without the warning, and that an oversized figure still validates and runs../run_pre_commit: all hooks pass.Notes
Approach follows the automated triage of #4858: soft warning rather than hard rejection, threshold chosen at the low end of the 100-200 range the reporter suggested.