Skip to content

Commit

Permalink
Avoid db hit and executor job for impossible history queries (#104724)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Nov 29, 2023
1 parent 1fefa93 commit 50f2c41
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 4 deletions.
5 changes: 3 additions & 2 deletions homeassistant/components/history/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from . import websocket_api
from .const import DOMAIN
from .helpers import entities_may_have_state_changes_after
from .helpers import entities_may_have_state_changes_after, has_recorder_run_after

CONF_ORDER = "use_include_order"

Expand Down Expand Up @@ -106,7 +106,8 @@ async def get(
no_attributes = "no_attributes" in request.query

if (
not include_start_time_state
(end_time and not has_recorder_run_after(hass, end_time))
or not include_start_time_state
and entity_ids
and not entities_may_have_state_changes_after(
hass, entity_ids, start_time, no_attributes
Expand Down
9 changes: 9 additions & 0 deletions homeassistant/components/history/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from collections.abc import Iterable
from datetime import datetime as dt

from homeassistant.components.recorder import get_instance
from homeassistant.components.recorder.models import process_timestamp
from homeassistant.core import HomeAssistant


Expand All @@ -21,3 +23,10 @@ def entities_may_have_state_changes_after(
return True

return False


def has_recorder_run_after(hass: HomeAssistant, run_time: dt) -> bool:
"""Check if the recorder has any runs after a specific time."""
return run_time >= process_timestamp(
get_instance(hass).recorder_runs_manager.first.start
)
5 changes: 3 additions & 2 deletions homeassistant/components/history/websocket_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import homeassistant.util.dt as dt_util

from .const import EVENT_COALESCE_TIME, MAX_PENDING_HISTORY_STATES
from .helpers import entities_may_have_state_changes_after
from .helpers import entities_may_have_state_changes_after, has_recorder_run_after

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -142,7 +142,8 @@ async def ws_get_history_during_period(
no_attributes = msg["no_attributes"]

if (
not include_start_time_state
(end_time and not has_recorder_run_after(hass, end_time))
or not include_start_time_state
and entity_ids
and not entities_may_have_state_changes_after(
hass, entity_ids, start_time, no_attributes
Expand Down

0 comments on commit 50f2c41

Please sign in to comment.