From b284eddc631ed484c8ef1739fcd85a690c301729 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 18 Mar 2022 00:49:11 -1000 Subject: [PATCH] Fix statistics doing I/O in the event loop (#68315) --- homeassistant/components/statistics/sensor.py | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/statistics/sensor.py b/homeassistant/components/statistics/sensor.py index 6d73f8ea6e7..d632e9710cf 100644 --- a/homeassistant/components/statistics/sensor.py +++ b/homeassistant/components/statistics/sensor.py @@ -12,6 +12,7 @@ from typing import Any, Literal, cast import voluptuous as vol from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN +from homeassistant.components.recorder import get_instance from homeassistant.components.recorder.models import StateAttributes, States from homeassistant.components.recorder.util import execute, session_scope from homeassistant.components.sensor import ( @@ -470,17 +471,8 @@ class StatisticsSensor(SensorEntity): self.hass, _scheduled_update, next_to_purge_timestamp ) - async def _initialize_from_database(self) -> None: - """Initialize the list of states from the database. - - The query will get the list of states in DESCENDING order so that we - can limit the result to self._sample_size. Afterwards reverse the - list so that we get it in the right order again. - - If MaxAge is provided then query will restrict to entries younger then - current datetime - MaxAge. - """ - + def _fetch_states_from_database(self) -> list[State]: + """Fetch the states from the database.""" _LOGGER.debug("%s: initializing values from the database", self.entity_id) states = [] @@ -512,8 +504,21 @@ class StatisticsSensor(SensorEntity): if not native.attributes: native.attributes = attributes.to_native() states.append(native) + return states - if states: + async def _initialize_from_database(self) -> None: + """Initialize the list of states from the database. + + The query will get the list of states in DESCENDING order so that we + can limit the result to self._sample_size. Afterwards reverse the + list so that we get it in the right order again. + + If MaxAge is provided then query will restrict to entries younger then + current datetime - MaxAge. + """ + if states := await get_instance(self.hass).async_add_executor_job( + self._fetch_states_from_database + ): for state in reversed(states): self._add_state_to_queue(state)