Delete devices / entities when we remove a config entry. (#23983)

* Remove device when last config entry removed

* Remove entities when config entry removed

* Update tests to use new behaviour
This commit is contained in:
Penny Wood 2019-05-19 17:41:39 +08:00 committed by Paulus Schoutsen
parent d7d83c683d
commit f991ec15f2
5 changed files with 27 additions and 13 deletions

View File

@ -219,6 +219,14 @@ class DeviceRegistry:
return new 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): async def async_load(self):
"""Load the device registry.""" """Load the device registry."""
data = await self._store.async_load() data = await self._store.async_load()
@ -278,10 +286,15 @@ class DeviceRegistry:
@callback @callback
def async_clear_config_entry(self, config_entry_id): def async_clear_config_entry(self, config_entry_id):
"""Clear config entry from registry entries.""" """Clear config entry from registry entries."""
remove = []
for dev_id, device in self.devices.items(): 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( self._async_update_device(
dev_id, remove_config_entry_id=config_entry_id) dev_id, remove_config_entry_id=config_entry_id)
for dev_id in remove:
self._async_remove_device(dev_id)
@callback @callback
def async_clear_area_id(self, area_id: str) -> None: def async_clear_area_id(self, area_id: str) -> None:

View File

@ -302,9 +302,11 @@ class EntityRegistry:
@callback @callback
def async_clear_config_entry(self, config_entry): def async_clear_config_entry(self, config_entry):
"""Clear config entry from registry entries.""" """Clear config entry from registry entries."""
for entity_id, entry in self.entities.items(): for entity_id in [
if config_entry == entry.config_entry_id: entity_id
self._async_update_entity(entity_id, config_entry_id=None) for entity_id, entry in self.entities.items()
if config_entry == entry.config_entry_id]:
self.async_remove(entity_id)
@bind_hass @bind_hass

View File

@ -211,10 +211,10 @@ async def test_removing_config_entries(hass, registry, update_events):
registry.async_clear_config_entry('123') registry.async_clear_config_entry('123')
entry = registry.async_get_device({('bridgeid', '0123')}, set()) 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 entry.config_entries == {'456'}
assert entry3.config_entries == set() assert entry3_removed is None
await hass.async_block_till_done() 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[2]['device_id'] == entry3.id
assert update_events[3]['action'] == 'update' assert update_events[3]['action'] == 'update'
assert update_events[3]['device_id'] == entry.id 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 assert update_events[4]['device_id'] == entry3.id

View File

@ -213,15 +213,14 @@ async def test_removing_config_entry_id(hass, registry, update_events):
assert entry.config_entry_id == 'mock-id-1' assert entry.config_entry_id == 'mock-id-1'
registry.async_clear_config_entry('mock-id-1') registry.async_clear_config_entry('mock-id-1')
entry = registry.entities[entry.entity_id] assert not registry.entities
assert entry.config_entry_id is None
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(update_events) == 2 assert len(update_events) == 2
assert update_events[0]['action'] == 'create' assert update_events[0]['action'] == 'create'
assert update_events[0]['entity_id'] == entry.entity_id 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 assert update_events[1]['entity_id'] == entry.entity_id

View File

@ -261,9 +261,9 @@ async def test_remove_entry(hass, manager):
# Just Group all_lights # Just Group all_lights
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_all()) == 1
# Check that entity registry entry no longer references config_entry_id # Check that entity registry entry has been removed
entity_entry = list(ent_reg.entities.values())[0] entity_entry_list = list(ent_reg.entities.values())
assert entity_entry.config_entry_id is None assert not entity_entry_list
async def test_remove_entry_handles_callback_error(hass, manager): async def test_remove_entry_handles_callback_error(hass, manager):