python-roborock 3.10.7__tar.gz → 3.10.9__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 (97) hide show
  1. {python_roborock-3.10.7 → python_roborock-3.10.9}/PKG-INFO +1 -1
  2. {python_roborock-3.10.7 → python_roborock-3.10.9}/pyproject.toml +1 -1
  3. python_roborock-3.10.9/roborock/devices/traits/a01/__init__.py +163 -0
  4. python_roborock-3.10.7/roborock/devices/traits/a01/__init__.py +0 -61
  5. {python_roborock-3.10.7 → python_roborock-3.10.9}/.gitignore +0 -0
  6. {python_roborock-3.10.7 → python_roborock-3.10.9}/LICENSE +0 -0
  7. {python_roborock-3.10.7 → python_roborock-3.10.9}/README.md +0 -0
  8. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/__init__.py +0 -0
  9. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/api.py +0 -0
  10. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/broadcast_protocol.py +0 -0
  11. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/callbacks.py +0 -0
  12. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/cli.py +0 -0
  13. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/cloud_api.py +0 -0
  14. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/command_cache.py +0 -0
  15. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/const.py +0 -0
  16. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/__init__.py +0 -0
  17. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/b01_q10/__init__.py +0 -0
  18. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
  19. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
  20. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/b01_q7/__init__.py +0 -0
  21. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
  22. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
  23. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/code_mappings.py +0 -0
  24. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/containers.py +0 -0
  25. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/dyad/__init__.py +0 -0
  26. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/dyad/dyad_code_mappings.py +0 -0
  27. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/dyad/dyad_containers.py +0 -0
  28. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/v1/__init__.py +0 -0
  29. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/v1/v1_clean_modes.py +0 -0
  30. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/v1/v1_code_mappings.py +0 -0
  31. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/v1/v1_containers.py +0 -0
  32. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/zeo/__init__.py +0 -0
  33. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/zeo/zeo_code_mappings.py +0 -0
  34. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/data/zeo/zeo_containers.py +0 -0
  35. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/device_features.py +0 -0
  36. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/README.md +0 -0
  37. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/__init__.py +0 -0
  38. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/a01_channel.py +0 -0
  39. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/b01_channel.py +0 -0
  40. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/cache.py +0 -0
  41. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/channel.py +0 -0
  42. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/device.py +0 -0
  43. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/device_manager.py +0 -0
  44. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/file_cache.py +0 -0
  45. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/local_channel.py +0 -0
  46. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/mqtt_channel.py +0 -0
  47. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/__init__.py +0 -0
  48. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/b01/__init__.py +0 -0
  49. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/traits_mixin.py +0 -0
  50. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/__init__.py +0 -0
  51. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/child_lock.py +0 -0
  52. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/clean_summary.py +0 -0
  53. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/command.py +0 -0
  54. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/common.py +0 -0
  55. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/consumeable.py +0 -0
  56. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/device_features.py +0 -0
  57. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
  58. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
  59. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/flow_led_status.py +0 -0
  60. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/home.py +0 -0
  61. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/led_status.py +0 -0
  62. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/map_content.py +0 -0
  63. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/maps.py +0 -0
  64. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/network_info.py +0 -0
  65. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/rooms.py +0 -0
  66. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/routines.py +0 -0
  67. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
  68. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/status.py +0 -0
  69. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
  70. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/volume.py +0 -0
  71. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
  72. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/devices/v1_channel.py +0 -0
  73. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/exceptions.py +0 -0
  74. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/map/__init__.py +0 -0
  75. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/map/map_parser.py +0 -0
  76. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/mqtt/__init__.py +0 -0
  77. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/mqtt/health_manager.py +0 -0
  78. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/mqtt/roborock_session.py +0 -0
  79. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/mqtt/session.py +0 -0
  80. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/protocol.py +0 -0
  81. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/protocols/__init__.py +0 -0
  82. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/protocols/a01_protocol.py +0 -0
  83. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/protocols/b01_protocol.py +0 -0
  84. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/protocols/v1_protocol.py +0 -0
  85. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/py.typed +0 -0
  86. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/roborock_future.py +0 -0
  87. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/roborock_message.py +0 -0
  88. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/roborock_typing.py +0 -0
  89. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/util.py +0 -0
  90. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/version_1_apis/__init__.py +0 -0
  91. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/version_1_apis/roborock_client_v1.py +0 -0
  92. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/version_1_apis/roborock_local_client_v1.py +0 -0
  93. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/version_1_apis/roborock_mqtt_client_v1.py +0 -0
  94. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/version_a01_apis/__init__.py +0 -0
  95. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/version_a01_apis/roborock_client_a01.py +0 -0
  96. {python_roborock-3.10.7 → python_roborock-3.10.9}/roborock/version_a01_apis/roborock_mqtt_client_a01.py +0 -0
  97. {python_roborock-3.10.7 → python_roborock-3.10.9}/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.7
