Repository navigation
Name the configured inverter components when inverter_type is unset (#4990) - #4992
Conversation
…4990) A window read that comes back empty is reported against the inverter's type, but the type is only "GE" because nothing in apps.yaml said otherwise until a component's automatic_config() sets it. On a Solis install a SolisCloud comms failure at startup therefore read as "check the GivEnergy credentials", naming hardware the reporter does not own. When the type was assumed rather than configured, name the inverter components that really are configured and say which of them is in error. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Automated correction to the Testing section above — a maintainer should still review this PR before merging. The PR body says
So the AST/line-length substitute described in the body is superseded — the real gate ran and is green. |
There was a problem hiding this comment.
🟡 Changes recommended
It introduces at least one test-state leakage risk (shared dummy_items mutation not restored) and a hardcoded assumed-type string that should be derived to prevent future drift.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR improves inverter “no data” warning messages when inverter_type was never set in apps.yaml, by naming the actually configured inverter components (and whether they are erroring) instead of attributing the failure to the default assumed GivEnergy type.
Changes:
- Add
Components.inverter_source_status()to enumerate configured inverter components with health states, including load/construct failures. - Update inverter warning text via
Inverter.inverter_source_name()/Inverter.inverter_source_hint()so defaultedinverter_typereports configured components rather than “check GivEnergy credentials”. - Add regression tests covering both the component-status listing and the window-warning wording for unset vs explicitly configured inverter types.
File summaries
| File | Description |
|---|---|
| apps/predbat/components.py | Adds inverter_source_status() to report inverter component names plus health/error state. |
| apps/predbat/inverter.py | Uses component-derived naming/hints in window “returned no data” warnings; tracks whether inverter_type was defaulted. |
| apps/predbat/tests/test_components.py | Adds test coverage for inverter_source_status() output across healthy/erroring/starting/failed components. |
| apps/predbat/tests/test_inverter.py | Adds regression test ensuring warnings don’t misattribute Solis failures to GivEnergy when inverter_type is unset. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…_type, charge-window entity guard, 255-char status clamp Co-Authored-By: Claude Code <noreply@anthropic.com>
|
Automated cleanup failed to complete for this PR - see the triage bot's logs for details. Not retrying automatically; remove |
…dow (#5000) Claude Code does not recognise "glm-5.3-flash:cloud", so it assumed a 200k context window and auto-compacted every run to fit. The model actually takes 1M, so each flow was compacting long before it needed to - and every compaction costs turns, which is a plausible route to the "Reached max turns (150)" that failed the #4992 cleanup on 2026-09-07. claude_env() already sets the Anthropic-compatible overrides that point the CLI at the local Ollama server; it now also sets CLAUDE_CODE_MAX_CONTEXT_TOKENS from a per-model map. Verified end to end: with the variable set, the 200k warning is gone from a real `claude -p` invocation against the same model and endpoint. Keyed by model rather than as a single constant on purpose. Overstating a window is the more damaging error: too low only compacts early, whereas too high lets a request run past what the model will accept and fail outright. A model absent from the map keeps Claude Code's own assumption - wrong but safe - so adding a new model is a deliberate one-line act, not something inherited by default. setdefault rather than assignment, so an operator who exports their own value for a one-off run keeps it. Tests: five new cases covering the known model on both the --ollama and --ollama_review routes, the unknown-model fallback, the operator override, and the no-Ollama path; confirmed to fail with the change reverted. Suite 214 passing, pre-commit clean. Co-authored-by: CI <ci@example.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…et-names-components-4990
|
Automated reply from the triage bot. — cleanup retry completed successfully (supersedes the BOT_FAILED run of 2026-09-07). The previous run's commit 9607205 had already implemented the fixes for the four threads it never replied to (255-char status clamp, shared Quality gate on this branch: |
There was a problem hiding this comment.
🟡 Changes recommended
Five moderate issues remain, including stale inverter-type reporting, lost warning details, and leaked shared test state.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 8/8 changed files
- Comments generated: 5
- Review effort level: Balanced
| if load_error is not None: | ||
| state = "failed to start: {}".format(load_error) |
| name = INVERTER_DEF.get(self.inverter_type, {}).get("name", None) | ||
| if name: | ||
| return name | ||
| components = getattr(self.base, "components", None) | ||
| names = components.inverter_source_names() if components else [] | ||
| return ", ".join(names) if names else self.inverter_type |
This is an automated draft PR generated from issue #4990 — a maintainer should review it before merging.
Fixes #4990
Summary
A window read that returns nothing is reported against the inverter's type, but
inverter_typeis onlyGEbecause nothing in apps.yaml said otherwise — on Solis it isautomatic_config()that sets it, and that only runs once discovery has succeeded. So a SolisCloud comms failure at startup left the type at the GE default and the warning read "check the GivEnergy credentials", naming hardware the reporter does not own and a credential they cannot have got wrong.Following the maintainer's steer on the issue ("say no inverter was set, list the configured inverter components (one or more) and if they are in error or not"):
Components.inverter_source_status()(new) lists every configured inverter component with its state —OK,in error, N errors so far,still starting, no data yet, orfailed to start: <reason>. Components that failed to construct are included even though they are inactive, since those are exactly the ones worth reporting.Inverter.inverter_source_hint()(new) replaces the inline "check the {source} credentials" hint at both the charge-window and export-window sites. When the type was assumed it says so and lists the components instead; an explicitly configured type keeps the original credentials wording, because there the type is the user's own statement about their hardware.Inverter.inverter_source_name()prefers the active component names over the assumedGEdisplay name, so the leading clause names the real source too.Inverter.__init__recordsinverter_type_default, reusing the existing "not set in apps.yaml" check rather than adding a second one.The reported case now produces:
Testing
New tests:
test_components.py::test_inverter_source_status_lists_components_and_errors— covers an erroring component, a healthy one, one still starting, one that failed to load, a non-inverter component that must not be listed, and the empty registry.test_inverter.py::test_window_warning_names_components_when_type_unset— drives a fullupdate_status()with no window data and asserts the status text, for both an unset type (must not say "GivEnergy credentials", must name Solis Cloud API and its error state) and an explicitly configuredGE(unchanged wording).Run green via
tools/triage_test.sh:components,inverter,execute,gateway,solis,component_base,component_health_status,control_ledger,inverter_write_poll.coverage/run_pre_commitcould not be run — this session's permission mode denied it (andcoverage/venv/bin/python -m pre_committoo), so Black/Flake8/interrogate/CSpell have not been executed locally. As a partial substitute I checked the four changed files with an AST/line-length scan: no new lines over 250 characters and no new function or class missing a docstring, and the only unusual words used (unconfigured,SolisCloud) already appear elsewhere in the tree. pre-commit.ci on this PR is the real check.Notes
The
inverter_source_active()/ transient-vs-permanent split this builds on is the one added for #4288/#4179; the "no source is configured at all" branch is untouched.