python-roborock 3.10.9__tar.gz → 3.11.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.
Files changed (96) hide show
  1. {python_roborock-3.10.9 → python_roborock-3.11.0}/PKG-INFO +1 -1
  2. {python_roborock-3.10.9 → python_roborock-3.11.0}/pyproject.toml +1 -1
  3. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/v1/v1_code_mappings.py +7 -0
  4. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/v1/v1_containers.py +6 -2
  5. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/a01_channel.py +5 -1
  6. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/a01/__init__.py +12 -5
  7. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/protocols/a01_protocol.py +18 -2
  8. {python_roborock-3.10.9 → python_roborock-3.11.0}/.gitignore +0 -0
  9. {python_roborock-3.10.9 → python_roborock-3.11.0}/LICENSE +0 -0
  10. {python_roborock-3.10.9 → python_roborock-3.11.0}/README.md +0 -0
  11. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/__init__.py +0 -0
  12. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/api.py +0 -0
  13. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/broadcast_protocol.py +0 -0
  14. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/callbacks.py +0 -0
  15. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/cli.py +0 -0
  16. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/cloud_api.py +0 -0
  17. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/command_cache.py +0 -0
  18. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/const.py +0 -0
  19. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/__init__.py +0 -0
  20. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/b01_q10/__init__.py +0 -0
  21. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
  22. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
  23. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/b01_q7/__init__.py +0 -0
  24. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
  25. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
  26. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/code_mappings.py +0 -0
  27. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/containers.py +0 -0
  28. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/dyad/__init__.py +0 -0
  29. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/dyad/dyad_code_mappings.py +0 -0
  30. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/dyad/dyad_containers.py +0 -0
  31. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/v1/__init__.py +0 -0
  32. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/v1/v1_clean_modes.py +0 -0
  33. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/zeo/__init__.py +0 -0
  34. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/zeo/zeo_code_mappings.py +0 -0
  35. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/data/zeo/zeo_containers.py +0 -0
  36. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/device_features.py +0 -0
  37. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/README.md +0 -0
  38. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/__init__.py +0 -0
  39. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/b01_channel.py +0 -0
  40. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/cache.py +0 -0
  41. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/channel.py +0 -0
  42. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/device.py +0 -0
  43. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/device_manager.py +0 -0
  44. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/file_cache.py +0 -0
  45. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/local_channel.py +0 -0
  46. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/mqtt_channel.py +0 -0
  47. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/__init__.py +0 -0
  48. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/b01/__init__.py +0 -0
  49. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/traits_mixin.py +0 -0
  50. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/__init__.py +0 -0
  51. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/child_lock.py +0 -0
  52. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/clean_summary.py +0 -0
  53. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/command.py +0 -0
  54. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/common.py +0 -0
  55. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/consumeable.py +0 -0
  56. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/device_features.py +0 -0
  57. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
  58. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
  59. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/flow_led_status.py +0 -0
  60. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/home.py +0 -0
  61. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/led_status.py +0 -0
  62. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/map_content.py +0 -0
  63. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/maps.py +0 -0
  64. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/network_info.py +0 -0
  65. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/rooms.py +0 -0
  66. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/routines.py +0 -0
  67. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
  68. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/status.py +0 -0
  69. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
  70. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/volume.py +0 -0
  71. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
  72. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/devices/v1_channel.py +0 -0
  73. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/exceptions.py +0 -0
  74. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/map/__init__.py +0 -0
  75. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/map/map_parser.py +0 -0
  76. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/mqtt/__init__.py +0 -0
  77. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/mqtt/health_manager.py +0 -0
  78. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/mqtt/roborock_session.py +0 -0
  79. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/mqtt/session.py +0 -0
  80. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/protocol.py +0 -0
  81. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/protocols/__init__.py +0 -0
  82. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/protocols/b01_protocol.py +0 -0
  83. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/protocols/v1_protocol.py +0 -0
  84. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/py.typed +0 -0
  85. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/roborock_future.py +0 -0
  86. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/roborock_message.py +0 -0
  87. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/roborock_typing.py +0 -0
  88. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/util.py +0 -0
  89. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/version_1_apis/__init__.py +0 -0
  90. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/version_1_apis/roborock_client_v1.py +0 -0
  91. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/version_1_apis/roborock_local_client_v1.py +0 -0
  92. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/version_1_apis/roborock_mqtt_client_v1.py +0 -0
  93. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/version_a01_apis/__init__.py +0 -0
  94. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/version_a01_apis/roborock_client_a01.py +0 -0
  95. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/version_a01_apis/roborock_mqtt_client_a01.py +0 -0
  96. {python_roborock-3.10.9 → python_roborock-3.11.0}/roborock/web_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-roborock
