From 58339d79d322aa60ef59e8eda9270f688280a35f Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Mon, 25 Aug 2025 22:48:30 +0200 Subject: [PATCH] Revert "Fix entities/devices stuck in disabled state after config entry re-add" (#151158) --- homeassistant/helpers/device_registry.py | 6 -- homeassistant/helpers/entity_registry.py | 10 +-- tests/helpers/test_device_registry.py | 92 ------------------------ tests/helpers/test_entity_registry.py | 91 ----------------------- 4 files changed, 1 insertion(+), 198 deletions(-) diff --git a/homeassistant/helpers/device_registry.py b/homeassistant/helpers/device_registry.py index 463b5c4dddc..c7f7d4c369d 100644 --- a/homeassistant/helpers/device_registry.py +++ b/homeassistant/helpers/device_registry.py @@ -1460,18 +1460,12 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): if config_entry_id not in config_entries: continue if config_entries == {config_entry_id}: - # Clear disabled_by if it was disabled by the config entry - if deleted_device.disabled_by is DeviceEntryDisabler.CONFIG_ENTRY: - disabled_by = None - else: - disabled_by = deleted_device.disabled_by # Add a time stamp when the deleted device became orphaned self.deleted_devices[deleted_device.id] = attr.evolve( deleted_device, orphaned_timestamp=now_time, config_entries=set(), config_entries_subentries={}, - disabled_by=disabled_by, ) else: config_entries = config_entries - {config_entry_id} diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index 3b506f9a2cd..5ed6afa4314 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -1622,17 +1622,9 @@ class EntityRegistry(BaseRegistry): for key, deleted_entity in list(self.deleted_entities.items()): if config_entry_id != deleted_entity.config_entry_id: continue - # Clear disabled_by if it was disabled by the config entry - if deleted_entity.disabled_by is RegistryEntryDisabler.CONFIG_ENTRY: - disabled_by = None - else: - disabled_by = deleted_entity.disabled_by # Add a time stamp when the deleted entity became orphaned self.deleted_entities[key] = attr.evolve( - deleted_entity, - orphaned_timestamp=now_time, - config_entry_id=None, - disabled_by=disabled_by, + deleted_entity, orphaned_timestamp=now_time, config_entry_id=None ) self.async_schedule_save() diff --git a/tests/helpers/test_device_registry.py b/tests/helpers/test_device_registry.py index d45c4f6cf91..d056c25fc3b 100644 --- a/tests/helpers/test_device_registry.py +++ b/tests/helpers/test_device_registry.py @@ -3368,98 +3368,6 @@ async def test_cleanup_startup(hass: HomeAssistant) -> None: assert len(mock_call.mock_calls) == 1 -async def test_deleted_device_clears_disabled_by_on_config_entry_removal( - hass: HomeAssistant, - device_registry: dr.DeviceRegistry, -) -> None: - """Test that disabled_by is cleared when config entry is removed.""" - config_entry = MockConfigEntry(domain="test", entry_id="mock-id-1") - config_entry.add_to_hass(hass) - - # Create a device disabled by the config entry - device = device_registry.async_get_or_create( - config_entry_id="mock-id-1", - identifiers={("test", "device_1")}, - name="Test Device", - disabled_by=dr.DeviceEntryDisabler.CONFIG_ENTRY, - ) - assert device.config_entries == {"mock-id-1"} - assert device.disabled_by is dr.DeviceEntryDisabler.CONFIG_ENTRY - - # Remove the device (it moves to deleted_devices) - device_registry.async_remove_device(device.id) - - assert len(device_registry.devices) == 0 - assert len(device_registry.deleted_devices) == 1 - deleted_device = device_registry.deleted_devices[device.id] - assert deleted_device.config_entries == {"mock-id-1"} - assert deleted_device.disabled_by is dr.DeviceEntryDisabler.CONFIG_ENTRY - assert deleted_device.orphaned_timestamp is None - - # Clear the config entry - device_registry.async_clear_config_entry("mock-id-1") - - # Verify disabled_by is cleared - deleted_device = device_registry.deleted_devices[device.id] - assert deleted_device.config_entries == set() - assert deleted_device.disabled_by is None # Should be cleared - assert deleted_device.orphaned_timestamp is not None - - # Now re-add the config entry and device to verify it can be enabled - config_entry2 = MockConfigEntry(domain="test", entry_id="mock-id-2") - config_entry2.add_to_hass(hass) - - # Re-create the device with same identifiers - device2 = device_registry.async_get_or_create( - config_entry_id="mock-id-2", - identifiers={("test", "device_1")}, - name="Test Device", - ) - assert device2.config_entries == {"mock-id-2"} - assert device2.disabled_by is None # Should not be disabled anymore - assert device2.id == device.id # Should keep the same device id - - -async def test_deleted_device_disabled_by_user_not_cleared( - hass: HomeAssistant, - device_registry: dr.DeviceRegistry, -) -> None: - """Test that disabled_by=USER is not cleared when config entry is removed.""" - config_entry = MockConfigEntry(domain="test", entry_id="mock-id-1") - config_entry.add_to_hass(hass) - - # Create a device disabled by the user - device = device_registry.async_get_or_create( - config_entry_id="mock-id-1", - identifiers={("test", "device_1")}, - name="Test Device", - disabled_by=dr.DeviceEntryDisabler.USER, - ) - assert device.config_entries == {"mock-id-1"} - assert device.disabled_by is dr.DeviceEntryDisabler.USER - - # Remove the device (it moves to deleted_devices) - device_registry.async_remove_device(device.id) - - assert len(device_registry.devices) == 0 - assert len(device_registry.deleted_devices) == 1 - deleted_device = device_registry.deleted_devices[device.id] - assert deleted_device.config_entries == {"mock-id-1"} - assert deleted_device.disabled_by is dr.DeviceEntryDisabler.USER - assert deleted_device.orphaned_timestamp is None - - # Clear the config entry - device_registry.async_clear_config_entry("mock-id-1") - - # Verify disabled_by is NOT cleared for USER disabled devices - deleted_device = device_registry.deleted_devices[device.id] - assert deleted_device.config_entries == set() - assert ( - deleted_device.disabled_by is dr.DeviceEntryDisabler.USER - ) # Should remain USER - assert deleted_device.orphaned_timestamp is not None - - @pytest.mark.parametrize("load_registries", [False]) async def test_cleanup_entity_registry_change( hass: HomeAssistant, mock_config_entry: MockConfigEntry diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index 151bd54dc2a..615560d8640 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -782,97 +782,6 @@ async def test_deleted_entity_removing_config_entry_id( assert entity_registry.deleted_entities[("light", "hue", "1234")] == deleted_entry2 -async def test_deleted_entity_clears_disabled_by_on_config_entry_removal( - hass: HomeAssistant, - entity_registry: er.EntityRegistry, -) -> None: - """Test that disabled_by is cleared when config entry is removed.""" - mock_config = MockConfigEntry(domain="light", entry_id="mock-id-1") - mock_config.add_to_hass(hass) - - # Create an entity disabled by the config entry - entry = entity_registry.async_get_or_create( - "light", - "hue", - "5678", - config_entry=mock_config, - disabled_by=er.RegistryEntryDisabler.CONFIG_ENTRY, - ) - assert entry.config_entry_id == "mock-id-1" - assert entry.disabled_by is er.RegistryEntryDisabler.CONFIG_ENTRY - - # Remove the entity (it moves to deleted_entities) - entity_registry.async_remove(entry.entity_id) - - assert len(entity_registry.entities) == 0 - assert len(entity_registry.deleted_entities) == 1 - deleted_entry = entity_registry.deleted_entities[("light", "hue", "5678")] - assert deleted_entry.config_entry_id == "mock-id-1" - assert deleted_entry.disabled_by is er.RegistryEntryDisabler.CONFIG_ENTRY - assert deleted_entry.orphaned_timestamp is None - - # Clear the config entry - entity_registry.async_clear_config_entry("mock-id-1") - - # Verify disabled_by is cleared - deleted_entry = entity_registry.deleted_entities[("light", "hue", "5678")] - assert deleted_entry.config_entry_id is None - assert deleted_entry.disabled_by is None # Should be cleared - assert deleted_entry.orphaned_timestamp is not None - - # Now re-add the config entry and entity to verify it can be enabled - mock_config2 = MockConfigEntry(domain="light", entry_id="mock-id-2") - mock_config2.add_to_hass(hass) - - # Re-create the entity with same unique ID - entry2 = entity_registry.async_get_or_create( - "light", "hue", "5678", config_entry=mock_config2 - ) - assert entry2.config_entry_id == "mock-id-2" - assert entry2.disabled_by is None # Should not be disabled anymore - - -async def test_deleted_entity_disabled_by_user_not_cleared( - hass: HomeAssistant, - entity_registry: er.EntityRegistry, -) -> None: - """Test that disabled_by=USER is not cleared when config entry is removed.""" - mock_config = MockConfigEntry(domain="light", entry_id="mock-id-1") - mock_config.add_to_hass(hass) - - # Create an entity disabled by the user - entry = entity_registry.async_get_or_create( - "light", - "hue", - "5678", - config_entry=mock_config, - disabled_by=er.RegistryEntryDisabler.USER, - ) - assert entry.config_entry_id == "mock-id-1" - assert entry.disabled_by is er.RegistryEntryDisabler.USER - - # Remove the entity (it moves to deleted_entities) - entity_registry.async_remove(entry.entity_id) - - assert len(entity_registry.entities) == 0 - assert len(entity_registry.deleted_entities) == 1 - deleted_entry = entity_registry.deleted_entities[("light", "hue", "5678")] - assert deleted_entry.config_entry_id == "mock-id-1" - assert deleted_entry.disabled_by is er.RegistryEntryDisabler.USER - assert deleted_entry.orphaned_timestamp is None - - # Clear the config entry - entity_registry.async_clear_config_entry("mock-id-1") - - # Verify disabled_by is NOT cleared for USER disabled entities - deleted_entry = entity_registry.deleted_entities[("light", "hue", "5678")] - assert deleted_entry.config_entry_id is None - assert ( - deleted_entry.disabled_by is er.RegistryEntryDisabler.USER - ) # Should remain USER - assert deleted_entry.orphaned_timestamp is not None - - async def test_removing_config_subentry_id( hass: HomeAssistant, entity_registry: er.EntityRegistry ) -> None: