mirror of
https://github.com/home-assistant/core.git
synced 2026-09-05 13:02:34 +01:00
Fix history stats missed state change during startup (#166748)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
co-authored by
Joost Lekkerkerker
parent
bca346df5f
commit
044a9d2d5a
@@ -91,12 +91,23 @@ class HistoryStatsUpdateCoordinator(DataUpdateCoordinator[HistoryStatsState]):
|
||||
self._track_events_listener = async_track_state_change_event(
|
||||
self.hass, [self._history_stats.entity_id], self._async_update_from_event
|
||||
)
|
||||
self.hass.async_create_task(self._async_poll_after_start())
|
||||
|
||||
async def _async_poll_after_start(self) -> None:
|
||||
"""Once we subscribe to tracking events at start, check the entity state one time."""
|
||||
new_state = self.hass.states.get(self._history_stats.entity_id)
|
||||
if new_state:
|
||||
self.async_set_updated_data(
|
||||
await self._history_stats.async_update(new_state)
|
||||
)
|
||||
|
||||
async def _async_update_from_event(
|
||||
self, event: Event[EventStateChangedData]
|
||||
) -> None:
|
||||
"""Process an update from an event."""
|
||||
self.async_set_updated_data(await self._history_stats.async_update(event))
|
||||
self.async_set_updated_data(
|
||||
await self._history_stats.async_update(event.data["new_state"])
|
||||
)
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> HistoryStatsState:
|
||||
|
||||
@@ -6,7 +6,7 @@ import logging
|
||||
import math
|
||||
|
||||
from homeassistant.components.recorder import get_instance, history
|
||||
from homeassistant.core import Event, EventStateChangedData, HomeAssistant, State
|
||||
from homeassistant.core import HomeAssistant, State
|
||||
from homeassistant.helpers.template import Template
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
@@ -62,12 +62,10 @@ class HistoryStats:
|
||||
self._end = end
|
||||
self._preview = preview
|
||||
|
||||
self._pending_events: list[Event[EventStateChangedData]] = []
|
||||
self._pending_events: list[State] = []
|
||||
self._query_count = 0
|
||||
|
||||
async def async_update(
|
||||
self, event: Event[EventStateChangedData] | None
|
||||
) -> HistoryStatsState:
|
||||
async def async_update(self, new_state: State | None) -> HistoryStatsState:
|
||||
"""Update the stats at a given time."""
|
||||
# Get previous values of start and end
|
||||
previous_period_start, previous_period_end = self._period
|
||||
@@ -99,8 +97,8 @@ class HistoryStats:
|
||||
# recorder query will be done and we need to hold the new
|
||||
# event so that we can append it after the second query.
|
||||
# Otherwise the event will be dropped.
|
||||
if event:
|
||||
self._pending_events.append(event)
|
||||
if new_state:
|
||||
self._pending_events.append(new_state)
|
||||
|
||||
if current_period_start_timestamp > now_timestamp:
|
||||
# History cannot tell the future
|
||||
@@ -135,7 +133,7 @@ class HistoryStats:
|
||||
self._prune_history_cache(current_period_start_timestamp)
|
||||
|
||||
new_data = False
|
||||
if event and (new_state := event.data["new_state"]) is not None:
|
||||
if new_state is not None:
|
||||
if current_period_start_timestamp <= floored_timestamp(
|
||||
new_state.last_changed
|
||||
):
|
||||
@@ -156,16 +154,15 @@ class HistoryStats:
|
||||
await self._async_history_from_db(
|
||||
current_period_start_timestamp, now_timestamp
|
||||
)
|
||||
for pending_event in self._pending_events:
|
||||
if (new_state := pending_event.data["new_state"]) is not None:
|
||||
if current_period_start_timestamp <= floored_timestamp(
|
||||
new_state.last_changed
|
||||
):
|
||||
self._history_current_period.append(
|
||||
HistoryState(
|
||||
new_state.state, new_state.last_changed_timestamp
|
||||
)
|
||||
for pending_state in self._pending_events:
|
||||
if current_period_start_timestamp <= floored_timestamp(
|
||||
pending_state.last_changed
|
||||
):
|
||||
self._history_current_period.append(
|
||||
HistoryState(
|
||||
pending_state.state, pending_state.last_changed_timestamp
|
||||
)
|
||||
)
|
||||
|
||||
self._has_recorder_data = True
|
||||
|
||||
|
||||
Reference in New Issue
Block a user