Fix multi-instance entity/device cross-wiring (#491)#499
Open
garycollins2002 wants to merge 1 commit into
Open
Fix multi-instance entity/device cross-wiring (#491)#499garycollins2002 wants to merge 1 commit into
garycollins2002 wants to merge 1 commit into
Conversation
get_miniserver_from_hass() always returned the first-registered config entry's MiniServer, ignoring which config_entry a platform's async_setup_entry was actually invoked for. With two or more Miniservers configured, the second (and subsequent) instance's platforms built entities from the first instance's structure file, producing duplicate unique_ids, "Platform loxone does not generate unique IDs" errors, and previously-working entities going unavailable. The 0.9.16 fix for JoDehli#491 namespaced the keep-alive/software-version sensor unique_ids by serial, but that only patches those two specific entities - every other platform (climate, switch, cover, light, binary_sensor, alarm_control_panel, etc.) was still affected. - miniserver.py: scope get_miniserver_from_hass() by config_entry.entry_id instead of always returning the first-registered instance; drop the dead, single-instance-only get_miniserver_from_config(). - Thread config_entry through to the lookup in all 12 platform files and __init__.py's loxone_discovered(). - alarm_control_panel.py: remove the async_setup_entry-time hass.bus.async_listen(EVENT, ...) call that fired before HA decided whether to accept the entity, leaving orphaned listeners bound to hass=None objects (RuntimeError: Attribute hass is None crash on every subsequent websocket event). LoxoneEntity's standard async_added_to_hass/async_will_remove_from_hass lifecycle now handles this like every other platform. Verified against two real Miniservers running concurrently for several days, including confirming device-registry entries no longer cross-associate between instances.
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.
Summary
Follows up on #491. The 0.9.16 fix for that issue namespaced the
keep-alive/software-version sensor unique IDs by serial, which helps
those two specific entities, but the actual root cause was untouched
and still affects every other platform.
Root cause:
get_miniserver_from_hass(hass)inminiserver.pyalways returns the first-registered config entry's
MiniServer:Every platform's
async_setup_entry(hass, config_entry, async_add_entities)calls this instead of using the
config_entryit was actually invokedfor. With two or more Miniservers configured, the second (and any
subsequent) instance's platforms build entities from the first
instance's structure file, producing duplicate
uuidAction/unique_identities that collide with the first instance's already-registered
entities ("Platform loxone does not generate unique IDs" errors) and
causing previously-working entities to go unavailable.
Separately,
alarm_control_panel.pyhas its own bug: it subscribes tothe event bus directly in
async_setup_entry, beforeasync_add_entitieshas decided whether the entity is actually accepted:
If HA rejects the entity for a duplicate unique_id (which happens today
because of the bug above), the listener is never unsubscribed and keeps
calling
self.async_schedule_update_ha_state()on an entity whose.hasswas never set, producing a repeatingRuntimeError: Attribute hass is Noneon every subsequent websocketevent.
Changes
miniserver.py: scopeget_miniserver_from_hass()byconfig_entry.entry_idinstead of always returning thefirst-registered instance; drop the dead, single-instance-only
get_miniserver_from_config().config_entrythrough to the lookup in all 12 platform files(
climate,switch,cover,sensor,binary_sensor,light,alarm_control_panel,button,fan,media_player,number,text) and__init__.py'sloxone_discovered().alarm_control_panel.py: remove the prematurehass.bus.async_listencall;
LoxoneAlarmalready inheritsLoxoneEntity's standardasync_added_to_hass/async_will_remove_from_hasslifecycle, whichnow handles subscription correctly like every other platform.
Test plan
buildings) running concurrently for several days.
startup with both instances configured.
RuntimeError: Attribute hass is Nonefromthe alarm platform.
alarm, etc.) stay available after both integrations finish
loading, regardless of setup order.
no longer cross-associated with the wrong config entry after
the fix (previously, two lighting-controller devices had leaked
an extra
config_entriesassociation from before the fix wasapplied; this is a one-time artifact of the old bug, not
something the fix needs to clean up itself).