Bump python-roborock to 1.0.0 (#115324)

* refactor base code

* refactor tests code
This commit is contained in:
Luke Lashley 2024-04-09 20:50:46 -04:00 committed by GitHub
parent fa3cba5b87
commit 968de08e4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 60 additions and 60 deletions

View File

@ -9,8 +9,8 @@ import logging
from typing import Any
from roborock import HomeDataRoom, RoborockException, RoborockInvalidCredentials
from roborock.cloud_api import RoborockMqttClient
from roborock.containers import DeviceData, HomeDataDevice, HomeDataProduct, UserData
from roborock.version_1_apis.roborock_mqtt_client_v1 import RoborockMqttClientV1
from roborock.web_api import RoborockApiClient
from homeassistant.config_entries import ConfigEntry
@ -75,7 +75,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
translation_key="no_coordinators",
)
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
coordinator.roborock_device_info.device.duid: coordinator
coordinator.api.device_info.device.duid: coordinator
for coordinator in valid_coordinators
}
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
@ -107,7 +107,7 @@ async def setup_device(
home_data_rooms: list[HomeDataRoom],
) -> RoborockDataUpdateCoordinator | None:
"""Set up a device Coordinator."""
mqtt_client = RoborockMqttClient(user_data, DeviceData(device, product_info.name))
mqtt_client = RoborockMqttClientV1(user_data, DeviceData(device, product_info.name))
try:
networking = await mqtt_client.get_networking()
if networking is None:
@ -138,7 +138,7 @@ async def setup_device(
await coordinator.async_config_entry_first_refresh()
except ConfigEntryNotReady as ex:
await coordinator.release()
if isinstance(coordinator.api, RoborockMqttClient):
if isinstance(coordinator.api, RoborockMqttClientV1):
_LOGGER.warning(
"Not setting up %s because the we failed to get data for the first time using the online client. "
"Please ensure your Home Assistant instance can communicate with this device. "

View File

@ -7,11 +7,11 @@ from datetime import timedelta
import logging
from roborock import HomeDataRoom
from roborock.cloud_api import RoborockMqttClient
from roborock.containers import DeviceData, HomeDataDevice, HomeDataProduct, NetworkInfo
from roborock.exceptions import RoborockException
from roborock.local_api import RoborockLocalClient
from roborock.roborock_typing import DeviceProp
from roborock.version_1_apis.roborock_local_client_v1 import RoborockLocalClientV1
from roborock.version_1_apis.roborock_mqtt_client_v1 import RoborockMqttClientV1
from homeassistant.const import ATTR_CONNECTIONS
from homeassistant.core import HomeAssistant
@ -36,7 +36,7 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]):
device: HomeDataDevice,
device_networking: NetworkInfo,
product_info: HomeDataProduct,
cloud_api: RoborockMqttClient,
cloud_api: RoborockMqttClientV1,
home_data_rooms: list[HomeDataRoom],
) -> None:
"""Initialize."""
@ -48,7 +48,7 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]):
DeviceProp(),
)
device_data = DeviceData(device, product_info.model, device_networking.ip)
self.api: RoborockLocalClient | RoborockMqttClient = RoborockLocalClient(
self.api: RoborockLocalClientV1 | RoborockMqttClientV1 = RoborockLocalClientV1(
device_data
)
self.cloud_api = cloud_api
@ -69,7 +69,7 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]):
async def verify_api(self) -> None:
"""Verify that the api is reachable. If it is not, switch clients."""
if isinstance(self.api, RoborockLocalClient):
if isinstance(self.api, RoborockLocalClientV1):
try:
await self.api.ping()
except RoborockException:

View File

@ -2,21 +2,21 @@
from typing import Any
from roborock.api import AttributeCache, RoborockClient
from roborock.cloud_api import RoborockMqttClient
from roborock.command_cache import CacheableAttribute
from roborock.containers import Consumable, Status
from roborock.exceptions import RoborockException
from roborock.roborock_message import RoborockDataProtocol
from roborock.roborock_typing import RoborockCommand
from roborock.version_1_apis.roborock_client_v1 import AttributeCache, RoborockClientV1
from roborock.version_1_apis.roborock_mqtt_client_v1 import RoborockMqttClientV1
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import RoborockDataUpdateCoordinator
from .const import DOMAIN
from .coordinator import RoborockDataUpdateCoordinator
class RoborockEntity(Entity):
@ -28,7 +28,7 @@ class RoborockEntity(Entity):
self,
unique_id: str,
device_info: DeviceInfo,
api: RoborockClient,
api: RoborockClientV1,
) -> None:
"""Initialize the coordinated Roborock Device."""
self._attr_unique_id = unique_id
@ -36,7 +36,7 @@ class RoborockEntity(Entity):
self._api = api
@property
def api(self) -> RoborockClient:
def api(self) -> RoborockClientV1:
"""Returns the api."""
return self._api
@ -116,7 +116,7 @@ class RoborockCoordinatedEntity(
return data.status
@property
def cloud_api(self) -> RoborockMqttClient:
def cloud_api(self) -> RoborockMqttClientV1:
"""Return the cloud api."""
return self.coordinator.cloud_api

View File

@ -7,7 +7,7 @@
"iot_class": "local_polling",
"loggers": ["roborock"],
"requirements": [
"python-roborock==0.40.0",
"python-roborock==1.0.0",
"vacuum-map-parser-roborock==0.1.1"
]
}

View File

@ -6,9 +6,9 @@ from dataclasses import dataclass
import logging
from typing import Any
from roborock.api import AttributeCache
from roborock.command_cache import CacheableAttribute
from roborock.exceptions import RoborockException
from roborock.version_1_apis.roborock_client_v1 import AttributeCache
from homeassistant.components.number import NumberEntity, NumberEntityDescription
from homeassistant.config_entries import ConfigEntry

View File

@ -8,8 +8,8 @@ from dataclasses import dataclass
import logging
from typing import Any
from roborock.api import AttributeCache
from roborock.command_cache import CacheableAttribute
from roborock.version_1_apis.roborock_client_v1 import AttributeCache
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.config_entries import ConfigEntry

View File

@ -8,9 +8,9 @@ from datetime import time
import logging
from typing import Any
from roborock.api import AttributeCache
from roborock.command_cache import CacheableAttribute
from roborock.exceptions import RoborockException
from roborock.version_1_apis.roborock_client_v1 import AttributeCache
from homeassistant.components.time import TimeEntity, TimeEntityDescription
from homeassistant.config_entries import ConfigEntry

View File

@ -2294,7 +2294,7 @@ python-rabbitair==0.0.8
python-ripple-api==0.0.3
# homeassistant.components.roborock
python-roborock==0.40.0
python-roborock==1.0.0
# homeassistant.components.smarttub
python-smarttub==0.0.36

View File

@ -1773,7 +1773,7 @@ python-qbittorrent==0.4.3
python-rabbitair==0.0.8
# homeassistant.components.roborock
python-roborock==0.40.0
python-roborock==1.0.0
# homeassistant.components.smarttub
python-smarttub==0.0.36

View File

