From c9d9d61931334478577be2468ca3497a618cd0e0 Mon Sep 17 00:00:00 2001 From: vize69 <138366174+vize69@users.noreply.github.com> Date: Wed, 7 Oct 2026 18:48:31 +0200 Subject: [PATCH] fix: select latest V1 cleaning record regardless of response order --- roborock/devices/traits/v1/clean_summary.py | 3 +- tests/devices/traits/v1/test_clean_summary.py | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/roborock/devices/traits/v1/clean_summary.py b/roborock/devices/traits/v1/clean_summary.py index 7f1b234e0..a03468faa 100644 --- a/roborock/devices/traits/v1/clean_summary.py +++ b/roborock/devices/traits/v1/clean_summary.py @@ -82,7 +82,8 @@ async def refresh(self) -> None: _LOGGER.debug("No clean records available in clean summary.") self.last_clean_record = None return - last_record_id = self.records[0] + # Record IDs are start timestamps; devices may return them in either order. + last_record_id = max(self.records) self.last_clean_record = await self.get_clean_record(last_record_id) async def get_clean_record(self, record_id: int) -> CleanRecord: diff --git a/tests/devices/traits/v1/test_clean_summary.py b/tests/devices/traits/v1/test_clean_summary.py index 2fe214a53..f5d74a7c1 100644 --- a/tests/devices/traits/v1/test_clean_summary.py +++ b/tests/devices/traits/v1/test_clean_summary.py @@ -97,6 +97,37 @@ async def test_get_clean_summary_success( ) +@pytest.mark.parametrize( + "records", + [ + [1700000000, 1700000400, 1700000800], + [1700000800, 1700000400, 1700000000], + [1700000400, 1700000800, 1700000000], + [1700000800], + ], + ids=["ascending", "descending", "unordered", "single"], +) +async def test_get_clean_summary_latest_record( + clean_summary_trait: CleanSummaryTrait, mock_rpc_channel: AsyncMock, records: list[int] +) -> None: + """Load the latest cleaning regardless of the order returned by the device.""" + mock_rpc_channel.send_command.side_effect = [ + [3600, 1000000, len(records), records], + [[1700000800, 1700000900, 100, 1000000]], + ] + + await clean_summary_trait.refresh() + + assert mock_rpc_channel.send_command.call_args_list == [ + call(RoborockCommand.GET_CLEAN_SUMMARY), + call(RoborockCommand.GET_CLEAN_RECORD, params=[1700000800]), + ] + assert clean_summary_trait.records == records + assert clean_summary_trait.last_clean_record is not None + assert clean_summary_trait.last_clean_record.begin == 1700000800 + assert clean_summary_trait.last_clean_record.end == 1700000900 + + async def test_get_clean_summary_clean_time_only( clean_summary_trait: CleanSummaryTrait, mock_rpc_channel: AsyncMock, sample_clean_summary: CleanSummary ) -> None: