fix(chargers): isolate car plans and preserve composed measurements - #4934
Closed
mgazza wants to merge 2 commits into
Closed
fix(chargers): isolate car plans and preserve composed measurements#4934mgazza wants to merge 2 commits into
mgazza wants to merge 2 commits into
Conversation
Predbat has no charger concept - only a flat, index-keyed list of "cars" (car_n, num_cars) where each index is really a car-charger pair. Five integrations autoconfigure into the same shared args, and they collide. Two distinct defects: 1. List replacement. Gateway, GivEnergy Cloud, Ohme and myenergi each assign their OWN discovered list to car_charging_planned/_energy/ _power. The last component to run wins; every earlier component's chargers vanish from the plan. 2. num_cars is a max, not a sum. Even the raise-only discipline in gecloud cannot compose: one GivEnergy charger plus one Ohme charger yields num_cars=1, and both claim slot 0. This adds apps/predbat/charger_registry.py. Components stop assigning car_charging_* directly and call register_chargers(source, entries) - an atomic, idempotent per-source replace. The registry keys chargers on (source, device_id), allocates a slot each, and materialises the flat args once. Crucially it also exposes slot_for(source, device_id). Every control loop previously assumed its own charger was car 0, or that its Nth charger was car N (myenergi's controlled_zappis docstring stated the invariant outright). Allocating slots across components without fixing those loops would drive a physical charger from another car's plan, so discovery and control are migrated together for all four components. Behaviour changes worth calling out in review: - num_cars is no longer raise-only. It is derived from registered chargers and floored at any value an external source claims, via a new set_external_num_cars() that Octopus and Kraken use for their IOG car counts. It can decrease when a charger source empties. - Charger N is no longer car N. Slots are allocated across all components by (source, device_id) sort, legacy slots first. Adding a source renumbers later chargers, and per-car apps.yaml settings are slot-addressed, so they follow the position. - Hand-written car_charging_* config now composes with autodiscovery instead of being overwritten: it is pre-registered as legacy slots, preserved verbatim (interior holes included), and discovered chargers append after it. Installs on the stock template are unchanged - an unresolved "re:" entry is treated as unconfigured. - set_arg_auto's apps.yaml-override note no longer fires for charger keys, because config is merged rather than discarded. - gateway_evc_control without gateway_evc_automatic now warns once rather than silently doing nothing. - EV commands carry charge_point_id. Older gateway firmware falls back to firstConnected(), so it degrades to the previous behaviour. Known limitations, documented rather than fixed here: the gateway's 6-character entity slug is not collision-proof, so two charge points with matching slug tails share an entity namespace; alphaess still writes car_charging_energy/_power directly and is not migrated; component restart leaves stale registrations, as it left stale args before. Tests: 57 registry tests registered in unit_test.py's TEST_REGISTRY so they run under --quick, plus regressions in the ohme, myenergi, ge_cloud, gateway, kraken and octopus suites.
mgazza
force-pushed
the
feat/charger-registry
branch
from
September 5, 2026 00:24
0b7720e to
569f325
Compare
Collaborator
Author
|
Superseded by #4928 — please close. These fixes are now folded into #4928 ( Everything here is in #4928: the registry allocation version carried from configuration fetch through to plan publication so no control loop acts on a plan built for an older mapping, the per-car published window list isolation, Ohme's retained energy and power contribution, and the legacy/discovered measurement dedupe — with their regressions. The branch is also rebased onto current main. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A charger moved to a different slot by #4928 can consume the previous occupant's published plan. Track the registry allocation version from configuration fetch through plan publication, and make all four charger controls wait for a plan built from the current mapping. Also keep each car's published window list separate: the previous list was shared across loop iterations, so later cars inherited earlier cars' windows.
Fix two measurement regressions: Ohme retains its energy and power contribution when another component registers first or discovery repeats; legacy and discovered measurements of the same charger are counted once. Matching uses the existing exact-entity and bounded manufacturer-serial rules, and legacy measurements are restored when discovery releases them.
Validation:
unit_test.py --quicksuite passed (four slow tests skipped).Slot numbering still follows the ordering documented in #4928; adding a charger may require adjusting per-car settings. This follow-up targets
feat/charger-registry, keeping the review fixes separate from the original feature.