@ -32,26 +32,26 @@ from tests.common import MockConfigEntry
def bypass_api_fixture() -> None:
"""Skip calls to the API."""
with (
patch("homeassistant.components.roborock.RoborockMqttClient.async_connect"),
patch("homeassistant.components.roborock.RoborockMqttClient._send_command"),
patch("homeassistant.components.roborock.RoborockMqttClientV1.async_connect"),
patch("homeassistant.components.roborock.RoborockMqttClientV1._send_command"),
patch(
"homeassistant.components.roborock.RoborockApiClient.get_home_data",
return_value=HOME_DATA,
),
patch(
"homeassistant.components.roborock.RoborockMqttClient.get_networking",
"homeassistant.components.roborock.RoborockMqttClientV1.get_networking",
return_value=NETWORK_INFO,
),
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.get_prop",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_prop",
return_value=PROP,
),
patch(
"homeassistant.components.roborock.coordinator.RoborockMqttClient.get_multi_maps_list",
"homeassistant.components.roborock.coordinator.RoborockMqttClientV1.get_multi_maps_list",
return_value=MULTI_MAP_LIST,
),
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.get_multi_maps_list",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_multi_maps_list",
return_value=MULTI_MAP_LIST,
),
patch(
@ -59,24 +59,24 @@ def bypass_api_fixture() -> None:
return_value=MAP_DATA,
),
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.send_message"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.send_message"
),
patch("homeassistant.components.roborock.RoborockMqttClient._wait_response"),
patch("homeassistant.components.roborock.RoborockMqttClientV1._wait_response"),
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient._wait_response"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1._wait_response"
),
patch(
"roborock.api.AttributeCache.async_value",
"roborock.version_1_apis.AttributeCache.async_value",
),
patch(
"roborock.api.AttributeCache.value",
"roborock.version_1_apis.AttributeCache.value",
),
patch(
"homeassistant.components.roborock.image.MAP_SLEEP",
0,
),
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.get_room_mapping",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_room_mapping",
return_value=[
RoomMapping(16, "2362048"),
RoomMapping(17, "2362044"),
@ -84,7 +84,7 @@ def bypass_api_fixture() -> None:
],
),
patch(
"homeassistant.components.roborock.coordinator.RoborockMqttClient.get_room_mapping",
"homeassistant.components.roborock.coordinator.RoborockMqttClientV1.get_room_mapping",
return_value=[
RoomMapping(16, "2362048"),
RoomMapping(17, "2362044"),

View File

@ -31,7 +31,7 @@ async def test_update_success(
# Ensure that the entity exist, as these test can pass even if there is no entity.
assert hass.states.get(entity_id).state == "unknown"
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.send_message"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.send_message"
) as mock_send_message:
await hass.services.async_call(
"button",

View File

@ -37,7 +37,7 @@ async def test_floorplan_image(
prop.status.in_cleaning = 1
with (
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.get_prop",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_prop",
return_value=prop,
),
patch(
@ -72,7 +72,7 @@ async def test_floorplan_image_failed_parse(
return_value=map_data,
),
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.get_prop",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_prop",
return_value=prop,
),
patch(

View File

@ -19,7 +19,7 @@ async def test_unload_entry(
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert setup_entry.state is ConfigEntryState.LOADED
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.async_release"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.async_release"
) as mock_disconnect:
assert await hass.config_entries.async_unload(setup_entry.entry_id)
await hass.async_block_till_done()
@ -37,7 +37,7 @@ async def test_config_entry_not_ready(
"homeassistant.components.roborock.RoborockApiClient.get_home_data",
),
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.get_prop",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_prop",
side_effect=RoborockException(),
),
):
@ -55,7 +55,7 @@ async def test_config_entry_not_ready_home_data(
side_effect=RoborockException(),
),
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.get_prop",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_prop",
side_effect=RoborockException(),
),
):
@ -68,7 +68,7 @@ async def test_get_networking_fails(
) -> None:
"""Test that when networking fails, we attempt to retry."""
with patch(
"homeassistant.components.roborock.RoborockMqttClient.get_networking",
"homeassistant.components.roborock.RoborockMqttClientV1.get_networking",
side_effect=RoborockException(),
):
await async_setup_component(hass, DOMAIN, {})
@ -80,7 +80,7 @@ async def test_get_networking_fails_none(
) -> None:
"""Test that when networking returns None, we attempt to retry."""
with patch(
"homeassistant.components.roborock.RoborockMqttClient.get_networking",
"homeassistant.components.roborock.RoborockMqttClientV1.get_networking",
return_value=None,
):
await async_setup_component(hass, DOMAIN, {})
@ -93,11 +93,11 @@ async def test_cloud_client_fails_props(
"""Test that if networking succeeds, but we can't communicate with the vacuum, we can't get props, fail."""
with (
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.ping",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.ping",
side_effect=RoborockException(),
),
patch(
"homeassistant.components.roborock.coordinator.RoborockMqttClient.get_prop",
"homeassistant.components.roborock.coordinator.RoborockMqttClientV1.get_prop",
side_effect=RoborockException(),
),
):
@ -110,7 +110,7 @@ async def test_local_client_fails_props(
) -> None:
"""Test that if networking succeeds, but we can't communicate locally with the vacuum, we can't get props, fail."""
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.get_prop",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_prop",
side_effect=RoborockException(),
):
await async_setup_component(hass, DOMAIN, {})
@ -122,7 +122,7 @@ async def test_fails_maps_continue(
) -> None:
"""Test that if we fail to get the maps, we still setup."""
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.get_multi_maps_list",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_multi_maps_list",
side_effect=RoborockException(),
):
await async_setup_component(hass, DOMAIN, {})

View File

