python-roborock 5.35.0__tar.gz → 5.36.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_roborock-5.35.0 → python_roborock-5.36.0}/PKG-INFO +1 -1
- {python_roborock-5.35.0 → python_roborock-5.36.0}/pyproject.toml +1 -1
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/rpc/a01_channel.py +13 -2
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/transport/mqtt_channel.py +7 -3
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/mqtt/roborock_session.py +12 -6
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/mqtt/session.py +25 -1
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/protocols/a01_protocol.py +5 -1
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/testing/channel.py +6 -1
- {python_roborock-5.35.0 → python_roborock-5.36.0}/.gitignore +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/LICENSE +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/README.md +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/broadcast_protocol.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/callbacks.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/cli.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/const.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/b01_q10/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/b01_q7/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/code_mappings.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/containers.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/dyad/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/dyad/dyad_code_mappings.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/dyad/dyad_containers.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/mower/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/mower/mower_containers.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/v1/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/v1/v1_clean_modes.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/v1/v1_code_mappings.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/v1/v1_containers.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/zeo/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/zeo/zeo_code_mappings.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/zeo/zeo_containers.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/device_features.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/README.md +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/cache.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/device.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/device_manager.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/file_cache.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/rpc/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/rpc/b01_q10_channel.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/rpc/b01_q7_channel.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/rpc/v1_channel.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/a01/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/button_light.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/child_lock.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/clean_history.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/command.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/common.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/consumable.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/do_not_disturb.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/dust_collection.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/map.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/network_info.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/remote.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/status.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/vacuum.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/volume.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q7/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q7/clean_summary.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q7/map.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q7/map_content.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/common.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/traits_mixin.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/child_lock.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/clean_summary.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/command.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/common.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/consumeable.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/device_features.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/flow_led_status.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/home.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/led_status.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/map_content.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/maps.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/network_info.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/rooms.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/routines.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/status.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/volume.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/transport/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/transport/channel.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/transport/local_channel.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/diagnostics.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/exceptions.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/map/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/map/b01_grid_layers.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/map/b01_map_parser.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/map/b01_q10_map_parser.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/map/b01_q10_overlays.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/map/b01_q10_render.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/map/map_parser.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/map/proto/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/map/proto/b01_scmap.proto +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/map/proto/b01_scmap_pb2.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/mqtt/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/mqtt/health_manager.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/protocol.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/protocols/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/protocols/b01_q10_protocol.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/protocols/b01_q7_protocol.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/protocols/v1_protocol.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/py.typed +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/roborock_message.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/roborock_typing.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/testing/__init__.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/testing/b01_q10_simulator.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/testing/cloud.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/testing/simulator.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/testing/v1_simulator.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/util.py +0 -0
- {python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/web_api.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-roborock
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.36.0
|
|
4
4
|
Summary: A package to control Roborock vacuums.
|
|
5
5
|
Project-URL: Repository, https://github.com/python-roborock/python-roborock
|
|
6
6
|
Project-URL: Documentation, https://python-roborock.readthedocs.io/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-roborock"
|
|
3
|
-
version = "5.
|
|
3
|
+
version = "5.36.0"
|
|
4
4
|
description = "A package to control Roborock vacuums."
|
|
5
5
|
authors = [{ name = "humbertogontijo", email = "humbertogontijo@users.noreply.github.com" }, {name="Lash-L"}, {name="allenporter"}]
|
|
6
6
|
requires-python = ">=3.11, <4"
|
|
@@ -7,6 +7,7 @@ from typing import Any, overload
|
|
|
7
7
|
|
|
8
8
|
from roborock.devices.transport.mqtt_channel import MqttChannel
|
|
9
9
|
from roborock.exceptions import RoborockException
|
|
10
|
+
from roborock.mqtt.session import MqttQos
|
|
10
11
|
from roborock.protocols.a01_protocol import (
|
|
11
12
|
decode_rpc_response,
|
|
12
13
|
encode_mqtt_payload,
|
|
@@ -30,6 +31,7 @@ async def send_decoded_command(
|
|
|
30
31
|
mqtt_channel: MqttChannel,
|
|
31
32
|
params: dict[RoborockDyadDataProtocol, Any],
|
|
32
33
|
value_encoder: Callable[[Any], Any] | None = None,
|
|
34
|
+
qos: MqttQos = MqttQos.AT_MOST_ONCE,
|
|
33
35
|
) -> dict[RoborockDyadDataProtocol, Any]: ...
|
|
34
36
|
|
|
35
37
|
|
|
@@ -38,6 +40,7 @@ async def send_decoded_command(
|
|
|
38
40
|
mqtt_channel: MqttChannel,
|
|
39
41
|
params: dict[RoborockZeoProtocol, Any],
|
|
40
42
|
value_encoder: Callable[[Any], Any] | None = None,
|
|
43
|
+
qos: MqttQos = MqttQos.AT_MOST_ONCE,
|
|
41
44
|
) -> dict[RoborockZeoProtocol, Any]: ...
|
|
42
45
|
|
|
43
46
|
|
|
@@ -45,8 +48,16 @@ async def send_decoded_command(
|
|
|
45
48
|
mqtt_channel: MqttChannel,
|
|
46
49
|
params: dict[RoborockDyadDataProtocol, Any] | dict[RoborockZeoProtocol, Any],
|
|
47
50
|
value_encoder: Callable[[Any], Any] | None = None,
|
|
51
|
+
qos: MqttQos = MqttQos.AT_MOST_ONCE,
|
|
48
52
|
) -> dict[RoborockDyadDataProtocol, Any] | dict[RoborockZeoProtocol, Any]:
|
|
49
|
-
"""Send a command on the MQTT channel and get a decoded response.
|
|
53
|
+
"""Send a command on the MQTT channel and get a decoded response.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
mqtt_channel: The MQTT channel to send the command on.
|
|
57
|
+
params: The parameters to send.
|
|
58
|
+
value_encoder: A function to encode the values of the dictionary.
|
|
59
|
+
qos: The MQTT QoS level. Defaults to AT_MOST_ONCE.
|
|
60
|
+
"""
|
|
50
61
|
_LOGGER.debug("Sending MQTT command: %s", params)
|
|
51
62
|
roborock_message = encode_mqtt_payload(params, value_encoder)
|
|
52
63
|
|
|
@@ -54,7 +65,7 @@ async def send_decoded_command(
|
|
|
54
65
|
# block waiting for a response. Queries are handled below.
|
|
55
66
|
param_values = {int(k): v for k, v in params.items()}
|
|
56
67
|
if not (query_values := param_values.get(_ID_QUERY)):
|
|
57
|
-
await mqtt_channel.publish(roborock_message)
|
|
68
|
+
await mqtt_channel.publish(roborock_message, qos=qos)
|
|
58
69
|
return {}
|
|
59
70
|
|
|
60
71
|
# Merge any results together than contain the requested data. This
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/transport/mqtt_channel.py
RENAMED
|
@@ -8,7 +8,7 @@ from roborock.callbacks import decoder_callback
|
|
|
8
8
|
from roborock.data import HomeDataDevice, RRiot, UserData
|
|
9
9
|
from roborock.exceptions import RoborockException
|
|
10
10
|
from roborock.mqtt.health_manager import HealthManager
|
|
11
|
-
from roborock.mqtt.session import MqttParams, MqttSession, MqttSessionException
|
|
11
|
+
from roborock.mqtt.session import MqttParams, MqttQos, MqttSession, MqttSessionException
|
|
12
12
|
from roborock.protocol import create_mqtt_decoder, create_mqtt_encoder
|
|
13
13
|
from roborock.roborock_message import RoborockMessage
|
|
14
14
|
from roborock.util import RoborockLoggerAdapter
|
|
@@ -89,11 +89,15 @@ class MqttChannel(Channel):
|
|
|
89
89
|
finally:
|
|
90
90
|
unsub()
|
|
91
91
|
|
|
92
|
-
async def publish(self, message: RoborockMessage) -> None:
|
|
92
|
+
async def publish(self, message: RoborockMessage, qos: MqttQos = MqttQos.AT_MOST_ONCE) -> None:
|
|
93
93
|
"""Publish a command message.
|
|
94
94
|
|
|
95
95
|
The caller is responsible for handling any responses and associating them
|
|
96
96
|
with the incoming request.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
message: The message to publish.
|
|
100
|
+
qos: The MQTT QoS level. Defaults to AT_MOST_ONCE.
|
|
97
101
|
"""
|
|
98
102
|
try:
|
|
99
103
|
encoded_msg = self._encoder(message)
|
|
@@ -101,7 +105,7 @@ class MqttChannel(Channel):
|
|
|
101
105
|
self._logger.exception("Error encoding MQTT message: %s", e)
|
|
102
106
|
raise RoborockException(f"Failed to encode MQTT message: {e}") from e
|
|
103
107
|
try:
|
|
104
|
-
return await self._mqtt_session.publish(self._publish_topic, encoded_msg)
|
|
108
|
+
return await self._mqtt_session.publish(self._publish_topic, encoded_msg, qos=qos)
|
|
105
109
|
except MqttSessionException as e:
|
|
106
110
|
self._logger.debug("Error publishing MQTT message: %s", e)
|
|
107
111
|
raise RoborockException(f"Failed to publish MQTT message: {e}") from e
|
|
@@ -22,7 +22,7 @@ from roborock.callbacks import CallbackMap
|
|
|
22
22
|
from roborock.diagnostics import Diagnostics, redact_topic_name
|
|
23
23
|
|
|
24
24
|
from .health_manager import HealthManager
|
|
25
|
-
from .session import MqttParams, MqttSession, MqttSessionException, MqttSessionUnauthorized
|
|
25
|
+
from .session import MqttParams, MqttQos, MqttSession, MqttSessionException, MqttSessionUnauthorized
|
|
26
26
|
|
|
27
27
|
_LOGGER = logging.getLogger(__name__)
|
|
28
28
|
_MQTT_LOGGER = logging.getLogger(f"{__name__}.aiomqtt")
|
|
@@ -361,8 +361,14 @@ class RoborockMqttSession(MqttSession):
|
|
|
361
361
|
|
|
362
362
|
return delayed_unsub
|
|
363
363
|
|
|
364
|
-
async def publish(self, topic: str, message: bytes) -> None:
|
|
365
|
-
"""Publish a message on the topic.
|
|
364
|
+
async def publish(self, topic: str, message: bytes, qos: MqttQos = MqttQos.AT_MOST_ONCE) -> None:
|
|
365
|
+
"""Publish a message on the topic.
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
topic: The MQTT topic to publish to.
|
|
369
|
+
message: The message payload.
|
|
370
|
+
qos: The MQTT QoS level. Defaults to AT_MOST_ONCE.
|
|
371
|
+
"""
|
|
366
372
|
_LOGGER.debug("Sending message to topic %s: %s", topic, message)
|
|
367
373
|
client: aiomqtt.Client
|
|
368
374
|
async with self._client_lock:
|
|
@@ -371,7 +377,7 @@ class RoborockMqttSession(MqttSession):
|
|
|
371
377
|
client = self._client
|
|
372
378
|
try:
|
|
373
379
|
with self._diagnostics.timer("publish"):
|
|
374
|
-
await client.publish(topic, message)
|
|
380
|
+
await client.publish(topic, message, qos=qos)
|
|
375
381
|
except MqttError as err:
|
|
376
382
|
raise MqttSessionException(f"Error publishing message: {err}") from err
|
|
377
383
|
|
|
@@ -417,13 +423,13 @@ class LazyMqttSession(MqttSession):
|
|
|
417
423
|
await self._maybe_start()
|
|
418
424
|
return await self._session.subscribe(device_id, callback)
|
|
419
425
|
|
|
420
|
-
async def publish(self, topic: str, message: bytes) -> None:
|
|
426
|
+
async def publish(self, topic: str, message: bytes, qos: MqttQos = MqttQos.AT_MOST_ONCE) -> None:
|
|
421
427
|
"""Publish a message on the specified topic.
|
|
422
428
|
|
|
423
429
|
This will raise an exception if the message could not be sent.
|
|
424
430
|
"""
|
|
425
431
|
await self._maybe_start()
|
|
426
|
-
return await self._session.publish(topic, message)
|
|
432
|
+
return await self._session.publish(topic, message, qos=qos)
|
|
427
433
|
|
|
428
434
|
async def close(self) -> None:
|
|
429
435
|
"""Cancels the mqtt loop.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
4
|
from collections.abc import Callable
|
|
5
5
|
from dataclasses import dataclass, field
|
|
6
|
+
from enum import IntEnum
|
|
6
7
|
|
|
7
8
|
from roborock.diagnostics import Diagnostics
|
|
8
9
|
from roborock.exceptions import RoborockException
|
|
@@ -10,6 +11,24 @@ from roborock.mqtt.health_manager import HealthManager
|
|
|
10
11
|
|
|
11
12
|
DEFAULT_TIMEOUT = 30.0
|
|
12
13
|
|
|
14
|
+
|
|
15
|
+
class MqttQos(IntEnum):
|
|
16
|
+
"""MQTT Quality of Service levels.
|
|
17
|
+
|
|
18
|
+
A01 devices (Zeo, Dyad) require ``AT_LEAST_ONCE`` for DP200 (start)
|
|
19
|
+
commands. Other protocol versions use ``AT_MOST_ONCE``.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
AT_MOST_ONCE = 0
|
|
23
|
+
"""Fire-and-forget. No acknowledgment required."""
|
|
24
|
+
|
|
25
|
+
AT_LEAST_ONCE = 1
|
|
26
|
+
"""Guaranteed delivery with possible duplicates. Broker sends PUBACK."""
|
|
27
|
+
|
|
28
|
+
EXACTLY_ONCE = 2
|
|
29
|
+
"""Guaranteed delivery with no duplicates. Broker sends PUBREC/PUBREL/PUBCOMP."""
|
|
30
|
+
|
|
31
|
+
|
|
13
32
|
SessionUnauthorizedHook = Callable[[], None]
|
|
14
33
|
|
|
15
34
|
|
|
@@ -76,10 +95,15 @@ class MqttSession(ABC):
|
|
|
76
95
|
"""
|
|
77
96
|
|
|
78
97
|
@abstractmethod
|
|
79
|
-
async def publish(self, topic: str, message: bytes) -> None:
|
|
98
|
+
async def publish(self, topic: str, message: bytes, qos: MqttQos = MqttQos.AT_MOST_ONCE) -> None:
|
|
80
99
|
"""Publish a message on the specified topic.
|
|
81
100
|
|
|
82
101
|
This will raise an exception if the message could not be sent.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
topic: The MQTT topic to publish to.
|
|
105
|
+
message: The message payload.
|
|
106
|
+
qos: The MQTT QoS level. Defaults to AT_MOST_ONCE.
|
|
83
107
|
"""
|
|
84
108
|
|
|
85
109
|
@abstractmethod
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
|
+
import time
|
|
5
6
|
from collections.abc import Callable
|
|
6
7
|
from typing import Any
|
|
7
8
|
|
|
@@ -42,7 +43,10 @@ def encode_mqtt_payload(
|
|
|
42
43
|
"""
|
|
43
44
|
if value_encoder is None:
|
|
44
45
|
value_encoder = _no_encode
|
|
45
|
-
dps_data = {
|
|
46
|
+
dps_data = {
|
|
47
|
+
"dps": {key: value_encoder(value) for key, value in data.items()},
|
|
48
|
+
"t": int(time.time()),
|
|
49
|
+
}
|
|
46
50
|
payload = pad(json.dumps(dps_data).encode("utf-8"), AES.block_size)
|
|
47
51
|
return RoborockMessage(
|
|
48
52
|
protocol=RoborockMessageProtocol.RPC_REQUEST,
|
|
@@ -12,6 +12,7 @@ from unittest.mock import AsyncMock, MagicMock
|
|
|
12
12
|
|
|
13
13
|
from roborock.devices.transport.channel import Channel
|
|
14
14
|
from roborock.mqtt.health_manager import HealthManager
|
|
15
|
+
from roborock.mqtt.session import MqttQos
|
|
15
16
|
from roborock.protocols.v1_protocol import LocalProtocolVersion
|
|
16
17
|
from roborock.roborock_message import RoborockMessage
|
|
17
18
|
|
|
@@ -83,6 +84,7 @@ class FakeChannel(Channel):
|
|
|
83
84
|
self.close = MagicMock(side_effect=self._close)
|
|
84
85
|
|
|
85
86
|
self.protocol_version = LocalProtocolVersion.V1
|
|
87
|
+
|
|
86
88
|
self.restart = AsyncMock()
|
|
87
89
|
self.health_manager = HealthManager(self.restart)
|
|
88
90
|
|
|
@@ -102,10 +104,13 @@ class FakeChannel(Channel):
|
|
|
102
104
|
"""Return true if locally connected."""
|
|
103
105
|
return self._is_connected and self._is_local
|
|
104
106
|
|
|
105
|
-
async def _publish(self, message: RoborockMessage) -> None:
|
|
107
|
+
async def _publish(self, message: RoborockMessage, qos: MqttQos = MqttQos.AT_MOST_ONCE) -> None:
|
|
106
108
|
"""Default publish implementation.
|
|
107
109
|
|
|
108
110
|
Records the message in ``published_messages`` and executes ``publish_handler``.
|
|
111
|
+
|
|
112
|
+
The ``qos`` parameter is accepted for compatibility with
|
|
113
|
+
``MqttChannel.publish`` but not simulated by the fake channel.
|
|
109
114
|
"""
|
|
110
115
|
self.published_messages.append(message)
|
|
111
116
|
if self.publish_side_effect:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/b01_q10/b01_q10_code_mappings.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/b01_q10/b01_q10_containers.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/data/b01_q7/b01_q7_code_mappings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/__init__.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/button_light.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/child_lock.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/clean_history.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/command.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/consumable.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/do_not_disturb.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/dust_collection.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q10/network_info.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q7/__init__.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q7/clean_summary.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/b01/q7/map_content.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/clean_summary.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/device_features.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/do_not_disturb.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/dust_collection_mode.py
RENAMED
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/flow_led_status.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/network_info.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/smart_wash_params.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/traits/v1/wash_towel_mode.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.35.0 → python_roborock-5.36.0}/roborock/devices/transport/local_channel.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|