Skip to content

Commit 8eabcf5

Browse files
committed
chore: address some comments
1 parent f792f49 commit 8eabcf5

File tree

5 files changed

+44
-10
lines changed

5 files changed

+44
-10
lines changed

roborock/devices/b01_channel.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ async def send_decoded_command(
3333
_LOGGER.debug("Sending MQTT command: %s", params)
3434
msg_id = str(get_next_int(100000000000, 999999999999))
3535
roborock_message = encode_mqtt_payload(dps, command, params, msg_id)
36-
finished = asyncio.Event()
37-
result: dict[str, Any] = {}
36+
future: asyncio.Future[dict[str, Any]] = asyncio.get_running_loop().create_future()
3837

3938
def find_response(response_message: RoborockMessage) -> None:
4039
"""Handle incoming messages and resolve the future."""
@@ -56,9 +55,11 @@ def find_response(response_message: RoborockMessage) -> None:
5655
if isinstance(inner, dict) and inner.get("msgId") == msg_id:
5756
_LOGGER.debug("Received query response: %s", inner)
5857
data = inner.get("data")
59-
if isinstance(data, dict):
60-
result.update(data)
61-
finished.set()
58+
if not future.done():
59+
if isinstance(data, dict):
60+
future.set_result(data)
61+
else:
62+
future.set_exception(RoborockException(f"Unexpected data type for response: {data}"))
6263
else:
6364
_LOGGER.debug("Received unexpected response: %s", dps_value)
6465

@@ -68,10 +69,8 @@ def find_response(response_message: RoborockMessage) -> None:
6869
try:
6970
await mqtt_channel.publish(roborock_message)
7071
try:
71-
await asyncio.wait_for(finished.wait(), timeout=_TIMEOUT)
72+
return await asyncio.wait_for(future, timeout=_TIMEOUT)
7273
except TimeoutError as ex:
7374
raise RoborockException(f"Command timed out after {_TIMEOUT}s") from ex
7475
finally:
7576
unsub()
76-
77-
return result

roborock/protocols/b01_protocol.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
RoborockMessage,
1414
RoborockMessageProtocol,
1515
)
16-
from roborock.util import get_next_int
1716

1817
_LOGGER = logging.getLogger(__name__)
1918

@@ -28,7 +27,7 @@ def encode_mqtt_payload(dps: int, command: CommandType, params: ParamsType, msg_
2827
"dps": {
2928
dps: {
3029
"method": str(command),
31-
"msgId": msg_id or str(get_next_int(100000000000, 999999999999)),
30+
"msgId": msg_id,
3231
"params": params or [],
3332
}
3433
}

tests/devices/traits/a01/__init__.py

Whitespace-only changes.

tests/devices/traits/b01/__init__.py

Whitespace-only changes.

tests/devices/traits/b01/test_b01_init.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
from Crypto.Util.Padding import pad, unpad
88

99
from roborock.data.b01_q7 import WorkStatusMapping
10+
from roborock.devices.b01_channel import send_decoded_command
1011
from roborock.devices.traits.b01.q7 import Q7PropertiesApi
12+
from roborock.exceptions import RoborockException
1113
from roborock.protocols.b01_protocol import B01_VERSION
1214
from roborock.roborock_message import RoborockB01Props, RoborockMessage, RoborockMessageProtocol
1315
from tests.conftest import FakeChannel
@@ -87,6 +89,7 @@ async def test_q7_api_query_values(q7_api: Q7PropertiesApi, fake_channel: FakeCh
8789
assert message.version == B01_VERSION
8890

8991
# Verify request payload
92+
assert message.payload is not None
9093
payload_data = json.loads(unpad(message.payload, AES.block_size))
9194
# {"dps": {"10000": {"method": "prop.get", "msgId": "123456789", "params": {"property": ["status", "wind"]}}}}
9295
assert "dps" in payload_data
@@ -128,3 +131,36 @@ async def test_q7_response_value_mapping(
128131
result = await q7_api.query_values(query)
129132

130133
assert result is not None
134+
135+
136+
async def test_send_decoded_command_non_dict_response(fake_channel: FakeChannel):
137+
"""Test validity of handling non-dict responses (should not timeout)."""
138+
msg_id = "123456789"
139+
140+
dps_payload = {
141+
"dps": {
142+
"10000": json.dumps(
143+
{
144+
"msgId": msg_id,
145+
"data": "some_string_error",
146+
}
147+
)
148+
}
149+
}
150+
message = RoborockMessage(
151+
protocol=RoborockMessageProtocol.RPC_RESPONSE,
152+
payload=pad(
153+
json.dumps(dps_payload).encode(),
154+
AES.block_size,
155+
),
156+
version=b"B01",
157+
seq=2021,
158+
)
159+
160+
fake_channel.response_queue.append(message)
161+
162+
with patch("roborock.devices.b01_channel.get_next_int", return_value=int(msg_id)):
163+
# Use a random string for command type to avoid needing import
164+
165+
with pytest.raises(RoborockException, match="Unexpected data type for response"):
166+
await send_decoded_command(fake_channel, 10000, "prop.get", []) # type: ignore[arg-type]

0 commit comments

Comments
 (0)