Skip to content

fix(inverter): stop holds commanding a grid charge on charge-target inverters - #4687

Open
romain-intel wants to merge 1 commit into
springfall2008:mainfrom
romain-intel:pr/hold-not-grid-charge
Open

fix(inverter): stop holds commanding a grid charge on charge-target inverters#4687
romain-intel wants to merge 1 commit into
springfall2008:mainfrom
romain-intel:pr/hold-not-grid-charge

Conversation

@romain-intel

Copy link
Copy Markdown
Contributor

Predbat holds the battery by writing a reserve one percent above the current SoC, which stops discharge on inverters that defend the reserve passively. The Powerwall instead treats the reserve as a level to charge towards, so every hold - freeze charge, Hold for car, Hold for iBoost - was a grid import request.

Adds a reserve_is_charge_target inverter capability (TESLA only; every other inverter definition is unchanged and reads the default via .get). When set:

  • hold_reserve_percent() holds exactly at the level instead of one above it
  • adjust_reserve() refuses to write a reserve above the current SoC at all, so the bug class is impossible regardless of what a caller asks for
  • freeze targets use a new calc_percent_limit_floor(), because rounding to nearest turns a 61.6% SoC into a 62% target - the same off-by-one by another route

Also fixes a related divergence in the Teslemetry scheduler emulator, which decided device commands from its own Fleet live_status poll rather than the SoC Predbat planned against (different on a site with local monitoring), and could replay a persisted idle reserve above SoC after a restart.

Refs #4424, #4432, #4440

…nverters

Predbat holds the battery by writing a reserve one percent above the current
SoC, which stops discharge on inverters that defend the reserve passively. The
Powerwall instead treats the reserve as a level to charge towards, so every
hold - freeze charge, Hold for car, Hold for iBoost - was a grid import request.

Adds a reserve_is_charge_target inverter capability (TESLA only; every other
inverter definition is unchanged and reads the default via .get). When set:

- hold_reserve_percent() holds exactly at the level instead of one above it
- adjust_reserve() refuses to write a reserve above the current SoC at all,
  so the bug class is impossible regardless of what a caller asks for
- freeze targets use a new calc_percent_limit_floor(), because rounding to
  nearest turns a 61.6% SoC into a 62% target - the same off-by-one by
  another route

Also fixes a related divergence in the Teslemetry scheduler emulator, which
decided device commands from its own Fleet live_status poll rather than the
SoC Predbat planned against (different on a site with local monitoring), and
could replay a persisted idle reserve above SoC after a restart.

Refs springfall2008#4424, springfall2008#4432, springfall2008#4440

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit d0082036754ace1cf05ebd2c624ba48e336379ed)
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