From 4d98a7e1562e6e11746f34031fb0b2b86cf89506 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 31 Aug 2021 08:56:47 -0400 Subject: [PATCH] Allow device_id template function to use device name as input (#55474) --- homeassistant/helpers/template.py | 24 ++++++++++++++++-------- tests/helpers/test_template.py | 15 +++++++++------ 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index ade580694c8..4e9f9c432e0 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -914,15 +914,23 @@ def device_entities(hass: HomeAssistant, _device_id: str) -> Iterable[str]: return [entry.entity_id for entry in entries] -def device_id(hass: HomeAssistant, entity_id: str) -> str | None: - """Get a device ID from an entity ID.""" - if not isinstance(entity_id, str) or "." not in entity_id: - raise TemplateError(f"Must provide an entity ID, got {entity_id}") # type: ignore +def device_id(hass: HomeAssistant, entity_id_or_device_name: str) -> str | None: + """Get a device ID from an entity ID or device name.""" entity_reg = entity_registry.async_get(hass) - entity = entity_reg.async_get(entity_id) - if entity is None: - return None - return entity.device_id + entity = entity_reg.async_get(entity_id_or_device_name) + if entity is not None: + return entity.device_id + + dev_reg = device_registry.async_get(hass) + return next( + ( + id + for id, device in dev_reg.devices.items() + if (name := device.name_by_user or device.name) + and (str(entity_id_or_device_name) == name) + ), + None, + ) def device_attr(hass: HomeAssistant, device_or_entity_id: str, attr_name: str) -> Any: diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 64b075b685a..d10ef114992 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -1599,6 +1599,7 @@ async def test_device_id(hass): config_entry_id=config_entry.entry_id, connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, model="test", + name="test", ) entity_entry = entity_registry.async_get_or_create( "sensor", "test", "test", suggested_object_id="test", device_id=device_entry.id @@ -1611,13 +1612,11 @@ async def test_device_id(hass): assert_result_info(info, None) assert info.rate_limit is None - with pytest.raises(TemplateError): - info = render_to_info(hass, "{{ 56 | device_id }}") - assert_result_info(info, None) + info = render_to_info(hass, "{{ 56 | device_id }}") + assert_result_info(info, None) - with pytest.raises(TemplateError): - info = render_to_info(hass, "{{ 'not_a_real_entity_id' | device_id }}") - assert_result_info(info, None) + info = render_to_info(hass, "{{ 'not_a_real_entity_id' | device_id }}") + assert_result_info(info, None) info = render_to_info( hass, f"{{{{ device_id('{entity_entry_no_device.entity_id}') }}}}" @@ -1629,6 +1628,10 @@ async def test_device_id(hass): assert_result_info(info, device_entry.id) assert info.rate_limit is None + info = render_to_info(hass, "{{ device_id('test') }}") + assert_result_info(info, device_entry.id) + assert info.rate_limit is None + async def test_device_attr(hass): """Test device_attr and is_device_attr functions."""