mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 22:57:17 +00:00
Improve derivative sensor tests (#148941)
This commit is contained in:
parent
9373bb287c
commit
ee35fc495d
@ -27,8 +27,25 @@ from tests.common import (
|
||||
mock_restore_cache_with_extra_data,
|
||||
)
|
||||
|
||||
A1 = {"attr": "value1"}
|
||||
A2 = {"attr": "value2"}
|
||||
|
||||
async def test_state(hass: HomeAssistant) -> None:
|
||||
|
||||
@pytest.mark.parametrize("force_update", [False, True])
|
||||
@pytest.mark.parametrize(
|
||||
"attributes",
|
||||
[
|
||||
# Same attributes, fires state report
|
||||
[A1, A1],
|
||||
# Changing attributes, fires state change with bumped last_updated
|
||||
[A1, A2],
|
||||
],
|
||||
)
|
||||
async def test_state(
|
||||
hass: HomeAssistant,
|
||||
force_update: bool,
|
||||
attributes: list[dict[str, Any]],
|
||||
) -> None:
|
||||
"""Test derivative sensor state."""
|
||||
config = {
|
||||
"sensor": {
|
||||
@ -45,12 +62,13 @@ async def test_state(hass: HomeAssistant) -> None:
|
||||
entity_id = config["sensor"]["source"]
|
||||
base = dt_util.utcnow()
|
||||
with freeze_time(base) as freezer:
|
||||
hass.states.async_set(entity_id, 1, {})
|
||||
for extra_attributes in attributes:
|
||||
hass.states.async_set(
|
||||
entity_id, 1, extra_attributes, force_update=force_update
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
freezer.move_to(dt_util.utcnow() + timedelta(seconds=3600))
|
||||
hass.states.async_set(entity_id, 1, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.derivative")
|
||||
assert state is not None
|
||||
@ -61,7 +79,24 @@ async def test_state(hass: HomeAssistant) -> None:
|
||||
assert state.attributes.get("unit_of_measurement") == "kW"
|
||||
|
||||
|
||||
async def test_no_change(hass: HomeAssistant) -> None:
|
||||
# Test unchanged states work both with and without max_sub_interval
|
||||
@pytest.mark.parametrize("extra_config", [{}, {"max_sub_interval": {"minutes": 9999}}])
|
||||
@pytest.mark.parametrize("force_update", [False, True])
|
||||
@pytest.mark.parametrize(
|
||||
"attributes",
|
||||
[
|
||||
# Same attributes, fires state report
|
||||
[A1, A1, A1, A1],
|
||||
# Changing attributes, fires state change with bumped last_updated
|
||||
[A1, A2, A1, A2],
|
||||
],
|
||||
)
|
||||
async def test_no_change(
|
||||
hass: HomeAssistant,
|
||||
extra_config: dict[str, Any],
|
||||
force_update: bool,
|
||||
attributes: list[dict[str, Any]],
|
||||
) -> None:
|
||||
"""Test derivative sensor state updated when source sensor doesn't change."""
|
||||
config = {
|
||||
"sensor": {
|
||||
@ -71,6 +106,7 @@ async def test_no_change(hass: HomeAssistant) -> None:
|
||||
"unit": "kW",
|
||||
"round": 2,
|
||||
}
|
||||
| extra_config
|
||||
}
|
||||
|
||||
assert await async_setup_component(hass, "sensor", config)
|
||||
@ -78,20 +114,13 @@ async def test_no_change(hass: HomeAssistant) -> None:
|
||||
entity_id = config["sensor"]["source"]
|
||||
base = dt_util.utcnow()
|
||||
with freeze_time(base) as freezer:
|
||||
hass.states.async_set(entity_id, 0, {})
|
||||
for value, extra_attributes in zip([0, 1, 1, 1], attributes, strict=True):
|
||||
hass.states.async_set(
|
||||
entity_id, value, extra_attributes, force_update=force_update
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
freezer.move_to(dt_util.utcnow() + timedelta(seconds=3600))
|
||||
hass.states.async_set(entity_id, 1, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
freezer.move_to(dt_util.utcnow() + timedelta(seconds=3600))
|
||||
hass.states.async_set(entity_id, 1, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
freezer.move_to(dt_util.utcnow() + timedelta(seconds=3600))
|
||||
hass.states.async_set(entity_id, 1, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.derivative")
|
||||
assert state is not None
|
||||
@ -138,7 +167,7 @@ async def setup_tests(
|
||||
# Testing a energy sensor with non-monotonic intervals and values
|
||||
base = dt_util.utcnow()
|
||||
with freeze_time(base) as freezer:
|
||||
for time, value in zip(times, values, strict=False):
|
||||
for time, value in zip(times, values, strict=True):
|
||||
freezer.move_to(base + timedelta(seconds=time))
|
||||
hass.states.async_set(entity_id, value, {})
|
||||
await hass.async_block_till_done()
|
||||
@ -213,7 +242,24 @@ async def test_dataSet6(hass: HomeAssistant) -> None:
|
||||
await setup_tests(hass, {}, times=[0, 60], values=[0, 1 / 60], expected_state=1)
|
||||
|
||||
|
||||
async def test_data_moving_average_with_zeroes(hass: HomeAssistant) -> None:
|
||||
# Test unchanged states work both with and without max_sub_interval
|
||||
@pytest.mark.parametrize("extra_config", [{}, {"max_sub_interval": {"minutes": 9999}}])
|
||||
@pytest.mark.parametrize("force_update", [False, True])
|
||||
@pytest.mark.parametrize(
|
||||
"attributes",
|
||||
[
|
||||
# Same attributes, fires state report
|
||||
[A1, A1] * 10 + [A1],
|
||||
# Changing attributes, fires state change with bumped last_updated
|
||||
[A1, A2] * 10 + [A1],
|
||||
],
|
||||
)
|
||||
async def test_data_moving_average_with_zeroes(
|
||||
hass: HomeAssistant,
|
||||
extra_config: dict[str, Any],
|
||||
force_update: bool,
|
||||
attributes: list[dict[str, Any]],
|
||||
) -> None:
|
||||
"""Test that zeroes are properly handled within the time window."""
|
||||
# We simulate the following situation:
|
||||
# The temperature rises 1 °C per minute for 10 minutes long. Then, it
|
||||
@ -235,16 +281,21 @@ async def test_data_moving_average_with_zeroes(hass: HomeAssistant) -> None:
|
||||
"time_window": {"seconds": time_window},
|
||||
"unit_time": UnitOfTime.MINUTES,
|
||||
"round": 1,
|
||||
},
|
||||
}
|
||||
| extra_config,
|
||||
)
|
||||
|
||||
base = dt_util.utcnow()
|
||||
with freeze_time(base) as freezer:
|
||||
last_derivative = 0
|
||||
for time, value in zip(times, temperature_values, strict=True):
|
||||
for time, value, extra_attributes in zip(
|
||||
times, temperature_values, attributes, strict=True
|
||||
):
|
||||
now = base + timedelta(seconds=time)
|
||||
freezer.move_to(now)
|
||||
hass.states.async_set(entity_id, value, {})
|
||||
hass.states.async_set(
|
||||
entity_id, value, extra_attributes, force_update=force_update
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.power")
|
||||
@ -273,7 +324,7 @@ async def test_data_moving_average_for_discrete_sensor(hass: HomeAssistant) -> N
|
||||
for temperature in range(30):
|
||||
temperature_values += [temperature] * 2 # two values per minute
|
||||
time_window = 600
|
||||
times = list(range(0, 1800 + 30, 30))
|
||||
times = list(range(0, 1800, 30))
|
||||
|
||||
config, entity_id = await _setup_sensor(
|
||||
hass,
|
||||
@ -286,7 +337,7 @@ async def test_data_moving_average_for_discrete_sensor(hass: HomeAssistant) -> N
|
||||
|
||||
base = dt_util.utcnow()
|
||||
with freeze_time(base) as freezer:
|
||||
for time, value in zip(times, temperature_values, strict=False):
|
||||
for time, value in zip(times, temperature_values, strict=True):
|
||||
now = base + timedelta(seconds=time)
|
||||
freezer.move_to(now)
|
||||
hass.states.async_set(entity_id, value, {})
|
||||
@ -330,7 +381,7 @@ async def test_data_moving_average_for_irregular_times(hass: HomeAssistant) -> N
|
||||
|
||||
base = dt_util.utcnow()
|
||||
with freeze_time(base) as freezer:
|
||||
for time, value in zip(times, temperature_values, strict=False):
|
||||
for time, value in zip(times, temperature_values, strict=True):
|
||||
now = base + timedelta(seconds=time)
|
||||
freezer.move_to(now)
|
||||
hass.states.async_set(entity_id, value, {})
|
||||
@ -368,7 +419,7 @@ async def test_double_signal_after_delay(hass: HomeAssistant) -> None:
|
||||
base = dt_util.utcnow()
|
||||
previous = 0
|
||||
with freeze_time(base) as freezer:
|
||||
for time, value in zip(times, temperature_values, strict=False):
|
||||
for time, value in zip(times, temperature_values, strict=True):
|
||||
now = base + timedelta(seconds=time)
|
||||
freezer.move_to(now)
|
||||
hass.states.async_set(entity_id, value, {})
|
||||
@ -506,7 +557,7 @@ async def test_sub_intervals_with_time_window(hass: HomeAssistant) -> None:
|
||||
base = dt_util.utcnow()
|
||||
with freeze_time(base) as freezer:
|
||||
last_state_change = None
|
||||
for time, value in zip(times, values, strict=False):
|
||||
for time, value in zip(times, values, strict=True):
|
||||
now = base + timedelta(seconds=time)
|
||||
freezer.move_to(now)
|
||||
hass.states.async_set(entity_id, value, {}, force_update=True)
|
||||
@ -636,7 +687,7 @@ async def test_total_increasing_reset(hass: HomeAssistant) -> None:
|
||||
actual_times = []
|
||||
actual_values = []
|
||||
with freeze_time(base_time) as freezer:
|
||||
for time, value in zip(times, values, strict=False):
|
||||
for time, value in zip(times, values, strict=True):
|
||||
current_time = base_time + timedelta(seconds=time)
|
||||
freezer.move_to(current_time)
|
||||
hass.states.async_set(
|
||||
@ -724,7 +775,7 @@ async def test_unavailable(
|
||||
# Testing a energy sensor with non-monotonic intervals and values
|
||||
base = dt_util.utcnow()
|
||||
with freeze_time(base) as freezer:
|
||||
for time, value, expect in zip(times, values, expected_state, strict=False):
|
||||
for time, value, expect in zip(times, values, expected_state, strict=True):
|
||||
freezer.move_to(base + timedelta(seconds=time))
|
||||
hass.states.async_set(entity_id, value, {})
|
||||
await hass.async_block_till_done()
|
||||
@ -759,7 +810,7 @@ async def test_unavailable_2(
|
||||
|
||||
base = dt_util.utcnow()
|
||||
with freeze_time(base) as freezer:
|
||||
for time, value in zip(times, values, strict=False):
|
||||
for time, value in zip(times, values, strict=True):
|
||||
freezer.move_to(base + timedelta(seconds=time))
|
||||
hass.states.async_set(entity_id, value, {})
|
||||
await hass.async_block_till_done()
|
||||
|
Loading…
x
Reference in New Issue
Block a user