Skip to content

fix(gateway): bind battery_scaling, battery_rate_max and inverter_time per inverter - #5331

Merged
springfall2008 merged 1 commit into
mainfrom
fix/gateway-per-inverter-args
Oct 2, 2026
Merged

springfall2008 merged 1 commit into
mainfrom
fix/gateway-per-inverter-args

Conversation

@springfall2008

Copy link
Copy Markdown
Owner

Problem

On a PredBat Gateway (Hub) site with two or more primary inverters, GatewayMQTT.automatic_config() bound three per-inverter args to the first inverter only:

self.set_arg("battery_scaling", [f"sensor.{base0}_battery_dod"])
self.set_arg("battery_rate_max", [f"sensor.{base0}_battery_rate_max"])
self.set_arg("inverter_time", [f"sensor.{base0}_inverter_time"])

inverter.py reads all three at index=self.id. So for inverter 1 onwards:

  • Every cycle logs Warn: Out of range index 1 within item battery_rate_max / battery_scaling / inverter_time, and config validation reports 3 errors (… has 1 entries, expected 2 based on num_inverters).
  • battery_rate_max silently falls back to 2600 W. In the field case (2 × GivEnergy AC Gen1 behind a Hub) the hub reports 3000 W for the second inverter, so PredBat planned that battery about 13% slower than it is and sent set_charge_rate power_w: 2600.
  • battery_scaling falls back to 1.0. That happens to match the hub's default 100% depth of discharge, but it isn't read from the hub.
  • inverter_time is never read for that inverter, so its clock-drift check doesn't run.

Every other per-inverter arg (soc_percent, battery_power, charge_rate, inverter_limit, …) is already built in the per-inverter loop. These three were left over from the single-inverter version.

Fix

Build the three lists inside the existing per-inverter loop, so each has one entry per primary inverter, in the same serial-sorted order as soc_percent. The hub already publishes battery_dod, battery_rate_max and inverter_time for every inverter. This was confirmed on the field instance, where both …_23g800_* and …_25g400_* exist with live values. So no gateway-side change is needed.

Single-inverter sites, and the Gateway-coordinated topology where automatic_config picks the Gateway as the sole control target, still get a one-entry list bound to the same serial as before. test_single_inverter_energy_and_health_args and TestBoundEntitiesAreWritten cover those cases and still pass.

Tests

  • New TestAutomaticConfig.test_multi_inverter_battery_args_have_one_entry_per_inverter: two primary inverters, and asserts each of the three args lists both inverters' entities in order. It failed before the fix (battery_scaling had a single entry) and passes after.
  • ./run_all --test gateway: passed.
  • ./run_all --quick: All tests passed (4 slow tests skipped, 80.95s).
  • pre-commit (ruff, black, cspell, whitespace): passed.

🤖 Generated with Claude Code

…e per inverter

automatic_config() built every per-inverter arg in the inverter loop except
these three, which were hard-coded to the first inverter's entity. inverter.py
reads them at index=self.id, so on a hub with two or more primary inverters
inverter 1+ hit "Out of range index 1" every cycle (plus three apps.yaml
validation errors) and silently fell back to defaults: battery_rate_max 2600 W
instead of the hub-reported rate (3000 W on the AC Gen1 field case), battery
scaling 1.0, and no clock-drift check.

The hub already publishes battery_dod, battery_rate_max and inverter_time for
every inverter, so the lists now carry one entry per inverter in the same
serial order as soc_percent. Single-inverter and Gateway-coordinated topologies
still get a one-entry list bound to the same serial as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 1, 2026 09:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The focused fix matches indexed inverter reads and includes appropriate regression coverage.

Review effort: Balanced
Findings: None

What changed in this PR

Fixes Gateway multi-inverter configuration so each inverter receives its own battery and clock entities.

Changes:

  • Builds three per-inverter entity lists in serial-sorted order.
  • Adds regression coverage for two primary inverters.
File Description
apps/​predbat/​gateway.py Binds battery scaling, maximum rate, and inverter time per inverter.
apps/​predbat/​tests/​test_gateway.py Verifies multi-inverter bindings and ordering.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@springfall2008
springfall2008 merged commit fb56428 into main Oct 2, 2026
3 checks passed
@springfall2008
springfall2008 deleted the fix/gateway-per-inverter-args branch October 2, 2026 06:50
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.

2 participants