Home Assistant Unofficial Reference 2024.12.1
significant_change.py
Go to the documentation of this file.
1 """Helper to test significant Water Heater state changes."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from homeassistant.const import UnitOfTemperature
8 from homeassistant.core import HomeAssistant, callback
10  check_absolute_change,
11  check_valid_float,
12 )
13 
14 from . import (
15  ATTR_AWAY_MODE,
16  ATTR_CURRENT_TEMPERATURE,
17  ATTR_OPERATION_MODE,
18  ATTR_TARGET_TEMP_HIGH,
19  ATTR_TARGET_TEMP_LOW,
20  ATTR_TEMPERATURE,
21 )
22 
23 SIGNIFICANT_ATTRIBUTES: set[str] = {
24  ATTR_CURRENT_TEMPERATURE,
25  ATTR_TEMPERATURE,
26  ATTR_TARGET_TEMP_HIGH,
27  ATTR_TARGET_TEMP_LOW,
28  ATTR_OPERATION_MODE,
29  ATTR_AWAY_MODE,
30 }
31 
32 
33 @callback
35  hass: HomeAssistant,
36  old_state: str,
37  old_attrs: dict,
38  new_state: str,
39  new_attrs: dict,
40  **kwargs: Any,
41 ) -> bool | None:
42  """Test if state significantly changed."""
43  if old_state != new_state:
44  return True
45 
46  old_attrs_s = set(
47  {k: v for k, v in old_attrs.items() if k in SIGNIFICANT_ATTRIBUTES}.items()
48  )
49  new_attrs_s = set(
50  {k: v for k, v in new_attrs.items() if k in SIGNIFICANT_ATTRIBUTES}.items()
51  )
52  changed_attrs: set[str] = {item[0] for item in old_attrs_s ^ new_attrs_s}
53  ha_unit = hass.config.units.temperature_unit
54 
55  for attr_name in changed_attrs:
56  if attr_name in [ATTR_OPERATION_MODE, ATTR_AWAY_MODE]:
57  return True
58 
59  old_attr_value = old_attrs.get(attr_name)
60  new_attr_value = new_attrs.get(attr_name)
61  if new_attr_value is None or not check_valid_float(new_attr_value):
62  # New attribute value is invalid, ignore it
63  continue
64 
65  if old_attr_value is None or not check_valid_float(old_attr_value):
66  # Old attribute value was invalid, we should report again
67  return True
68 
69  if ha_unit == UnitOfTemperature.FAHRENHEIT:
70  absolute_change = 1.0
71  else:
72  absolute_change = 0.5
73 
74  if check_absolute_change(old_attr_value, new_attr_value, absolute_change):
75  return True
76 
77  # no significant attribute change detected
78  return False
bool|None async_check_significant_change(HomeAssistant hass, str old_state, dict old_attrs, str new_state, dict new_attrs, **Any kwargs)
bool check_absolute_change(float|None val1, float|None val2, float change)