Repository navigation
fix(car): low-load test needs live load power to be low too before cancelling an Intelligent dispatch - #5462
Merged
Merged
Conversation
…ncelling an Intelligent dispatch (#5461) The Octopus Intelligent slot confirmation cancelled a genuine dispatch while a 7.4kW car was charging in view of the CT: the 5 minute load figure read 4.80kW against a 5.4kW cut-off while the inverter reported 7410W. The 5 minute figure lags a car that is still ramping up, and a cloud inverter's late readings. - A low 5 minute figure now only counts as "not charging" when the live load_power total is also under the cut-off. Live load that is not low, or has no reading, makes the window no evidence either way. - Installs without load_power keep the 5 minute figure alone. - The cut-off drops from 90% to 85% of car_charging_threshold, for a load sensor that under-reads while the battery is charging. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Live-load aggregation omits configured load_power_N sensors, allowing false cancellations on split-load installations.
1 open finding
What changed in this PR
Prevents false Intelligent dispatch cancellations by requiring both averaged and live load to be low.
Changes:
- Adds an 85% low-load threshold and live-load cross-check.
- Treats mixed or unavailable live readings as no evidence.
- Adds documentation and regression tests.
| File | Description |
|---|---|
apps/predbat/const.py |
Defines the 85% factor. |
apps/predbat/plan.py |
Implements live-load evidence checks. |
apps/predbat/tests/test_dynamic_load.py |
Updates threshold commentary. |
apps/predbat/tests/test_dynamic_load_car.py |
Adds live-load regression scenarios. |
docs/car-charging.md |
Documents dispatch-check behavior. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+405
to
+409
| for inverter_n, entity_id in enumerate(entities): | ||
| try: | ||
| power = float(self.resolve_arg("load_power", entity_id, default=None, quiet=True, required_unit="W")) | ||
| except (ValueError, TypeError): | ||
| return True, None |
…e load (#5461) Review of #5462: the live load total read load_power only, while the inverter sums load_power plus the type's extra load_power_N sensors (Solis reports the bypass load on load_power_1). A car visible only on the extra sensor could still read as low live load and have its genuine dispatch cancelled. The total is now summed as Inverter.update_status() sums it; an extra sensor that is set but unreadable leaves no total. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 9, 2026
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.

Fixes #5461.
Problem
With
octopus_intelligent_dynamicon and nocar_charging_nowsensor, the slot confirmation falls back to the house load. It cancelled a genuine dispatch while a 7.4 kW car was charging in view of the CT: the 5-minute load figure read 4.80 kW against a 5.4 kW cut-off, at a moment when the inverter reported 7410 W. Once the slots were cancelled the battery hold was released and the battery discharged into the car.The 5-minute figure lags a car that is still ramping up, and a cloud inverter whose readings arrive late. The load path has no start band, so the ramp window itself can start the grace clock and one more marginal window cancels.
Change
dynamic_load_car_evidence(), a low 5-minute figure only counts as "not charging" when the liveload_powertotal is also under the cut-off.car_charging_threshold(5.1 kW on the 6 kW default), asDYNAMIC_LOAD_CAR_LOW_FACTOR. This gives margin for a load sensor that under-reads while the battery is grid-charging.load_powerkeep the 5-minute figure alone, as before.The live figure is read from the
load_powersensors directly and summed across inverters, becausedynamic_load_car_check()runs beforefetch_inverter_data()and the inverter objects still hold the previous cycle's value. If any inverter's sensor isunknown,unavailableor missing, there is no total.Things to review
dynamic_load_classify()is shared withdynamic_load(), so the 85% factor also moves the publishedload_energy_last_periodstatus: a load between 85% and 90% of the threshold now reads "baseline" where it read "low". The battery-rate 0.9 in the same test is unchanged.car_charging_threshold. Not changed here.Testing
tests/test_dynamic_load_car.py(./run_all --test dynamic_load_car_not_charging): the 4.80 kW / 7410 W case from the issue, both figures low, two inverters summed, unavailable / partly unavailable / missing sensors, noload_power, a cancelled car with high live load, and the 85% boundary on both figures. They failed before the change.apps.yamlsetsload_power, so the module removes it for the older scenarios, which judge the 5-minute figure alone../run_all --quick: all tests passed (4 slow tests skipped).Docs:
docs/car-charging.md, "Checking Intelligent dispatches against the car".🤖 Generated with Claude Code