3
+ Version: 3.10.9
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.7"
3
+ version = "3.10.9"
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"
@@ -0,0 +1,163 @@
1
+ from collections.abc import Callable
2
+ from datetime import time
3
+ from typing import Any
4
+
5
+ from roborock.data import DyadProductInfo, DyadSndState, HomeDataProduct, RoborockCategory
6
+ from roborock.data.dyad.dyad_code_mappings import (
7
+ DyadBrushSpeed,
8
+ DyadCleanMode,
9
+ DyadError,
10
+ DyadSelfCleanLevel,
11
+ DyadSelfCleanMode,
12
+ DyadSuction,
13
+ DyadWarmLevel,
14
+ DyadWaterLevel,
15
+ RoborockDyadStateCode,
16
+ )
17
+ from roborock.data.zeo.zeo_code_mappings import (
18
+ ZeoDetergentType,
19
+ ZeoDryingMode,
20
+ ZeoError,
21
+ ZeoMode,
22
+ ZeoProgram,
23
+ ZeoRinse,
24
+ ZeoSoftenerType,
25
+ ZeoSpin,
26
+ ZeoState,
27
+ ZeoTemperature,
28
+ )
29
+ from roborock.devices.a01_channel import send_decoded_command
30
+ from roborock.devices.mqtt_channel import MqttChannel
31
+ from roborock.devices.traits import Trait
32
+ from roborock.roborock_message import RoborockDyadDataProtocol, RoborockZeoProtocol
33
+
34
+ __init__ = [
35
+ "DyadApi",
36
+ "ZeoApi",
37
+ ]
38
+
39
+
40
+ DYAD_PROTOCOL_ENTRIES: dict[RoborockDyadDataProtocol, Callable] = {
41
+ RoborockDyadDataProtocol.STATUS: lambda val: RoborockDyadStateCode(val).name,
42
+ RoborockDyadDataProtocol.SELF_CLEAN_MODE: lambda val: DyadSelfCleanMode(val).name,
43
+ RoborockDyadDataProtocol.SELF_CLEAN_LEVEL: lambda val: DyadSelfCleanLevel(val).name,
44
+ RoborockDyadDataProtocol.WARM_LEVEL: lambda val: DyadWarmLevel(val).name,
45
+ RoborockDyadDataProtocol.CLEAN_MODE: lambda val: DyadCleanMode(val).name,
46
+ RoborockDyadDataProtocol.SUCTION: lambda val: DyadSuction(val).name,
47
+ RoborockDyadDataProtocol.WATER_LEVEL: lambda val: DyadWaterLevel(val).name,
48
+ RoborockDyadDataProtocol.BRUSH_SPEED: lambda val: DyadBrushSpeed(val).name,
49
+ RoborockDyadDataProtocol.POWER: lambda val: int(val),
50
+ RoborockDyadDataProtocol.AUTO_DRY: lambda val: bool(val),
51
+ RoborockDyadDataProtocol.MESH_LEFT: lambda val: int(360000 - val * 60),
52
+ RoborockDyadDataProtocol.BRUSH_LEFT: lambda val: int(360000 - val * 60),
53
+ RoborockDyadDataProtocol.ERROR: lambda val: DyadError(val).name,
54
+ RoborockDyadDataProtocol.VOLUME_SET: lambda val: int(val),
55
+ RoborockDyadDataProtocol.STAND_LOCK_AUTO_RUN: lambda val: bool(val),
56
+ RoborockDyadDataProtocol.AUTO_DRY_MODE: lambda val: bool(val),
57
+ RoborockDyadDataProtocol.SILENT_DRY_DURATION: lambda val: int(val), # in minutes
58
+ RoborockDyadDataProtocol.SILENT_MODE: lambda val: bool(val),
59
+ RoborockDyadDataProtocol.SILENT_MODE_START_TIME: lambda val: time(
60
+ hour=int(val / 60), minute=val % 60
61
+ ), # in minutes since 00:00
62
+ RoborockDyadDataProtocol.SILENT_MODE_END_TIME: lambda val: time(
63
+ hour=int(val / 60), minute=val % 60
64
+ ), # in minutes since 00:00
65
+ RoborockDyadDataProtocol.RECENT_RUN_TIME: lambda val: [
66
+ int(v) for v in val.split(",")
67
+ ], # minutes of cleaning in past few days.
68
+ RoborockDyadDataProtocol.TOTAL_RUN_TIME: lambda val: int(val),
69
+ RoborockDyadDataProtocol.SND_STATE: lambda val: DyadSndState.from_dict(val),
70
+ RoborockDyadDataProtocol.PRODUCT_INFO: lambda val: DyadProductInfo.from_dict(val),
71
+ }
72
+
73
+ ZEO_PROTOCOL_ENTRIES: dict[RoborockZeoProtocol, Callable] = {
74
+ # read-only
75
+ RoborockZeoProtocol.STATE: lambda val: ZeoState(val).name,
76
+ RoborockZeoProtocol.COUNTDOWN: lambda val: int(val),
77
+ RoborockZeoProtocol.WASHING_LEFT: lambda val: int(val),
78
+ RoborockZeoProtocol.ERROR: lambda val: ZeoError(val).name,
79
+ RoborockZeoProtocol.TIMES_AFTER_CLEAN: lambda val: int(val),
80
+ RoborockZeoProtocol.DETERGENT_EMPTY: lambda val: bool(val),
81
+ RoborockZeoProtocol.SOFTENER_EMPTY: lambda val: bool(val),
82
+ # read-write
83
+ RoborockZeoProtocol.MODE: lambda val: ZeoMode(val).name,
84
+ RoborockZeoProtocol.PROGRAM: lambda val: ZeoProgram(val).name,
85
+ RoborockZeoProtocol.TEMP: lambda val: ZeoTemperature(val).name,
86
+ RoborockZeoProtocol.RINSE_TIMES: lambda val: ZeoRinse(val).name,
87
+ RoborockZeoProtocol.SPIN_LEVEL: lambda val: ZeoSpin(val).name,
88
+ RoborockZeoProtocol.DRYING_MODE: lambda val: ZeoDryingMode(val).name,
89
+ RoborockZeoProtocol.DETERGENT_TYPE: lambda val: ZeoDetergentType(val).name,
90
+ RoborockZeoProtocol.SOFTENER_TYPE: lambda val: ZeoSoftenerType(val).name,
91
+ RoborockZeoProtocol.SOUND_SET: lambda val: bool(val),
92
+ }
93
+
94
+
95
+ def convert_dyad_value(protocol_value: RoborockDyadDataProtocol, value: Any) -> Any:
96
+ """Convert a dyad protocol value to its corresponding type."""
97
+ if (converter := DYAD_PROTOCOL_ENTRIES.get(protocol_value)) is not None:
98
+ try:
99
+ return converter(value)
100
+ except (ValueError, TypeError):
101
+ return None
102
+ return None
103
+
104
+
105
+ def convert_zeo_value(protocol_value: RoborockZeoProtocol, value: Any) -> Any:
106
+ """Convert a zeo protocol value to its corresponding type."""
107
+ if (converter := ZEO_PROTOCOL_ENTRIES.get(protocol_value)) is not None:
108
+ try:
109
+ return converter(value)
110
+ except (ValueError, TypeError):
111
+ return None
112
+ return None
113
+
114
+
115
+ class DyadApi(Trait):
116
+ """API for interacting with Dyad devices."""
117
+
118
+ def __init__(self, channel: MqttChannel) -> None:
119
+ """Initialize the Dyad API."""
120
+ self._channel = channel
121
+
122
+ async def query_values(self, protocols: list[RoborockDyadDataProtocol]) -> dict[RoborockDyadDataProtocol, Any]:
123
+ """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)
126
+ return {protocol: convert_dyad_value(protocol, response.get(protocol)) for protocol in protocols}
127
+
128
+ async def set_value(self, protocol: RoborockDyadDataProtocol, value: Any) -> dict[RoborockDyadDataProtocol, Any]:
129
+ """Set a value for a specific protocol on the device."""
130
+ params = {protocol: value}
131
+ return await send_decoded_command(self._channel, params)
132
+
133
+
134
+ class ZeoApi(Trait):
135
+ """API for interacting with Zeo devices."""
136
+
137
+ name = "zeo"
138
+
139
+ def __init__(self, channel: MqttChannel) -> None:
140
+ """Initialize the Zeo API."""
141
+ self._channel = channel
142
+
143
+ async def query_values(self, protocols: list[RoborockZeoProtocol]) -> dict[RoborockZeoProtocol, Any]:
144
+ """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)
147
+ return {protocol: convert_zeo_value(protocol, response.get(protocol)) for protocol in protocols}
148
+
149
+ async def set_value(self, protocol: RoborockZeoProtocol, value: Any) -> dict[RoborockZeoProtocol, Any]:
150
+ """Set a value for a specific protocol on the device."""
151
+ params = {protocol: value}
152
+ return await send_decoded_command(self._channel, params)
153
+
154
+
155
+ def create(product: HomeDataProduct, mqtt_channel: MqttChannel) -> DyadApi | ZeoApi:
156
+ """Create traits for A01 devices."""
157
+ match product.category:
158
+ case RoborockCategory.WET_DRY_VAC:
159
+ return DyadApi(mqtt_channel)
160
+ case RoborockCategory.WASHING_MACHINE:
161
+ return ZeoApi(mqtt_channel)
162
+ case _:
163
+ raise NotImplementedError(f"Unsupported category {product.category}")
@@ -1,61 +0,0 @@
1
- from typing import Any
2
-
3
- from roborock.data import HomeDataProduct, RoborockCategory
4
- from roborock.devices.a01_channel import send_decoded_command
5
- from roborock.devices.mqtt_channel import MqttChannel
6
- from roborock.devices.traits import Trait
7
- from roborock.roborock_message import RoborockDyadDataProtocol, RoborockZeoProtocol
8
-
9
- __init__ = [
10
- "DyadApi",
11
- "ZeoApi",
12
- ]
13
-
14
-
15
- class DyadApi(Trait):
16
- """API for interacting with Dyad devices."""
17
-
18
- def __init__(self, channel: MqttChannel) -> None:
19
- """Initialize the Dyad API."""
20
- self._channel = channel
21
-
22
- async def query_values(self, protocols: list[RoborockDyadDataProtocol]) -> dict[RoborockDyadDataProtocol, Any]:
23
- """Query the device for the values of the given Dyad protocols."""
24
- params = {RoborockDyadDataProtocol.ID_QUERY: [int(p) for p in protocols]}
25
- return await send_decoded_command(self._channel, params)
26
-
27
- async def set_value(self, protocol: RoborockDyadDataProtocol, value: Any) -> dict[RoborockDyadDataProtocol, Any]:
28
- """Set a value for a specific protocol on the device."""
29
- params = {protocol: value}
30
- return await send_decoded_command(self._channel, params)
31
-
32
-
33
- class ZeoApi(Trait):
34
- """API for interacting with Zeo devices."""
35
-
36
- name = "zeo"
37
-
38
- def __init__(self, channel: MqttChannel) -> None:
39
- """Initialize the Zeo API."""
40
- self._channel = channel
41
-
42
- async def query_values(self, protocols: list[RoborockZeoProtocol]) -> dict[RoborockZeoProtocol, Any]:
43
- """Query the device for the values of the given protocols."""
44
- params = {RoborockZeoProtocol.ID_QUERY: [int(p) for p in protocols]}
45
- return await send_decoded_command(self._channel, params)
46
-
47
- async def set_value(self, protocol: RoborockZeoProtocol, value: Any) -> dict[RoborockZeoProtocol, Any]:
48
- """Set a value for a specific protocol on the device."""
49
- params = {protocol: value}
50
- return await send_decoded_command(self._channel, params)
51
-
52
-
53
- def create(product: HomeDataProduct, mqtt_channel: MqttChannel) -> DyadApi | ZeoApi:
54
- """Create traits for A01 devices."""
55
- match product.category:
56
- case RoborockCategory.WET_DRY_VAC:
57
- return DyadApi(mqtt_channel)
58
- case RoborockCategory.WASHING_MACHINE:
59
- return ZeoApi(mqtt_channel)
60
- case _:
61
- raise NotImplementedError(f"Unsupported category {product.category}")