Summary
When require_connection_before_registry=True, the setup flow can return SetupComplete before entities are registered. The Remote then asks for available entities and gets an empty list.
Here's the sequence:
- Setup completes →
config.add_or_update() triggers on_device_added()
on_device_added() is sync, so it can't await — it uses create_task(async_add_configured_device()) (fire-and-forget)
- The setup flow does
sleep(1) then returns SetupComplete()
- The background task is still connecting and registering entities
- The Remote receives
SetupComplete, asks for entities — nothing is there yet
The startup path (register_all_device_instances) does not have this problem because it directly awaits async_add_configured_device() in a loop.
Some Devices Are More Affected
There is a 1 second sleep before returning SetupComplete(), I'm assuming that is there to provide some buffer for connect to complete, but I don't know for sure.
But going on that assumption, it may be an assumption that device.connect() will complete within a specific amount of time. A connection init sequence may include initial state collection and processing which may take an unknown amount of time.
Possible Fixes
Option A — Signal-based wait (no API changes):
Store the task handle from create_task() somewhere accessible, and have the setup flow await it (or an associated event/future) before returning SetupComplete. This keeps on_device_added sync but gives the setup flow a way to know when entity registration is complete.
Option B — Make handlers async (major version bump):
Make BaseConfigManager handlers async so on_device_added can directly await async_add_configured_device(). The setup flow would then naturally wait because add_or_update() wouldn't return until the device is connected and entities are registered. This would be a breaking change requiring a major version bump. It would be possible to support both sync and async handlers during a transition, though maintaining both paths long-term isn't ideal.
References
Summary
When
require_connection_before_registry=True, the setup flow can returnSetupCompletebefore entities are registered. The Remote then asks for available entities and gets an empty list.Here's the sequence:
config.add_or_update()triggerson_device_added()on_device_added()is sync, so it can't await — it usescreate_task(async_add_configured_device())(fire-and-forget)sleep(1)then returnsSetupComplete()SetupComplete, asks for entities — nothing is there yetThe startup path (
register_all_device_instances) does not have this problem because it directlyawaitsasync_add_configured_device()in a loop.Some Devices Are More Affected
There is a 1 second sleep before returning
SetupComplete(), I'm assuming that is there to provide some buffer for connect to complete, but I don't know for sure.But going on that assumption, it may be an assumption that
device.connect()will complete within a specific amount of time. A connection init sequence may include initial state collection and processing which may take an unknown amount of time.Possible Fixes
Option A — Signal-based wait (no API changes):
Store the task handle from
create_task()somewhere accessible, and have the setup flow await it (or an associated event/future) before returningSetupComplete. This keepson_device_addedsync but gives the setup flow a way to know when entity registration is complete.Option B — Make handlers async (major version bump):
Make
BaseConfigManagerhandlers async soon_device_addedcan directlyawait async_add_configured_device(). The setup flow would then naturally wait becauseadd_or_update()wouldn't return until the device is connected and entities are registered. This would be a breaking change requiring a major version bump. It would be possible to support both sync and async handlers during a transition, though maintaining both paths long-term isn't ideal.References