Compare commits

...

6 Commits

Author SHA1 Message Date
Ludovic BOUÉ
8f5a8e572d Enhance v1 status refresh test to verify call order of refresh methods 2026-02-22 18:12:29 +01:00
Ludovic BOUÉ
f04c6295f2 Merge branch 'dev' into feat/roborock-v1-status-refresh-after-command 2026-02-22 17:55:55 +01:00
Ludovic BOUÉ
9c3c7b1360 Add test for v1 status refresh fallback 2026-02-22 07:16:10 +01:00
Ludovic BOUÉ
f459b91b19 Strengthen v1 status refresh ordering test 2026-02-21 21:22:15 +01:00
Ludovic BOUÉ
9621c0a8c4 Avoid duplicate sync refresh after v1 vacuum commands 2026-02-21 21:17:18 +01:00
Ludovic BOUÉ
a10cb2359e Refresh v1 status immediately after vacuum commands 2026-02-21 20:59:21 +01:00
2 changed files with 75 additions and 2 deletions

View File

@@ -1,5 +1,6 @@
"""Support for Roborock device base class."""
import logging
from typing import Any
from roborock.devices.traits.v1.command import CommandTrait
@@ -19,6 +20,8 @@ from .coordinator import (
RoborockDataUpdateCoordinatorA01,
)
_LOGGER = logging.getLogger(__name__)
class RoborockEntity(Entity):
"""Representation of a base Roborock Entity."""
@@ -106,7 +109,15 @@ class RoborockCoordinatedEntityV1(
) -> dict:
"""Overloads normal send command but refreshes coordinator."""
res = await super().send(command, params)
await self.coordinator.async_refresh()
try:
await self.coordinator.properties_api.status.refresh()
except RoborockException as err:
_LOGGER.debug("Failed to refresh status after command: %s", err)
else:
self.async_write_ha_state()
await self.coordinator.async_request_refresh()
return res

View File

@@ -1,7 +1,7 @@
"""Tests for Roborock vacuums."""
from typing import Any
from unittest.mock import Mock, call
from unittest.mock import AsyncMock, Mock, call
import pytest
from roborock import RoborockException
@@ -180,6 +180,68 @@ async def test_failed_user_command(
)
async def test_v1_refreshes_status_after_command(
hass: HomeAssistant,
setup_entry: MockConfigEntry,
fake_vacuum: FakeDevice,
) -> None:
"""Test v1 commands refresh status before coordinator refresh request."""
assert fake_vacuum.v1_properties is not None
coordinator = setup_entry.runtime_data.v1[0]
# Patch async_request_refresh to check ordering
ordering = []
async def status_refresh_side_effect(*args, **kwargs):
ordering.append("status_refresh")
fake_vacuum.v1_properties.status.refresh = AsyncMock(
side_effect=status_refresh_side_effect
)
async def async_request_refresh_side_effect(*args, **kwargs):
ordering.append("async_request_refresh")
coordinator.async_request_refresh = AsyncMock(
side_effect=async_request_refresh_side_effect
)
await hass.services.async_call(
VACUUM_DOMAIN,
SERVICE_START,
{ATTR_ENTITY_ID: ENTITY_ID},
blocking=True,
)
assert ordering == ["status_refresh", "async_request_refresh"], (
f"Ordering was {ordering}"
)
assert coordinator.async_request_refresh.call_count == 1
assert fake_vacuum.v1_properties.status.refresh.call_count == 1
async def test_v1_status_refresh_failure_still_requests_coordinator_refresh(
hass: HomeAssistant,
setup_entry: MockConfigEntry,
fake_vacuum: FakeDevice,
) -> None:
"""Test v1 command flow continues when status refresh fails."""
assert fake_vacuum.v1_properties is not None
coordinator = setup_entry.runtime_data.v1[0]
fake_vacuum.v1_properties.status.refresh.side_effect = RoborockException()
coordinator.async_request_refresh = AsyncMock()
await hass.services.async_call(
VACUUM_DOMAIN,
SERVICE_START,
{ATTR_ENTITY_ID: ENTITY_ID},
blocking=True,
)
assert coordinator.async_request_refresh.call_count == 1
async def test_get_maps(
hass: HomeAssistant,
setup_entry: MockConfigEntry,