Fix history_stats for timezones with a positive offset from UTC (#71038)

This commit is contained in:
J. Nick Koston 2022-04-29 01:48:58 -05:00 committed by GitHub
parent b9c7a89b47
commit aafe6ff0e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 84 additions and 1 deletions

View file

@ -11,6 +11,8 @@ import homeassistant.util.dt as dt_util
from .helpers import async_calculate_period, floored_timestamp
MIN_TIME_UTC = datetime.datetime.min.replace(tzinfo=dt_util.UTC)
@dataclass
class HistoryStatsState:
@ -36,7 +38,7 @@ class HistoryStats:
"""Init the history stats manager."""
self.hass = hass
self.entity_id = entity_id
self._period = (datetime.datetime.min, datetime.datetime.min)
self._period = (MIN_TIME_UTC, MIN_TIME_UTC)
self._state: HistoryStatsState = HistoryStatsState(None, None, self._period)
self._history_current_period: list[State] = []
self._previous_run_before_start = False

View file

@ -1306,3 +1306,84 @@ async def test_measure_from_end_going_backwards(hass, recorder_mock):
assert hass.states.get("sensor.sensor2").state == "0.83"
assert hass.states.get("sensor.sensor3").state == "1"
assert hass.states.get("sensor.sensor4").state == "83.3"
async def test_measure_cet(hass, recorder_mock):
"""Test the history statistics sensor measure with a non-UTC timezone."""
hass.config.set_time_zone("Europe/Berlin")
start_time = dt_util.utcnow() - timedelta(minutes=60)
t0 = start_time + timedelta(minutes=20)
t1 = t0 + timedelta(minutes=10)
t2 = t1 + timedelta(minutes=10)
# Start t0 t1 t2 End
# |--20min--|--20min--|--10min--|--10min--|
# |---off---|---on----|---off---|---on----|
def _fake_states(*args, **kwargs):
return {
"binary_sensor.test_id": [
ha.State("binary_sensor.test_id", "on", last_changed=t0),
ha.State("binary_sensor.test_id", "off", last_changed=t1),
ha.State("binary_sensor.test_id", "on", last_changed=t2),
]
}
await async_setup_component(
hass,
"sensor",
{
"sensor": [
{
"platform": "history_stats",
"entity_id": "binary_sensor.test_id",
"name": "sensor1",
"state": "on",
"start": "{{ as_timestamp(now()) - 3600 }}",
"end": "{{ now() }}",
"type": "time",
},
{
"platform": "history_stats",
"entity_id": "binary_sensor.test_id",
"name": "sensor2",
"state": "on",
"start": "{{ as_timestamp(now()) - 3600 }}",
"end": "{{ now() }}",
"type": "time",
},
{
"platform": "history_stats",
"entity_id": "binary_sensor.test_id",
"name": "sensor3",
"state": "on",
"start": "{{ as_timestamp(now()) - 3600 }}",
"end": "{{ now() }}",
"type": "count",
},
{
"platform": "history_stats",
"entity_id": "binary_sensor.test_id",
"name": "sensor4",
"state": "on",
"start": "{{ as_timestamp(now()) - 3600 }}",
"end": "{{ now() }}",
"type": "ratio",
},
]
},
)
await hass.async_block_till_done()
with patch(
"homeassistant.components.recorder.history.state_changes_during_period",
_fake_states,
):
for i in range(1, 5):
await async_update_entity(hass, f"sensor.sensor{i}")
await hass.async_block_till_done()
assert hass.states.get("sensor.sensor1").state == "0.83"
assert hass.states.get("sensor.sensor2").state == "0.83"
assert hass.states.get("sensor.sensor3").state == "1"
assert hass.states.get("sensor.sensor4").state == "83.3"