botslab360 0.4.1__tar.gz → 0.4.2__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.
Potentially problematic release.
This version of botslab360 might be problematic. Click here for more details.
- {botslab360-0.4.1/src/botslab360.egg-info → botslab360-0.4.2}/PKG-INFO +11 -3
- {botslab360-0.4.1 → botslab360-0.4.2}/README.md +10 -2
- {botslab360-0.4.1 → botslab360-0.4.2}/pyproject.toml +1 -1
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360/__init__.py +2 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360/models.py +10 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360/rooms.py +10 -0
- {botslab360-0.4.1 → botslab360-0.4.2/src/botslab360.egg-info}/PKG-INFO +11 -3
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_rooms.py +50 -3
- {botslab360-0.4.1 → botslab360-0.4.2}/ATTRIBUTION.md +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/LICENSE +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/setup.cfg +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360/auth.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360/client.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360/commands.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360/exceptions.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360/protocol.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360/quc.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360.egg-info/SOURCES.txt +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360.egg-info/dependency_links.txt +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360.egg-info/requires.txt +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/src/botslab360.egg-info/top_level.txt +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_android_360_diagnostic.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_auth.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_commands.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_compare_android_quc.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_credentials_auth_example.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_devices.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_protocol.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_public_robot360_auth_diagnostic.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_public_room_api_diagnostic.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_quc.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_room_diagnostic.py +0 -0
- {botslab360-0.4.1 → botslab360-0.4.2}/tests/test_status.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: botslab360
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: Async Python client for Botslab/360 robot vacuums
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Source, https://github.com/placix/python-botslab360
|
|
@@ -217,12 +217,13 @@ map coordinate system (integer millimetres, original point order). Missing or
|
|
|
217
217
|
malformed polygons are exposed as `None`; raw MapInfo data is not exposed.
|
|
218
218
|
|
|
219
219
|
The Android room-attribute UI defines one or two cleaning passes, four suction
|
|
220
|
-
modes,
|
|
221
|
-
current attributes for selected rooms in one cleaning request:
|
|
220
|
+
modes, three mopping water levels, and three cleaning modes. Optional settings
|
|
221
|
+
can override the current attributes for selected rooms in one cleaning request:
|
|
222
222
|
|
|
223
223
|
```python
|
|
224
224
|
from botslab360 import (
|
|
225
225
|
RoomCleaningSettings,
|
|
226
|
+
RoomCleaningMode,
|
|
226
227
|
RoomFanMode,
|
|
227
228
|
RoomWaterLevel,
|
|
228
229
|
)
|
|
@@ -232,6 +233,7 @@ await client.clean_rooms(
|
|
|
232
233
|
[1],
|
|
233
234
|
room_settings={
|
|
234
235
|
1: RoomCleaningSettings(
|
|
236
|
+
mode=RoomCleaningMode.SWEEP,
|
|
235
237
|
clean_times=2,
|
|
236
238
|
fan_mode=RoomFanMode.STRONG,
|
|
237
239
|
water_pump=RoomWaterLevel.MEDIUM,
|
|
@@ -248,6 +250,12 @@ Water levels are `1` (low), `2` (medium), and `3` (high). An existing vendor
|
|
|
248
250
|
`waterPump=0` value is preserved when not overridden, but `0` is not exposed as
|
|
249
251
|
an "off" choice because that meaning has not been confirmed.
|
|
250
252
|
|
|
253
|
+
Cleaning modes are `1` (sweep and mop), `2` (sweep), and `3` (mop). Mode `2`
|
|
254
|
+
has been verified on a real robot; the assignments for modes `1` and `3` remain
|
|
255
|
+
provisional pending real-device verification. `Room.mode` preserves unknown
|
|
256
|
+
integer values reported by future vendor firmware, while outgoing overrides are
|
|
257
|
+
limited to the currently supported values.
|
|
258
|
+
|
|
251
259
|
## Status information
|
|
252
260
|
|
|
253
261
|
Depending on the robot model, status information may include:
|
|
@@ -197,12 +197,13 @@ map coordinate system (integer millimetres, original point order). Missing or
|
|
|
197
197
|
malformed polygons are exposed as `None`; raw MapInfo data is not exposed.
|
|
198
198
|
|
|
199
199
|
The Android room-attribute UI defines one or two cleaning passes, four suction
|
|
200
|
-
modes,
|
|
201
|
-
current attributes for selected rooms in one cleaning request:
|
|
200
|
+
modes, three mopping water levels, and three cleaning modes. Optional settings
|
|
201
|
+
can override the current attributes for selected rooms in one cleaning request:
|
|
202
202
|
|
|
203
203
|
```python
|
|
204
204
|
from botslab360 import (
|
|
205
205
|
RoomCleaningSettings,
|
|
206
|
+
RoomCleaningMode,
|
|
206
207
|
RoomFanMode,
|
|
207
208
|
RoomWaterLevel,
|
|
208
209
|
)
|
|
@@ -212,6 +213,7 @@ await client.clean_rooms(
|
|
|
212
213
|
[1],
|
|
213
214
|
room_settings={
|
|
214
215
|
1: RoomCleaningSettings(
|
|
216
|
+
mode=RoomCleaningMode.SWEEP,
|
|
215
217
|
clean_times=2,
|
|
216
218
|
fan_mode=RoomFanMode.STRONG,
|
|
217
219
|
water_pump=RoomWaterLevel.MEDIUM,
|
|
@@ -228,6 +230,12 @@ Water levels are `1` (low), `2` (medium), and `3` (high). An existing vendor
|
|
|
228
230
|
`waterPump=0` value is preserved when not overridden, but `0` is not exposed as
|
|
229
231
|
an "off" choice because that meaning has not been confirmed.
|
|
230
232
|
|
|
233
|
+
Cleaning modes are `1` (sweep and mop), `2` (sweep), and `3` (mop). Mode `2`
|
|
234
|
+
has been verified on a real robot; the assignments for modes `1` and `3` remain
|
|
235
|
+
provisional pending real-device verification. `Room.mode` preserves unknown
|
|
236
|
+
integer values reported by future vendor firmware, while outgoing overrides are
|
|
237
|
+
limited to the currently supported values.
|
|
238
|
+
|
|
231
239
|
## Status information
|
|
232
240
|
|
|
233
241
|
Depending on the robot model, status information may include:
|
|
@@ -19,6 +19,7 @@ from .models import (
|
|
|
19
19
|
QihooCredentials,
|
|
20
20
|
RobotStatus,
|
|
21
21
|
Room,
|
|
22
|
+
RoomCleaningMode,
|
|
22
23
|
RoomCleaningSettings,
|
|
23
24
|
RoomFanMode,
|
|
24
25
|
RoomWaterLevel,
|
|
@@ -42,6 +43,7 @@ __all__ = [
|
|
|
42
43
|
"QucAuthenticationError",
|
|
43
44
|
"RobotStatus",
|
|
44
45
|
"Room",
|
|
46
|
+
"RoomCleaningMode",
|
|
45
47
|
"RoomCleaningSettings",
|
|
46
48
|
"RoomFanMode",
|
|
47
49
|
"RoomWaterLevel",
|
|
@@ -111,6 +111,7 @@ class Room:
|
|
|
111
111
|
fan_mode: str | None
|
|
112
112
|
water_pump: int | None
|
|
113
113
|
vertices: tuple[tuple[int, int], ...] | None = None
|
|
114
|
+
mode: int | None = None
|
|
114
115
|
|
|
115
116
|
|
|
116
117
|
class RoomFanMode(str, Enum):
|
|
@@ -130,6 +131,14 @@ class RoomWaterLevel(IntEnum):
|
|
|
130
131
|
HIGH = 3
|
|
131
132
|
|
|
132
133
|
|
|
134
|
+
class RoomCleaningMode(IntEnum):
|
|
135
|
+
"""Cleaning modes supported by the Android room-attribute UI."""
|
|
136
|
+
|
|
137
|
+
SWEEP_AND_MOP = 1
|
|
138
|
+
SWEEP = 2
|
|
139
|
+
MOP = 3
|
|
140
|
+
|
|
141
|
+
|
|
133
142
|
ROOM_CLEAN_TIMES = (1, 2)
|
|
134
143
|
|
|
135
144
|
|
|
@@ -140,6 +149,7 @@ class RoomCleaningSettings:
|
|
|
140
149
|
clean_times: int | None = None
|
|
141
150
|
fan_mode: str | None = None
|
|
142
151
|
water_pump: int | None = None
|
|
152
|
+
mode: int | None = None
|
|
143
153
|
|
|
144
154
|
|
|
145
155
|
@dataclass(frozen=True, slots=True)
|
|
@@ -18,6 +18,7 @@ from .exceptions import ApiError
|
|
|
18
18
|
from .models import (
|
|
19
19
|
ROOM_CLEAN_TIMES,
|
|
20
20
|
Room,
|
|
21
|
+
RoomCleaningMode,
|
|
21
22
|
RoomCleaningSettings,
|
|
22
23
|
RoomFanMode,
|
|
23
24
|
RoomWaterLevel,
|
|
@@ -73,6 +74,7 @@ class RoomMap:
|
|
|
73
74
|
|
|
74
75
|
_ROOM_FAN_MODE_VALUES = frozenset(mode.value for mode in RoomFanMode)
|
|
75
76
|
_ROOM_WATER_LEVEL_VALUES = frozenset(level.value for level in RoomWaterLevel)
|
|
77
|
+
_ROOM_CLEANING_MODE_VALUES = frozenset(mode.value for mode in RoomCleaningMode)
|
|
76
78
|
|
|
77
79
|
|
|
78
80
|
def validate_room_cleaning_settings(settings: object) -> RoomCleaningSettings:
|
|
@@ -99,6 +101,11 @@ def validate_room_cleaning_settings(settings: object) -> RoomCleaningSettings:
|
|
|
99
101
|
raise TypeError("water_pump must be an integer")
|
|
100
102
|
if settings.water_pump not in _ROOM_WATER_LEVEL_VALUES:
|
|
101
103
|
raise ValueError("water_pump must be 1, 2, or 3")
|
|
104
|
+
if settings.mode is not None:
|
|
105
|
+
if isinstance(settings.mode, bool) or not isinstance(settings.mode, int):
|
|
106
|
+
raise TypeError("mode must be an integer")
|
|
107
|
+
if settings.mode not in _ROOM_CLEANING_MODE_VALUES:
|
|
108
|
+
raise ValueError("mode must be 1, 2, or 3")
|
|
102
109
|
return settings
|
|
103
110
|
|
|
104
111
|
|
|
@@ -273,6 +280,7 @@ def parse_room_map(map_info: object) -> RoomMap:
|
|
|
273
280
|
fan_mode=_optional_str(area.get("windMode")),
|
|
274
281
|
water_pump=_optional_int(area.get("waterPump")),
|
|
275
282
|
vertices=_room_vertices(area.get("vertexs")),
|
|
283
|
+
mode=_optional_int(area.get("mode")),
|
|
276
284
|
)
|
|
277
285
|
)
|
|
278
286
|
return RoomMap(
|
|
@@ -299,6 +307,8 @@ def _apply_room_settings(
|
|
|
299
307
|
area["windMode"] = settings.fan_mode
|
|
300
308
|
if settings.water_pump is not None:
|
|
301
309
|
area["waterPump"] = settings.water_pump
|
|
310
|
+
if settings.mode is not None:
|
|
311
|
+
area["mode"] = settings.mode
|
|
302
312
|
|
|
303
313
|
|
|
304
314
|
def prepare_area_setting(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: botslab360
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: Async Python client for Botslab/360 robot vacuums
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Source, https://github.com/placix/python-botslab360
|
|
@@ -217,12 +217,13 @@ map coordinate system (integer millimetres, original point order). Missing or
|
|
|
217
217
|
malformed polygons are exposed as `None`; raw MapInfo data is not exposed.
|
|
218
218
|
|
|
219
219
|
The Android room-attribute UI defines one or two cleaning passes, four suction
|
|
220
|
-
modes,
|
|
221
|
-
current attributes for selected rooms in one cleaning request:
|
|
220
|
+
modes, three mopping water levels, and three cleaning modes. Optional settings
|
|
221
|
+
can override the current attributes for selected rooms in one cleaning request:
|
|
222
222
|
|
|
223
223
|
```python
|
|
224
224
|
from botslab360 import (
|
|
225
225
|
RoomCleaningSettings,
|
|
226
|
+
RoomCleaningMode,
|
|
226
227
|
RoomFanMode,
|
|
227
228
|
RoomWaterLevel,
|
|
228
229
|
)
|
|
@@ -232,6 +233,7 @@ await client.clean_rooms(
|
|
|
232
233
|
[1],
|
|
233
234
|
room_settings={
|
|
234
235
|
1: RoomCleaningSettings(
|
|
236
|
+
mode=RoomCleaningMode.SWEEP,
|
|
235
237
|
clean_times=2,
|
|
236
238
|
fan_mode=RoomFanMode.STRONG,
|
|
237
239
|
water_pump=RoomWaterLevel.MEDIUM,
|
|
@@ -248,6 +250,12 @@ Water levels are `1` (low), `2` (medium), and `3` (high). An existing vendor
|
|
|
248
250
|
`waterPump=0` value is preserved when not overridden, but `0` is not exposed as
|
|
249
251
|
an "off" choice because that meaning has not been confirmed.
|
|
250
252
|
|
|
253
|
+
Cleaning modes are `1` (sweep and mop), `2` (sweep), and `3` (mop). Mode `2`
|
|
254
|
+
has been verified on a real robot; the assignments for modes `1` and `3` remain
|
|
255
|
+
provisional pending real-device verification. `Room.mode` preserves unknown
|
|
256
|
+
integer values reported by future vendor firmware, while outgoing overrides are
|
|
257
|
+
limited to the currently supported values.
|
|
258
|
+
|
|
251
259
|
## Status information
|
|
252
260
|
|
|
253
261
|
Depending on the robot model, status information may include:
|
|
@@ -17,6 +17,7 @@ from botslab360 import (
|
|
|
17
17
|
Device,
|
|
18
18
|
InvalidSessionError,
|
|
19
19
|
Room,
|
|
20
|
+
RoomCleaningMode,
|
|
20
21
|
RoomCleaningSettings,
|
|
21
22
|
RoomFanMode,
|
|
22
23
|
RoomWaterLevel,
|
|
@@ -56,7 +57,7 @@ def smart_area() -> dict:
|
|
|
56
57
|
"forbidType": "none",
|
|
57
58
|
"id": room_id,
|
|
58
59
|
"material": 0,
|
|
59
|
-
"mode":
|
|
60
|
+
"mode": 2,
|
|
60
61
|
"name": encoded_name(f"Room {room_id}"),
|
|
61
62
|
"radius": 0,
|
|
62
63
|
"relativeRoom": -1,
|
|
@@ -143,6 +144,7 @@ def test_map_info_parses_ten_public_rooms() -> None:
|
|
|
143
144
|
clean_times=2,
|
|
144
145
|
fan_mode="max",
|
|
145
146
|
water_pump=2,
|
|
147
|
+
mode=2,
|
|
146
148
|
)
|
|
147
149
|
assert parsed.rooms[9].room_type is None
|
|
148
150
|
assert parsed.map_id == 1
|
|
@@ -213,6 +215,22 @@ def test_room_model_remains_compatible_without_vertices() -> None:
|
|
|
213
215
|
room = Room(1, "Bad", None, 2, "max", 0)
|
|
214
216
|
|
|
215
217
|
assert room.vertices is None
|
|
218
|
+
assert room.mode is None
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
@pytest.mark.parametrize("mode", [1, 2, 3, 99])
|
|
222
|
+
def test_room_mode_parsing_preserves_supported_and_unknown_values(mode: int) -> None:
|
|
223
|
+
payload = map_info()
|
|
224
|
+
payload["smartArea"]["value"][1]["mode"] = mode
|
|
225
|
+
|
|
226
|
+
assert parse_room_map(payload).rooms[1].mode == mode
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def test_room_mode_parsing_ignores_malformed_values() -> None:
|
|
230
|
+
payload = map_info()
|
|
231
|
+
payload["smartArea"]["value"][1]["mode"] = "future-mode"
|
|
232
|
+
|
|
233
|
+
assert parse_room_map(payload).rooms[1].mode is None
|
|
216
234
|
|
|
217
235
|
|
|
218
236
|
def test_public_room_setting_choices_match_android_values() -> None:
|
|
@@ -224,6 +242,19 @@ def test_public_room_setting_choices_match_android_values() -> None:
|
|
|
224
242
|
"max",
|
|
225
243
|
]
|
|
226
244
|
assert [level.value for level in RoomWaterLevel] == [1, 2, 3]
|
|
245
|
+
assert [mode.value for mode in RoomCleaningMode] == [1, 2, 3]
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
@pytest.mark.parametrize("mode", [1, 2, 3])
|
|
249
|
+
def test_prepare_area_setting_accepts_supported_cleaning_modes(mode: int) -> None:
|
|
250
|
+
room_map = parse_room_map(map_info())
|
|
251
|
+
|
|
252
|
+
result = json.loads(
|
|
253
|
+
prepare_area_setting(room_map, [1], {1: RoomCleaningSettings(mode=mode)})
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
assert result["value"][1]["mode"] == mode
|
|
257
|
+
assert result["value"][0] == room_map.area_setting["value"][0]
|
|
227
258
|
|
|
228
259
|
|
|
229
260
|
@pytest.mark.parametrize(
|
|
@@ -232,13 +263,20 @@ def test_public_room_setting_choices_match_android_values() -> None:
|
|
|
232
263
|
(RoomCleaningSettings(clean_times=1), {"cleanTimes": 1}),
|
|
233
264
|
(RoomCleaningSettings(fan_mode="quiet"), {"windMode": "quiet"}),
|
|
234
265
|
(RoomCleaningSettings(water_pump=3), {"waterPump": 3}),
|
|
266
|
+
(RoomCleaningSettings(mode=2), {"mode": 2}),
|
|
235
267
|
(
|
|
236
268
|
RoomCleaningSettings(
|
|
237
269
|
clean_times=1,
|
|
238
270
|
fan_mode=RoomFanMode.AUTO,
|
|
239
271
|
water_pump=RoomWaterLevel.LOW,
|
|
272
|
+
mode=RoomCleaningMode.SWEEP_AND_MOP,
|
|
240
273
|
),
|
|
241
|
-
{
|
|
274
|
+
{
|
|
275
|
+
"cleanTimes": 1,
|
|
276
|
+
"windMode": "auto",
|
|
277
|
+
"waterPump": 1,
|
|
278
|
+
"mode": 1,
|
|
279
|
+
},
|
|
242
280
|
),
|
|
243
281
|
],
|
|
244
282
|
)
|
|
@@ -300,6 +338,10 @@ def test_prepare_area_setting_supports_different_selected_room_settings() -> Non
|
|
|
300
338
|
(RoomCleaningSettings(water_pump=4), ValueError),
|
|
301
339
|
(RoomCleaningSettings(water_pump=True), TypeError),
|
|
302
340
|
(RoomCleaningSettings(water_pump="1"), TypeError), # type: ignore[arg-type]
|
|
341
|
+
(RoomCleaningSettings(mode=0), ValueError),
|
|
342
|
+
(RoomCleaningSettings(mode=4), ValueError),
|
|
343
|
+
(RoomCleaningSettings(mode=True), TypeError),
|
|
344
|
+
(RoomCleaningSettings(mode="2"), TypeError), # type: ignore[arg-type]
|
|
303
345
|
(object(), TypeError),
|
|
304
346
|
],
|
|
305
347
|
)
|
|
@@ -477,13 +519,15 @@ def test_clean_rooms_sends_per_room_overrides_through_public_api(
|
|
|
477
519
|
(RoomCleaningSettings(clean_times=1), {"cleanTimes": 1}),
|
|
478
520
|
(RoomCleaningSettings(fan_mode="quiet"), {"windMode": "quiet"}),
|
|
479
521
|
(RoomCleaningSettings(water_pump=3), {"waterPump": 3}),
|
|
522
|
+
(RoomCleaningSettings(mode=2), {"mode": 2}),
|
|
480
523
|
(
|
|
481
524
|
RoomCleaningSettings(
|
|
482
525
|
clean_times=1,
|
|
483
526
|
fan_mode="strong",
|
|
484
527
|
water_pump=3,
|
|
528
|
+
mode=3,
|
|
485
529
|
),
|
|
486
|
-
{"cleanTimes": 1, "windMode": "strong", "waterPump": 3},
|
|
530
|
+
{"cleanTimes": 1, "windMode": "strong", "waterPump": 3, "mode": 3},
|
|
487
531
|
),
|
|
488
532
|
],
|
|
489
533
|
)
|
|
@@ -603,6 +647,9 @@ def test_clean_rooms_preserves_vendor_water_pump_zero(monkeypatch) -> None:
|
|
|
603
647
|
([1], {1: RoomCleaningSettings(water_pump=0)}, ValueError),
|
|
604
648
|
([1], {1: RoomCleaningSettings(water_pump=4)}, ValueError),
|
|
605
649
|
([1], {1: RoomCleaningSettings(water_pump=True)}, TypeError),
|
|
650
|
+
([1], {1: RoomCleaningSettings(mode=0)}, ValueError),
|
|
651
|
+
([1], {1: RoomCleaningSettings(mode=4)}, ValueError),
|
|
652
|
+
([1], {1: RoomCleaningSettings(mode=True)}, TypeError),
|
|
606
653
|
([1], {1: object()}, TypeError),
|
|
607
654
|
([1], {6: RoomCleaningSettings(clean_times=1)}, ValueError),
|
|
608
655
|
([1], {True: RoomCleaningSettings(clean_times=1)}, TypeError),
|
|
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
|