mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 04:07:08 +00:00
Add floor template functions (#110847)
This commit is contained in:
parent
25be71e05b
commit
fc6a83559f
@ -83,6 +83,7 @@ from . import (
|
|||||||
area_registry,
|
area_registry,
|
||||||
device_registry,
|
device_registry,
|
||||||
entity_registry,
|
entity_registry,
|
||||||
|
floor_registry as fr,
|
||||||
issue_registry,
|
issue_registry,
|
||||||
location as loc_helper,
|
location as loc_helper,
|
||||||
)
|
)
|
||||||
@ -1387,6 +1388,45 @@ def issue(hass: HomeAssistant, domain: str, issue_id: str) -> dict[str, Any] | N
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def floors(hass: HomeAssistant) -> Iterable[str | None]:
|
||||||
|
"""Return all floors."""
|
||||||
|
floor_registry = fr.async_get(hass)
|
||||||
|
return [floor.floor_id for floor in floor_registry.async_list_floors()]
|
||||||
|
|
||||||
|
|
||||||
|
def floor_id(hass: HomeAssistant, lookup_value: Any) -> str | None:
|
||||||
|
"""Get the floor ID from a floor name."""
|
||||||
|
floor_registry = fr.async_get(hass)
|
||||||
|
if floor := floor_registry.async_get_floor_by_name(str(lookup_value)):
|
||||||
|
return floor.floor_id
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def floor_name(hass: HomeAssistant, lookup_value: str) -> str | None:
|
||||||
|
"""Get the floor name from a floor id."""
|
||||||
|
floor_registry = fr.async_get(hass)
|
||||||
|
if floor := floor_registry.async_get_floor(lookup_value):
|
||||||
|
return floor.name
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def floor_areas(hass: HomeAssistant, floor_id_or_name: str) -> Iterable[str]:
|
||||||
|
"""Return area IDs for a given floor ID or name."""
|
||||||
|
_floor_id: str | None
|
||||||
|
# If floor_name returns a value, we know the input was an ID, otherwise we
|
||||||
|
# assume it's a name, and if it's neither, we return early
|
||||||
|
if floor_name(hass, floor_id_or_name) is not None:
|
||||||
|
_floor_id = floor_id_or_name
|
||||||
|
else:
|
||||||
|
_floor_id = floor_id(hass, floor_id_or_name)
|
||||||
|
if _floor_id is None:
|
||||||
|
return []
|
||||||
|
|
||||||
|
area_reg = area_registry.async_get(hass)
|
||||||
|
entries = area_registry.async_entries_for_floor(area_reg, _floor_id)
|
||||||
|
return [entry.id for entry in entries if entry.id]
|
||||||
|
|
||||||
|
|
||||||
def areas(hass: HomeAssistant) -> Iterable[str | None]:
|
def areas(hass: HomeAssistant) -> Iterable[str | None]:
|
||||||
"""Return all areas."""
|
"""Return all areas."""
|
||||||
area_reg = area_registry.async_get(hass)
|
area_reg = area_registry.async_get(hass)
|
||||||
@ -2668,6 +2708,18 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
|
|||||||
self.globals["area_devices"] = hassfunction(area_devices)
|
self.globals["area_devices"] = hassfunction(area_devices)
|
||||||
self.filters["area_devices"] = self.globals["area_devices"]
|
self.filters["area_devices"] = self.globals["area_devices"]
|
||||||
|
|
||||||
|
self.globals["floors"] = hassfunction(floors)
|
||||||
|
self.filters["floors"] = self.globals["floors"]
|
||||||
|
|
||||||
|
self.globals["floor_id"] = hassfunction(floor_id)
|
||||||
|
self.filters["floor_id"] = self.globals["floor_id"]
|
||||||
|
|
||||||
|
self.globals["floor_name"] = hassfunction(floor_name)
|
||||||
|
self.filters["floor_name"] = self.globals["floor_name"]
|
||||||
|
|
||||||
|
self.globals["floor_areas"] = hassfunction(floor_areas)
|
||||||
|
self.filters["floor_areas"] = self.globals["floor_areas"]
|
||||||
|
|
||||||
self.globals["integration_entities"] = hassfunction(integration_entities)
|
self.globals["integration_entities"] = hassfunction(integration_entities)
|
||||||
self.filters["integration_entities"] = self.globals["integration_entities"]
|
self.filters["integration_entities"] = self.globals["integration_entities"]
|
||||||
|
|
||||||
@ -2700,6 +2752,8 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
|
|||||||
"device_id",
|
"device_id",
|
||||||
"area_id",
|
"area_id",
|
||||||
"area_name",
|
"area_name",
|
||||||
|
"floor_id",
|
||||||
|
"floor_name",
|
||||||
"relative_time",
|
"relative_time",
|
||||||
"today_at",
|
"today_at",
|
||||||
]
|
]
|
||||||
@ -2709,6 +2763,8 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
|
|||||||
"device_id",
|
"device_id",
|
||||||
"area_id",
|
"area_id",
|
||||||
"area_name",
|
"area_name",
|
||||||
|
"floor_id",
|
||||||
|
"floor_name",
|
||||||
"has_value",
|
"has_value",
|
||||||
]
|
]
|
||||||
hass_tests = [
|
hass_tests = [
|
||||||
|
@ -38,6 +38,7 @@ from homeassistant.helpers import (
|
|||||||
device_registry as dr,
|
device_registry as dr,
|
||||||
entity,
|
entity,
|
||||||
entity_registry as er,
|
entity_registry as er,
|
||||||
|
floor_registry as fr,
|
||||||
issue_registry as ir,
|
issue_registry as ir,
|
||||||
template,
|
template,
|
||||||
translation,
|
translation,
|
||||||
@ -5167,3 +5168,144 @@ async def test_lru_increases_with_many_entities(hass: HomeAssistant) -> None:
|
|||||||
assert template.CACHED_TEMPLATE_NO_COLLECT_LRU.get_size() == int(
|
assert template.CACHED_TEMPLATE_NO_COLLECT_LRU.get_size() == int(
|
||||||
round(mock_entity_count * template.ENTITY_COUNT_GROWTH_FACTOR)
|
round(mock_entity_count * template.ENTITY_COUNT_GROWTH_FACTOR)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_floors(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
floor_registry: fr.FloorRegistry,
|
||||||
|
) -> None:
|
||||||
|
"""Test floors function."""
|
||||||
|
|
||||||
|
# Test no floors
|
||||||
|
info = render_to_info(hass, "{{ floors() }}")
|
||||||
|
assert_result_info(info, [])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Test one floor
|
||||||
|
floor1 = floor_registry.async_create("First floor")
|
||||||
|
info = render_to_info(hass, "{{ floors() }}")
|
||||||
|
assert_result_info(info, [floor1.floor_id])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Test multiple floors
|
||||||
|
floor2 = floor_registry.async_create("Second floor")
|
||||||
|
info = render_to_info(hass, "{{ floors() }}")
|
||||||
|
assert_result_info(info, [floor1.floor_id, floor2.floor_id])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_floor_id(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
floor_registry: fr.FloorRegistry,
|
||||||
|
) -> None:
|
||||||
|
"""Test floor_id function."""
|
||||||
|
|
||||||
|
# Test non existing floor name
|
||||||
|
info = render_to_info(hass, "{{ floor_id('Third floor') }}")
|
||||||
|
assert_result_info(info, None)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
info = render_to_info(hass, "{{ 'Third floor' | floor_id }}")
|
||||||
|
assert_result_info(info, None)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Test wrong value type
|
||||||
|
info = render_to_info(hass, "{{ floor_id(42) }}")
|
||||||
|
assert_result_info(info, None)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
info = render_to_info(hass, "{{ 42 | floor_id }}")
|
||||||
|
assert_result_info(info, None)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Test with an actual floor
|
||||||
|
floor = floor_registry.async_create("First floor")
|
||||||
|
info = render_to_info(hass, "{{ floor_id('First floor') }}")
|
||||||
|
assert_result_info(info, floor.floor_id)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
info = render_to_info(hass, "{{ 'First floor' | floor_id }}")
|
||||||
|
assert_result_info(info, floor.floor_id)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_floor_name(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
floor_registry: fr.FloorRegistry,
|
||||||
|
) -> None:
|
||||||
|
"""Test floor_name function."""
|
||||||
|
# Test non existing floor ID
|
||||||
|
info = render_to_info(hass, "{{ floor_name('third_floor') }}")
|
||||||
|
assert_result_info(info, None)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
info = render_to_info(hass, "{{ 'third_floor' | floor_name }}")
|
||||||
|
assert_result_info(info, None)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Test wrong value type
|
||||||
|
info = render_to_info(hass, "{{ floor_name(42) }}")
|
||||||
|
assert_result_info(info, None)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
info = render_to_info(hass, "{{ 42 | floor_name }}")
|
||||||
|
assert_result_info(info, None)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Test existing floor ID
|
||||||
|
floor = floor_registry.async_create("First floor")
|
||||||
|
info = render_to_info(hass, f"{{{{ floor_name('{floor.floor_id}') }}}}")
|
||||||
|
assert_result_info(info, floor.name)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
info = render_to_info(hass, f"{{{{ '{floor.floor_id}' | floor_name }}}}")
|
||||||
|
assert_result_info(info, floor.name)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_floor_areas(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
floor_registry: fr.FloorRegistry,
|
||||||
|
area_registry: ar.AreaRegistry,
|
||||||
|
) -> None:
|
||||||
|
"""Test floor_areas function."""
|
||||||
|
|
||||||
|
# Test non existing floor ID
|
||||||
|
info = render_to_info(hass, "{{ floor_areas('skyring') }}")
|
||||||
|
assert_result_info(info, [])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
info = render_to_info(hass, "{{ 'skyring' | floor_areas }}")
|
||||||
|
assert_result_info(info, [])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Test wrong value type
|
||||||
|
info = render_to_info(hass, "{{ floor_areas(42) }}")
|
||||||
|
assert_result_info(info, [])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
info = render_to_info(hass, "{{ 42 | floor_areas }}")
|
||||||
|
assert_result_info(info, [])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
floor = floor_registry.async_create("First floor")
|
||||||
|
area = area_registry.async_create("Living room")
|
||||||
|
area_registry.async_update(area.id, floor_id=floor.floor_id)
|
||||||
|
|
||||||
|
# Get areas by floor ID
|
||||||
|
info = render_to_info(hass, f"{{{{ floor_areas('{floor.floor_id}') }}}}")
|
||||||
|
assert_result_info(info, [area.id])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
info = render_to_info(hass, f"{{{{ '{floor.floor_id}' | floor_areas }}}}")
|
||||||
|
assert_result_info(info, [area.id])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Get entities by floor name
|
||||||
|
info = render_to_info(hass, f"{{{{ floor_areas('{floor.name}') }}}}")
|
||||||
|
assert_result_info(info, [area.id])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
info = render_to_info(hass, f"{{{{ '{floor.name}' | floor_areas }}}}")
|
||||||
|
assert_result_info(info, [area.id])
|
||||||
|
assert info.rate_limit is None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user