diff --git a/homeassistant/components/recorder/history/modern.py b/homeassistant/components/recorder/history/modern.py index 6a15ae774bf..d48c7a0de9a 100644 --- a/homeassistant/components/recorder/history/modern.py +++ b/homeassistant/components/recorder/history/modern.py @@ -441,10 +441,10 @@ def state_changes_during_period( ) -def _get_last_state_changes_stmt(number_of_states: int, metadata_id: int) -> Select: - stmt = _stmt_and_join_attributes(False, False) - if number_of_states == 1: - stmt = stmt.join( +def _get_last_state_changes_single_stmt(metadata_id: int) -> Select: + return ( + _stmt_and_join_attributes(False, False) + .join( ( lastest_state_for_metadata_id := ( select( @@ -464,8 +464,19 @@ def _get_last_state_changes_stmt(number_of_states: int, metadata_id: int) -> Sel == lastest_state_for_metadata_id.c.max_last_updated, ), ) - else: - stmt = stmt.where( + .outerjoin( + StateAttributes, States.attributes_id == StateAttributes.attributes_id + ) + .order_by(States.state_id.desc()) + ) + + +def _get_last_state_changes_multiple_stmt( + number_of_states: int, metadata_id: int +) -> Select: + return ( + _stmt_and_join_attributes(False, False) + .where( States.state_id == ( select(States.state_id) @@ -475,10 +486,11 @@ def _get_last_state_changes_stmt(number_of_states: int, metadata_id: int) -> Sel .subquery() ).c.state_id ) - stmt = stmt.outerjoin( - StateAttributes, States.attributes_id == StateAttributes.attributes_id - ).order_by(States.state_id.desc()) - return stmt + .outerjoin( + StateAttributes, States.attributes_id == StateAttributes.attributes_id + ) + .order_by(States.state_id.desc()) + ) def get_last_state_changes( @@ -502,10 +514,16 @@ def get_last_state_changes( return {} metadata_id = possible_metadata_id entity_id_to_metadata_id: dict[str, int | None] = {entity_id_lower: metadata_id} - stmt = lambda_stmt( - lambda: _get_last_state_changes_stmt(number_of_states, metadata_id), - track_on=[number_of_states == 1], - ) + if number_of_states == 1: + stmt = lambda_stmt( + lambda: _get_last_state_changes_single_stmt(metadata_id), + ) + else: + stmt = lambda_stmt( + lambda: _get_last_state_changes_multiple_stmt( + number_of_states, metadata_id + ), + ) states = list(execute_stmt_lambda_element(session, stmt)) return cast( MutableMapping[str, list[State]], diff --git a/tests/components/recorder/test_history.py b/tests/components/recorder/test_history.py index 97498041725..2c1af4702ff 100644 --- a/tests/components/recorder/test_history.py +++ b/tests/components/recorder/test_history.py @@ -41,7 +41,6 @@ from .common import ( wait_recording_done, ) -from tests.common import mock_state_change_event from tests.typing import RecorderInstanceGenerator @@ -118,44 +117,6 @@ def _add_db_entries( ) -def _setup_get_states(hass): - """Set up for testing get_states.""" - states = [] - now = dt_util.utcnow() - with patch( - "homeassistant.components.recorder.core.dt_util.utcnow", return_value=now - ): - for i in range(5): - state = ha.State( - f"test.point_in_time_{i % 5}", - f"State {i}", - {"attribute_test": i}, - ) - - mock_state_change_event(hass, state) - - states.append(state) - - wait_recording_done(hass) - - future = now + timedelta(seconds=1) - with patch( - "homeassistant.components.recorder.core.dt_util.utcnow", return_value=future - ): - for i in range(5): - state = ha.State( - f"test.point_in_time_{i % 5}", - f"State {i}", - {"attribute_test": i}, - ) - - mock_state_change_event(hass, state) - - wait_recording_done(hass) - - return now, future, states - - def test_get_full_significant_states_with_session_entity_no_matches( hass_recorder: Callable[..., HomeAssistant] ) -> None: