diff --git a/roborock/api.py b/roborock/api.py index bcda9a26..611aaf3d 100644 --- a/roborock/api.py +++ b/roborock/api.py @@ -34,6 +34,7 @@ RoomMapping, SmartWashParams, Status, + StatusOldModes, UserData, WashTowelMode, ) @@ -206,6 +207,8 @@ async def send_command(self, device_id: str, method: RoborockCommand, params: Op async def get_status(self, device_id: str) -> Status | None: status = await self.send_command(device_id, RoborockCommand.GET_STATUS) if isinstance(status, dict): + if self.devices_info[device_id].device.uses_old_codes: + return StatusOldModes.from_dict(status) return Status.from_dict(status) return None diff --git a/roborock/code_mappings.py b/roborock/code_mappings.py index 9bdd3cb5..0be4f681 100644 --- a/roborock/code_mappings.py +++ b/roborock/code_mappings.py @@ -181,3 +181,12 @@ def create_code_enum(name: str, data: dict) -> RoborockEnum: 2: "deep", }, ) + +OldRoborockFanPowerCode = create_code_enum( + "OldRoborockFanPowerCode", + {101: "silent", 102: "balanced", 103: "turbo", 104: "max", 105: "gentle", 106: "customize (auto)"}, +) + +OldRoborockMopIntensityCode = create_code_enum( + "OldRoborockMopModeCode", {200: "off", 201: "low", 202: "medium", 203: "high", 207: "custom (levels)"} +) diff --git a/roborock/containers.py b/roborock/containers.py index 0ccf7846..73e0589e 100644 --- a/roborock/containers.py +++ b/roborock/containers.py @@ -15,6 +15,8 @@ ) from .code_mappings import ( + OldRoborockFanPowerCode, + OldRoborockMopIntensityCode, RoborockDockDustCollectionModeCode, RoborockDockErrorCode, RoborockErrorCode, @@ -125,7 +127,7 @@ class HomeDataDeviceStatus(RoborockBase): id: Optional[Any] = None name: Optional[Any] = None code: Optional[Any] = None - model: Optional[Any] = None + model: Optional[str] = None icon_url: Optional[Any] = None attribute: Optional[Any] = None capability: Optional[Any] = None @@ -160,6 +162,11 @@ class HomeDataDevice(RoborockBase): new_feature_set: Optional[str] = None device_status: Optional[HomeDataDeviceStatus] = None silent_ota_switch: Optional[bool] = None + uses_old_codes: bool = False + + def __post_init__(self): + if self.device_status and self.device_status.model == "roborock.vacuum.a10": + self.uses_old_codes = True @dataclass @@ -235,6 +242,11 @@ class Status(RoborockBase): unsave_map_flag: Optional[int] = None +class StatusOldModes(Status): + water_box_mode: Optional[OldRoborockMopIntensityCode] = None # type: ignore[valid-type] + fan_power: Optional[OldRoborockFanPowerCode] = None # type: ignore[valid-type] + + @dataclass class DNDTimer(RoborockBase): start_hour: Optional[int] = None diff --git a/roborock/typing.py b/roborock/typing.py index 6a23d202..71b016d4 100644 --- a/roborock/typing.py +++ b/roborock/typing.py @@ -107,6 +107,7 @@ class RoborockCommand(str, Enum): GET_DEVICE_ICE = "get_device_ice" START_VOICE_CHAT = "start_voice_chat" SEND_SDP_TO_ROBOT = "send_sdp_to_robot" + GET_FW_FEATURES = "get_fw_features" @dataclass diff --git a/tests/test_containers.py b/tests/test_containers.py index 0b82c0cb..85859c49 100644 --- a/tests/test_containers.py +++ b/tests/test_containers.py @@ -1,5 +1,6 @@ -from roborock import CleanRecord, CleanSummary, Consumable, DNDTimer, HomeData, Status, UserData +from roborock import CleanRecord, CleanSummary, Consumable, DNDTimer, HomeData, Status, StatusOldModes, UserData from roborock.code_mappings import ( + OldRoborockFanPowerCode, RoborockDockErrorCode, RoborockDockTypeCode, RoborockErrorCode, @@ -153,6 +154,14 @@ def test_status(): assert s.unsave_map_flag == 0 +def test_old_status(): + s = StatusOldModes.from_dict(STATUS) + assert s.msg_ver == 2 + assert s.msg_seq == 458 + assert s.state == RoborockStateCode["8"] + assert s.fan_power == OldRoborockFanPowerCode["102"] + + def test_dnd_timer(): dnd = DNDTimer.from_dict(DND_TIMER) assert dnd.start_hour == 22