Home Assistant Unofficial Reference 2024.12.1
significant_change.py
Go to the documentation of this file.
1 """Helper to test significant Number state changes."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from homeassistant.const import (
8  ATTR_DEVICE_CLASS,
9  ATTR_UNIT_OF_MEASUREMENT,
10  PERCENTAGE,
11  UnitOfTemperature,
12 )
13 from homeassistant.core import HomeAssistant, callback
15  check_absolute_change,
16  check_percentage_change,
17  check_valid_float,
18 )
19 
20 from .const import NumberDeviceClass
21 
22 
24  old_state: float | None,
25  new_state: float | None,
26  absolute_change: float,
27  percentage_change: float,
28 ) -> bool:
29  return check_absolute_change(
30  old_state, new_state, absolute_change
31  ) and check_percentage_change(old_state, new_state, percentage_change)
32 
33 
34 @callback
36  hass: HomeAssistant,
37  old_state: str,
38  old_attrs: dict,
39  new_state: str,
40  new_attrs: dict,
41  **kwargs: Any,
42 ) -> bool | None:
43  """Test if state significantly changed."""
44  if (device_class := new_attrs.get(ATTR_DEVICE_CLASS)) is None:
45  return None
46 
47  percentage_change: float | None = None
48 
49  # special for temperature
50  if device_class == NumberDeviceClass.TEMPERATURE:
51  if new_attrs.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfTemperature.FAHRENHEIT:
52  absolute_change = 1.0
53  else:
54  absolute_change = 0.5
55 
56  # special for percentage
57  elif device_class in (
58  NumberDeviceClass.BATTERY,
59  NumberDeviceClass.HUMIDITY,
60  NumberDeviceClass.MOISTURE,
61  ):
62  absolute_change = 1.0
63 
64  # special for power factor
65  elif device_class == NumberDeviceClass.POWER_FACTOR:
66  if new_attrs.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE:
67  absolute_change = 1.0
68  else:
69  absolute_change = 0.1
70  percentage_change = 2.0
71 
72  # default for all other classified
73  else:
74  absolute_change = 1.0
75  percentage_change = 2.0
76 
77  if not check_valid_float(new_state):
78  # New state is invalid, don't report it
79  return False
80 
81  if not check_valid_float(old_state):
82  # Old state was invalid, we should report again
83  return True
84 
85  if percentage_change is not None:
87  float(old_state), float(new_state), absolute_change, percentage_change
88  )
89  return check_absolute_change(float(old_state), float(new_state), absolute_change)
bool _absolute_and_relative_change(float|None old_state, float|None new_state, float absolute_change, float percentage_change)
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)
bool check_percentage_change(float|None old_state, float|None new_state, float change)