python-roborock 5.7.0__tar.gz → 5.8.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 (103) hide show
  1. {python_roborock-5.7.0 → python_roborock-5.8.0}/PKG-INFO +2 -2
  2. {python_roborock-5.7.0 → python_roborock-5.8.0}/pyproject.toml +2 -2
  3. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/v1/v1_containers.py +1 -1
  4. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/clean_summary.py +10 -1
  5. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/common.py +11 -2
  6. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/rooms.py +16 -2
  7. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/exceptions.py +14 -0
  8. {python_roborock-5.7.0 → python_roborock-5.8.0}/.gitignore +0 -0
  9. {python_roborock-5.7.0 → python_roborock-5.8.0}/LICENSE +0 -0
  10. {python_roborock-5.7.0 → python_roborock-5.8.0}/README.md +0 -0
  11. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/__init__.py +0 -0
  12. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/broadcast_protocol.py +0 -0
  13. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/callbacks.py +0 -0
  14. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/cli.py +0 -0
  15. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/const.py +0 -0
  16. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/__init__.py +0 -0
  17. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/b01_q10/__init__.py +0 -0
  18. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
  19. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
  20. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/b01_q7/__init__.py +0 -0
  21. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
  22. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
  23. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/code_mappings.py +0 -0
  24. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/containers.py +0 -0
  25. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/dyad/__init__.py +0 -0
  26. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/dyad/dyad_code_mappings.py +0 -0
  27. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/dyad/dyad_containers.py +0 -0
  28. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/v1/__init__.py +0 -0
  29. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/v1/v1_clean_modes.py +0 -0
  30. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/v1/v1_code_mappings.py +0 -0
  31. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/zeo/__init__.py +0 -0
  32. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/zeo/zeo_code_mappings.py +0 -0
  33. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/data/zeo/zeo_containers.py +0 -0
  34. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/device_features.py +0 -0
  35. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/README.md +0 -0
  36. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/__init__.py +0 -0
  37. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/cache.py +0 -0
  38. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/device.py +0 -0
  39. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/device_manager.py +0 -0
  40. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/file_cache.py +0 -0
  41. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/rpc/__init__.py +0 -0
  42. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/rpc/a01_channel.py +0 -0
  43. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/rpc/b01_q10_channel.py +0 -0
  44. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/rpc/b01_q7_channel.py +0 -0
  45. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/rpc/v1_channel.py +0 -0
  46. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/__init__.py +0 -0
  47. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/a01/__init__.py +0 -0
  48. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/b01/__init__.py +0 -0
  49. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/b01/q10/__init__.py +0 -0
  50. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/b01/q10/command.py +0 -0
  51. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/b01/q10/common.py +0 -0
  52. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/b01/q10/status.py +0 -0
  53. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/b01/q10/vacuum.py +0 -0
  54. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/b01/q7/__init__.py +0 -0
  55. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/b01/q7/clean_summary.py +0 -0
  56. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/b01/q7/map.py +0 -0
  57. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/b01/q7/map_content.py +0 -0
  58. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/traits_mixin.py +0 -0
  59. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/__init__.py +0 -0
  60. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/child_lock.py +0 -0
  61. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/command.py +0 -0
  62. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/consumeable.py +0 -0
  63. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/device_features.py +0 -0
  64. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
  65. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
  66. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/flow_led_status.py +0 -0
  67. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/home.py +0 -0
  68. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/led_status.py +0 -0
  69. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/map_content.py +0 -0
  70. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/maps.py +0 -0
  71. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/network_info.py +0 -0
  72. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/routines.py +0 -0
  73. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
  74. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/status.py +0 -0
  75. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
  76. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/volume.py +0 -0
  77. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
  78. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/transport/__init__.py +0 -0
  79. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/transport/channel.py +0 -0
  80. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/transport/local_channel.py +0 -0
  81. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/devices/transport/mqtt_channel.py +0 -0
  82. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/diagnostics.py +0 -0
  83. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/map/__init__.py +0 -0
  84. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/map/b01_map_parser.py +0 -0
  85. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/map/map_parser.py +0 -0
  86. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/map/proto/__init__.py +0 -0
  87. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/map/proto/b01_scmap.proto +0 -0
  88. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/map/proto/b01_scmap_pb2.py +0 -0
  89. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/mqtt/__init__.py +0 -0
  90. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/mqtt/health_manager.py +0 -0
  91. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/mqtt/roborock_session.py +0 -0
  92. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/mqtt/session.py +0 -0
  93. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/protocol.py +0 -0
  94. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/protocols/__init__.py +0 -0
  95. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/protocols/a01_protocol.py +0 -0
  96. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/protocols/b01_q10_protocol.py +0 -0
  97. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/protocols/b01_q7_protocol.py +0 -0
  98. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/protocols/v1_protocol.py +0 -0
  99. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/py.typed +0 -0
  100. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/roborock_message.py +0 -0
  101. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/roborock_typing.py +0 -0
  102. {python_roborock-5.7.0 → python_roborock-5.8.0}/roborock/util.py +0 -0
  103. {python_roborock-5.7.0 → python_roborock-5.8.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.7.0
3
+ Version: 5.8.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/
@@ -21,7 +21,7 @@ Requires-Dist: click-shell~=2.1
21
21
  Requires-Dist: click>=8
22
22
  Requires-Dist: construct<3,>=2.10.57
23
23
  Requires-Dist: paho-mqtt<3.0.0,>=1.6.1
24
- Requires-Dist: protobuf<7,>=6.31.1
24
+ Requires-Dist: protobuf<8,>=6.31.1
25
25
  Requires-Dist: pycryptodomex~=3.18; sys_platform == 'darwin'
26
26
  Requires-Dist: pycryptodome~=3.18
27
27
  Requires-Dist: pyrate-limiter<5,>=4.0.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "python-roborock"
3
- version = "5.7.0"
3
+ version = "5.8.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"
@@ -25,7 +25,7 @@ dependencies = [
25
25
  "pycryptodomex~=3.18 ; sys_platform == 'darwin'",
26
26
  "paho-mqtt>=1.6.1,<3.0.0",
27
27
  "construct>=2.10.57,<3",
28
- "protobuf>=6.31.1,<7",
28
+ "protobuf>=6.31.1,<8",
29
29
  "vacuum-map-parser-roborock",
30
30
  "pyrate-limiter>=4.0.0,<5",
31
31
  "aiomqtt>=2.5.0,<3",
@@ -792,7 +792,7 @@ class AppInitStatusLocalInfo(RoborockBase):
792
792
  class AppInitStatus(RoborockBase):
793
793
  local_info: AppInitStatusLocalInfo
794
794
  feature_info: list[int]
795
- new_feature_info: int
795
+ new_feature_info: int = 0
796
796
  new_feature_info_str: str = ""
797
797
  new_feature_info_2: int | None = None
798
798
  carriage_type: int | None = None
@@ -2,6 +2,7 @@ import logging
2
2
 
3
3
  from roborock.data import CleanRecord, CleanSummaryWithDetail, RoborockBase
4
4
  from roborock.devices.traits.v1 import common
5
+ from roborock.exceptions import RoborockParsingException
5
6
  from roborock.roborock_typing import RoborockCommand
6
7
  from roborock.util import unpack_list
7
8
 
@@ -87,4 +88,12 @@ class CleanSummaryTrait(CleanSummaryWithDetail, common.V1TraitMixin):
87
88
  async def get_clean_record(self, record_id: int) -> CleanRecord:
88
89
  """Load a specific clean record by ID."""
89
90
  response = await self.rpc_channel.send_command(RoborockCommand.GET_CLEAN_RECORD, params=[record_id])
90
- return self.clean_record_converter.convert(response)
91
+ try:
92
+ return self.clean_record_converter.convert(response)
93
+ except (TypeError, ValueError) as err:
94
+ raise RoborockParsingException(
95
+ trait_name=type(self).__name__,
96
+ command=RoborockCommand.GET_CLEAN_RECORD,
97
+ payload=response,
98
+ inner_error=err,
99
+ ) from err
@@ -9,6 +9,7 @@ from dataclasses import fields
9
9
  from typing import ClassVar
10
10
 
11
11
  from roborock.data import RoborockBase
12
+ from roborock.exceptions import RoborockParsingException
12
13
  from roborock.protocols.v1_protocol import V1RpcChannel
13
14
  from roborock.roborock_typing import RoborockCommand
14
15
 
@@ -63,7 +64,7 @@ class V1TraitMixin(ABC):
63
64
 
64
65
  def __init__(self) -> None:
65
66
  """Initialize the V1TraitMixin."""
66
- self._rpc_channel = None
67
+ self._rpc_channel: V1RpcChannel | None = None
67
68
 
68
69
  @property
69
70
  def rpc_channel(self) -> V1RpcChannel:
@@ -75,7 +76,15 @@ class V1TraitMixin(ABC):
75
76
  async def refresh(self) -> None:
76
77
  """Refresh the contents of this trait."""
77
78
  response = await self.rpc_channel.send_command(self.command)
78
- new_data = self.converter.convert(response)
79
+ try:
80
+ new_data = self.converter.convert(response)
81
+ except (TypeError, ValueError) as err:
82
+ raise RoborockParsingException(
83
+ trait_name=type(self).__name__,
84
+ command=self.command,
85
+ payload=response,
86
+ inner_error=err,
87
+ ) from err
79
88
  merge_trait_values(self, new_data) # type: ignore[arg-type]
80
89
 
81
90
 
@@ -5,6 +5,7 @@ from dataclasses import dataclass
5
5
 
6
6
  from roborock.data import HomeData, HomeDataRoom, NamedRoomMapping, RoborockBase
7
7
  from roborock.devices.traits.v1 import common
8
+ from roborock.exceptions import RoborockParsingException
8
9
  from roborock.roborock_typing import RoborockCommand
9
10
  from roborock.web_api import UserWebApiClient
10
11
 
@@ -94,7 +95,12 @@ class RoomsTrait(Rooms, common.V1TraitMixin):
94
95
  """Refresh room mappings and backfill unknown room names from the web API."""
95
96
  response = await self.rpc_channel.send_command(self.command)
96
97
  if not isinstance(response, list):
97
- raise ValueError(f"Unexpected RoomsTrait response format: {response!r}")
98
+ raise RoborockParsingException(
99
+ trait_name=type(self).__name__,
100
+ command=self.command,
101
+ payload=response,
102
+ inner_error="Unexpected RoomsTrait response format",
103
+ )
98
104
 
99
105
  segment_map = RoomsConverter.extract_segment_map(response)
100
106
  # Track all iot ids seen before. Refresh the room list when new ids are found.
@@ -105,8 +111,16 @@ class RoomsTrait(Rooms, common.V1TraitMixin):
105
111
  _LOGGER.debug("Updating rooms: %s", list(updated_rooms))
106
112
  self._home_data.rooms = updated_rooms
107
113
  self._discovered_iot_ids.update(new_iot_ids)
114
+ try:
115
+ rooms = self.converter.convert(response)
116
+ except (TypeError, ValueError) as err:
117
+ raise RoborockParsingException(
118
+ trait_name=type(self).__name__,
119
+ command=self.command,
120
+ payload=response,
121
+ inner_error=err,
122
+ ) from err
108
123
 
109
- rooms = self.converter.convert(response)
110
124
  rooms = rooms.with_room_names(self._home_data.rooms_name_map)
111
125
  common.merge_trait_values(self, rooms)
112
126
 
@@ -1,5 +1,8 @@
1
1
  """Roborock exceptions."""
2
2
 
3
+ from enum import Enum
4
+ from typing import Any
5
+
3
6
 
4
7
  class RoborockException(Exception):
5
8
  """Class for Roborock exceptions."""
@@ -91,3 +94,14 @@ class RoborockInvalidStatus(RoborockException):
91
94
 
92
95
  class RoborockUnsupportedFeature(RoborockException):
93
96
  """Class for Roborock unsupported feature exceptions."""
97
+
98
+
99
+ class RoborockParsingException(RoborockException):
100
+ """Class for Roborock exceptions when parsing device responses."""
101
+
102
+ def __init__(self, trait_name: str, command: Enum | str, payload: Any, inner_error: Exception | str) -> None:
103
+ cmd_name = command.name if isinstance(command, Enum) else str(command)
104
+ self.message = (
105
+ f"Failed to parse {cmd_name} response for {trait_name}. Payload: {payload!r} Error: {inner_error!r}"
106
+ )
107
+ super().__init__(self.message)
File without changes