Warn if a sensor with state_class_total has a decreasing value (#55197)

This commit is contained in:
Erik Montnemery
2021-08-25 13:01:55 +02:00
committed by GitHub
parent ffbd2d79c8
commit bb42eb1176
3 changed files with 46 additions and 4 deletions

View File

@ -298,7 +298,12 @@ class EnergyCostSensor(SensorEntity):
)
return
if reset_detected(energy, float(self._last_energy_sensor_state)):
if reset_detected(
self.hass,
cast(str, self._config[self._adapter.entity_energy_key]),
energy,
float(self._last_energy_sensor_state),
):
# Energy meter was reset, reset cost sensor too
self._reset(0)
# Update with newly incurred cost

View File

@ -39,6 +39,7 @@ from homeassistant.const import (
VOLUME_CUBIC_METERS,
)
from homeassistant.core import HomeAssistant, State
from homeassistant.helpers.entity import entity_sources
import homeassistant.util.dt as dt_util
import homeassistant.util.pressure as pressure_util
import homeassistant.util.temperature as temperature_util
@ -106,6 +107,8 @@ UNIT_CONVERSIONS: dict[str, dict[str, Callable]] = {
},
}
# Keep track of entities for which a warning about decreasing value has been logged
WARN_DIP = "sensor_warn_total_increasing_dip"
# Keep track of entities for which a warning about unsupported unit has been logged
WARN_UNSUPPORTED_UNIT = "sensor_warn_unsupported_unit"
WARN_UNSTABLE_UNIT = "sensor_warn_unstable_unit"
@ -229,9 +232,36 @@ def _normalize_states(
return DEVICE_CLASS_UNITS[device_class], fstates
def reset_detected(state: float, previous_state: float | None) -> bool:
def warn_dip(hass: HomeAssistant, entity_id: str) -> None:
"""Log a warning once if a sensor with state_class_total has a decreasing value."""
if WARN_DIP not in hass.data:
hass.data[WARN_DIP] = set()
if entity_id not in hass.data[WARN_DIP]:
hass.data[WARN_DIP].add(entity_id)
domain = entity_sources(hass).get(entity_id, {}).get("domain")
if domain in ["energy", "growatt_server", "solaredge"]:
return
_LOGGER.warning(
"Entity %s %shas state class total_increasing, but its state is "
"not strictly increasing. Please create a bug report at %s",
entity_id,
f"from integration {domain} " if domain else "",
"https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue"
"+label%3A%22integration%3A+recorder%22",
)
def reset_detected(
hass: HomeAssistant, entity_id: str, state: float, previous_state: float | None
) -> bool:
"""Test if a total_increasing sensor has been reset."""
return previous_state is not None and state < 0.9 * previous_state
if previous_state is None:
return False
if 0.9 * previous_state <= state < previous_state:
warn_dip(hass, entity_id)
return state < 0.9 * previous_state
def compile_statistics(
@ -337,7 +367,8 @@ def compile_statistics(
fstate,
)
elif state_class == STATE_CLASS_TOTAL_INCREASING and (
old_state is None or reset_detected(fstate, new_state)
old_state is None
or reset_detected(hass, entity_id, fstate, new_state)
):
reset = True
_LOGGER.info(

View File

@ -427,6 +427,12 @@ def test_compile_hourly_sum_statistics_total_increasing_small_dip(
]
}
assert "Error while processing event StatisticsTask" not in caplog.text
assert (
"Entity sensor.test1 has state class total_increasing, but its state is not "
"strictly increasing. Please create a bug report at https://github.com/"
"home-assistant/core/issues?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A"
"+recorder%22"
) in caplog.text
def test_compile_hourly_energy_statistics_unsupported(hass_recorder, caplog):