Skip to content

Commit 1cb88d8

Browse files
committed
chore: mild clean ups
1 parent b52d817 commit 1cb88d8

3 files changed

Lines changed: 42 additions & 5 deletions

File tree

roborock/devices/traits/v1/obstacle_photos.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,16 @@ async def get_enabled(self) -> bool:
8888
raise RoborockException("get_camera_status response did not contain camera status")
8989
return bool((response[0] >> _MAP_OBJECT_PHOTO_ENABLED_BIT) & 1)
9090

91-
async def get_photo(self, photo_id: str, photo_type: int = _PHOTO_TYPE_SMALL) -> ObstaclePhoto:
92-
"""Fetch an obstacle photo by its map photo id."""
91+
async def get_photo(self, photo_id: str) -> ObstaclePhoto:
92+
"""Fetch the small obstacle photo for a map photo ID.
93+
94+
Photo IDs are available as ``Obstacle.details.photo_name`` in
95+
``ParsedMapData.map_data.obstacles_with_photo`` and
96+
``ParsedMapData.map_data.ignored_obstacles_with_photo``.
97+
"""
9398
response = await self.rpc_channel.send_command(
9499
self.command,
95-
params={"img_id": photo_id, "type": photo_type},
100+
params={"img_id": photo_id, "type": _PHOTO_TYPE_SMALL},
96101
)
97102
photo = self.converter.convert(response)
98103
photo.photo_id = photo_id

roborock/protocols/v1_protocol.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
from __future__ import annotations
44

55
import base64
6+
import gzip
67
import json
78
import logging
89
import secrets
910
import struct
11+
import zlib
1012
from collections.abc import Callable
1113
from dataclasses import dataclass, field
1214
from enum import StrEnum
@@ -297,7 +299,7 @@ def _decode_blob_response(message: RoborockMessage) -> BlobResponse | None:
297299
raise RoborockException("Invalid V1 blob response format")
298300
try:
299301
data = Utils.decompress(payload[header_size:end_offset])
300-
except Exception as err:
302+
except (gzip.BadGzipFile, EOFError, zlib.error) as err:
301303
raise RoborockException("Failed to decode blob message payload") from err
302304
return BlobResponse(request_id=request_id, data=data)
303305

tests/devices/traits/v1/test_obstacle_photos.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Tests for the ObstaclePhotoTrait."""
22

33
import gzip
4-
from unittest.mock import AsyncMock
4+
from unittest.mock import AsyncMock, patch
55

66
import pytest
77

@@ -11,6 +11,7 @@
1111
parse_photo_data,
1212
)
1313
from roborock.exceptions import RoborockException
14+
from roborock.protocol import Utils
1415
from roborock.protocols.v1_protocol import create_blob_response_decoder
1516
from roborock.roborock_message import RoborockMessage, RoborockMessageProtocol
1617
from roborock.roborock_typing import RoborockCommand
@@ -81,6 +82,35 @@ def test_decode_blob_response() -> None:
8182
assert response.data == decompressed
8283

8384

85+
def test_decode_blob_response_wraps_decompression_errors() -> None:
86+
"""Test expected gzip decompression errors are wrapped."""
87+
payload = bytearray(25)
88+
payload[:8] = b"ROBOROCK"
89+
payload[16:18] = (24).to_bytes(2, "little")
90+
payload[20:24] = (1).to_bytes(4, "little")
91+
92+
with pytest.raises(RoborockException, match="Failed to decode blob message payload"):
93+
create_blob_response_decoder()(
94+
RoborockMessage(protocol=RoborockMessageProtocol.MAP_RESPONSE, payload=bytes(payload))
95+
)
96+
97+
98+
def test_decode_blob_response_does_not_wrap_unexpected_errors() -> None:
99+
"""Test unexpected decompression errors propagate unchanged."""
100+
payload = bytearray(25)
101+
payload[:8] = b"ROBOROCK"
102+
payload[16:18] = (24).to_bytes(2, "little")
103+
payload[20:24] = (1).to_bytes(4, "little")
104+
105+
with (
106+
patch.object(Utils, "decompress", side_effect=RuntimeError("unexpected")),
107+
pytest.raises(RuntimeError, match="unexpected"),
108+
):
109+
create_blob_response_decoder()(
110+
RoborockMessage(protocol=RoborockMessageProtocol.MAP_RESPONSE, payload=bytes(payload))
111+
)
112+
113+
84114
def test_obstacle_photo_trait_metadata() -> None:
85115
"""Test obstacle photos use the blob RPC channel when discovered."""
86116
assert ObstaclePhotoTrait.blob_rpc_channel is True

0 commit comments

Comments
 (0)