This commit is contained in:
J. Nick Koston
2023-04-11 08:44:51 -10:00
parent 85caf26ccd
commit 01d2188a59
2 changed files with 33 additions and 30 deletions

View File

@@ -321,6 +321,7 @@ def _state_changed_during_period_stmt(
end_time_ts: float | None, end_time_ts: float | None,
single_metadata_id: int, single_metadata_id: int,
no_attributes: bool, no_attributes: bool,
descending: bool,
limit: int | None, limit: int | None,
include_start_time_state: bool, include_start_time_state: bool,
run_start_ts: float | None, run_start_ts: float | None,
@@ -347,28 +348,32 @@ def _state_changed_during_period_stmt(
if not include_start_time_state or not run_start_ts: if not include_start_time_state or not run_start_ts:
return stmt.order_by( return stmt.order_by(
States.metadata_id, States.metadata_id,
States.last_updated_ts, States.last_updated_ts.desc() if descending else States.last_updated_ts,
) )
return _select_from_subquery(
union_all( union_subquery = union_all(
_select_from_subquery( _select_from_subquery(
_get_single_entity_start_time_stmt( _get_single_entity_start_time_stmt(
start_time_ts, start_time_ts,
single_metadata_id, single_metadata_id,
no_attributes,
False,
).subquery(),
no_attributes, no_attributes,
False, False,
), ).subquery(),
_select_from_subquery( no_attributes,
stmt.subquery(), False,
no_attributes, ),
False, _select_from_subquery(
), stmt.order_by(States.metadata_id, States.last_updated_ts).subquery(),
).subquery(), no_attributes,
no_attributes, False,
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()
) )
@@ -412,6 +417,7 @@ def state_changes_during_period(
end_time_ts, end_time_ts,
single_metadata_id, single_metadata_id,
no_attributes, no_attributes,
descending,
limit, limit,
include_start_time_state, include_start_time_state,
run_start_ts, run_start_ts,
@@ -419,6 +425,7 @@ def state_changes_during_period(
track_on=[ track_on=[
bool(end_time_ts), bool(end_time_ts),
no_attributes, no_attributes,
descending,
bool(limit), bool(limit),
include_start_time_state, include_start_time_state,
], ],
@@ -430,7 +437,6 @@ def state_changes_during_period(
start_time_ts if include_start_time_state else None, start_time_ts if include_start_time_state else None,
entity_ids, entity_ids,
entity_id_to_metadata_id, entity_id_to_metadata_id,
descending=descending,
), ),
) )
@@ -648,7 +654,6 @@ def _sorted_states_to_dict(
entity_id_to_metadata_id: dict[str, int | None], entity_id_to_metadata_id: dict[str, int | None],
minimal_response: bool = False, minimal_response: bool = False,
compressed_state_format: bool = False, compressed_state_format: bool = False,
descending: bool = False,
) -> MutableMapping[str, list[State | dict[str, Any]]]: ) -> MutableMapping[str, list[State | dict[str, Any]]]:
"""Convert SQL results into JSON friendly data structure. """Convert SQL results into JSON friendly data structure.
@@ -773,9 +778,5 @@ def _sorted_states_to_dict(
if (state := row[state_idx]) != prev_state 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. # Filter out the empty lists if some states had 0 results.
return {key: val for key, val in result.items() if val} return {key: val for key, val in result.items() if val}

View File

@@ -266,10 +266,10 @@ def test_state_changes_during_period_descending(
start = dt_util.utcnow() start = dt_util.utcnow()
point = start + timedelta(seconds=1) point = start + timedelta(seconds=1)
point2 = start + timedelta(seconds=1, microseconds=2) point2 = start + timedelta(seconds=1, microseconds=10)
point3 = start + timedelta(seconds=1, microseconds=3) point3 = start + timedelta(seconds=1, microseconds=20)
point4 = start + timedelta(seconds=1, microseconds=4) point4 = start + timedelta(seconds=1, microseconds=30)
end = point + timedelta(seconds=1) end = point + timedelta(seconds=1, microseconds=40)
with patch( with patch(
"homeassistant.components.recorder.core.dt_util.utcnow", return_value=start "homeassistant.components.recorder.core.dt_util.utcnow", return_value=start
@@ -313,9 +313,10 @@ def test_state_changes_during_period_descending(
states, list(reversed(list(hist[entity_id]))) states, list(reversed(list(hist[entity_id])))
) )
start_time = point2 + timedelta(microseconds=1)
hist = history.state_changes_during_period( hist = history.state_changes_during_period(
hass, hass,
point2, # Pick a point where we will generate a start time state start_time, # Pick a point where we will generate a start time state
end, end,
entity_id, entity_id,
no_attributes=False, no_attributes=False,
@@ -323,6 +324,7 @@ def test_state_changes_during_period_descending(
include_start_time_state=True, include_start_time_state=True,
) )
hist_states = list(hist[entity_id]) hist_states = list(hist[entity_id])
assert hist_states[-1].last_updated == start_time
assert len(hist_states) == 3 assert len(hist_states) == 3
# Make sure they are in descending order # Make sure they are in descending order
assert ( assert (