From dfcc4d1ae4cee34d271ec25481d36184dca04aec Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 24 Jun 2026 15:47:39 +0200 Subject: [PATCH] Fix friendly name for restored unavailable entities (#174614) --- homeassistant/helpers/entity_registry.py | 4 +- tests/helpers/test_entity_registry.py | 65 ++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index 4d273478e226..01a1d8b18f2f 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -442,8 +442,8 @@ class RegistryEntry: if icon is not None: attrs[ATTR_ICON] = icon - name = self.name or self.original_name - if name is not None: + name = async_get_full_entity_name(hass, self) + if name: attrs[ATTR_FRIENDLY_NAME] = name if self.supported_features is not None: diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index 4af607e168af..0f8d66d04aca 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -2619,6 +2619,71 @@ async def test_restore_states( assert hass.states.get("light.all_info_set") is None +@pytest.mark.parametrize( + ("original_name", "entity_name", "device_name_by_user", "expected_friendly_name"), + [ + pytest.param( + None, None, None, "Pedestal Fan", id="primary_entity_uses_device_name" + ), + pytest.param( + "Temperature", + None, + None, + "Pedestal Fan Temperature", + id="entity_name_prefixed_with_device_name", + ), + pytest.param( + "Pedestal Fan", "Angle", None, "Angle", id="user_rename_replaces_full_name" + ), + pytest.param( + None, None, "Living Room Fan", "Living Room Fan", id="device_rename_applied" + ), + ], +) +async def test_restore_state_uses_device_name( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + device_registry: dr.DeviceRegistry, + original_name: str | None, + entity_name: str | None, + device_name_by_user: str | None, + expected_friendly_name: str, +) -> None: + """Test the restored state friendly name is composed like the live state.""" + hass.set_state(CoreState.not_running) + + config_entry = MockConfigEntry(domain="fan") + config_entry.add_to_hass(hass) + device_entry = device_registry.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + name="Pedestal Fan", + ) + device_registry.async_update_device( + device_entry.id, name_by_user=device_name_by_user + ) + + entry = entity_registry.async_get_or_create( + "fan", + "demo", + "1234", + suggested_object_id="test", + config_entry=config_entry, + device_id=device_entry.id, + has_entity_name=True, + original_name=original_name, + ) + entity_registry.async_update_entity(entry.entity_id, name=entity_name) + + hass.bus.async_fire(EVENT_HOMEASSISTANT_START, {}) + await hass.async_block_till_done() + + state = hass.states.get("fan.test") + assert state is not None + assert state.state == STATE_UNAVAILABLE + assert state.attributes["friendly_name"] == expected_friendly_name + + async def test_remove_device_removes_entities( hass: HomeAssistant, entity_registry: er.EntityRegistry,