python-roborock 5.15.1__tar.gz → 5.15.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.
- {python_roborock-5.15.1 → python_roborock-5.15.2}/PKG-INFO +1 -1
- {python_roborock-5.15.1 → python_roborock-5.15.2}/pyproject.toml +1 -1
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/web_api.py +43 -3
- {python_roborock-5.15.1 → python_roborock-5.15.2}/.gitignore +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/LICENSE +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/README.md +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/broadcast_protocol.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/callbacks.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/cli.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/const.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/b01_q10/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/b01_q7/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/code_mappings.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/containers.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/dyad/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/dyad/dyad_code_mappings.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/dyad/dyad_containers.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/v1/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/v1/v1_clean_modes.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/v1/v1_code_mappings.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/v1/v1_containers.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/zeo/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/zeo/zeo_code_mappings.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/zeo/zeo_containers.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/device_features.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/README.md +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/cache.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/device.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/device_manager.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/file_cache.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/rpc/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/rpc/a01_channel.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/rpc/b01_q10_channel.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/rpc/b01_q7_channel.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/rpc/v1_channel.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/a01/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q10/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q10/command.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q10/remote.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q10/status.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q10/vacuum.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q7/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q7/clean_summary.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q7/map.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q7/map_content.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/common.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/traits_mixin.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/child_lock.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/clean_summary.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/command.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/common.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/consumeable.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/device_features.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/flow_led_status.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/home.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/led_status.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/map_content.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/maps.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/network_info.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/rooms.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/routines.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/status.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/volume.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/transport/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/transport/channel.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/transport/local_channel.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/transport/mqtt_channel.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/diagnostics.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/exceptions.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/map/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/map/b01_map_parser.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/map/map_parser.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/map/proto/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/map/proto/b01_scmap.proto +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/map/proto/b01_scmap_pb2.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/mqtt/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/mqtt/health_manager.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/mqtt/roborock_session.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/mqtt/session.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/protocol.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/protocols/__init__.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/protocols/a01_protocol.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/protocols/b01_q10_protocol.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/protocols/b01_q7_protocol.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/protocols/v1_protocol.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/py.typed +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/roborock_message.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/roborock_typing.py +0 -0
- {python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/util.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-roborock
|
|
3
|
-
Version: 5.15.
|
|
3
|
+
Version: 5.15.2
|
|
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/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-roborock"
|
|
3
|
-
version = "5.15.
|
|
3
|
+
version = "5.15.2"
|
|
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"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import hashlib
|
|
3
3
|
import hmac
|
|
4
|
+
import json
|
|
4
5
|
import logging
|
|
5
6
|
import math
|
|
6
7
|
import secrets
|
|
@@ -646,6 +647,31 @@ class RoborockApiClient:
|
|
|
646
647
|
else:
|
|
647
648
|
raise RoborockException(f"schedule_response result was an unexpected type: {schedules}")
|
|
648
649
|
|
|
650
|
+
async def create_job(self, user_data: UserData, device_id: str, job: dict) -> dict:
|
|
651
|
+
"""Create a /jobs entry (schedule or one-time room clean) on a B01 device.
|
|
652
|
+
|
|
653
|
+
Body-bearing writes must sign the request body in the Hawk payload slot and send those same
|
|
654
|
+
compact bytes via ``data=``; ``json=`` would re-serialize with spaces and break the MAC.
|
|
655
|
+
"""
|
|
656
|
+
rriot = user_data.rriot
|
|
657
|
+
if rriot is None:
|
|
658
|
+
raise RoborockException("rriot is none")
|
|
659
|
+
if rriot.r.a is None:
|
|
660
|
+
raise RoborockException("Missing field 'a' in rriot reference")
|
|
661
|
+
path = f"/user/devices/{device_id}/jobs"
|
|
662
|
+
job_request = PreparedRequest(
|
|
663
|
+
rriot.r.a,
|
|
664
|
+
self.session,
|
|
665
|
+
{
|
|
666
|
+
"Authorization": _get_hawk_authentication(rriot, path, body=job),
|
|
667
|
+
"Content-Type": "application/json",
|
|
668
|
+
},
|
|
669
|
+
)
|
|
670
|
+
response = await job_request.request("post", path, data=_compact_json(job).encode())
|
|
671
|
+
if not response.get("success"):
|
|
672
|
+
raise RoborockException(response)
|
|
673
|
+
return response
|
|
674
|
+
|
|
649
675
|
async def get_products(self, user_data: UserData) -> ProductResponse:
|
|
650
676
|
"""Gets all products and their schemas, good for determining status codes and model numbers."""
|
|
651
677
|
base_url = await self.base_url
|
|
@@ -738,11 +764,25 @@ def _process_extra_hawk_values(values: dict | None) -> str:
|
|
|
738
764
|
return hashlib.md5("&".join(result).encode()).hexdigest()
|
|
739
765
|
|
|
740
766
|
|
|
741
|
-
def
|
|
767
|
+
def _compact_json(body: dict) -> str:
|
|
768
|
+
"""Serialize a JSON body to the exact compact bytes that are both signed and sent."""
|
|
769
|
+
return json.dumps(body, separators=(",", ":"))
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
def _get_hawk_authentication(
|
|
773
|
+
rriot: RRiot,
|
|
774
|
+
url: str,
|
|
775
|
+
formdata: dict | None = None,
|
|
776
|
+
params: dict | None = None,
|
|
777
|
+
body: dict | None = None,
|
|
778
|
+
) -> str:
|
|
742
779
|
timestamp = math.floor(time.time())
|
|
743
780
|
nonce = secrets.token_urlsafe(6)
|
|
744
|
-
formdata_str = _process_extra_hawk_values(formdata)
|
|
745
781
|
params_str = _process_extra_hawk_values(params)
|
|
782
|
+
if body is not None:
|
|
783
|
+
payload_str = hashlib.md5(_compact_json(body).encode()).hexdigest()
|
|
784
|
+
else:
|
|
785
|
+
payload_str = _process_extra_hawk_values(formdata)
|
|
746
786
|
|
|
747
787
|
prestr = ":".join(
|
|
748
788
|
[
|
|
@@ -752,7 +792,7 @@ def _get_hawk_authentication(rriot: RRiot, url: str, formdata: dict | None = Non
|
|
|
752
792
|
str(timestamp),
|
|
753
793
|
hashlib.md5(url.encode()).hexdigest(),
|
|
754
794
|
params_str,
|
|
755
|
-
|
|
795
|
+
payload_str,
|
|
756
796
|
]
|
|
757
797
|
)
|
|
758
798
|
mac = base64.b64encode(hmac.new(rriot.h.encode(), prestr.encode(), hashlib.sha256).digest()).decode()
|
|
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-5.15.1 → python_roborock-5.15.2}/roborock/data/b01_q10/b01_q10_code_mappings.py
RENAMED
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/data/b01_q10/b01_q10_containers.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/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
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q10/__init__.py
RENAMED
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q10/command.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q7/__init__.py
RENAMED
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q7/clean_summary.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/b01/q7/map_content.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/clean_summary.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/device_features.py
RENAMED
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/do_not_disturb.py
RENAMED
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/dust_collection_mode.py
RENAMED
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/flow_led_status.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/network_info.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/smart_wash_params.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/traits/v1/wash_towel_mode.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/transport/local_channel.py
RENAMED
|
File without changes
|
{python_roborock-5.15.1 → python_roborock-5.15.2}/roborock/devices/transport/mqtt_channel.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
|