Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion homeassistant/components/roborock/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ def __init__(
# Tracks the last successful update to control when we report failure
# to the base class. This is reset on successful data update.
self._last_update_success_time: datetime | None = None
self._has_connected_locally: bool = False

@cached_property
def dock_device_info(self) -> DeviceInfo:
Expand Down Expand Up @@ -191,7 +192,8 @@ async def update_map(self) -> None:
async def _verify_api(self) -> None:
"""Verify that the api is reachable."""
if self._device.is_connected:
if self._device.is_local_connected:
self._has_connected_locally |= self._device.is_local_connected
if self._has_connected_locally:
async_delete_issue(
self.hass, DOMAIN, f"cloud_api_used_{self.duid_slug}"
)
Expand Down Expand Up @@ -234,6 +236,7 @@ async def _update_device_prop(self) -> None:

async def _async_update_data(self) -> DeviceState:
"""Update data via library."""
await self._verify_api()
try:
# Update device props and standard api information
await self._update_device_prop()
Expand Down
57 changes: 57 additions & 0 deletions tests/components/roborock/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,63 @@ async def test_cloud_api_repair(
assert len(issue_registry.issues) == 0


@pytest.mark.parametrize("platforms", [[Platform.SENSOR]])
async def test_cloud_api_repair_cleared_on_update(
hass: HomeAssistant,
mock_roborock_entry: MockConfigEntry,
fake_vacuum: FakeDevice,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test that a repair is created then cleared if the device is reachable locally again."""

# Fake that the device is only reachable via cloud
fake_vacuum.is_connected = True
fake_vacuum.is_local_connected = False

# Load the integration and verify that a repair issue is created
await async_setup_component(hass, HA_DOMAIN, {})
await hass.config_entries.async_setup(mock_roborock_entry.entry_id)
await hass.async_block_till_done()
assert mock_roborock_entry.state is ConfigEntryState.LOADED

issue_registry = ir.async_get(hass)
assert len(issue_registry.issues) == 1

# Fake that the device is reachable locally again.
fake_vacuum.is_local_connected = True

# Refresh the coordinator using an arbitrary sensor, which should
# clear the repair issue.
sensor_entity_id = "sensor.roborock_s7_maxv_battery"
await hass.services.async_call(
HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
{ATTR_ENTITY_ID: sensor_entity_id},
blocking=True,
)
await hass.async_block_till_done()

# Verify that the repair issue is cleared
issue_registry = ir.async_get(hass)
assert len(issue_registry.issues) == 0

# Fake the device is cloud only again. Refreshing the coordinator
# should not recreate the repair issue.
fake_vacuum.is_local_connected = False

await hass.services.async_call(
HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
{ATTR_ENTITY_ID: sensor_entity_id},
blocking=True,
)
await hass.async_block_till_done()

# Verify that the repair issue still does not exist
issue_registry = ir.async_get(hass)
assert len(issue_registry.issues) == 0


@pytest.mark.parametrize("platforms", [[Platform.SENSOR]])
async def test_zeo_device_fails_setup(
hass: HomeAssistant,
Expand Down
Loading