mirror of
https://github.com/home-assistant/core.git
synced 2025-07-09 14:27:07 +00:00
Update Roborock Map on status change (#140873)
* update map on status change * Update tests/components/roborock/test_image.py Co-authored-by: Allen Porter <allen.porter@gmail.com> * update code to handle state logic within async_update_data * Update homeassistant/components/roborock/coordinator.py Co-authored-by: Allen Porter <allen.porter@gmail.com> * move previous_state and allow update on None --------- Co-authored-by: Allen Porter <allen.porter@gmail.com>
This commit is contained in:
parent
de1823070f
commit
1cae866da9
@ -279,6 +279,7 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]):
|
|||||||
|
|
||||||
async def _async_update_data(self) -> DeviceProp:
|
async def _async_update_data(self) -> DeviceProp:
|
||||||
"""Update data via library."""
|
"""Update data via library."""
|
||||||
|
previous_state = self.roborock_device_info.props.status.state_name
|
||||||
try:
|
try:
|
||||||
# Update device props and standard api information
|
# Update device props and standard api information
|
||||||
await self._update_device_prop()
|
await self._update_device_prop()
|
||||||
@ -288,11 +289,14 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]):
|
|||||||
|
|
||||||
# If the vacuum is currently cleaning and it has been IMAGE_CACHE_INTERVAL
|
# If the vacuum is currently cleaning and it has been IMAGE_CACHE_INTERVAL
|
||||||
# since the last map update, you can update the map.
|
# since the last map update, you can update the map.
|
||||||
if (
|
new_status = self.roborock_device_info.props.status
|
||||||
self.current_map is not None
|
if self.current_map is not None and (
|
||||||
and self.roborock_device_info.props.status.in_cleaning
|
(
|
||||||
and (dt_util.utcnow() - self.maps[self.current_map].last_updated)
|
new_status.in_cleaning
|
||||||
> IMAGE_CACHE_INTERVAL
|
and (dt_util.utcnow() - self.maps[self.current_map].last_updated)
|
||||||
|
> IMAGE_CACHE_INTERVAL
|
||||||
|
)
|
||||||
|
or previous_state != new_status.state_name
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
await self.update_map()
|
await self.update_map()
|
||||||
|
@ -11,6 +11,7 @@ from roborock import RoborockException
|
|||||||
from vacuum_map_parser_base.map_data import ImageConfig, ImageData
|
from vacuum_map_parser_base.map_data import ImageConfig, ImageData
|
||||||
|
|
||||||
from homeassistant.components.roborock import DOMAIN
|
from homeassistant.components.roborock import DOMAIN
|
||||||
|
from homeassistant.components.roborock.const import V1_LOCAL_NOT_CLEANING_INTERVAL
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -158,9 +159,6 @@ async def test_fail_to_load_image(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Test that we gracefully handle failing to load an image."""
|
"""Test that we gracefully handle failing to load an image."""
|
||||||
with (
|
with (
|
||||||
patch(
|
|
||||||
"homeassistant.components.roborock.coordinator.RoborockMapDataParser.parse",
|
|
||||||
) as parse_map,
|
|
||||||
patch(
|
patch(
|
||||||
"homeassistant.components.roborock.roborock_storage.Path.exists",
|
"homeassistant.components.roborock.roborock_storage.Path.exists",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
@ -177,8 +175,6 @@ async def test_fail_to_load_image(
|
|||||||
await hass.config_entries.async_reload(setup_entry.entry_id)
|
await hass.config_entries.async_reload(setup_entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert read_bytes.call_count == 4
|
assert read_bytes.call_count == 4
|
||||||
# Ensure that we never updated the map manually since we couldn't load it.
|
|
||||||
assert parse_map.call_count == 0
|
|
||||||
assert "Unable to read map file" in caplog.text
|
assert "Unable to read map file" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
@ -298,3 +294,52 @@ async def test_index_error_map(
|
|||||||
# last_updated timestamp.
|
# last_updated timestamp.
|
||||||
assert resp.ok
|
assert resp.ok
|
||||||
assert previous_state == hass.states.get("image.roborock_s7_maxv_upstairs").state
|
assert previous_state == hass.states.get("image.roborock_s7_maxv_upstairs").state
|
||||||
|
|
||||||
|
|
||||||
|
async def test_map_status_change(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_entry: MockConfigEntry,
|
||||||
|
hass_client: ClientSessionGenerator,
|
||||||
|
) -> None:
|
||||||
|
"""Test floor plan map image is correctly updated on status change."""
|
||||||
|
assert len(hass.states.async_all("image")) == 4
|
||||||
|
|
||||||
|
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")
|
||||||
|
assert resp.status == HTTPStatus.OK
|
||||||
|
old_body = await resp.read()
|
||||||
|
assert old_body[0:4] == b"\x89PNG"
|
||||||
|
|
||||||
|
# Call a second time. This interval does not directly trigger a map update, but does
|
||||||
|
# trigger a status update which detects the state has changed and uddates the map
|
||||||
|
now = dt_util.utcnow() + V1_LOCAL_NOT_CLEANING_INTERVAL
|
||||||
|
|
||||||
|
# Copy the device prop so we don't override it
|
||||||
|
prop = copy.deepcopy(PROP)
|
||||||
|
prop.status.state_name = "testing"
|
||||||
|
new_map_data = copy.deepcopy(MAP_DATA)
|
||||||
|
new_map_data.image = ImageData(
|
||||||
|
100, 10, 10, 10, 10, ImageConfig(), Image.new("RGB", (2, 2)), lambda p: p
|
||||||
|
)
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_prop",
|
||||||
|
return_value=prop,
|
||||||
|
),
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.roborock.coordinator.dt_util.utcnow",
|
||||||
|
return_value=now,
|
||||||
|
),
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.roborock.coordinator.RoborockMapDataParser.parse",
|
||||||
|
return_value=new_map_data,
|
||||||
|
),
|
||||||
|
):
|
||||||
|
async_fire_time_changed(hass, now)
|
||||||
|
resp = await client.get("/api/image_proxy/image.roborock_s7_maxv_upstairs")
|
||||||
|
assert resp.status == HTTPStatus.OK
|
||||||
|
assert resp.status == HTTPStatus.OK
|
||||||
|
body = await resp.read()
|
||||||
|
assert body is not None
|
||||||
|
assert body != old_body
|
||||||
|
Loading…
x
Reference in New Issue
Block a user