python-roborock 4.2.2__tar.gz → 4.4.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-4.2.2 → python_roborock-4.4.0}/PKG-INFO +1 -1
- {python_roborock-4.2.2 → python_roborock-4.4.0}/pyproject.toml +1 -1
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/containers.py +7 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/v1/v1_containers.py +35 -7
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/__init__.py +7 -1
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/device_features.py +30 -6
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/web_api.py +10 -6
- {python_roborock-4.2.2 → python_roborock-4.4.0}/.gitignore +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/LICENSE +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/README.md +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/broadcast_protocol.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/callbacks.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/cli.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/const.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/b01_q10/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/b01_q7/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/code_mappings.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/dyad/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/dyad/dyad_code_mappings.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/dyad/dyad_containers.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/v1/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/v1/v1_clean_modes.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/v1/v1_code_mappings.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/zeo/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/zeo/zeo_code_mappings.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/data/zeo/zeo_containers.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/device_features.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/README.md +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/cache.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/device.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/device_manager.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/file_cache.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/rpc/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/rpc/a01_channel.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/rpc/b01_q10_channel.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/rpc/b01_q7_channel.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/rpc/v1_channel.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/a01/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/b01/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/b01/q10/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/b01/q10/command.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/b01/q7/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/traits_mixin.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/child_lock.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/clean_summary.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/command.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/common.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/consumeable.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/flow_led_status.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/home.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/led_status.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/map_content.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/maps.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/network_info.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/rooms.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/routines.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/status.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/volume.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/transport/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/transport/channel.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/transport/local_channel.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/transport/mqtt_channel.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/diagnostics.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/exceptions.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/map/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/map/map_parser.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/mqtt/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/mqtt/health_manager.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/mqtt/roborock_session.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/mqtt/session.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/protocol.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/protocols/__init__.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/protocols/a01_protocol.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/protocols/b01_q10_protocol.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/protocols/b01_q7_protocol.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/protocols/v1_protocol.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/py.typed +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/roborock_message.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/roborock_typing.py +0 -0
- {python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/util.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-roborock
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.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 = "4.
|
|
3
|
+
version = "4.4.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"
|
|
@@ -232,6 +232,13 @@ class HomeDataProduct(RoborockBase):
|
|
|
232
232
|
"""Return a string with key product information for logging purposes."""
|
|
233
233
|
return f"{self.name} (model={self.model}, category={self.category})"
|
|
234
234
|
|
|
235
|
+
@cached_property
|
|
236
|
+
def supported_schema_codes(self) -> set[str]:
|
|
237
|
+
"""Return a set of fields that are supported by the device."""
|
|
238
|
+
if self.schema is None:
|
|
239
|
+
return set()
|
|
240
|
+
return {schema.code for schema in self.schema if schema.code is not None}
|
|
241
|
+
|
|
235
242
|
|
|
236
243
|
@dataclass
|
|
237
244
|
class HomeDataDevice(RoborockBase):
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import datetime
|
|
2
2
|
import logging
|
|
3
|
-
from dataclasses import dataclass
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from enum import StrEnum
|
|
4
5
|
from typing import Any
|
|
5
6
|
|
|
6
7
|
from roborock.const import (
|
|
@@ -91,12 +92,39 @@ from .v1_code_mappings import (
|
|
|
91
92
|
_LOGGER = logging.getLogger(__name__)
|
|
92
93
|
|
|
93
94
|
|
|
95
|
+
class FieldNameBase(StrEnum):
|
|
96
|
+
"""A base enum class that represents a field name in a RoborockBase dataclass."""
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class StatusField(FieldNameBase):
|
|
100
|
+
"""An enum that represents a field in the `Status` class.
|
|
101
|
+
|
|
102
|
+
This is used with `roborock.devices.traits.v1.status.DeviceFeaturesTrait`
|
|
103
|
+
to understand if a feature is supported by the device using `is_field_supported`.
|
|
104
|
+
|
|
105
|
+
The enum values are names of fields in the `Status` class. Each field is
|
|
106
|
+
annotated with `requires_schema_code` metadata to map the field to a schema
|
|
107
|
+
code in the product schema, which may have a different name than the field/attribute name.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
STATE = "state"
|
|
111
|
+
BATTERY = "battery"
|
|
112
|
+
FAN_POWER = "fan_power"
|
|
113
|
+
WATER_BOX_MODE = "water_box_mode"
|
|
114
|
+
CHARGE_STATUS = "charge_status"
|
|
115
|
+
DRY_STATUS = "dry_status"
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _requires_schema_code(requires_schema_code: str, default=None) -> Any:
|
|
119
|
+
return field(metadata={"requires_schema_code": requires_schema_code}, default=default)
|
|
120
|
+
|
|
121
|
+
|
|
94
122
|
@dataclass
|
|
95
123
|
class Status(RoborockBase):
|
|
96
124
|
msg_ver: int | None = None
|
|
97
125
|
msg_seq: int | None = None
|
|
98
|
-
state: RoborockStateCode | None = None
|
|
99
|
-
battery: int | None = None
|
|
126
|
+
state: RoborockStateCode | None = _requires_schema_code("state", default=None)
|
|
127
|
+
battery: int | None = _requires_schema_code("battery", default=None)
|
|
100
128
|
clean_time: int | None = None
|
|
101
129
|
clean_area: int | None = None
|
|
102
130
|
error_code: RoborockErrorCode | None = None
|
|
@@ -109,12 +137,12 @@ class Status(RoborockBase):
|
|
|
109
137
|
back_type: int | None = None
|
|
110
138
|
wash_phase: int | None = None
|
|
111
139
|
wash_ready: int | None = None
|
|
112
|
-
fan_power: RoborockFanPowerCode | None = None
|
|
140
|
+
fan_power: RoborockFanPowerCode | None = _requires_schema_code("fan_power", default=None)
|
|
113
141
|
dnd_enabled: int | None = None
|
|
114
142
|
map_status: int | None = None
|
|
115
143
|
is_locating: int | None = None
|
|
116
144
|
lock_status: int | None = None
|
|
117
|
-
water_box_mode: RoborockMopIntensityCode | None = None
|
|
145
|
+
water_box_mode: RoborockMopIntensityCode | None = _requires_schema_code("water_box_mode", default=None)
|
|
118
146
|
water_box_carriage_status: int | None = None
|
|
119
147
|
mop_forbidden_enable: int | None = None
|
|
120
148
|
camera_status: int | None = None
|
|
@@ -132,13 +160,13 @@ class Status(RoborockBase):
|
|
|
132
160
|
collision_avoid_status: int | None = None
|
|
133
161
|
switch_map_mode: int | None = None
|
|
134
162
|
dock_error_status: RoborockDockErrorCode | None = None
|
|
135
|
-
charge_status: int | None = None
|
|
163
|
+
charge_status: int | None = _requires_schema_code("charge_status", default=None)
|
|
136
164
|
unsave_map_reason: int | None = None
|
|
137
165
|
unsave_map_flag: int | None = None
|
|
138
166
|
wash_status: int | None = None
|
|
139
167
|
distance_off: int | None = None
|
|
140
168
|
in_warmup: int | None = None
|
|
141
|
-
dry_status: int | None = None
|
|
169
|
+
dry_status: int | None = _requires_schema_code("drying_status", default=None)
|
|
142
170
|
rdt: int | None = None
|
|
143
171
|
clean_percent: int | None = None
|
|
144
172
|
rss: int | None = None
|
|
@@ -44,6 +44,12 @@ optional traits:
|
|
|
44
44
|
available features.
|
|
45
45
|
- `requires_dock_type` - If set, this is a function that accepts a `RoborockDockTypeCode`
|
|
46
46
|
and returns a boolean indicating whether the trait is supported for that dock type.
|
|
47
|
+
|
|
48
|
+
Additionally, DeviceFeaturesTrait has a method `is_field_supported` that is used to
|
|
49
|
+
check individual trait field values. This is a more fine grained version to allow
|
|
50
|
+
optional fields in a dataclass, vs the above feature checks that apply to an entire
|
|
51
|
+
trait. The `requires_schema_code` field metadata attribute is a string of the schema
|
|
52
|
+
code in HomeDataProduct Schema that is required for the field to be supported.
|
|
47
53
|
"""
|
|
48
54
|
|
|
49
55
|
import logging
|
|
@@ -189,7 +195,7 @@ class PropertiesApi(Trait):
|
|
|
189
195
|
self.maps = MapsTrait(self.status)
|
|
190
196
|
self.map_content = MapContentTrait(map_parser_config)
|
|
191
197
|
self.home = HomeTrait(self.status, self.maps, self.map_content, self.rooms, self._device_cache)
|
|
192
|
-
self.device_features = DeviceFeaturesTrait(product
|
|
198
|
+
self.device_features = DeviceFeaturesTrait(product, self._device_cache)
|
|
193
199
|
self.network_info = NetworkInfoTrait(device_uid, self._device_cache)
|
|
194
200
|
self.routines = RoutinesTrait(device_uid, web_api)
|
|
195
201
|
|
{python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/device_features.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from dataclasses import fields
|
|
1
|
+
from dataclasses import Field, fields
|
|
2
2
|
|
|
3
|
-
from roborock.data import AppInitStatus,
|
|
3
|
+
from roborock.data import AppInitStatus, HomeDataProduct, RoborockBase
|
|
4
|
+
from roborock.data.v1.v1_containers import FieldNameBase
|
|
4
5
|
from roborock.device_features import DeviceFeatures
|
|
5
6
|
from roborock.devices.cache import DeviceCache
|
|
6
7
|
from roborock.devices.traits.v1 import common
|
|
@@ -8,19 +9,42 @@ from roborock.roborock_typing import RoborockCommand
|
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class DeviceFeaturesTrait(DeviceFeatures, common.V1TraitMixin):
|
|
11
|
-
"""Trait for managing
|
|
12
|
+
"""Trait for managing supported features on Roborock devices."""
|
|
12
13
|
|
|
13
14
|
command = RoborockCommand.APP_GET_INIT_STATUS
|
|
14
15
|
|
|
15
|
-
def __init__(self,
|
|
16
|
-
"""Initialize
|
|
17
|
-
self.
|
|
16
|
+
def __init__(self, product: HomeDataProduct, device_cache: DeviceCache) -> None: # pylint: disable=super-init-not-called
|
|
17
|
+
"""Initialize DeviceFeaturesTrait."""
|
|
18
|
+
self._product = product
|
|
19
|
+
self._nickname = product.product_nickname
|
|
18
20
|
self._device_cache = device_cache
|
|
19
21
|
# All fields of DeviceFeatures are required. Initialize them to False
|
|
20
22
|
# so we have some known state.
|
|
21
23
|
for field in fields(self):
|
|
22
24
|
setattr(self, field.name, False)
|
|
23
25
|
|
|
26
|
+
def is_field_supported(self, cls: type[RoborockBase], field_name: FieldNameBase) -> bool:
|
|
27
|
+
"""Determines if the specified field is supported by this device.
|
|
28
|
+
|
|
29
|
+
We use dataclass attributes on the field to specify the schema code that is required
|
|
30
|
+
for the field to be supported and it is compared against the list of
|
|
31
|
+
supported schema codes for the device returned in the product information.
|
|
32
|
+
"""
|
|
33
|
+
dataclass_field: Field | None = None
|
|
34
|
+
for field in fields(cls):
|
|
35
|
+
if field.name == field_name:
|
|
36
|
+
dataclass_field = field
|
|
37
|
+
break
|
|
38
|
+
if dataclass_field is None:
|
|
39
|
+
raise ValueError(f"Field {field_name} not found in {cls}")
|
|
40
|
+
|
|
41
|
+
requires_schema_code = dataclass_field.metadata.get("requires_schema_code", None)
|
|
42
|
+
if requires_schema_code is None:
|
|
43
|
+
# We assume the field is supported
|
|
44
|
+
return True
|
|
45
|
+
# If the field requires a protocol that is not supported, we return False
|
|
46
|
+
return requires_schema_code in self._product.supported_schema_codes
|
|
47
|
+
|
|
24
48
|
async def refresh(self) -> None:
|
|
25
49
|
"""Refresh the contents of this trait.
|
|
26
50
|
|
|
@@ -62,7 +62,7 @@ class RoborockApiClient:
|
|
|
62
62
|
Rate(40, Duration.DAY),
|
|
63
63
|
]
|
|
64
64
|
|
|
65
|
-
_login_limiter = Limiter(_LOGIN_RATES)
|
|
65
|
+
_login_limiter = Limiter(_LOGIN_RATES, max_delay=1000)
|
|
66
66
|
_home_data_limiter = Limiter(_HOME_DATA_RATES)
|
|
67
67
|
|
|
68
68
|
def __init__(
|
|
@@ -74,11 +74,11 @@ class RoborockApiClient:
|
|
|
74
74
|
self._device_identifier = secrets.token_urlsafe(16)
|
|
75
75
|
self.session = session
|
|
76
76
|
self._iot_login_info: IotLoginInfo | None = None
|
|
77
|
+
self._base_urls = BASE_URLS if base_url is None else [base_url]
|
|
77
78
|
|
|
78
79
|
async def _get_iot_login_info(self) -> IotLoginInfo:
|
|
79
80
|
if self._iot_login_info is None:
|
|
80
|
-
|
|
81
|
-
for iot_url in valid_urls:
|
|
81
|
+
for iot_url in self._base_urls:
|
|
82
82
|
url_request = PreparedRequest(iot_url, self.session)
|
|
83
83
|
response = await url_request.request(
|
|
84
84
|
"post",
|
|
@@ -205,7 +205,7 @@ class RoborockApiClient:
|
|
|
205
205
|
|
|
206
206
|
async def request_code(self) -> None:
|
|
207
207
|
try:
|
|
208
|
-
self._login_limiter.
|
|
208
|
+
await self._login_limiter.try_acquire_async("login")
|
|
209
209
|
except BucketFullException as ex:
|
|
210
210
|
_LOGGER.info(ex.meta_info)
|
|
211
211
|
raise RoborockRateLimit("Reached maximum requests for login. Please try again later.") from ex
|
|
@@ -239,7 +239,7 @@ class RoborockApiClient:
|
|
|
239
239
|
_LOGGER.info("No country code or country found, trying old version of request code.")
|
|
240
240
|
return await self.request_code()
|
|
241
241
|
try:
|
|
242
|
-
self._login_limiter.
|
|
242
|
+
await self._login_limiter.try_acquire_async("login")
|
|
243
243
|
except BucketFullException as ex:
|
|
244
244
|
_LOGGER.info(ex.meta_info)
|
|
245
245
|
raise RoborockRateLimit("Reached maximum requests for login. Please try again later.") from ex
|
|
@@ -269,6 +269,10 @@ class RoborockApiClient:
|
|
|
269
269
|
raise RoborockAccountDoesNotExist("Account does not exist - check your login and try again.")
|
|
270
270
|
elif response_code == 9002:
|
|
271
271
|
raise RoborockTooFrequentCodeRequests("You have attempted to request too many codes. Try again later")
|
|
272
|
+
elif response_code == 3030 and len(self._base_urls) > 1:
|
|
273
|
+
self._base_urls = self._base_urls[1:]
|
|
274
|
+
self._iot_login_info = None
|
|
275
|
+
return await self.request_code_v4()
|
|
272
276
|
else:
|
|
273
277
|
raise RoborockException(f"{code_response.get('msg')} - response code: {code_response.get('code')}")
|
|
274
278
|
|
|
@@ -363,7 +367,7 @@ class RoborockApiClient:
|
|
|
363
367
|
|
|
364
368
|
async def pass_login(self, password: str) -> UserData:
|
|
365
369
|
try:
|
|
366
|
-
self._login_limiter.
|
|
370
|
+
await self._login_limiter.try_acquire_async("login")
|
|
367
371
|
except BucketFullException as ex:
|
|
368
372
|
_LOGGER.info(ex.meta_info)
|
|
369
373
|
raise RoborockRateLimit("Reached maximum requests for login. Please try again later.") from ex
|
|
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-4.2.2 → python_roborock-4.4.0}/roborock/data/b01_q10/b01_q10_code_mappings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.2.2 → python_roborock-4.4.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/do_not_disturb.py
RENAMED
|
File without changes
|
{python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/dust_collection_mode.py
RENAMED
|
File without changes
|
{python_roborock-4.2.2 → python_roborock-4.4.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/smart_wash_params.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.2.2 → python_roborock-4.4.0}/roborock/devices/traits/v1/wash_towel_mode.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
|