Skip to content

Commit 4651956

Browse files
authored
Merge pull request #358 from Olen/fix/registry-entry-fallback
fix: replace ConfigEntryNotReady with retry loop for device registry
2 parents 67f275e + cb36591 commit 4651956

File tree

3 files changed

+39
-19
lines changed

3 files changed

+39
-19
lines changed

custom_components/plant/__init__.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import asyncio
56
import logging
67

78
import voluptuous as vol
@@ -23,7 +24,6 @@
2324
Platform,
2425
)
2526
from homeassistant.core import HomeAssistant, ServiceCall, callback
26-
from homeassistant.exceptions import ConfigEntryNotReady
2727
from homeassistant.helpers import config_validation as cv
2828
from homeassistant.helpers import device_registry as dr
2929
from homeassistant.helpers import entity_registry as er
@@ -316,6 +316,10 @@ async def replace_sensor(call: ServiceCall) -> None:
316316
return True
317317

318318

319+
_REGISTRY_RETRY_DELAY = 1 # seconds between retries
320+
_REGISTRY_MAX_RETRIES = 5
321+
322+
319323
async def _plant_add_to_device_registry(
320324
hass: HomeAssistant,
321325
plant_entities: list[Entity],
@@ -328,12 +332,30 @@ async def _plant_add_to_device_registry(
328332
# device_id when adding the entities.
329333
erreg = er.async_get(hass)
330334
for entity in plant_entities:
331-
if entity.registry_entry is None:
332-
raise ConfigEntryNotReady(
333-
f"Entity {entity.entity_id} not yet registered, retrying setup"
335+
registry_entry = entity.registry_entry or erreg.async_get(entity.entity_id)
336+
retries = 0
337+
while registry_entry is None and retries < _REGISTRY_MAX_RETRIES:
338+
retries += 1
339+
_LOGGER.debug(
340+
"Entity %s not yet in registry, retrying (%s/%s)",
341+
entity.entity_id,
342+
retries,
343+
_REGISTRY_MAX_RETRIES,
334344
)
345+
await asyncio.sleep(_REGISTRY_RETRY_DELAY)
346+
registry_entry = entity.registry_entry or erreg.async_get(entity.entity_id)
347+
348+
if registry_entry is None:
349+
_LOGGER.warning(
350+
"Entity %s not found in registry after %s retries, "
351+
"skipping device assignment",
352+
entity.entity_id,
353+
retries,
354+
)
355+
continue
356+
335357
erreg.async_update_entity(
336-
entity.registry_entry.entity_id,
358+
registry_entry.entity_id,
337359
device_id=device_id,
338360
config_entry_id=entry.entry_id,
339361
)

custom_components/plant/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717
"requirements": [
1818
"async-timeout>=4.0.2"
1919
],
20-
"version": "2026.2.1-beta3"
20+
"version": "2026.2.1-beta4"
2121
}

tests/test_init.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,33 +127,31 @@ async def test_remove_entry(
127127
)
128128
assert device_after is None
129129

130-
async def test_setup_entry_retries_when_registry_not_ready(
130+
async def test_setup_completes_when_registry_entry_not_immediate(
131131
self,
132132
hass: HomeAssistant,
133133
mock_external_sensors: None,
134134
) -> None:
135-
"""Test setup raises ConfigEntryNotReady when entity registry_entry is None."""
135+
"""Test setup completes gracefully when registry_entry is None initially.
136+
137+
The function should retry with registry lookup and give up gracefully
138+
instead of blocking the entire setup with ConfigEntryNotReady.
139+
"""
136140
from tests.conftest import create_plant_config_data
137141

138142
config_data = create_plant_config_data()
139143
entry = MockConfigEntry(
140144
domain=DOMAIN,
141145
data=config_data,
142-
entry_id="test_registry_not_ready",
146+
entry_id="test_registry_delayed",
143147
)
144148
entry.add_to_hass(hass)
145149

146-
with patch(
147-
"custom_components.plant._plant_add_to_device_registry",
148-
side_effect=__import__(
149-
"homeassistant.exceptions", fromlist=["ConfigEntryNotReady"]
150-
).ConfigEntryNotReady("Entity not yet registered"),
151-
):
152-
await hass.config_entries.async_setup(entry.entry_id)
153-
await hass.async_block_till_done()
150+
await hass.config_entries.async_setup(entry.entry_id)
151+
await hass.async_block_till_done()
154152

155-
# Entry should be in SETUP_RETRY state
156-
assert entry.state.name == "SETUP_RETRY"
153+
# Setup should complete successfully (not stuck in SETUP_RETRY)
154+
assert entry.state.name == "LOADED"
157155

158156
async def test_setup_entry_no_plant_info(
159157
self,

0 commit comments

Comments
 (0)