3
- Version: 3.10.9
3
+ Version: 3.11.0
4
4
  Summary: A package to control Roborock vacuums.
5
5
  Project-URL: Repository, https://github.com/humbertogontijo/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 = "3.10.9"
3
+ version = "3.11.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"
@@ -123,6 +123,13 @@ class DustBagStatus(RoborockDssCodes):
123
123
  full = 34
124
124
 
125
125
 
126
+ class CleanFluidStatus(RoborockDssCodes):
127
+ """Status of the cleaning fluid container."""
128
+
129
+ empty_not_installed = 1
130
+ okay = 2
131
+
132
+
126
133
  class RoborockErrorCode(RoborockEnum):
127
134
  none = 0
128
135
  lidar_blocked = 1
@@ -39,6 +39,7 @@ from roborock.exceptions import RoborockException
39
39
 
40
40
  from ..containers import RoborockBase, RoborockBaseTimer, _attr_repr
41
41
  from .v1_code_mappings import (
42
+ CleanFluidStatus,
42
43
  ClearWaterBoxStatus,
43
44
  DirtyWaterBoxStatus,
44
45
  DustBagStatus,
@@ -229,9 +230,12 @@ class Status(RoborockBase):
229
230
  return None
230
231
 
231
232
  @property
232
- def clean_fluid_status(self) -> int | None:
233
+ def clean_fluid_status(self) -> CleanFluidStatus | None:
233
234
  if self.dss:
234
- return (self.dss >> 10) & 3
235
+ value = (self.dss >> 10) & 3
236
+ if value == 0:
237
+ return None # Feature not supported by this device
238
+ return CleanFluidStatus(value)
235
239
  return None
236
240
 
237
241
  @property
@@ -2,6 +2,7 @@
2
2
 
3
3
  import asyncio
4
4
  import logging
5
+ from collections.abc import Callable
5
6
  from typing import Any, overload
6
7
 
7
8
  from roborock.exceptions import RoborockException
@@ -29,6 +30,7 @@ _ID_QUERY = int(RoborockDyadDataProtocol.ID_QUERY)
29
30
  async def send_decoded_command(
30
31
  mqtt_channel: MqttChannel,
31
32
  params: dict[RoborockDyadDataProtocol, Any],
33
+ value_encoder: Callable[[Any], Any] | None = None,
32
34
  ) -> dict[RoborockDyadDataProtocol, Any]: ...
33
35
 
34
36
 
@@ -36,16 +38,18 @@ async def send_decoded_command(
36
38
  async def send_decoded_command(
37
39
  mqtt_channel: MqttChannel,
38
40
  params: dict[RoborockZeoProtocol, Any],
41
+ value_encoder: Callable[[Any], Any] | None = None,
39
42
  ) -> dict[RoborockZeoProtocol, Any]: ...
40
43
 
41
44
 
42
45
  async def send_decoded_command(
43
46
  mqtt_channel: MqttChannel,
44
47
  params: dict[RoborockDyadDataProtocol, Any] | dict[RoborockZeoProtocol, Any],
48
+ value_encoder: Callable[[Any], Any] | None = None,
45
49
  ) -> dict[RoborockDyadDataProtocol, Any] | dict[RoborockZeoProtocol, Any]:
46
50
  """Send a command on the MQTT channel and get a decoded response."""
47
51
  _LOGGER.debug("Sending MQTT command: %s", params)
48
- roborock_message = encode_mqtt_payload(params)
52
+ roborock_message = encode_mqtt_payload(params, value_encoder)
49
53
 
50
54
  # For commands that set values: send the command and do not
51
55
  # block waiting for a response. Queries are handled below.
@@ -1,3 +1,4 @@
1
+ import json
1
2
  from collections.abc import Callable
2
3
  from datetime import time
3
4
  from typing import Any
@@ -121,8 +122,11 @@ class DyadApi(Trait):
121
122
 
122
123
  async def query_values(self, protocols: list[RoborockDyadDataProtocol]) -> dict[RoborockDyadDataProtocol, Any]:
123
124
  """Query the device for the values of the given Dyad protocols."""
124
- params = {RoborockDyadDataProtocol.ID_QUERY: str([int(p) for p in protocols])}
125
- response = await send_decoded_command(self._channel, params)
125
+ response = await send_decoded_command(
126
+ self._channel,
127
+ {RoborockDyadDataProtocol.ID_QUERY: protocols},
128
+ value_encoder=json.dumps,
129
+ )
126
130
  return {protocol: convert_dyad_value(protocol, response.get(protocol)) for protocol in protocols}
127
131
 
128
132
  async def set_value(self, protocol: RoborockDyadDataProtocol, value: Any) -> dict[RoborockDyadDataProtocol, Any]:
@@ -142,14 +146,17 @@ class ZeoApi(Trait):
142
146
 
143
147
  async def query_values(self, protocols: list[RoborockZeoProtocol]) -> dict[RoborockZeoProtocol, Any]:
144
148
  """Query the device for the values of the given protocols."""
145
- params = {RoborockZeoProtocol.ID_QUERY: str([int(p) for p in protocols])}
146
- response = await send_decoded_command(self._channel, params)
149
+ response = await send_decoded_command(
150
+ self._channel,
151
+ {RoborockZeoProtocol.ID_QUERY: protocols},
152
+ value_encoder=json.dumps,
153
+ )
147
154
  return {protocol: convert_zeo_value(protocol, response.get(protocol)) for protocol in protocols}
148
155
 
149
156
  async def set_value(self, protocol: RoborockZeoProtocol, value: Any) -> dict[RoborockZeoProtocol, Any]:
150
157
  """Set a value for a specific protocol on the device."""
151
158
  params = {protocol: value}
152
- return await send_decoded_command(self._channel, params)
159
+ return await send_decoded_command(self._channel, params, value_encoder=lambda x: x)
153
160
 
154
161
 
155
162
  def create(product: HomeDataProduct, mqtt_channel: MqttChannel) -> DyadApi | ZeoApi:
@@ -2,6 +2,7 @@
2
2
 
3
3
  import json
4
4
  import logging
5
+ from collections.abc import Callable
5
6
  from typing import Any
6
7
 
7
8
  from Crypto.Cipher import AES
@@ -20,13 +21,28 @@ _LOGGER = logging.getLogger(__name__)
20
21
  A01_VERSION = b"A01"
21
22
 
22
23
 
24
+ def _no_encode(value: Any) -> Any:
25
+ return value
26
+
27
+
23
28
  def encode_mqtt_payload(
24
29
  data: dict[RoborockDyadDataProtocol, Any]
25
30
  | dict[RoborockZeoProtocol, Any]
26
31
  | dict[RoborockDyadDataProtocol | RoborockZeoProtocol, Any],
32
+ value_encoder: Callable[[Any], Any] | None = None,
27
33
  ) -> RoborockMessage:
28
- """Encode payload for A01 commands over MQTT."""
29
- dps_data = {"dps": data}
34
+ """Encode payload for A01 commands over MQTT.
35
+
36
+ Args:
37
+ data: The data to encode.
38
+ value_encoder: A function to encode the values of the dictionary.
39
+
40
+ Returns:
41
+ RoborockMessage: The encoded message.
42
+ """
43
+ if value_encoder is None:
44
+ value_encoder = _no_encode
45
+ dps_data = {"dps": {key: value_encoder(value) for key, value in data.items()}}
30
46
  payload = pad(json.dumps(dps_data).encode("utf-8"), AES.block_size)
31
47
  return RoborockMessage(
32
48
  protocol=RoborockMessageProtocol.RPC_REQUEST,