Warn if total_increasing sensor has negative states (#56564)
This commit is contained in:
parent
3a56e3a823
commit
6954614e62
5 changed files with 188 additions and 27 deletions
|
@ -8,6 +8,7 @@ from unittest.mock import patch
|
|||
import pytest
|
||||
from pytest import approx
|
||||
|
||||
from homeassistant import loader
|
||||
from homeassistant.components.recorder import history
|
||||
from homeassistant.components.recorder.const import DATA_INSTANCE
|
||||
from homeassistant.components.recorder.models import process_timestamp_to_utc_isoformat
|
||||
|
@ -609,6 +610,114 @@ def test_compile_hourly_sum_statistics_nan_inf_state(
|
|||
assert "Error while processing event StatisticsTask" not in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"entity_id,warning_1,warning_2",
|
||||
[
|
||||
(
|
||||
"sensor.test1",
|
||||
"",
|
||||
"bug report at https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue",
|
||||
),
|
||||
(
|
||||
"sensor.today_energy",
|
||||
"from integration demo ",
|
||||
"bug report at https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+demo%22",
|
||||
),
|
||||
(
|
||||
"sensor.custom_sensor",
|
||||
"from integration test ",
|
||||
"report it to the custom component author",
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("state_class", ["total_increasing"])
|
||||
@pytest.mark.parametrize(
|
||||
"device_class,unit,native_unit,factor",
|
||||
[
|
||||
("energy", "kWh", "kWh", 1),
|
||||
],
|
||||
)
|
||||
def test_compile_hourly_sum_statistics_negative_state(
|
||||
hass_recorder,
|
||||
caplog,
|
||||
entity_id,
|
||||
warning_1,
|
||||
warning_2,
|
||||
state_class,
|
||||
device_class,
|
||||
unit,
|
||||
native_unit,
|
||||
factor,
|
||||
):
|
||||
"""Test compiling hourly statistics with negative states."""
|
||||
zero = dt_util.utcnow()
|
||||
hass = hass_recorder()
|
||||
hass.data.pop(loader.DATA_CUSTOM_COMPONENTS)
|
||||
recorder = hass.data[DATA_INSTANCE]
|
||||
|
||||
platform = getattr(hass.components, "test.sensor")
|
||||
platform.init(empty=True)
|
||||
mocksensor = platform.MockSensor(name="custom_sensor")
|
||||
mocksensor._attr_should_poll = False
|
||||
platform.ENTITIES["custom_sensor"] = mocksensor
|
||||
|
||||
setup_component(
|
||||
hass, "sensor", {"sensor": [{"platform": "demo"}, {"platform": "test"}]}
|
||||
)
|
||||
hass.block_till_done()
|
||||
attributes = {
|
||||
"device_class": device_class,
|
||||
"state_class": state_class,
|
||||
"unit_of_measurement": unit,
|
||||
}
|
||||
seq = [15, 16, 15, 16, 20, -20, 20, 10]
|
||||
|
||||
states = {entity_id: []}
|
||||
if state := hass.states.get(entity_id):
|
||||
states[entity_id].append(state)
|
||||
one = zero
|
||||
for i in range(len(seq)):
|
||||
one = one + timedelta(seconds=5)
|
||||
_states = record_meter_state(hass, one, entity_id, attributes, seq[i : i + 1])
|
||||
states[entity_id].extend(_states[entity_id])
|
||||
|
||||
hist = history.get_significant_states(
|
||||
hass,
|
||||
zero - timedelta.resolution,
|
||||
one + timedelta.resolution,
|
||||
significant_changes_only=False,
|
||||
)
|
||||
assert dict(states)[entity_id] == dict(hist)[entity_id]
|
||||
|
||||
recorder.do_adhoc_statistics(start=zero)
|
||||
wait_recording_done(hass)
|
||||
statistic_ids = list_statistic_ids(hass)
|
||||
assert {
|
||||
"statistic_id": entity_id,
|
||||
"unit_of_measurement": native_unit,
|
||||
} in statistic_ids
|
||||
stats = statistics_during_period(hass, zero, period="5minute")
|
||||
assert stats[entity_id] == [
|
||||
{
|
||||
"statistic_id": entity_id,
|
||||
"start": process_timestamp_to_utc_isoformat(zero),
|
||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
||||
"max": None,
|
||||
"mean": None,
|
||||
"min": None,
|
||||
"last_reset": None,
|
||||
"state": approx(factor * seq[7]),
|
||||
"sum": approx(factor * 15), # (15 - 10) + (10 - 0)
|
||||
},
|
||||
]
|
||||
assert "Error while processing event StatisticsTask" not in caplog.text
|
||||
assert (
|
||||
f"Entity {entity_id} {warning_1}has state class total_increasing, but its state is negative"
|
||||
in caplog.text
|
||||
)
|
||||
assert warning_2 in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_class,unit,native_unit,factor",
|
||||
[
|
||||
|
@ -823,16 +932,14 @@ def test_compile_hourly_sum_statistics_total_increasing_small_dip(
|
|||
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"
|
||||
"home-assistant/core/issues?q=is%3Aopen+is%3Aissue"
|
||||
) not in caplog.text
|
||||
recorder.do_adhoc_statistics(start=period2)
|
||||
wait_recording_done(hass)
|
||||
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"
|
||||
"home-assistant/core/issues?q=is%3Aopen+is%3Aissue"
|
||||
) in caplog.text
|
||||
statistic_ids = list_statistic_ids(hass)
|
||||
assert statistic_ids == [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue