Skip to content

Commit b387acf

Browse files
jbouwhemontnemery
authored andcommitted
Fix update of the entity ID does not clean up an old restored state (home-assistant#151696)
Co-authored-by: Erik Montnemery <[email protected]>
1 parent 36b3133 commit b387acf

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

homeassistant/helpers/entity_registry.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1898,11 +1898,25 @@ def _async_setup_entity_restore(hass: HomeAssistant, registry: EntityRegistry) -
18981898
@callback
18991899
def cleanup_restored_states_filter(event_data: Mapping[str, Any]) -> bool:
19001900
"""Clean up restored states filter."""
1901-
return bool(event_data["action"] == "remove")
1901+
return (event_data["action"] == "remove") or (
1902+
event_data["action"] == "update"
1903+
and "old_entity_id" in event_data
1904+
and event_data["entity_id"] != event_data["old_entity_id"]
1905+
)
19021906

19031907
@callback
19041908
def cleanup_restored_states(event: Event[EventEntityRegistryUpdatedData]) -> None:
19051909
"""Clean up restored states."""
1910+
if event.data["action"] == "update":
1911+
old_entity_id = event.data["old_entity_id"]
1912+
old_state = hass.states.get(old_entity_id)
1913+
if old_state is None or not old_state.attributes.get(ATTR_RESTORED):
1914+
return
1915+
hass.states.async_remove(old_entity_id, context=event.context)
1916+
if entry := registry.async_get(event.data["entity_id"]):
1917+
entry.write_unavailable_state(hass)
1918+
return
1919+
19061920
state = hass.states.get(event.data["entity_id"])
19071921

19081922
if state is None or not state.attributes.get(ATTR_RESTORED):

tests/helpers/test_entity_registry.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,9 +1462,56 @@ async def test_update_entity_unique_id_conflict(
14621462
)
14631463

14641464

1465-
async def test_update_entity_entity_id(entity_registry: er.EntityRegistry) -> None:
1466-
"""Test entity's entity_id is updated."""
1465+
async def test_update_entity_entity_id(
1466+
hass: HomeAssistant, entity_registry: er.EntityRegistry
1467+
) -> None:
1468+
"""Test entity's entity_id is updated for entity with a restored state."""
1469+
hass.set_state(CoreState.not_running)
1470+
1471+
mock_config = MockConfigEntry(domain="light", entry_id="mock-id-1")
1472+
mock_config.add_to_hass(hass)
1473+
entry = entity_registry.async_get_or_create(
1474+
"light", "hue", "5678", config_entry=mock_config
1475+
)
1476+
hass.bus.async_fire(EVENT_HOMEASSISTANT_START, {})
1477+
await hass.async_block_till_done()
1478+
assert (
1479+
entity_registry.async_get_entity_id("light", "hue", "5678") == entry.entity_id
1480+
)
1481+
state = hass.states.get(entry.entity_id)
1482+
assert state is not None
1483+
assert state.state == "unavailable"
1484+
assert state.attributes == {"restored": True, "supported_features": 0}
1485+
1486+
new_entity_id = "light.blah"
1487+
assert new_entity_id != entry.entity_id
1488+
with patch.object(entity_registry, "async_schedule_save") as mock_schedule_save:
1489+
updated_entry = entity_registry.async_update_entity(
1490+
entry.entity_id, new_entity_id=new_entity_id
1491+
)
1492+
assert updated_entry != entry
1493+
assert updated_entry.entity_id == new_entity_id
1494+
assert mock_schedule_save.call_count == 1
1495+
1496+
assert entity_registry.async_get(entry.entity_id) is None
1497+
assert entity_registry.async_get(new_entity_id) is not None
1498+
1499+
# The restored state should be removed
1500+
old_state = hass.states.get(entry.entity_id)
1501+
assert old_state is None
1502+
1503+
# The new entity should have an unavailable initial state
1504+
new_state = hass.states.get(new_entity_id)
1505+
assert new_state is not None
1506+
assert new_state.state == "unavailable"
1507+
1508+
1509+
async def test_update_entity_entity_id_without_state(
1510+
entity_registry: er.EntityRegistry,
1511+
) -> None:
1512+
"""Test entity's entity_id is updated for entity without a state."""
14671513
entry = entity_registry.async_get_or_create("light", "hue", "5678")
1514+
14681515
assert (
14691516
entity_registry.async_get_entity_id("light", "hue", "5678") == entry.entity_id
14701517
)

0 commit comments

Comments
 (0)