core/homeassistant/components/group/util.py

58 lines
1.5 KiB
Python

"""Utility functions to combine state attributes from multiple entities."""
from __future__ import annotations
from collections.abc import Callable, Iterator
from itertools import groupby
from typing import Any
from homeassistant.core import State
def find_state_attributes(states: list[State], key: str) -> Iterator[Any]:
"""Find attributes with matching key from states."""
for state in states:
value = state.attributes.get(key)
if value is not None:
yield value
def mean_int(*args: Any) -> int:
"""Return the mean of the supplied values."""
return int(sum(args) / len(args))
def mean_tuple(*args: Any) -> tuple[float | Any, ...]:
"""Return the mean values along the columns of the supplied values."""
return tuple(sum(x) / len(x) for x in zip(*args))
def attribute_equal(states: list[State], key: str) -> bool:
"""Return True if all attributes found matching key from states are equal.
Note: Returns True if no matching attribute is found.
"""
attrs = find_state_attributes(states, key)
grp = groupby(attrs)
return bool(next(grp, True) and not next(grp, False))
def reduce_attribute(
states: list[State],
key: str,
default: Any | None = None,
reduce: Callable[..., Any] = mean_int,
) -> Any:
"""Find the first attribute matching key from states.
If none are found, return default.
"""
attrs = list(find_state_attributes(states, key))
if not attrs:
return default
if len(attrs) == 1:
return attrs[0]
return reduce(*attrs)