Home Assistant Unofficial Reference 2024.12.1
util.py
Go to the documentation of this file.
1 """Utility functions to combine state attributes from multiple entities."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable, Iterator
6 from itertools import groupby
7 from typing import Any
8 
9 from homeassistant.core import State
10 
11 
12 def find_state_attributes(states: list[State], key: str) -> Iterator[Any]:
13  """Find attributes with matching key from states."""
14  for state in states:
15  if (value := state.attributes.get(key)) is not None:
16  yield value
17 
18 
19 def find_state(states: list[State]) -> Iterator[Any]:
20  """Find state from states."""
21  for state in states:
22  yield state.state
23 
24 
25 def mean_int(*args: Any) -> int:
26  """Return the mean of the supplied values."""
27  return int(sum(args) / len(args))
28 
29 
30 def mean_tuple(*args: Any) -> tuple[float | Any, ...]:
31  """Return the mean values along the columns of the supplied values."""
32  return tuple(sum(x) / len(x) for x in zip(*args, strict=False))
33 
34 
35 def attribute_equal(states: list[State], key: str) -> bool:
36  """Return True if all attributes found matching key from states are equal.
37 
38  Note: Returns True if no matching attribute is found.
39  """
40  return _values_equal(find_state_attributes(states, key))
41 
42 
43 def most_frequent_attribute(states: list[State], key: str) -> Any | None:
44  """Find attributes with matching key from states."""
45  if attrs := list(find_state_attributes(states, key)):
46  return max(set(attrs), key=attrs.count)
47  return None
48 
49 
50 def states_equal(states: list[State]) -> bool:
51  """Return True if all states are equal.
52 
53  Note: Returns True if no matching attribute is found.
54  """
55  return _values_equal(find_state(states))
56 
57 
58 def _values_equal(values: Iterator[Any]) -> bool:
59  """Return True if all values are equal.
60 
61  Note: Returns True if no matching attribute is found.
62  """
63  grp = groupby(values)
64  return bool(next(grp, True) and not next(grp, False))
65 
66 
68  states: list[State],
69  key: str,
70  default: Any | None = None,
71  reduce: Callable[..., Any] = mean_int,
72 ) -> Any:
73  """Find the first attribute matching key from states.
74 
75  If none are found, return default.
76  """
77  attrs = list(find_state_attributes(states, key))
78 
79  if not attrs:
80  return default
81 
82  if len(attrs) == 1:
83  return attrs[0]
84 
85  return reduce(*attrs)
bool attribute_equal(list[State] states, str key)
Definition: util.py:35
bool states_equal(list[State] states)
Definition: util.py:50
Iterator[Any] find_state_attributes(list[State] states, str key)
Definition: util.py:12
tuple[float|Any,...] mean_tuple(*Any args)
Definition: util.py:30
Any|None most_frequent_attribute(list[State] states, str key)
Definition: util.py:43
bool _values_equal(Iterator[Any] values)
Definition: util.py:58
Any reduce_attribute(list[State] states, str key, Any|None default=None, Callable[..., Any] reduce=mean_int)
Definition: util.py:72
Iterator[Any] find_state(list[State] states)
Definition: util.py:19