@ -27,7 +27,7 @@ async def test_update_success(
# Ensure that the entity exist, as these test can pass even if there is no entity.
assert hass.states.get(entity_id) is not None
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.send_message"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.send_message"
) as mock_send_message:
await hass.services.async_call(
"number",

View File

@ -30,7 +30,7 @@ async def test_update_success(
# Ensure that the entity exist, as these test can pass even if there is no entity.
assert hass.states.get(entity_id) is not None
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.send_message"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.send_message"
) as mock_send_message:
await hass.services.async_call(
"select",
@ -50,7 +50,7 @@ async def test_update_failure(
"""Test that changing a value will raise a homeassistanterror when it fails."""
with (
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.send_message",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.send_message",
side_effect=RoborockException(),
),
pytest.raises(HomeAssistantError),

View File

@ -3,7 +3,6 @@
from unittest.mock import patch
from roborock import DeviceData, HomeDataDevice
from roborock.cloud_api import RoborockMqttClient
from roborock.const import (
FILTER_REPLACE_TIME,
MAIN_BRUSH_REPLACE_TIME,
@ -11,6 +10,7 @@ from roborock.const import (
SIDE_BRUSH_REPLACE_TIME,
)
from roborock.roborock_message import RoborockMessage, RoborockMessageProtocol
from roborock.version_1_apis import RoborockMqttClientV1
from homeassistant.core import HomeAssistant
@ -62,11 +62,11 @@ async def test_listener_update(
"""Test that when we receive a mqtt topic, we successfully update the entity."""
assert hass.states.get("sensor.roborock_s7_maxv_status").state == "charging"
# Listeners are global based on uuid - so this is okay
client = RoborockMqttClient(
client = RoborockMqttClientV1(
USER_DATA, DeviceData(device=HomeDataDevice("abc123", "", "", "", ""), model="")
)
# Test Status
with patch("roborock.api.AttributeCache.value", STATUS.as_dict()):
with patch("roborock.version_1_apis.AttributeCache.value", STATUS.as_dict()):
# Symbolizes a mqtt message coming in
client.on_message_received(
[
@ -80,7 +80,7 @@ async def test_listener_update(
assert hass.states.get("sensor.roborock_s7_maxv_filter_time_left").state == str(
FILTER_REPLACE_TIME - 74382
)
with patch("roborock.api.AttributeCache.value", CONSUMABLE.as_dict()):
with patch("roborock.version_1_apis.AttributeCache.value", CONSUMABLE.as_dict()):
client.on_message_received(
[
RoborockMessage(

View File

@ -28,7 +28,7 @@ async def test_update_success(
# Ensure that the entity exist, as these test can pass even if there is no entity.
assert hass.states.get(entity_id) is not None
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient._send_command"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1._send_command"
) as mock_send_message:
await hass.services.async_call(
"switch",
@ -39,7 +39,7 @@ async def test_update_success(
)
assert mock_send_message.assert_called_once
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.send_message"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.send_message"
) as mock_send_message:
await hass.services.async_call(
"switch",

View File

@ -28,7 +28,7 @@ async def test_update_success(
# Ensure that the entity exist, as these test can pass even if there is no entity.
assert hass.states.get(entity_id) is not None
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient._send_command"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1._send_command"
) as mock_send_message:
await hass.services.async_call(
"time",

View File

@ -82,7 +82,7 @@ async def test_commands(
data = {ATTR_ENTITY_ID: ENTITY_ID, **(service_params or {})}
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.send_command"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.send_command"
) as mock_send_command:
await hass.services.async_call(
Platform.VACUUM,
@ -115,7 +115,7 @@ async def test_resume_cleaning(
prop = copy.deepcopy(PROP)
prop.status.in_cleaning = in_cleaning_int
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.get_prop",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.get_prop",
return_value=prop,
):
await async_setup_component(hass, DOMAIN, {})
@ -124,7 +124,7 @@ async def test_resume_cleaning(
data = {ATTR_ENTITY_ID: ENTITY_ID}
with patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.send_command"
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.send_command"
) as mock_send_command:
await hass.services.async_call(
Platform.VACUUM,
@ -145,7 +145,7 @@ async def test_failed_user_command(
data = {ATTR_ENTITY_ID: ENTITY_ID, "command": "fake_command"}
with (
patch(
"homeassistant.components.roborock.coordinator.RoborockLocalClient.send_command",
"homeassistant.components.roborock.coordinator.RoborockLocalClientV1.send_command",
side_effect=RoborockException(),
),
pytest.raises(HomeAssistantError, match="Error while calling fake_command"),