From 3c57b12cd1daef98bb5287b255a2ba48b28b89cd Mon Sep 17 00:00:00 2001 From: Luke Lashley Date: Tue, 11 Mar 2025 10:31:20 -0400 Subject: [PATCH] Fix bug with all Roborock maps being set to the wrong map when empty (#138493) * Fix bug with all maps being set to the same when empty * fix parens * fix other parens * rework some of the logic * few small updates * Remove test that is no longer relevant * remove updated time bump --- homeassistant/components/roborock/image.py | 28 +++++++----------- tests/components/roborock/test_image.py | 34 ---------------------- 2 files changed, 11 insertions(+), 51 deletions(-) diff --git a/homeassistant/components/roborock/image.py b/homeassistant/components/roborock/image.py index 70f06dd4b92..2fb5d644826 100644 --- a/homeassistant/components/roborock/image.py +++ b/homeassistant/components/roborock/image.py @@ -117,19 +117,6 @@ class RoborockMap(RoborockCoordinatedEntityV1, ImageEntity): """Return if this map is the currently selected map.""" return self.map_flag == self.coordinator.current_map - def is_map_valid(self) -> bool: - """Update the map if it is valid. - - Update this map if it is the currently active map, and the - vacuum is cleaning, or if it has never been set at all. - """ - return self.cached_map == b"" or ( - self.is_selected - and self.image_last_updated is not None - and self.coordinator.roborock_device_info.props.status is not None - and bool(self.coordinator.roborock_device_info.props.status.in_cleaning) - ) - async def async_added_to_hass(self) -> None: """When entity is added to hass load any previously cached maps from disk.""" await super().async_added_to_hass() @@ -142,15 +129,22 @@ class RoborockMap(RoborockCoordinatedEntityV1, ImageEntity): # Bump last updated every third time the coordinator runs, so that async_image # will be called and we will evaluate on the new coordinator data if we should # update the cache. - if ( - dt_util.utcnow() - self.image_last_updated - ).total_seconds() > IMAGE_CACHE_INTERVAL and self.is_map_valid(): + if self.is_selected and ( + ( + (dt_util.utcnow() - self.image_last_updated).total_seconds() + > IMAGE_CACHE_INTERVAL + and self.coordinator.roborock_device_info.props.status is not None + and bool(self.coordinator.roborock_device_info.props.status.in_cleaning) + ) + or self.cached_map == b"" + ): + # This will tell async_image it should update. self._attr_image_last_updated = dt_util.utcnow() super()._handle_coordinator_update() async def async_image(self) -> bytes | None: """Update the image if it is not cached.""" - if self.is_map_valid(): + if self.is_selected: response = await asyncio.gather( *( self.cloud_api.get_map_v1(), diff --git a/tests/components/roborock/test_image.py b/tests/components/roborock/test_image.py index fd6c8b2796a..7d79cf4f6ab 100644 --- a/tests/components/roborock/test_image.py +++ b/tests/components/roborock/test_image.py @@ -3,7 +3,6 @@ import copy from datetime import timedelta from http import HTTPStatus -import io from unittest.mock import patch from PIL import Image @@ -111,39 +110,6 @@ async def test_floorplan_image_failed_parse( assert not resp.ok -async def test_load_stored_image( - hass: HomeAssistant, - hass_client: ClientSessionGenerator, - setup_entry: MockConfigEntry, -) -> None: - """Test that we correctly load an image from storage when it already exists.""" - img_byte_arr = io.BytesIO() - MAP_DATA.image.data.save(img_byte_arr, format="PNG") - img_bytes = img_byte_arr.getvalue() - - # Load the image on demand, which should queue it to be cached on disk - client = await hass_client() - resp = await client.get("/api/image_proxy/image.roborock_s7_maxv_upstairs") - assert resp.status == HTTPStatus.OK - - with patch( - "homeassistant.components.roborock.image.RoborockMapDataParser.parse", - ) as parse_map: - # Reload the config entry so that the map is saved in storage and entities exist. - await hass.config_entries.async_reload(setup_entry.entry_id) - await hass.async_block_till_done() - assert hass.states.get("image.roborock_s7_maxv_upstairs") is not None - client = await hass_client() - resp = await client.get("/api/image_proxy/image.roborock_s7_maxv_upstairs") - # Test that we can get the image and it correctly serialized and unserialized. - assert resp.status == HTTPStatus.OK - body = await resp.read() - assert body == img_bytes - - # Ensure that we never tried to update the map, and only used the cached image. - assert parse_map.call_count == 0 - - async def test_fail_to_save_image( hass: HomeAssistant, hass_client: ClientSessionGenerator,