mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
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
This commit is contained in:
parent
ca33d7263f
commit
3c57b12cd1
@ -117,19 +117,6 @@ class RoborockMap(RoborockCoordinatedEntityV1, ImageEntity):
|
|||||||
"""Return if this map is the currently selected map."""
|
"""Return if this map is the currently selected map."""
|
||||||
return self.map_flag == self.coordinator.current_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:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""When entity is added to hass load any previously cached maps from disk."""
|
"""When entity is added to hass load any previously cached maps from disk."""
|
||||||
await super().async_added_to_hass()
|
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
|
# 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
|
# will be called and we will evaluate on the new coordinator data if we should
|
||||||
# update the cache.
|
# update the cache.
|
||||||
if (
|
if self.is_selected and (
|
||||||
dt_util.utcnow() - self.image_last_updated
|
(
|
||||||
).total_seconds() > IMAGE_CACHE_INTERVAL and self.is_map_valid():
|
(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()
|
self._attr_image_last_updated = dt_util.utcnow()
|
||||||
super()._handle_coordinator_update()
|
super()._handle_coordinator_update()
|
||||||
|
|
||||||
async def async_image(self) -> bytes | None:
|
async def async_image(self) -> bytes | None:
|
||||||
"""Update the image if it is not cached."""
|
"""Update the image if it is not cached."""
|
||||||
if self.is_map_valid():
|
if self.is_selected:
|
||||||
response = await asyncio.gather(
|
response = await asyncio.gather(
|
||||||
*(
|
*(
|
||||||
self.cloud_api.get_map_v1(),
|
self.cloud_api.get_map_v1(),
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
import copy
|
import copy
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
import io
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
@ -111,39 +110,6 @@ async def test_floorplan_image_failed_parse(
|
|||||||
assert not resp.ok
|
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(
|
async def test_fail_to_save_image(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
hass_client: ClientSessionGenerator,
|
hass_client: ClientSessionGenerator,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user