Home Assistant Unofficial Reference 2024.12.1
significant_change.py
Go to the documentation of this file.
1 """Helper to test significant sensor 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  UnitOfTemperature,
11 )
12 from homeassistant.core import HomeAssistant, callback
14  check_absolute_change,
15  check_percentage_change,
16  check_valid_float,
17 )
18 
19 from . import SensorDeviceClass
20 
21 
23  old_state: float | None,
24  new_state: float | None,
25  absolute_change: float,
26  percentage_change: float,
27 ) -> bool:
28  return check_absolute_change(
29  old_state, new_state, absolute_change
30  ) and check_percentage_change(old_state, new_state, percentage_change)
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 (device_class := new_attrs.get(ATTR_DEVICE_CLASS)) is None:
44  return None
45 
46  absolute_change: float | None = None
47  percentage_change: float | None = None
48  if device_class == SensorDeviceClass.TEMPERATURE:
49  if new_attrs.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfTemperature.FAHRENHEIT:
50  absolute_change = 1.0
51  else:
52  absolute_change = 0.5
53 
54  if device_class in (SensorDeviceClass.BATTERY, SensorDeviceClass.HUMIDITY):
55  absolute_change = 1.0
56 
57  if device_class in (
58  SensorDeviceClass.AQI,
59  SensorDeviceClass.CO,
60  SensorDeviceClass.CO2,
61  SensorDeviceClass.PM25,
62  SensorDeviceClass.PM10,
63  SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS,
64  ):
65  absolute_change = 1.0
66  percentage_change = 2.0
67 
68  if not check_valid_float(new_state):
69  # New state is invalid, don't report it
70  return False
71 
72  if not check_valid_float(old_state):
73  # Old state was invalid, we should report again
74  return True
75 
76  if absolute_change is not None and percentage_change is not None:
78  float(old_state), float(new_state), absolute_change, percentage_change
79  )
80  if absolute_change is not None:
81  return check_absolute_change(
82  float(old_state), float(new_state), absolute_change
83  )
84  return None
bool|None async_check_significant_change(HomeAssistant hass, str old_state, dict old_attrs, str new_state, dict new_attrs, **Any kwargs)
bool _absolute_and_relative_change(float|None old_state, float|None new_state, float absolute_change, float percentage_change)
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)