Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a template function to access area attributes #136974

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions homeassistant/helpers/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -1649,6 +1649,19 @@ def area_devices(hass: HomeAssistant, area_id_or_name: str) -> Iterable[str]:
return [entry.id for entry in entries]


def area_attr(hass: HomeAssistant, area_id_or_name: str, attr_name: str) -> Any:
"""Get area specific attribute."""
area_reg = area_registry.async_get(hass)
area = area_reg.async_get_area(area_id_or_name) or area_reg.async_get_area_by_name(
area_id_or_name
)

if area is None or not hasattr(area, attr_name):
return None

return getattr(area, attr_name)


def labels(hass: HomeAssistant, lookup_value: Any = None) -> Iterable[str | None]:
"""Return all labels, or those from a area ID, device ID, or entity ID."""
label_reg = label_registry.async_get(hass)
Expand Down Expand Up @@ -3036,6 +3049,9 @@ def wrapper(_: Any, *args: _P.args, **kwargs: _P.kwargs) -> _R:
self.globals["area_devices"] = hassfunction(area_devices)
self.filters["area_devices"] = self.globals["area_devices"]

self.globals["area_attr"] = hassfunction(area_attr)
self.filters["area_attr"] = self.globals["area_attr"]

self.globals["floors"] = hassfunction(floors)
self.filters["floors"] = self.globals["floors"]

Expand Down
57 changes: 57 additions & 0 deletions tests/helpers/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

from homeassistant import config_entries
from homeassistant.components import group
from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_UNIT_OF_MEASUREMENT,
STATE_ON,
STATE_UNAVAILABLE,
Expand Down Expand Up @@ -4414,6 +4416,61 @@ async def test_area_devices(
assert info.rate_limit is None


async def test_area_attr(
hass: HomeAssistant,
area_registry: ar.AreaRegistry,
device_registry: dr.DeviceRegistry,
) -> None:
"""Test area_attr functions."""
# Test non existing area id (area_attr)
info = render_to_info(hass, "{{ area_attr('deadbeef', 'name') }}")
assert_result_info(info, None)
assert info.rate_limit is None

# Test non existing area name (area_attr)
info = render_to_info(hass, "{{ area_attr('fake area name', 'name') }}")
assert_result_info(info, None)
assert info.rate_limit is None

# Test wrong value type (area_attr)
info = render_to_info(hass, "{{ area_attr('56', 'name') }}")
assert_result_info(info, None)
assert info.rate_limit is None

hass.states.async_set(
"sensor.mock_temperature",
"20",
{
ATTR_DEVICE_CLASS: SensorDeviceClass.TEMPERATURE,
ATTR_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS,
},
)

area_entry = area_registry.async_get_or_create("sensor.fake")
area_registry.async_update(
area_entry.id, temperature_entity_id="sensor.mock_temperature"
)

# Test non existent area attribute (area_attr)
info = render_to_info(
hass, f"{{{{ area_attr('{area_entry.id}', 'invalid_attr') }}}}"
)
assert_result_info(info, None)
assert info.rate_limit is None

# Test temperature_entity_id area attribute (area_attr)
info = render_to_info(
hass, f"{{{{ area_attr('{area_entry.id}', 'temperature_entity_id') }}}}"
)
assert_result_info(info, "sensor.mock_temperature")

# Test temperature_entity_id area attribute (area_attr)
info = render_to_info(
hass, f"{{{{ area_attr('{area_entry.name}', 'temperature_entity_id') }}}}"
)
assert_result_info(info, "sensor.mock_temperature")


def test_closest_function_to_coord(hass: HomeAssistant) -> None:
"""Test closest function to coord."""
hass.states.async_set(
Expand Down