diff --git a/homeassistant/components/recorder/history/modern.py b/homeassistant/components/recorder/history/modern.py index d48c7a0de9a..101eb01caa4 100644 --- a/homeassistant/components/recorder/history/modern.py +++ b/homeassistant/components/recorder/history/modern.py @@ -321,7 +321,6 @@ def _state_changed_during_period_stmt( end_time_ts: float | None, single_metadata_id: int, no_attributes: bool, - descending: bool, limit: int | None, include_start_time_state: bool, run_start_ts: float | None, @@ -348,32 +347,28 @@ def _state_changed_during_period_stmt( if not include_start_time_state or not run_start_ts: return stmt.order_by( States.metadata_id, - States.last_updated_ts.desc() if descending else States.last_updated_ts, + States.last_updated_ts, ) - - union_subquery = union_all( - _select_from_subquery( - _get_single_entity_start_time_stmt( - start_time_ts, - single_metadata_id, + return _select_from_subquery( + union_all( + _select_from_subquery( + _get_single_entity_start_time_stmt( + start_time_ts, + single_metadata_id, + no_attributes, + False, + ).subquery(), no_attributes, False, - ).subquery(), - no_attributes, - False, - ), - _select_from_subquery( - stmt.order_by(States.metadata_id, States.last_updated_ts).subquery(), - no_attributes, - False, - ), - ).subquery() - stmt = _select_from_subquery(union_subquery, no_attributes, False) - if not descending: - return stmt - # If descending, we need to reverse the results - return stmt.order_by( - union_subquery.c.metadata_id, union_subquery.c.last_updated_ts.desc() + ), + _select_from_subquery( + stmt.subquery(), + no_attributes, + False, + ), + ).subquery(), + no_attributes, + False, ) @@ -417,7 +412,6 @@ def state_changes_during_period( end_time_ts, single_metadata_id, no_attributes, - descending, limit, include_start_time_state, run_start_ts, @@ -425,7 +419,6 @@ def state_changes_during_period( track_on=[ bool(end_time_ts), no_attributes, - descending, bool(limit), include_start_time_state, ], @@ -437,6 +430,7 @@ def state_changes_during_period( start_time_ts if include_start_time_state else None, entity_ids, entity_id_to_metadata_id, + descending=descending, ), ) @@ -654,6 +648,7 @@ def _sorted_states_to_dict( entity_id_to_metadata_id: dict[str, int | None], minimal_response: bool = False, compressed_state_format: bool = False, + descending: bool = False, ) -> MutableMapping[str, list[State | dict[str, Any]]]: """Convert SQL results into JSON friendly data structure. @@ -778,5 +773,9 @@ def _sorted_states_to_dict( if (state := row[state_idx]) != prev_state ) + if descending: + for ent_results in result.values(): + ent_results.reverse() + # Filter out the empty lists if some states had 0 results. return {key: val for key, val in result.items() if val} diff --git a/tests/components/recorder/test_history.py b/tests/components/recorder/test_history.py index 2c1af4702ff..3128a3b2f04 100644 --- a/tests/components/recorder/test_history.py +++ b/tests/components/recorder/test_history.py @@ -303,6 +303,7 @@ def test_state_changes_during_period_descending( hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes=False, descending=False ) + assert_multiple_states_equal_without_context(states, hist[entity_id]) hist = history.state_changes_during_period( @@ -312,6 +313,24 @@ def test_state_changes_during_period_descending( states, list(reversed(list(hist[entity_id]))) ) + hist = history.state_changes_during_period( + hass, + point2, # Pick a point where we will generate a start time state + end, + entity_id, + no_attributes=False, + descending=True, + include_start_time_state=True, + ) + hist_states = list(hist[entity_id]) + assert len(hist_states) == 3 + # Make sure they are in descending order + assert ( + hist_states[0].last_updated + > hist_states[1].last_updated + > hist_states[2].last_updated + ) + def test_get_last_state_changes(hass_recorder: Callable[..., HomeAssistant]) -> None: """Test number of state changes."""