python-roborock 4.0.2__tar.gz → 4.1.1__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.0.2 → python_roborock-4.1.1}/PKG-INFO +1 -1
- {python_roborock-4.0.2 → python_roborock-4.1.1}/pyproject.toml +1 -1
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/cli.py +32 -31
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/code_mappings.py +5 -4
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/README.md +0 -2
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/device_manager.py +3 -1
- {python_roborock-4.0.2 → python_roborock-4.1.1}/.gitignore +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/LICENSE +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/README.md +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/broadcast_protocol.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/callbacks.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/const.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/b01_q10/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/b01_q7/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/containers.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/dyad/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/dyad/dyad_code_mappings.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/dyad/dyad_containers.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/v1/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/v1/v1_clean_modes.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/v1/v1_code_mappings.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/v1/v1_containers.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/zeo/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/zeo/zeo_code_mappings.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/data/zeo/zeo_containers.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/device_features.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/a01_channel.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/b01_q7_channel.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/cache.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/channel.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/device.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/file_cache.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/local_channel.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/mqtt_channel.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/a01/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/b01/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/b01/q10/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/b01/q7/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/traits_mixin.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/child_lock.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/clean_summary.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/command.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/common.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/consumeable.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/device_features.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/flow_led_status.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/home.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/led_status.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/map_content.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/maps.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/network_info.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/rooms.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/routines.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/status.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/volume.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/v1_channel.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/diagnostics.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/exceptions.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/map/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/map/map_parser.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/mqtt/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/mqtt/health_manager.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/mqtt/roborock_session.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/mqtt/session.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/protocol.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/protocols/__init__.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/protocols/a01_protocol.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/protocols/b01_q10_protocol.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/protocols/b01_q7_protocol.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/protocols/v1_protocol.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/py.typed +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/roborock_message.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/roborock_typing.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/util.py +0 -0
- {python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/web_api.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-roborock
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.1.1
|
|
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.1.1"
|
|
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"
|
|
@@ -41,8 +41,8 @@ from pyshark import FileCapture # type: ignore
|
|
|
41
41
|
from pyshark.capture.live_capture import LiveCapture, UnknownInterfaceException # type: ignore
|
|
42
42
|
from pyshark.packet.packet import Packet # type: ignore
|
|
43
43
|
|
|
44
|
-
from roborock import
|
|
45
|
-
from roborock.data import
|
|
44
|
+
from roborock import RoborockCommand
|
|
45
|
+
from roborock.data import RoborockBase, UserData
|
|
46
46
|
from roborock.device_features import DeviceFeatures
|
|
47
47
|
from roborock.devices.cache import Cache, CacheData
|
|
48
48
|
from roborock.devices.device import RoborockDevice
|
|
@@ -53,7 +53,6 @@ from roborock.devices.traits.v1.consumeable import ConsumableAttribute
|
|
|
53
53
|
from roborock.devices.traits.v1.map_content import MapContentTrait
|
|
54
54
|
from roborock.exceptions import RoborockException, RoborockUnsupportedFeature
|
|
55
55
|
from roborock.protocol import MessageParser
|
|
56
|
-
from roborock.version_1_apis.roborock_mqtt_client_v1 import RoborockMqttClientV1
|
|
57
56
|
from roborock.web_api import RoborockApiClient
|
|
58
57
|
|
|
59
58
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -822,44 +821,46 @@ async def get_device_info(ctx: click.Context):
|
|
|
822
821
|
"""
|
|
823
822
|
click.echo("Discovering devices...")
|
|
824
823
|
context: RoborockContext = ctx.obj
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
all_devices = home_data.get_all_devices()
|
|
830
|
-
if not all_devices:
|
|
824
|
+
device_connection_manager = await context.get_device_manager()
|
|
825
|
+
device_manager = await device_connection_manager.ensure_device_manager()
|
|
826
|
+
devices = await device_manager.get_devices()
|
|
827
|
+
if not devices:
|
|
831
828
|
click.echo("No devices found.")
|
|
832
829
|
return
|
|
833
830
|
|
|
834
|
-
click.echo(f"Found {len(
|
|
831
|
+
click.echo(f"Found {len(devices)} devices. Fetching data...")
|
|
835
832
|
|
|
836
833
|
all_products_data = {}
|
|
837
834
|
|
|
838
|
-
for device in
|
|
835
|
+
for device in devices:
|
|
839
836
|
click.echo(f" - Processing {device.name} ({device.duid})")
|
|
840
|
-
product_info = home_data.product_map[device.product_id]
|
|
841
|
-
device_data = DeviceData(device, product_info.model)
|
|
842
|
-
mqtt_client = RoborockMqttClientV1(connection_cache.user_data, device_data)
|
|
843
837
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
)
|
|
848
|
-
product_nickname = SHORT_MODEL_TO_ENUM.get(product_info.model.split(".")[-1]).name
|
|
849
|
-
current_product_data = {
|
|
850
|
-
"Protocol Version": device.pv,
|
|
851
|
-
"Product Nickname": product_nickname,
|
|
852
|
-
"New Feature Info": init_status_result.get("new_feature_info"),
|
|
853
|
-
"New Feature Info Str": init_status_result.get("new_feature_info_str"),
|
|
854
|
-
"Feature Info": init_status_result.get("feature_info"),
|
|
855
|
-
}
|
|
838
|
+
if device.product.model in all_products_data:
|
|
839
|
+
click.echo(f" - Skipping duplicate model {device.product.model}")
|
|
840
|
+
continue
|
|
856
841
|
|
|
857
|
-
|
|
842
|
+
current_product_data = {
|
|
843
|
+
"Protocol Version": device.device_info.pv,
|
|
844
|
+
"Product Nickname": device.product.product_nickname.name,
|
|
845
|
+
}
|
|
846
|
+
if device.v1_properties is not None:
|
|
847
|
+
try:
|
|
848
|
+
result: list[dict[str, Any]] = await device.v1_properties.command.send(
|
|
849
|
+
RoborockCommand.APP_GET_INIT_STATUS
|
|
850
|
+
)
|
|
851
|
+
except Exception as e:
|
|
852
|
+
click.echo(f" - Error processing device {device.name}: {e}", err=True)
|
|
853
|
+
continue
|
|
854
|
+
init_status_result = result[0] if result else {}
|
|
855
|
+
current_product_data.update(
|
|
856
|
+
{
|
|
857
|
+
"New Feature Info": init_status_result.get("new_feature_info"),
|
|
858
|
+
"New Feature Info Str": init_status_result.get("new_feature_info_str"),
|
|
859
|
+
"Feature Info": init_status_result.get("feature_info"),
|
|
860
|
+
}
|
|
861
|
+
)
|
|
858
862
|
|
|
859
|
-
|
|
860
|
-
click.echo(f" - Error processing device {device.name}: {e}", err=True)
|
|
861
|
-
finally:
|
|
862
|
-
await mqtt_client.async_release()
|
|
863
|
+
all_products_data[device.product.model] = current_product_data
|
|
863
864
|
|
|
864
865
|
if all_products_data:
|
|
865
866
|
click.echo("\n--- Device Information (copy to your YAML file) ---\n")
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import logging
|
|
4
4
|
from collections import namedtuple
|
|
5
5
|
from enum import Enum, IntEnum, StrEnum
|
|
6
|
+
from typing import Self
|
|
6
7
|
|
|
7
8
|
_LOGGER = logging.getLogger(__name__)
|
|
8
9
|
completed_warnings = set()
|
|
@@ -57,7 +58,7 @@ class RoborockModeEnum(StrEnum):
|
|
|
57
58
|
code: int
|
|
58
59
|
"""The integer code associated with the enum member."""
|
|
59
60
|
|
|
60
|
-
def __new__(cls, value: str, code: int) ->
|
|
61
|
+
def __new__(cls, value: str, code: int) -> Self:
|
|
61
62
|
"""Creates a new enum member."""
|
|
62
63
|
member = str.__new__(cls, value)
|
|
63
64
|
member._value_ = value
|
|
@@ -65,7 +66,7 @@ class RoborockModeEnum(StrEnum):
|
|
|
65
66
|
return member
|
|
66
67
|
|
|
67
68
|
@classmethod
|
|
68
|
-
def from_code(cls, code: int) ->
|
|
69
|
+
def from_code(cls, code: int) -> Self:
|
|
69
70
|
for member in cls:
|
|
70
71
|
if member.code == code:
|
|
71
72
|
return member
|
|
@@ -83,7 +84,7 @@ class RoborockModeEnum(StrEnum):
|
|
|
83
84
|
return None
|
|
84
85
|
|
|
85
86
|
@classmethod
|
|
86
|
-
def from_value(cls, value: str) ->
|
|
87
|
+
def from_value(cls, value: str) -> Self:
|
|
87
88
|
"""Find enum member by string value (case-insensitive)."""
|
|
88
89
|
for member in cls:
|
|
89
90
|
if member.value.lower() == value.lower():
|
|
@@ -91,7 +92,7 @@ class RoborockModeEnum(StrEnum):
|
|
|
91
92
|
raise ValueError(f"{value} is not a valid value for {cls.__name__}")
|
|
92
93
|
|
|
93
94
|
@classmethod
|
|
94
|
-
def from_name(cls, name: str) ->
|
|
95
|
+
def from_name(cls, name: str) -> Self:
|
|
95
96
|
"""Find enum member by name (case-insensitive)."""
|
|
96
97
|
for member in cls:
|
|
97
98
|
if member.name.lower() == name.lower():
|
|
@@ -556,8 +556,6 @@ The new design:
|
|
|
556
556
|
- Clear separation of concerns through layers
|
|
557
557
|
- Users work with devices, not raw clients
|
|
558
558
|
|
|
559
|
-
**Note**: Legacy APIs in `version_1_apis/` and `version_a01_apis/` are deprecated and will be removed.
|
|
560
|
-
|
|
561
559
|
|
|
562
560
|
## Implementation Details
|
|
563
561
|
|
|
@@ -186,6 +186,7 @@ async def create_device_manager(
|
|
|
186
186
|
session: aiohttp.ClientSession | None = None,
|
|
187
187
|
ready_callback: DeviceReadyCallback | None = None,
|
|
188
188
|
mqtt_session_unauthorized_hook: SessionUnauthorizedHook | None = None,
|
|
189
|
+
prefer_cache: bool = True,
|
|
189
190
|
) -> DeviceManager:
|
|
190
191
|
"""Convenience function to create and initialize a DeviceManager.
|
|
191
192
|
|
|
@@ -198,6 +199,7 @@ async def create_device_manager(
|
|
|
198
199
|
mqtt_session_unauthorized_hook: Optional hook for MQTT session unauthorized
|
|
199
200
|
events which may indicate rate limiting or revoked credentials. The
|
|
200
201
|
caller may use this to refresh authentication tokens as needed.
|
|
202
|
+
prefer_cache: Whether to prefer cached device data over always fetching it from the API.
|
|
201
203
|
|
|
202
204
|
Returns:
|
|
203
205
|
An initialized DeviceManager with discovered devices.
|
|
@@ -259,5 +261,5 @@ async def create_device_manager(
|
|
|
259
261
|
return dev
|
|
260
262
|
|
|
261
263
|
manager = DeviceManager(web_api, device_creator, mqtt_session=mqtt_session, cache=cache, diagnostics=diagnostics)
|
|
262
|
-
await manager.discover_devices()
|
|
264
|
+
await manager.discover_devices(prefer_cache)
|
|
263
265
|
return manager
|
|
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.0.2 → python_roborock-4.1.1}/roborock/data/b01_q10/b01_q10_code_mappings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.0.2 → python_roborock-4.1.1}/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
|
{python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/device_features.py
RENAMED
|
File without changes
|
{python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/do_not_disturb.py
RENAMED
|
File without changes
|
{python_roborock-4.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/dust_collection_mode.py
RENAMED
|
File without changes
|
{python_roborock-4.0.2 → python_roborock-4.1.1}/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.0.2 → python_roborock-4.1.1}/roborock/devices/traits/v1/smart_wash_params.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.0.2 → python_roborock-4.1.1}/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
|