diff --git a/homeassistant/helpers/device_registry.py b/homeassistant/helpers/device_registry.py index 5c066967437..d090e571a8b 100644 --- a/homeassistant/helpers/device_registry.py +++ b/homeassistant/helpers/device_registry.py @@ -219,6 +219,14 @@ class DeviceRegistry: return new + def _async_remove_device(self, device_id): + del self.devices[device_id] + self.hass.bus.async_fire(EVENT_DEVICE_REGISTRY_UPDATED, { + 'action': 'remove', + 'device_id': device_id, + }) + self.async_schedule_save() + async def async_load(self): """Load the device registry.""" data = await self._store.async_load() @@ -278,10 +286,15 @@ class DeviceRegistry: @callback def async_clear_config_entry(self, config_entry_id): """Clear config entry from registry entries.""" + remove = [] for dev_id, device in self.devices.items(): - if config_entry_id in device.config_entries: + if device.config_entries == {config_entry_id}: + remove.append(dev_id) + else: self._async_update_device( dev_id, remove_config_entry_id=config_entry_id) + for dev_id in remove: + self._async_remove_device(dev_id) @callback def async_clear_area_id(self, area_id: str) -> None: diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index 0a0c441b9cf..2fb32d5214e 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -302,9 +302,11 @@ class EntityRegistry: @callback def async_clear_config_entry(self, config_entry): """Clear config entry from registry entries.""" - for entity_id, entry in self.entities.items(): - if config_entry == entry.config_entry_id: - self._async_update_entity(entity_id, config_entry_id=None) + for entity_id in [ + entity_id + for entity_id, entry in self.entities.items() + if config_entry == entry.config_entry_id]: + self.async_remove(entity_id) @bind_hass diff --git a/tests/helpers/test_device_registry.py b/tests/helpers/test_device_registry.py index 4b08bf960bf..444bd44133b 100644 --- a/tests/helpers/test_device_registry.py +++ b/tests/helpers/test_device_registry.py @@ -211,10 +211,10 @@ async def test_removing_config_entries(hass, registry, update_events): registry.async_clear_config_entry('123') entry = registry.async_get_device({('bridgeid', '0123')}, set()) - entry3 = registry.async_get_device({('bridgeid', '4567')}, set()) + entry3_removed = registry.async_get_device({('bridgeid', '4567')}, set()) assert entry.config_entries == {'456'} - assert entry3.config_entries == set() + assert entry3_removed is None await hass.async_block_till_done() @@ -227,7 +227,7 @@ async def test_removing_config_entries(hass, registry, update_events): assert update_events[2]['device_id'] == entry3.id assert update_events[3]['action'] == 'update' assert update_events[3]['device_id'] == entry.id - assert update_events[4]['action'] == 'update' + assert update_events[4]['action'] == 'remove' assert update_events[4]['device_id'] == entry3.id diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index 3af9394a202..61d3af6e6f2 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -213,15 +213,14 @@ async def test_removing_config_entry_id(hass, registry, update_events): assert entry.config_entry_id == 'mock-id-1' registry.async_clear_config_entry('mock-id-1') - entry = registry.entities[entry.entity_id] - assert entry.config_entry_id is None + assert not registry.entities await hass.async_block_till_done() assert len(update_events) == 2 assert update_events[0]['action'] == 'create' assert update_events[0]['entity_id'] == entry.entity_id - assert update_events[1]['action'] == 'update' + assert update_events[1]['action'] == 'remove' assert update_events[1]['entity_id'] == entry.entity_id diff --git a/tests/test_config_entries.py b/tests/test_config_entries.py index 9de31a6d5ca..752cb5eb277 100644 --- a/tests/test_config_entries.py +++ b/tests/test_config_entries.py @@ -261,9 +261,9 @@ async def test_remove_entry(hass, manager): # Just Group all_lights assert len(hass.states.async_all()) == 1 - # Check that entity registry entry no longer references config_entry_id - entity_entry = list(ent_reg.entities.values())[0] - assert entity_entry.config_entry_id is None + # Check that entity registry entry has been removed + entity_entry_list = list(ent_reg.entities.values()) + assert not entity_entry_list async def test_remove_entry_handles_callback_error(hass, manager):