Skip to content

fix(gateway): read car battery size per slot as a float - #5117

Open
mgazza wants to merge 1 commit into
mainfrom
fix/gateway-car-battery-size
Open

mgazza wants to merge 1 commit into
mainfrom
fix/gateway-car-battery-size

Conversation

@mgazza

@mgazza mgazza commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

Problem

When a gateway EV charger doesn't report SoC, the gateway estimates it from the session energy and car_charging_battery_size. It reads that arg with an int default and no index:

battery_size_kwh = self.get_arg("car_charging_battery_size", 100)

car_charging_battery_size is a per-car arg (entries: num_cars), so this fails two ways:

  • A list such as [10.5] or [sensor.my_car_battery_size] fails int coercion. get_arg then logs Return bad int value [...] and sets had_errors on every telemetry update, so the warning sticks in the status. It falls back to 100 kWh, and the SoC estimate is off by the ratio of the real battery to 100.
  • A fractional size such as 10.5 kWh is truncated to 10 by the int default.

The planner already reads this arg with 100.0, index=car_n (fetch.py), so the gateway was the only unindexed reader.

Fix

battery_size_kwh = self.get_arg("car_charging_battery_size", 100.0, index=0)

Gateway EV auto-config places the charger in car slot 0, so read that slot with a float default. A scalar value still resolves as before, because index 0 on a non-list is a no-op.

Tests

The existing TestEvTelemetry tests replace get_arg with a lambda, so they can't see how the value is resolved. The new test_ev_soc_battery_size_through_get_arg runs _inject_ev_entities against the real PredBat.get_arg for four forms of the arg:

  • a per-car list of numbers;
  • a per-car list of entity ids;
  • a single entity id;
  • a single fractional number.

Each must give 50% for 5.25 kWh delivered into a 10.5 kWh battery, without setting had_errors. It runs from run_gateway_tests when a PredBat is passed, and restores the args, entity and status it touches.

  • ./run_all --test gateway: passes, including the new test.
  • Against the previous line, the new test fails: expected SoC 50.0 from a 10.5 kWh battery, got 5.2.
  • pre-commit (ruff, black, cspell) passes on both files.

🤖 Generated with Claude Code

The gateway's SoC estimate for chargers that do not report SoC read
car_charging_battery_size with an int default and no index. The arg is a
per-car list (entries: num_cars), so:

- a list, e.g. [10.5] or a list of entity ids, failed int coercion, logged
  "Return bad int value" every telemetry update, set had_errors, and fell
  back to 100 kWh;
- a fractional size such as 10.5 kWh was truncated to 10.

Read slot 0, where gateway auto-config places the charger, with a float
default. A scalar value still resolves as before.

The new test drives the gateway through the real get_arg rather than a stub,
for a per-car number list, a per-car entity-pointer list, a single entity
pointer and a single fractional number; it fails against the previous line.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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