Sigenergy: let Axle keep the inverter during its events (option B for #4454) - #4456
Sigenergy: let Axle keep the inverter during its events (option B for #4454)#4456mgazza wants to merge 1 commit into
Conversation
…vents Predbat already has an axle_control option: when it is set and an Axle event is active, Fetch.fetch_config_options() raises set_read_only_axle so Predbat stands down and lets Axle drive the battery. That flag was only ever consumed by execute.py and output.py, so it never reached the Sigenergy component. The result on Sigenergy is that the stand-down does not work. VPP mode (Predbat) and the NorthBound Interface (Axle) are mutually exclusive, and _manage_vpp_registration reads the user-facing switch.predbat_set_read_only rather than the effective read-only state — so it never learned Axle had the floor and pulled the system back into VPP, evicting Axle mid-dispatch. Observed on a live system on 2026-08-06: Axle took the inverter into Northbound Integration at 19:35:18 and it was back in VPP at 19:40:12. This wires the existing flag through: - _axle_has_control() reads set_read_only_axle from the parent - during an event the operating mode is left exactly as it is. If Axle has moved the system to NBI it stays there; if the event has started but Axle has not switched yet, do not drop to MSC either — that hands control to the owner's app rather than to Axle - battery commands are suppressed for the same window, so Predbat is not issuing charge/discharge at an inverter Axle is dispatching - when the event ends, VPP is reclaimed on the next check and that is logged - stop reporting a system in NBI as pending_approval. The SaaS UI renders that as an amber "approve this in the Sigenergy app" banner, so every Axle event told the user to approve something that needed no approval Behaviour is unchanged unless axle_control is enabled — without it Predbat keeps ownership and reclaims VPP exactly as before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Customer-impact tracking and fleet scope: Predictive-Cloud-Ltd/predbat-saas#1591 (private). Alternative approach: #4455. |
|
Superseded by #4457. These two were opened as mutually-exclusive alternatives — Predbat keeps the inverter, or Axle does. That framing was wrong. A code review found that this PR's faster reclaim actively defeats the The real either/or was never in the code: it is the policy question of whether #4457 combines both, plus fixes for the three review findings (the stale |
What this does
Lets Axle keep the Sigenergy inverter for the duration of its events, by finishing a feature that already exists.
Predbat already has an
axle_controloption: when it is set and an Axle event is active,Fetch.fetch_config_options()raisesset_read_only_axleso Predbat stands down and lets Axle drive. That flag was only ever consumed byexecute.py:63andoutput.py:955, so it never reached the Sigenergy component.The result is that the stand-down does not work on Sigenergy. VPP mode and the NorthBound Interface are mutually exclusive, and
_manage_vpp_registration()reads the user-facingswitch.predbat_set_read_onlyrather than the effective read-only state — so it never learns Axle has the floor and pulls the system back into VPP, evicting Axle mid-dispatch.Observed live on 2026-08-06: Axle took the inverter into Northbound Integration at 19:35:18 and it was back in VPP at 19:40:12.
Changes
_axle_has_control()readsset_read_only_axlefrom the parent (defensively, so unit tests without aComponentBaseparent still work).pending_approval— same downstream false "approve in app" banner as Sigenergy: make Predbat's ownership of the inverter deliberate (option A for #4454) #4455 fixes.Trade-off
Behaviour is unchanged unless
axle_controlis enabled — without it Predbat keeps ownership and reclaims VPP exactly as before. That makes this safe to merge, but it also means it does nothing on its own:axle_controlis currently not set for any of our fleet, so adopting this position also requires a config/template change.It also means Predbat's own plan for that window becomes redundant — Predbat still ingests the Axle session as an export window via
load_axle_slot()but won't execute it. Worth deciding in #4454 whetheraxle_controlshould also suppress that planning.Tests
4 new tests in
tests/test_sigenergy.py: mode-untouched in both NBI and VPP during an event, controls suppressed, resume-on-event-end, and NBI-not-pending-approval. Full Sigenergy suite 72 pass / 0 fail;axle,fetch_config_optionsandexecutesuites pass;unit_test.py --quickpasses with 0 failures.run_pre_commitclean.