Skip to content

Sigenergy: make Predbat's ownership of the inverter deliberate (option A for #4454) - #4455

Closed
mgazza wants to merge 1 commit into
mainfrom
feat/sigenergy-predbat-owns-vpp
Closed

Sigenergy: make Predbat's ownership of the inverter deliberate (option A for #4454)#4455
mgazza wants to merge 1 commit into
mainfrom
feat/sigenergy-predbat-owns-vpp

Conversation

@mgazza

@mgazza mgazza commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Option A of two mutually-exclusive alternatives for #4454. Only one of this and the sibling PR should merge.

What this does

Keeps Predbat as the owner of a Sigenergy inverter, but makes that a decision rather than a race.

A Sigenergy accepts one controller at a time, and VPP mode (Predbat) and the NorthBound Interface (Axle's dispatch channel) are mutually exclusive. Today _manage_vpp_registration() runs on the 5-minute poll tick and silently switches the system back to VPP, so an Axle dispatch can hold the inverter for up to 5 minutes before being displaced with no indication of what happened.

Observed live on 2026-08-06: mode went to Northbound Integration at 19:35:18 and back to VPP at 19:40:12 — exactly one poll interval — while the log only said "controls skipped until onboard is approved".

Changes

  • Reclaim VPP every 60s (SIGENERGY_VPP_RECLAIM_INTERVAL) instead of every 300s, so control is never ambiguous for long. set_operating_mode() is an MQTT publish and only fires when the mode is actually wrong, so this costs nothing against the REST rate limit. The onboard_status cache write stays on the 300s cadence.
  • Log the reclaim explicitly, naming the controller being displaced, instead of a generic warning.
  • Stop reporting a contended system as pending_approval. Downstream UIs render that as an amber "approve this in the Sigenergy app" banner, so every Axle event told the user to approve something needing no approval. A system in NBI is fully onboarded.
  • Expose contended_by on the onboard-status sensor so support can tell contention from a genuine onboarding failure.

Predbat already ingests Axle sessions as its own export windows (load_axle_slot()), so events still run — under Predbat's plan rather than Axle's dispatch.

Trade-off

This is the "Predbat always wins" position. It's self-contained and needs no config change, but it does override Axle's schedule on every event. If Axle credits delivery from its own NBI dispatch rather than from meter data, this costs the customer the payment even though the energy flowed. That question is open in #4454.

Tests

4 new tests in tests/test_sigenergy.py: reclaim-from-third-party, contention-not-pending-approval, reclaim-cadence, and the controls-skipped message. Full Sigenergy suite 72 pass / 0 fail; unit_test.py --quick passes with 0 failures. run_pre_commit clean (ruff, black, cspell).

A Sigenergy accepts one controller at a time, and VPP mode (Predbat) and the
NorthBound Interface (Axle's VPP dispatch channel) are mutually exclusive.
Today Predbat wins that contest by accident: _manage_vpp_registration ran on
the 5 minute poll tick and silently switched the system back to VPP, so an
Axle dispatch could hold the inverter for up to 5 minutes before being
displaced with no indication of what had happened.

Observed on a live system on 2026-08-06: mode went to Northbound Integration
at 19:35:18 and back to VPP at 19:40:12 — exactly one poll interval — while
the log only said "controls skipped until onboard is approved".

This keeps Predbat as the owner but makes that a decision rather than a race:

- reclaim VPP every minute instead of every 5, so control is never ambiguous
  for long (set_operating_mode is an MQTT publish and only fires when the mode
  is wrong, so this costs nothing against the REST rate limit)
- log the reclaim explicitly, naming the controller being displaced
- stop reporting a contended system 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 go and approve something that needed no approval
- expose contended_by on the onboard-status sensor so support can tell
  contention apart from a real onboarding failure

Predbat already ingests Axle sessions as its own export windows, so events
still run — under Predbat's plan rather than Axle's dispatch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mgazza

mgazza commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

Customer-impact tracking and fleet scope: Predictive-Cloud-Ltd/predbat-saas#1591 (private). Alternative approach: #4456.

@mgazza

mgazza commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

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 axle_control option, which meant option A had to honour axle_control regardless — and once it does, it contains option B. They were complementary all along, not alternatives.

The real either/or was never in the code: it is the policy question of whether axle_control should be enabled, which #4454 now tracks separately.

#4457 combines both, plus fixes for the three review findings (the stale set_read_only_axle flag on restart, the reclaim defeating axle_control, and the contention marker being cleared before it was ever published).

@mgazza mgazza closed this Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant