From 88e50be4d4553dc5260f693251f3c0c7a267b92f Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 29 Jun 2023 08:59:10 -0400 Subject: [PATCH 1/3] Default device name to config entry title --- homeassistant/helpers/entity_platform.py | 15 +++---- tests/helpers/test_entity_platform.py | 50 ++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index 675d368873af5..2930652c19eaa 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -608,18 +608,13 @@ async def _async_add_entity( # noqa: C901 entity.add_to_platform_abort() return - if self.config_entry is not None: - config_entry_id: str | None = self.config_entry.entry_id - else: - config_entry_id = None - device_info = entity.device_info device_id = None device = None - if config_entry_id is not None and device_info is not None: + if self.config_entry and device_info is not None: processed_dev_info: dict[str, str | None] = { - "config_entry_id": config_entry_id + "config_entry_id": self.config_entry.entry_id } for key in ( "connections", @@ -641,6 +636,12 @@ async def _async_add_entity( # noqa: C901 key # type: ignore[literal-required] ] + if ( + "default_name" not in processed_dev_info + and not processed_dev_info.get("name") + ): + processed_dev_info["name"] = self.config_entry.title + if "configuration_url" in device_info: if device_info["configuration_url"] is None: processed_dev_info["configuration_url"] = None diff --git a/tests/helpers/test_entity_platform.py b/tests/helpers/test_entity_platform.py index 46806510f4026..df4f4d1c6439a 100644 --- a/tests/helpers/test_entity_platform.py +++ b/tests/helpers/test_entity_platform.py @@ -1827,3 +1827,53 @@ async def async_setup_entry(hass, config_entry, async_add_entities): assert len(hass.states.async_entity_ids()) == 1 assert registry.async_get(expected_entity_id) is not None + + +@pytest.mark.parametrize( + ("entity_device_name", "entity_device_default_name", "expected_device_name"), + [ + (None, None, "Mock Config Entry Title"), + ("", None, "Mock Config Entry Title"), + (None, "Hello", "Hello"), + ("Mock Device Name", None, "Mock Device Name"), + ], +) +async def test_device_name_defaulting_config_entry( + hass: HomeAssistant, + entity_device_name: str, + entity_device_default_name: str, + expected_device_name: str, +) -> None: + """Test setting the device name based on input info.""" + device_info = { + "identifiers": {("hue", "1234")}, + "name": entity_device_name, + } + + if entity_device_default_name: + device_info["default_name"] = entity_device_default_name + + class DeviceNameEntity(Entity): + _attr_unique_id = "qwer" + _attr_device_info = device_info + + async def async_setup_entry(hass, config_entry, async_add_entities): + """Mock setup entry method.""" + async_add_entities([DeviceNameEntity()]) + return True + + platform = MockPlatform(async_setup_entry=async_setup_entry) + config_entry = MockConfigEntry( + title="Mock Config Entry Title", entry_id="super-mock-id" + ) + entity_platform = MockEntityPlatform( + hass, platform_name=config_entry.domain, platform=platform + ) + + assert await entity_platform.async_setup_entry(config_entry) + await hass.async_block_till_done() + + dev_reg = dr.async_get(hass) + device = dev_reg.async_get_device({("hue", "1234")}) + assert device is not None + assert device.name == expected_device_name From 592e2973bc3cac31f68d5fdf34ea6b321c507df1 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 29 Jun 2023 13:20:52 -0400 Subject: [PATCH 2/3] Only apply name default if device info provided --- homeassistant/helpers/entity_platform.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index 2930652c19eaa..97588bd0acf44 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -613,9 +613,7 @@ async def _async_add_entity( # noqa: C901 device = None if self.config_entry and device_info is not None: - processed_dev_info: dict[str, str | None] = { - "config_entry_id": self.config_entry.entry_id - } + processed_dev_info: dict[str, str | None] = {} for key in ( "connections", "default_manufacturer", @@ -637,7 +635,9 @@ async def _async_add_entity( # noqa: C901 ] if ( - "default_name" not in processed_dev_info + # device info that is purely meant for linking doesn't need default name + set(processed_dev_info) > {"identifiers", "connections"} + and "default_name" not in processed_dev_info and not processed_dev_info.get("name") ): processed_dev_info["name"] = self.config_entry.title @@ -661,7 +661,8 @@ async def _async_add_entity( # noqa: C901 try: device = device_registry.async_get_or_create( - **processed_dev_info # type: ignore[arg-type] + config_entry_id=self.config_entry.entry_id, + **processed_dev_info, # type: ignore[arg-type] ) device_id = device.id except RequiredParameterMissing: From 456232f821cc4fbaa7e52c111d8414ea1062b3f9 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 29 Jun 2023 21:59:36 -0400 Subject: [PATCH 3/3] Fix logic detecting type of device info --- homeassistant/helpers/entity_platform.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index 97588bd0acf44..66a74edf8f91a 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -636,7 +636,10 @@ async def _async_add_entity( # noqa: C901 if ( # device info that is purely meant for linking doesn't need default name - set(processed_dev_info) > {"identifiers", "connections"} + any( + key not in {"identifiers", "connections"} + for key in (processed_dev_info) + ) and "default_name" not in processed_dev_info and not processed_dev_info.get("name") ):