Conversation
A hub can briefly report an inverter with an empty serial and no battery block. _needs_reconfigure() counted '' as a newly discovered inverter, automatic_config() then bound inverter 0 to it, and every control command went out with an empty serial and failed its read-back until the real serial reappeared and triggered another re-config. _inject_entities() also published predbat_gateway__* entities for the phantom. - _needs_reconfigure() never treats a serial-less inverter as new. - automatic_config() never binds a serial-less inverter. Such units still count when classifying the topology, so an EMS or Gateway that has not reported its serial yet is not bypassed in favour of its AIOs. If nothing addressable is selected it logs a warning and returns without touching the existing binding, leaving _auto_configured unchanged so a first-run config retries on the next telemetry. - _process_telemetry() treats a status whose inverters all lack a serial like an empty status: the last good status is kept and it does not count as fresh telemetry. - _inject_entities() publishes no per-inverter or inverter_time entities for serial-less inverters. EMS aggregates carry no serial in their names and are still published. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Only GivEnergy discovery reads a unit's serial; the other hub drivers never report one, so their inverters always arrive with serial "". Treating every blank serial as missing would have left those sites with no inverter bound at all. The guard now applies to GivEnergy inverters, EMS and Gateway units only; every other type binds exactly as before. While a GivEnergy EMS or Gateway is listed without its serial, the control point itself is uncertain, so auto-config skips that status whatever else it lists (including a Gateway with a single AIO) and keeps any existing binding. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ssing A status that only lists GivEnergy units without their serial is not counted as inverter telemetry, but it still carries device-level data. Publish its gateway-online, EV charger and EMS aggregate entities, and register any new EV charger straight away instead of waiting for an inverter serial to come back. When auto-config skips a status because a GivEnergy EMS or Gateway is unidentified, new EV chargers are registered too, so they no longer re-trigger auto-config (and its log lines) on every telemetry. The missing-serial and auto-config-skipped warnings are rate limited to once every ten minutes each, so the condition is visible in the log without repeating on every status. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Problem
A gateway hub briefly reported a status listing one GivEnergy inverter with an empty serial and no battery block. The gateway component treated it as a real unit:
_needs_reconfigure()counted''as a newly discovered serial and re-ran auto-config (new inverter(s) discovered ['']).automatic_config()bound inverter 0 to that entry, so every entity arg used an empty suffix (number.predbat_gateway__reserve_soc, ...) and every control command went out with"serial": "". The writes failed their read-back (Inverter 0 write to reserve failed), SoC read 0, andsoc_maxfell back to its default with asoc_max element Nonevalidation error._inject_entities()publishedpredbat_gateway__*entities for the phantom unit.Control only recovered when the real serial reappeared, counted as "new" again and triggered another re-config.
Fix
A blank serial only means "missing" for GivEnergy units (inverter, EMS, Gateway). GivEnergy discovery always reads the serial, whereas the other hub drivers never report one, so their inverters always arrive with serial
"". For every other type nothing changes: a blank serial binds exactly as before.For a GivEnergy unit reported without its serial (
_serial_missing()):_needs_reconfigure()never treats it as a new inverter.automatic_config()never binds it, but it still counts when deciding the control point. Dropping it first could choose wrong: a second AIO without its serial would stop the Gateway being chosen._auto_configuredare left alone, so a first-run config retries on the next status. When the serial is reported it is a new serial and re-runs auto-config.inverter_timeentities, so nopredbat_gateway__*entities appear. EMS aggregates carry no serial in their names and are still published.Tests
All in
TestGatewayUnitControlBinding, most driven through_process_telemetry():automatic_config()keeps the binding and warns."": these still configure as before.On
mainall but the non-GivEnergy test fail (that one checksmain's behaviour is kept). I also reverted each guard individually (type scoping, whitespace strip, coordinator rule, binding filter, EMS lookup, entity filter, telemetry early-out, re-config filter, configured-serials filter, EV registration in both paths, rate limit), and each revert makes at least one test fail../run_all --test gatewaypasses (284) and./run_all --quickpasses.🤖 Generated with Claude Code