diff --git a/homeassistant/components/diagnostics/util.py b/homeassistant/components/diagnostics/util.py index c40b38c6de1..9b07fbd2d14 100644 --- a/homeassistant/components/diagnostics/util.py +++ b/homeassistant/components/diagnostics/util.py @@ -51,7 +51,6 @@ def _entity_entry_filter(a: attr.Attribute, _: Any) -> bool: return a.name not in ( "_cache", "compat_aliases", - "compat_name", "original_name_unprefixed", ) diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index 33276acfafd..851ab2c8990 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -80,7 +80,7 @@ EVENT_ENTITY_REGISTRY_UPDATED: EventType[EventEntityRegistryUpdatedData] = Event _LOGGER = logging.getLogger(__name__) STORAGE_VERSION_MAJOR = 1 -STORAGE_VERSION_MINOR = 21 +STORAGE_VERSION_MINOR = 22 STORAGE_KEY = "core.entity_registry" CLEANUP_INTERVAL = 3600 * 24 @@ -240,7 +240,6 @@ class RegistryEntry: # For backwards compatibility, should be removed in the future compat_aliases: list[str] = attr.ib(factory=list, eq=False) - compat_name: str | None = attr.ib(default=None, eq=False) # original_name_unprefixed is used to store the result of stripping # the device name prefix from the original_name, if possible. @@ -413,8 +412,7 @@ class RegistryEntry: "has_entity_name": self.has_entity_name, "labels": list(self.labels), "modified_at": self.modified_at, - "name": self.compat_name, - "name_v2": self.name, + "name": self.name, "object_id_base": self.object_id_base, "options": self.options, "original_device_class": self.original_device_class, @@ -471,6 +469,7 @@ def _async_get_full_entity_name( original_name: str | None, original_name_unprefixed: str | None | UndefinedType = UNDEFINED, overridden_name: str | None = None, + use_legacy_naming: bool = False, ) -> str: """Get full name for an entity. @@ -480,7 +479,7 @@ def _async_get_full_entity_name( if name is None and overridden_name is not None: name = overridden_name - else: + elif not use_legacy_naming or name is None: device_name: str | None = None if ( device_id is not None @@ -533,6 +532,7 @@ def async_get_full_entity_name( name=entry.name, original_name=original_name, original_name_unprefixed=original_name_unprefixed, + use_legacy_naming=True, ) @@ -660,7 +660,6 @@ class DeletedRegistryEntry: # For backwards compatibility, should be removed in the future compat_aliases: list[str] = attr.ib(factory=list, eq=False) - compat_name: str | None = attr.ib(default=None, eq=False) _cache: dict[str, Any] = attr.ib(factory=dict, eq=False, init=False) @@ -696,8 +695,7 @@ class DeletedRegistryEntry: "id": self.id, "labels": list(self.labels), "modified_at": self.modified_at, - "name": self.compat_name, - "name_v2": self.name, + "name": self.name, "options": self.options if self.options is not UNDEFINED else {}, "options_undefined": self.options is UNDEFINED, "orphaned_timestamp": self.orphaned_timestamp, @@ -850,46 +848,37 @@ class EntityRegistryStore(storage.Store[dict[str, list[dict[str, Any]]]]): for entity in data["entities"]: entity["object_id_base"] = entity["original_name"] - if old_minor_version < 21: - # Version 1.21 migrates the full name to include device name, - # even if entity name is overwritten by user. - # It also adds support for COMPUTED_NAME in aliases and starts preserving their order. - # To avoid a major version bump, we keep the old name and aliases as-is - # and use new name_v2 and aliases_v2 fields instead. + if old_minor_version == 21: + # Version 1.21 has been reverted. + # It migrated entity names to the new format stored in `name_v2` + # field, automatically stripping any device name prefix present. + # The old name was stored in `name` field for backwards compatibility. + # For users who already migrated to v1.21, we restore old names + # but try to preserve any user renames made since that migration. device_registry = dr.async_get(self.hass) for entity in data["entities"]: - alias_to_add: str | None = None + old_name = entity["name"] + name = entity.pop("name_v2") if ( - (name := entity["name"]) + (name != old_name) and (device_id := entity["device_id"]) is not None and (device := device_registry.async_get(device_id)) is not None and (device_name := device.name_by_user or device.name) ): - # Strip the device name prefix from the entity name if present, - # and add the full generated name as an alias. - # If the name doesn't have the device name prefix and the - # entity is exposed to a voice assistant, add the previous - # name as an alias instead to preserve backwards compatibility. - if ( - new_name := _async_strip_prefix_from_entity_name( - name, device_name - ) - ) is not None: - name = new_name - elif any( - entity.get("options", {}).get(key, {}).get("should_expose") - for key in ("conversation", "cloud.google_assistant") - ): - alias_to_add = name + name = f"{device_name} {name}" - entity["name_v2"] = name - entity["aliases_v2"] = [alias_to_add, *entity["aliases"]] + entity["name"] = name + + if old_minor_version < 22: + # Version 1.22 adds support for COMPUTED_NAME in aliases and starts preserving + # their order. + # To avoid a major version bump, we keep the old aliases as-is and use aliases_v2 + # field instead. + for entity in data["entities"]: + entity["aliases_v2"] = [None, *entity["aliases"]] for entity in data["deleted_entities"]: - # We don't know what the device name was, so the only thing we can do - # is to clear the overwritten name to not mislead users. - entity["name_v2"] = None entity["aliases_v2"] = [None, *entity["aliases"]] if old_major_version > 1: @@ -1363,7 +1352,6 @@ class EntityRegistry(BaseRegistry): area_id = deleted_entity.area_id categories = deleted_entity.categories compat_aliases = deleted_entity.compat_aliases - compat_name = deleted_entity.compat_name created_at = deleted_entity.created_at device_class = deleted_entity.device_class if deleted_entity.disabled_by is not UNDEFINED: @@ -1395,7 +1383,6 @@ class EntityRegistry(BaseRegistry): area_id = None categories = {} compat_aliases = [] - compat_name = None device_class = None icon = None labels = set() @@ -1443,7 +1430,6 @@ class EntityRegistry(BaseRegistry): categories=categories, capabilities=none_if_undefined(capabilities), compat_aliases=compat_aliases, - compat_name=compat_name, config_entry_id=none_if_undefined(config_entry_id), config_subentry_id=none_if_undefined(config_subentry_id), created_at=created_at, @@ -1506,7 +1492,6 @@ class EntityRegistry(BaseRegistry): area_id=entity.area_id, categories=entity.categories, compat_aliases=entity.compat_aliases, - compat_name=entity.compat_name, config_entry_id=config_entry_id, config_subentry_id=entity.config_subentry_id, created_at=entity.created_at, @@ -1620,14 +1605,27 @@ class EntityRegistry(BaseRegistry): for entity in entities: if entity.has_entity_name: continue - name = ( - entity.original_name_unprefixed - if by_user and entity.name is None - else UNDEFINED - ) + + # When a user renames a device, update entity names to reflect + # the new device name. + # An empty name_unprefixed means the entity name equals + # the device name (e.g. a main sensor); a non-empty one + # is appended as a suffix. + name: str | None | UndefinedType = UNDEFINED + if ( + by_user + and entity.name is None + and (name_unprefixed := entity.original_name_unprefixed) is not None + ): + if not name_unprefixed: + name = device_name + elif device_name: + name = f"{device_name} {name_unprefixed}" + original_name_unprefixed = _async_strip_prefix_from_entity_name( entity.original_name, device_name ) + self._async_update_entity( entity.entity_id, name=name, @@ -1995,7 +1993,6 @@ class EntityRegistry(BaseRegistry): categories=entity["categories"], capabilities=entity["capabilities"], compat_aliases=entity["aliases"], - compat_name=entity["name"], config_entry_id=entity["config_entry_id"], config_subentry_id=entity["config_subentry_id"], created_at=datetime.fromisoformat(entity["created_at"]), @@ -2016,7 +2013,7 @@ class EntityRegistry(BaseRegistry): has_entity_name=entity["has_entity_name"], labels=set(entity["labels"]), modified_at=datetime.fromisoformat(entity["modified_at"]), - name=entity["name_v2"], + name=entity["name"], object_id_base=entity.get("object_id_base"), options=entity["options"], original_device_class=entity["original_device_class"], @@ -2067,7 +2064,6 @@ class EntityRegistry(BaseRegistry): area_id=entity["area_id"], categories=entity["categories"], compat_aliases=entity["aliases"], - compat_name=entity["name"], config_entry_id=entity["config_entry_id"], config_subentry_id=entity["config_subentry_id"], created_at=datetime.fromisoformat(entity["created_at"]), @@ -2087,7 +2083,7 @@ class EntityRegistry(BaseRegistry): id=entity["id"], labels=set(entity["labels"]), modified_at=datetime.fromisoformat(entity["modified_at"]), - name=entity["name_v2"], + name=entity["name"], options=entity["options"] if not entity["options_undefined"] else UNDEFINED, diff --git a/tests/components/zwave_js/test_init.py b/tests/components/zwave_js/test_init.py index 95049d01a9a..035d657bbeb 100644 --- a/tests/components/zwave_js/test_init.py +++ b/tests/components/zwave_js/test_init.py @@ -801,7 +801,7 @@ async def test_existing_node_not_replaced_when_not_ready( await hass.async_block_till_done() state = hass.states.get(custom_entity) assert state - assert state.name == "Custom Device Name Custom Entity Name" + assert state.name == "Custom Entity Name" assert not hass.states.get(motion_entity) node_state = deepcopy(zp3111_not_ready_state) @@ -835,7 +835,7 @@ async def test_existing_node_not_replaced_when_not_ready( state = hass.states.get(custom_entity) assert state - assert state.name == "Custom Device Name Custom Entity Name" + assert state.name == "Custom Entity Name" event = Event( type="ready", @@ -866,7 +866,7 @@ async def test_existing_node_not_replaced_when_not_ready( state = hass.states.get(custom_entity) assert state assert state.state != STATE_UNAVAILABLE - assert state.name == "Custom Device Name Custom Entity Name" + assert state.name == "Custom Entity Name" @pytest.mark.usefixtures("client") @@ -1857,7 +1857,7 @@ async def test_node_model_change( assert not hass.states.get(motion_entity) state = hass.states.get(custom_entity) assert state - assert state.name == "Custom Device Name Custom Entity Name" + assert state.name == "Custom Entity Name" # Unload the integration assert await hass.config_entries.async_unload(integration.entry_id) @@ -1887,7 +1887,7 @@ async def test_node_model_change( assert not hass.states.get(motion_entity) state = hass.states.get(custom_entity) assert state - assert state.name == "Custom Device Name Custom Entity Name" + assert state.name == "Custom Entity Name" @pytest.mark.usefixtures("zp3111", "integration") diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index b26a7d23d47..94f330f63e2 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -684,7 +684,6 @@ async def test_load_bad_data( "labels": [], "modified_at": "2024-02-14T12:00:00.900075+00:00", "name": None, - "name_v2": None, "object_id_base": None, "options": None, "original_device_class": None, @@ -719,7 +718,6 @@ async def test_load_bad_data( "labels": [], "modified_at": "2024-02-14T12:00:00.900075+00:00", "name": None, - "name_v2": None, "object_id_base": None, "options": None, "original_device_class": None, @@ -754,7 +752,6 @@ async def test_load_bad_data( "labels": [], "modified_at": "2024-02-14T12:00:00.900075+00:00", "name": None, - "name_v2": None, "options": None, "options_undefined": False, "orphaned_timestamp": None, @@ -780,7 +777,6 @@ async def test_load_bad_data( "labels": [], "modified_at": "2024-02-14T12:00:00.900075+00:00", "name": None, - "name_v2": None, "options": None, "options_undefined": False, "orphaned_timestamp": None, @@ -1135,7 +1131,6 @@ async def test_migration_1_1(hass: HomeAssistant, hass_storage: dict[str, Any]) "labels": [], "modified_at": "1970-01-01T00:00:00+00:00", "name": None, - "name_v2": None, "object_id_base": None, "options": {}, "original_device_class": "best_class", @@ -1331,7 +1326,6 @@ async def test_migration_1_11( "labels": [], "modified_at": "1970-01-01T00:00:00+00:00", "name": None, - "name_v2": None, "object_id_base": None, "options": {}, "original_device_class": "best_class", @@ -1367,7 +1361,6 @@ async def test_migration_1_11( "labels": [], "modified_at": "1970-01-01T00:00:00+00:00", "name": None, - "name_v2": None, "options": {}, "options_undefined": True, "orphaned_timestamp": None, @@ -1500,7 +1493,6 @@ async def test_migration_1_18( "labels": [], "modified_at": "1970-01-01T00:00:00+00:00", "name": None, - "name_v2": None, "object_id_base": "Test Entity", "options": {}, "original_device_class": "best_class", @@ -1536,7 +1528,6 @@ async def test_migration_1_18( "labels": [], "modified_at": "1970-01-01T00:00:00+00:00", "name": None, - "name_v2": None, "options": {}, "options_undefined": False, "orphaned_timestamp": None, @@ -1554,10 +1545,14 @@ async def test_migration_1_18( @pytest.mark.parametrize("load_registries", [False]) -async def test_migration_1_20( - hass: HomeAssistant, hass_storage: dict[str, Any] +async def test_migration_1_21( + hass: HomeAssistant, + hass_storage: dict[str, Any], ) -> None: - """Test migration from version 1.20.""" + """Test migration from version 1.21. + + Version 1.21 stored entity names in a new format, but was reverted. + """ hass_storage[dr.STORAGE_KEY] = { "version": dr.STORAGE_VERSION_MAJOR, "minor_version": dr.STORAGE_VERSION_MINOR, @@ -1565,24 +1560,25 @@ async def test_migration_1_20( "devices": [ { "area_id": None, - "config_entries": ["mock-config-entry"], - "config_entries_subentries": {"mock-config-entry": [None]}, + "config_entries": ["mock_entry"], + "config_entries_subentries": {"mock_entry": [None]}, "configuration_url": None, "connections": [], "created_at": "1970-01-01T00:00:00+00:00", "disabled_by": None, + "disabled_by_undefined": False, "entry_type": None, "hw_version": None, - "id": "device-1", - "identifiers": [["test", "device-1"]], + "id": "device_1234", + "identifiers": [["test", "device_1"]], "labels": [], "manufacturer": None, "model": None, "model_id": None, "modified_at": "1970-01-01T00:00:00+00:00", - "name": "My Device", "name_by_user": None, - "primary_config_entry": "mock-config-entry", + "name": "My Device", + "primary_config_entry": "mock_entry", "serial_number": None, "sw_version": None, "via_device_id": None, @@ -1591,238 +1587,121 @@ async def test_migration_1_20( "deleted_devices": [], }, } + dr.async_setup(hass) await dr.async_load(hass) - # Entity registry data at version 1.20 + entity_base = { + "aliases": [], + "area_id": None, + "capabilities": {}, + "categories": {}, + "config_entry_id": None, + "config_subentry_id": None, + "created_at": "1970-01-01T00:00:00+00:00", + "device_id": "device_1234", + "disabled_by": None, + "entity_category": None, + "has_entity_name": False, + "hidden_by": None, + "icon": None, + "labels": [], + "modified_at": "1970-01-01T00:00:00+00:00", + "object_id_base": "Temperature", + "options": {}, + "original_device_class": "temperature", + "original_icon": None, + "original_name": "Temperature", + "platform": "super_platform", + "previous_unique_id": None, + "suggested_object_id": None, + "supported_features": 0, + "translation_key": None, + "unit_of_measurement": None, + "device_class": None, + } hass_storage[er.STORAGE_KEY] = { "version": 1, - "minor_version": 20, + "minor_version": 21, "data": { "entities": [ { - # Entity with name=None - # name should be preserved - # should add None to aliases - "aliases": [], - "area_id": None, - "capabilities": {}, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_id": "device-1", - "disabled_by": None, - "entity_category": None, - "entity_id": "test.entity_name_no_custom", - "has_entity_name": True, - "hidden_by": None, - "icon": None, - "id": "entity-1", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": None, - "object_id_base": "Test entity", - "options": {}, - "original_device_class": None, - "original_icon": None, - "original_name": "Test entity", - "platform": "test_platform", - "previous_unique_id": None, - "suggested_object_id": None, - "supported_features": 0, - "translation_key": None, - "unique_id": "unique-1", - "unit_of_measurement": None, - "device_class": None, - }, - { - # Entity with no device_id - # name should be preserved - # should add None to aliases - "aliases": [], - "area_id": None, - "capabilities": {}, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_id": None, - "disabled_by": None, - "entity_category": None, - "entity_id": "test.no_device", - "has_entity_name": True, - "hidden_by": None, - "icon": None, - "id": "entity-2", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": "Standalone Sensor", - "object_id_base": "Test entity", - "options": {}, - "original_device_class": None, - "original_icon": None, - "original_name": "Test entity", - "platform": "test_platform", - "previous_unique_id": None, - "suggested_object_id": None, - "supported_features": 0, - "translation_key": None, - "unique_id": "unique-2", - "unit_of_measurement": None, - "device_class": None, - }, - { - # Entity with name starting with device name - # name should be stripped to remove device name prefix - # should add None to aliases - "aliases": [], - "area_id": None, - "capabilities": {}, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_id": "device-1", - "disabled_by": None, - "entity_category": None, - "entity_id": "test.name_with_device_prefix", - "has_entity_name": True, - "hidden_by": None, - "icon": None, - "id": "entity-3", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": "My device temperature", - "object_id_base": "Test entity", - "options": {}, - "original_device_class": None, - "original_icon": None, - "original_name": "Test entity", - "platform": "test_platform", - "previous_unique_id": None, - "suggested_object_id": None, - "supported_features": 0, - "translation_key": None, - "unique_id": "unique-3", - "unit_of_measurement": None, - "device_class": None, - }, - { - # Entity with custom name not starting with device name - # not exposed to any voice assistant - # name should be preserved - # should add None to aliases - "aliases": [], - "area_id": None, - "capabilities": {}, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_id": "device-1", - "disabled_by": None, - "entity_category": None, + **entity_base, "entity_id": "test.custom_name", - "has_entity_name": True, - "hidden_by": None, - "icon": None, - "id": "entity-4", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": "Living Room Light", - "object_id_base": "Test entity", - "options": {}, - "original_device_class": None, - "original_icon": None, - "original_name": "Test entity", - "platform": "test_platform", - "previous_unique_id": None, - "suggested_object_id": None, - "supported_features": 0, - "translation_key": None, - "unique_id": "unique-4", - "unit_of_measurement": None, - "device_class": None, + "id": "entity_custom_name", + "unique_id": "custom_name", + "name": "My Custom Name", + "name_v2": "My Custom Name", }, { - # Entity with custom name not starting with device name - # exposed to conversation assistant - # name should be preserved - # should add name to aliases - "aliases": [], - "area_id": None, - "capabilities": {}, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_id": "device-1", - "disabled_by": None, - "entity_category": None, - "entity_id": "test.custom_name_exposed", - "has_entity_name": True, - "hidden_by": None, - "icon": None, - "id": "entity-5", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": "Living Room Light", - "object_id_base": "Test entity", - "options": { - "conversation": {"should_expose": True}, - }, - "original_device_class": None, - "original_icon": None, - "original_name": "Test entity", - "platform": "test_platform", - "previous_unique_id": None, - "suggested_object_id": None, - "supported_features": 0, - "translation_key": None, - "unique_id": "unique-5", - "unit_of_measurement": None, - "device_class": None, + **entity_base, + "entity_id": "test.stripped", + "id": "entity_stripped", + "unique_id": "stripped", + "name": "My Device Temperature", + "name_v2": "Temperature", + }, + { + **entity_base, + "entity_id": "test.stripped_and_renamed", + "id": "entity_stripped_and_renamed", + "unique_id": "stripped_and_renamed", + "name": "My Device Temperature", + "name_v2": "Heat", }, ], - "deleted_entities": [ - { - # Deleted entity - # name should be reset to None - # should add None to aliases - "aliases": ["deleted_alias"], - "area_id": None, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_class": None, - "disabled_by": None, - "disabled_by_undefined": False, - "entity_id": "test.deleted_entity", - "hidden_by": None, - "hidden_by_undefined": False, - "icon": None, - "id": "deleted-1", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": "Deleted Name", - "options": {}, - "options_undefined": False, - "orphaned_timestamp": None, - "platform": "test_platform", - "unique_id": "deleted-unique", - } - ], + "deleted_entities": [], }, } await er.async_load(hass) registry = er.async_get(hass) + entry = registry.async_get_or_create("test", "super_platform", "custom_name") + assert entry.name == "My Custom Name" + + entry = registry.async_get_or_create("test", "super_platform", "stripped") + assert entry.name == "My Device Temperature" + + entry = registry.async_get_or_create( + "test", "super_platform", "stripped_and_renamed" + ) + assert entry.name == "My Device Heat" + # Check migrated data await flush_store(registry._store) migrated_data = hass_storage[er.STORAGE_KEY] + + migrated_entity_base = { + "aliases": [], + "aliases_v2": [None], + "area_id": None, + "capabilities": {}, + "categories": {}, + "config_entry_id": None, + "config_subentry_id": None, + "created_at": "1970-01-01T00:00:00+00:00", + "device_id": "device_1234", + "disabled_by": None, + "entity_category": None, + "has_entity_name": False, + "hidden_by": None, + "icon": None, + "labels": [], + "modified_at": "1970-01-01T00:00:00+00:00", + "object_id_base": "Temperature", + "options": {}, + "original_device_class": "temperature", + "original_icon": None, + "original_name": "Temperature", + "platform": "super_platform", + "previous_unique_id": None, + "suggested_object_id": None, + "supported_features": 0, + "translation_key": None, + "unit_of_measurement": None, + "device_class": None, + } assert migrated_data == { "version": er.STORAGE_VERSION_MAJOR, "minor_version": er.STORAGE_VERSION_MINOR, @@ -1830,211 +1709,28 @@ async def test_migration_1_20( "data": { "entities": [ { - "aliases": [], - "aliases_v2": [None], - "area_id": None, - "capabilities": {}, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_id": "device-1", - "disabled_by": None, - "entity_category": None, - "entity_id": "test.entity_name_no_custom", - "has_entity_name": True, - "hidden_by": None, - "icon": None, - "id": "entity-1", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": None, - "name_v2": None, - "object_id_base": "Test entity", - "options": {}, - "original_device_class": None, - "original_icon": None, - "original_name": "Test entity", - "platform": "test_platform", - "previous_unique_id": None, - "suggested_object_id": None, - "supported_features": 0, - "translation_key": None, - "unique_id": "unique-1", - "unit_of_measurement": None, - "device_class": None, - }, - { - "aliases": [], - "aliases_v2": [None], - "area_id": None, - "capabilities": {}, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_id": None, - "disabled_by": None, - "entity_category": None, - "entity_id": "test.no_device", - "has_entity_name": True, - "hidden_by": None, - "icon": None, - "id": "entity-2", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": "Standalone Sensor", - "name_v2": "Standalone Sensor", - "object_id_base": "Test entity", - "options": {}, - "original_device_class": None, - "original_icon": None, - "original_name": "Test entity", - "platform": "test_platform", - "previous_unique_id": None, - "suggested_object_id": None, - "supported_features": 0, - "translation_key": None, - "unique_id": "unique-2", - "unit_of_measurement": None, - "device_class": None, - }, - { - "aliases": [], - "aliases_v2": [None], - "area_id": None, - "capabilities": {}, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_id": "device-1", - "disabled_by": None, - "entity_category": None, - "entity_id": "test.name_with_device_prefix", - "has_entity_name": True, - "hidden_by": None, - "icon": None, - "id": "entity-3", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": "My device temperature", - "name_v2": "Temperature", - "object_id_base": "Test entity", - "options": {}, - "original_device_class": None, - "original_icon": None, - "original_name": "Test entity", - "platform": "test_platform", - "previous_unique_id": None, - "suggested_object_id": None, - "supported_features": 0, - "translation_key": None, - "unique_id": "unique-3", - "unit_of_measurement": None, - "device_class": None, - }, - { - "aliases": [], - "aliases_v2": [None], - "area_id": None, - "capabilities": {}, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_id": "device-1", - "disabled_by": None, - "entity_category": None, + **migrated_entity_base, "entity_id": "test.custom_name", - "has_entity_name": True, - "hidden_by": None, - "icon": None, - "id": "entity-4", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": "Living Room Light", - "name_v2": "Living Room Light", - "object_id_base": "Test entity", - "options": {}, - "original_device_class": None, - "original_icon": None, - "original_name": "Test entity", - "platform": "test_platform", - "previous_unique_id": None, - "suggested_object_id": None, - "supported_features": 0, - "translation_key": None, - "unique_id": "unique-4", - "unit_of_measurement": None, - "device_class": None, + "id": "entity_custom_name", + "unique_id": "custom_name", + "name": "My Custom Name", }, { - "aliases": [], - "aliases_v2": ["Living Room Light"], - "area_id": None, - "capabilities": {}, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_id": "device-1", - "disabled_by": None, - "entity_category": None, - "entity_id": "test.custom_name_exposed", - "has_entity_name": True, - "hidden_by": None, - "icon": None, - "id": "entity-5", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": "Living Room Light", - "name_v2": "Living Room Light", - "object_id_base": "Test entity", - "options": { - "conversation": {"should_expose": True}, - }, - "original_device_class": None, - "original_icon": None, - "original_name": "Test entity", - "platform": "test_platform", - "previous_unique_id": None, - "suggested_object_id": None, - "supported_features": 0, - "translation_key": None, - "unique_id": "unique-5", - "unit_of_measurement": None, - "device_class": None, + **migrated_entity_base, + "entity_id": "test.stripped", + "id": "entity_stripped", + "unique_id": "stripped", + "name": "My Device Temperature", }, - ], - "deleted_entities": [ { - "aliases": ["deleted_alias"], - "aliases_v2": [None, "deleted_alias"], - "area_id": None, - "categories": {}, - "config_entry_id": None, - "config_subentry_id": None, - "created_at": "1970-01-01T00:00:00+00:00", - "device_class": None, - "disabled_by": None, - "disabled_by_undefined": False, - "entity_id": "test.deleted_entity", - "hidden_by": None, - "hidden_by_undefined": False, - "icon": None, - "id": "deleted-1", - "labels": [], - "modified_at": "1970-01-01T00:00:00+00:00", - "name": "Deleted Name", - "name_v2": None, - "options": {}, - "options_undefined": False, - "orphaned_timestamp": None, - "platform": "test_platform", - "unique_id": "deleted-unique", + **migrated_entity_base, + "entity_id": "test.stripped_and_renamed", + "id": "entity_stripped_and_renamed", + "unique_id": "stripped_and_renamed", + "name": "My Device Heat", }, ], + "deleted_entities": [], }, } @@ -3353,7 +3049,7 @@ async def test_has_entity_name_false_device_name_changes( assert updated.original_name_unprefixed == "Light Temperature" updated2 = entity_registry.async_get(entry2.entity_id) - assert updated2.name == "Brightness" + assert updated2.name == "Hue Brightness" assert updated2.original_name_unprefixed is None updated3 = entity_registry.async_get(entry3.entity_id) diff --git a/tests/syrupy.py b/tests/syrupy.py index db173602860..ec795151955 100644 --- a/tests/syrupy.py +++ b/tests/syrupy.py @@ -203,7 +203,6 @@ class HomeAssistantSnapshotSerializer(AmberDataSerializer): ) serialized.pop("categories") serialized.pop("compat_aliases") - serialized.pop("compat_name") serialized.pop("original_name_unprefixed") serialized.pop("_cache") serialized["aliases"] = er._serialize_aliases(serialized["aliases"])