Add template function: device_name (#142683)

This commit is contained in:
Paul Bottein 2025-04-14 14:30:00 +02:00 committed by GitHub
parent 5f2ae37ee5
commit 8ec436423f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 85 additions and 0 deletions

View File

@ -1413,6 +1413,28 @@ def device_id(hass: HomeAssistant, entity_id_or_device_name: str) -> str | None:
)
def device_name(hass: HomeAssistant, lookup_value: str) -> str | None:
"""Get the device name from an device id, or entity id."""
device_reg = device_registry.async_get(hass)
if device := device_reg.async_get(lookup_value):
return device.name_by_user or device.name
ent_reg = entity_registry.async_get(hass)
# Import here, not at top-level to avoid circular import
from . import config_validation as cv # pylint: disable=import-outside-toplevel
try:
cv.entity_id(lookup_value)
except vol.Invalid:
pass
else:
if entity := ent_reg.async_get(lookup_value):
if entity.device_id and (device := device_reg.async_get(entity.device_id)):
return device.name_by_user or device.name
return None
def device_attr(hass: HomeAssistant, device_or_entity_id: str, attr_name: str) -> Any:
"""Get the device specific attribute."""
device_reg = device_registry.async_get(hass)
@ -3230,6 +3252,9 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
# Device extensions
self.globals["device_name"] = hassfunction(device_name)
self.filters["device_name"] = self.globals["device_name"]
self.globals["device_attr"] = hassfunction(device_attr)
self.filters["device_attr"] = self.globals["device_attr"]

View File

@ -3887,6 +3887,66 @@ async def test_device_id(
assert info.rate_limit is None
async def test_device_name(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test device_name function."""
config_entry = MockConfigEntry(domain="light")
config_entry.add_to_hass(hass)
# Test non existing entity id
info = render_to_info(hass, "{{ device_name('sensor.fake') }}")
assert_result_info(info, None)
assert info.rate_limit is None
# Test non existing device id
info = render_to_info(hass, "{{ device_name('1234567890') }}")
assert_result_info(info, None)
assert info.rate_limit is None
# Test wrong value type
info = render_to_info(hass, "{{ device_name(56) }}")
assert_result_info(info, None)
assert info.rate_limit is None
# Test device with single entity
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="A light",
)
entity_entry = entity_registry.async_get_or_create(
"light",
"hue",
"5678",
config_entry=config_entry,
device_id=device_entry.id,
)
info = render_to_info(hass, f"{{{{ device_name('{device_entry.id}') }}}}")
assert_result_info(info, device_entry.name)
assert info.rate_limit is None
info = render_to_info(hass, f"{{{{ device_name('{entity_entry.entity_id}') }}}}")
assert_result_info(info, device_entry.name)
assert info.rate_limit is None
# Test device after renaming
device_entry = device_registry.async_update_device(
device_entry.id,
name_by_user="My light",
)
info = render_to_info(hass, f"{{{{ device_name('{device_entry.id}') }}}}")
assert_result_info(info, device_entry.name_by_user)
assert info.rate_limit is None
info = render_to_info(hass, f"{{{{ device_name('{entity_entry.entity_id}') }}}}")
assert_result_info(info, device_entry.name_by_user)
assert info.rate_limit is None
async def test_device_attr(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,