pymammotion 0.0.40__tar.gz → 0.0.41__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 pymammotion might be problematic. Click here for more details.
- {pymammotion-0.0.40 → pymammotion-0.0.41}/PKG-INFO +10 -4
- {pymammotion-0.0.40 → pymammotion-0.0.41}/README.md +7 -1
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/__init__.py +4 -2
- pymammotion-0.0.41/pymammotion/aliyun/__init__.py +1 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/aliyun/cloud_gateway.py +74 -95
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/aliyun/tmp_constant.py +2 -6
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/bluetooth/ble.py +4 -12
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/bluetooth/ble_message.py +12 -36
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/bluetooth/data/convert.py +1 -3
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/bluetooth/data/notifydata.py +0 -1
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/model/device.py +62 -3
- pymammotion-0.0.41/pymammotion/data/model/hash_list.py +37 -0
- pymammotion-0.0.41/pymammotion/data/model/location.py +40 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/model/rapid_state.py +1 -5
- pymammotion-0.0.41/pymammotion/data/state_manager.py +84 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/event/event.py +18 -3
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/http/http.py +2 -6
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/mammotion_command.py +1 -3
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/messages/driver.py +7 -21
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/messages/media.py +4 -9
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/messages/navigation.py +42 -107
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/messages/network.py +10 -30
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/messages/system.py +11 -26
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/messages/video.py +1 -3
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/control/joystick.py +9 -33
- pymammotion-0.0.41/pymammotion/mammotion/devices/__init__.py +5 -0
- pymammotion-0.0.40/pymammotion/mammotion/devices/luba.py → pymammotion-0.0.41/pymammotion/mammotion/devices/mammotion.py +299 -110
- pymammotion-0.0.41/pymammotion/mqtt/__init__.py +5 -0
- pymammotion-0.0.40/pymammotion/mqtt/mqtt.py → pymammotion-0.0.41/pymammotion/mqtt/mammotion_mqtt.py +46 -50
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/utility/constant/device_constant.py +14 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/utility/datatype_converter.py +52 -9
- pymammotion-0.0.41/pymammotion/utility/device_type.py +261 -0
- pymammotion-0.0.41/pymammotion/utility/periodic.py +106 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/utility/rocker_util.py +63 -4
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pyproject.toml +6 -4
- pymammotion-0.0.40/pymammotion/data/model/hash_list.py +0 -17
- pymammotion-0.0.40/pymammotion/luba/_init_.py +0 -0
- pymammotion-0.0.40/pymammotion/luba/base.py +0 -52
- pymammotion-0.0.40/pymammotion/mammotion/devices/__init__.py +0 -1
- pymammotion-0.0.40/pymammotion/utility/device_type.py +0 -152
- pymammotion-0.0.40/pymammotion/utility/periodic.py +0 -41
- {pymammotion-0.0.40 → pymammotion-0.0.41}/LICENSE +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/aliyun/cloud_service.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/aliyun/dataclass/aep_response.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/aliyun/dataclass/connect_response.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/aliyun/dataclass/dev_by_account_response.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/aliyun/dataclass/login_by_oauth_response.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/aliyun/dataclass/regions_response.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/aliyun/dataclass/session_by_authcode_response.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/bluetooth/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/bluetooth/const.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/bluetooth/data/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/bluetooth/data/framectrldata.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/const.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/model/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/model/enums.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/model/excute_boarder_params.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/model/execute_boarder.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/model/generate_route_information.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/model/mowing_modes.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/model/plan.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/model/region_data.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/mqtt/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/mqtt/event.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/mqtt/properties.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/data/mqtt/status.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/event/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/http/_init_.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/abstract_message.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/messages/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/commands/messages/ota.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/mammotion/control/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/__init__.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/common.proto +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/common.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/common_pb2.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/common_pb2.pyi +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/dev_net.proto +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/dev_net.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/dev_net_pb2.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/dev_net_pb2.pyi +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/luba_msg.proto +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/luba_msg.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/luba_msg_pb2.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/luba_msg_pb2.pyi +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/luba_mul.proto +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/luba_mul.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/luba_mul_pb2.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/luba_mul_pb2.pyi +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_driver.proto +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_driver.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_driver_pb2.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_driver_pb2.pyi +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_nav.proto +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_nav.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_nav_pb2.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_nav_pb2.pyi +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_ota.proto +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_ota.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_ota_pb2.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_ota_pb2.pyi +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_pept.proto +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_pept.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_pept_pb2.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_pept_pb2.pyi +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_sys.proto +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_sys.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_sys_pb2.py +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/proto/mctrl_sys_pb2.pyi +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/py.typed +0 -0
- {pymammotion-0.0.40 → pymammotion-0.0.41}/pymammotion/utility/constant/__init__.py +0 -0
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pymammotion
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.41
|
|
4
4
|
Summary:
|
|
5
5
|
License: GNU-3.0
|
|
6
6
|
Author: Michael Arthur
|
|
7
7
|
Author-email: michael@jumblesoft.co.nz
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.12.0,<3.13.0
|
|
9
9
|
Classifier: License :: Other/Proprietary License
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
12
|
Requires-Dist: aiohttp (>=3.9.1,<4.0.0)
|
|
14
13
|
Requires-Dist: alibabacloud-apigateway-util (>=0.0.2,<0.0.3)
|
|
@@ -27,6 +26,7 @@ Requires-Dist: paho-mqtt (>=1.6.1,<2.0.0)
|
|
|
27
26
|
Requires-Dist: protobuf (>=4.23.1)
|
|
28
27
|
Requires-Dist: py-jsonic (>=0.0.2,<0.0.3)
|
|
29
28
|
Requires-Dist: pyjoystick (>=1.2.4,<2.0.0)
|
|
29
|
+
Requires-Dist: pyproj (>=3.6.1,<4.0.0)
|
|
30
30
|
Description-Content-Type: text/markdown
|
|
31
31
|
|
|
32
32
|
# PyMammotion - Python API for Mammotion Mowers [](https://discord.gg/vpZdWhJX8x)
|
|
@@ -35,7 +35,7 @@ Description-Content-Type: text/markdown
|
|
|
35
35
|
[![PyPI Releases][img_pypi]][url_pypi]
|
|
36
36
|
[![Supported Python Versions][img_pyversions]][url_pyversions]
|
|
37
37
|
|
|
38
|
-
[img_version]: https://img.shields.io/static/v1.svg?label=SemVer&message=0.0
|
|
38
|
+
[img_version]: https://img.shields.io/static/v1.svg?label=SemVer&message=0.4.0&color=blue
|
|
39
39
|
[url_version]: https://pypi.org/project/pymammotion/
|
|
40
40
|
|
|
41
41
|
[img_pypi]: https://img.shields.io/badge/PyPI-wheels-green.svg
|
|
@@ -90,3 +90,9 @@ If you encounter any issues:
|
|
|
90
90
|
|
|
91
91
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
92
92
|
|
|
93
|
+
|
|
94
|
+
## Trademark Notice
|
|
95
|
+
|
|
96
|
+
The trademarks "Mammotion," "Luba," and "Yuka" referenced herein are registered trademarks of their respective owners. The author of this software repository is not affiliated with, endorsed by, or connected to these trademark owners in any way.
|
|
97
|
+
|
|
98
|
+
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[![PyPI Releases][img_pypi]][url_pypi]
|
|
5
5
|
[![Supported Python Versions][img_pyversions]][url_pyversions]
|
|
6
6
|
|
|
7
|
-
[img_version]: https://img.shields.io/static/v1.svg?label=SemVer&message=0.0
|
|
7
|
+
[img_version]: https://img.shields.io/static/v1.svg?label=SemVer&message=0.4.0&color=blue
|
|
8
8
|
[url_version]: https://pypi.org/project/pymammotion/
|
|
9
9
|
|
|
10
10
|
[img_pypi]: https://img.shields.io/badge/PyPI-wheels-green.svg
|
|
@@ -58,3 +58,9 @@ If you encounter any issues:
|
|
|
58
58
|
## License 📄
|
|
59
59
|
|
|
60
60
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
## Trademark Notice
|
|
64
|
+
|
|
65
|
+
The trademarks "Mammotion," "Luba," and "Yuka" referenced herein are registered trademarks of their respective owners. The author of this software repository is not affiliated with, endorsed by, or connected to these trademark owners in any way.
|
|
66
|
+
|
|
@@ -14,7 +14,9 @@ from pymammotion.http.http import LubaHTTP, connect_http
|
|
|
14
14
|
|
|
15
15
|
# TODO make a working device that will work outside HA too.
|
|
16
16
|
from pymammotion.mammotion.devices import MammotionBaseBLEDevice
|
|
17
|
-
from pymammotion.mqtt
|
|
17
|
+
from pymammotion.mqtt import MammotionMQTT
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
18
20
|
|
|
19
21
|
# TODO provide interface to pick between mqtt/cloud/bluetooth
|
|
20
22
|
|
|
@@ -28,7 +30,7 @@ if __name__ == "__main__":
|
|
|
28
30
|
CLIENT_ID = os.environ.get("CLIENT_ID")
|
|
29
31
|
IOT_TOKEN = os.environ.get("IOT_TOKEN")
|
|
30
32
|
REGION = os.environ.get("REGION")
|
|
31
|
-
luba =
|
|
33
|
+
luba = MammotionMQTT(
|
|
32
34
|
iot_token=IOT_TOKEN,
|
|
33
35
|
region_id=REGION,
|
|
34
36
|
product_key=PRODUCT_KEY,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Aliyun API interfaces."""
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Module for interacting with Aliyun Cloud IoT Gateway."""
|
|
2
|
+
|
|
1
3
|
import base64
|
|
2
4
|
import hashlib
|
|
3
5
|
import hmac
|
|
@@ -30,9 +32,6 @@ from pymammotion.utility.datatype_converter import DatatypeConverter
|
|
|
30
32
|
|
|
31
33
|
logger = getLogger(__name__)
|
|
32
34
|
|
|
33
|
-
# init client
|
|
34
|
-
|
|
35
|
-
|
|
36
35
|
MOVE_HEADERS = (
|
|
37
36
|
"x-ca-signature",
|
|
38
37
|
"x-ca-signature-headers",
|
|
@@ -47,6 +46,8 @@ MOVE_HEADERS = (
|
|
|
47
46
|
|
|
48
47
|
|
|
49
48
|
class CloudIOTGateway:
|
|
49
|
+
"""Class for interacting with Aliyun Cloud IoT Gateway."""
|
|
50
|
+
|
|
50
51
|
_client_id = ""
|
|
51
52
|
_device_sn = ""
|
|
52
53
|
_utdid = ""
|
|
@@ -61,19 +62,20 @@ class CloudIOTGateway:
|
|
|
61
62
|
converter = DatatypeConverter()
|
|
62
63
|
|
|
63
64
|
def __init__(self):
|
|
65
|
+
"""Initialize the CloudIOTGateway."""
|
|
64
66
|
self._app_key = APP_KEY
|
|
65
67
|
self._app_secret = APP_SECRET
|
|
66
68
|
self.domain = ALIYUN_DOMAIN
|
|
67
69
|
|
|
68
|
-
self._client_id = self.generate_hardware_string(8) # 8
|
|
69
|
-
self._device_sn = self.generate_hardware_string(32) # 32
|
|
70
|
-
self._utdid = self.generate_hardware_string(32) # 32
|
|
70
|
+
self._client_id = self.generate_hardware_string(8) # 8 characters
|
|
71
|
+
self._device_sn = self.generate_hardware_string(32) # 32 characters
|
|
72
|
+
self._utdid = self.generate_hardware_string(32) # 32 characters
|
|
71
73
|
|
|
72
74
|
@staticmethod
|
|
73
75
|
def generate_random_string(length):
|
|
76
|
+
"""Generate a random string of specified length."""
|
|
74
77
|
characters = string.ascii_letters + string.digits
|
|
75
|
-
|
|
76
|
-
return random_string
|
|
78
|
+
return "".join(random.choice(characters) for _ in range(length))
|
|
77
79
|
|
|
78
80
|
@staticmethod
|
|
79
81
|
def generate_hardware_string(length) -> str:
|
|
@@ -82,28 +84,24 @@ class CloudIOTGateway:
|
|
|
82
84
|
return "".join(itertools.islice(itertools.cycle(hashed_uuid), length))
|
|
83
85
|
|
|
84
86
|
def sign(self, data):
|
|
87
|
+
"""Generate signature for the given data."""
|
|
85
88
|
keys = ["appKey", "clientId", "deviceSn", "timestamp"]
|
|
86
89
|
concatenated_str = ""
|
|
87
90
|
for key in keys:
|
|
88
91
|
concatenated_str += f"{key}{data.get(key, '')}"
|
|
89
92
|
|
|
90
|
-
logger.debug(
|
|
93
|
+
logger.debug("sign(), toSignStr = %s", concatenated_str)
|
|
91
94
|
|
|
92
|
-
|
|
95
|
+
return hmac.new(
|
|
93
96
|
self._app_secret.encode("utf-8"),
|
|
94
97
|
concatenated_str.encode("utf-8"),
|
|
95
98
|
hashlib.sha1,
|
|
96
99
|
).hexdigest()
|
|
97
100
|
|
|
98
|
-
return sign
|
|
99
|
-
|
|
100
101
|
def get_region(self, country_code: str, auth_code: str):
|
|
101
|
-
|
|
102
|
-
# https://api.link.aliyun.com/living/account/region/get?x-ca-request-id=59abc767-fbbc-4333-9127-e65d792133a8
|
|
103
|
-
# x-ca-request-id is a random UUID on each request
|
|
104
|
-
|
|
102
|
+
"""Get the region based on country code and auth code."""
|
|
105
103
|
config = Config(
|
|
106
|
-
app_key=self._app_key,
|
|
104
|
+
app_key=self._app_key,
|
|
107
105
|
app_secret=self._app_secret,
|
|
108
106
|
domain=self.domain,
|
|
109
107
|
)
|
|
@@ -123,45 +121,42 @@ class CloudIOTGateway:
|
|
|
123
121
|
)
|
|
124
122
|
|
|
125
123
|
# send request
|
|
126
|
-
|
|
127
|
-
response = client.do_request(
|
|
128
|
-
"/living/account/region/get", "https", "POST", None, body, RuntimeOptions()
|
|
129
|
-
)
|
|
124
|
+
response = client.do_request("/living/account/region/get", "https", "POST", None, body, RuntimeOptions())
|
|
130
125
|
logger.debug(response.status_message)
|
|
131
126
|
logger.debug(response.headers)
|
|
132
127
|
logger.debug(response.status_code)
|
|
133
128
|
logger.debug(response.body)
|
|
134
129
|
|
|
135
|
-
#
|
|
130
|
+
# Decode the response body
|
|
136
131
|
response_body_str = response.body.decode("utf-8")
|
|
137
132
|
|
|
138
|
-
#
|
|
133
|
+
# Load the JSON string into a dictionary
|
|
139
134
|
response_body_dict = json.loads(response_body_str)
|
|
140
135
|
|
|
141
136
|
if int(response_body_dict.get("code")) != 200:
|
|
142
137
|
raise Exception("Error in getting regions: " + response_body_dict["msg"])
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
138
|
+
|
|
139
|
+
self._region = RegionResponse.from_dict(response_body_dict)
|
|
140
|
+
logger.debug("Endpoint: %s", self._region.data.mqttEndpoint)
|
|
146
141
|
|
|
147
142
|
return response.body
|
|
148
143
|
|
|
149
144
|
def aep_handle(self):
|
|
150
|
-
|
|
145
|
+
"""Handle AEP authentication."""
|
|
151
146
|
aep_domain = self.domain
|
|
152
147
|
|
|
153
148
|
if self._region.data.apiGatewayEndpoint is not None:
|
|
154
149
|
aep_domain = self._region.data.apiGatewayEndpoint
|
|
155
150
|
|
|
156
151
|
config = Config(
|
|
157
|
-
app_key=self._app_key,
|
|
152
|
+
app_key=self._app_key,
|
|
158
153
|
app_secret=self._app_secret,
|
|
159
154
|
domain=aep_domain,
|
|
160
155
|
)
|
|
161
156
|
client = Client(config)
|
|
162
157
|
|
|
163
158
|
request = CommonParams(api_ver="1.0.0", language="en-US")
|
|
164
|
-
logger.debug("client id ", self._client_id)
|
|
159
|
+
logger.debug("client id %s", self._client_id)
|
|
165
160
|
time_now = time.time()
|
|
166
161
|
data_to_sign = {
|
|
167
162
|
"appKey": self._app_key,
|
|
@@ -185,10 +180,7 @@ class CloudIOTGateway:
|
|
|
185
180
|
)
|
|
186
181
|
|
|
187
182
|
# send request
|
|
188
|
-
|
|
189
|
-
response = client.do_request(
|
|
190
|
-
"/app/aepauth/handle", "https", "POST", None, body, RuntimeOptions()
|
|
191
|
-
)
|
|
183
|
+
response = client.do_request("/app/aepauth/handle", "https", "POST", None, body, RuntimeOptions())
|
|
192
184
|
logger.debug(response.status_message)
|
|
193
185
|
logger.debug(response.headers)
|
|
194
186
|
logger.debug(response.status_code)
|
|
@@ -199,19 +191,16 @@ class CloudIOTGateway:
|
|
|
199
191
|
response_body_dict = json.loads(response_body_str)
|
|
200
192
|
|
|
201
193
|
if int(response_body_dict.get("code")) != 200:
|
|
202
|
-
raise Exception(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
else:
|
|
206
|
-
self._aep_response = AepResponse.from_dict(response_body_dict)
|
|
194
|
+
raise Exception("Error in getting mqtt credentials: " + response_body_dict["msg"])
|
|
195
|
+
|
|
196
|
+
self._aep_response = AepResponse.from_dict(response_body_dict)
|
|
207
197
|
|
|
208
198
|
logger.debug(response_body_dict)
|
|
209
199
|
|
|
210
200
|
return response.body
|
|
211
201
|
|
|
212
|
-
# returns vid
|
|
213
|
-
|
|
214
202
|
async def connect(self):
|
|
203
|
+
"""Connect to the Aliyun Cloud IoT Gateway."""
|
|
215
204
|
region_url = "sdk.openaccount.aliyun.com"
|
|
216
205
|
async with ClientSession() as session:
|
|
217
206
|
headers = {
|
|
@@ -255,14 +244,12 @@ class CloudIOTGateway:
|
|
|
255
244
|
header = "".join(f"{k}:{dic[k]}\n" for k in keys).strip()
|
|
256
245
|
|
|
257
246
|
headers["x-ca-signature-headers"] = sign_headers
|
|
258
|
-
string_to_sign = (
|
|
259
|
-
"
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
json.dumps(_bodyParam, separators=(",", ":")),
|
|
265
|
-
)
|
|
247
|
+
string_to_sign = "POST\n{}\n\n{}\n{}\n{}\n/api/prd/connect.json?request={}".format(
|
|
248
|
+
headers["accept"],
|
|
249
|
+
headers["content-type"],
|
|
250
|
+
headers["date"],
|
|
251
|
+
header,
|
|
252
|
+
json.dumps(_bodyParam, separators=(",", ":")),
|
|
266
253
|
)
|
|
267
254
|
|
|
268
255
|
hash_val = hmac.new(
|
|
@@ -276,15 +263,14 @@ class CloudIOTGateway:
|
|
|
276
263
|
async with session.post(
|
|
277
264
|
f"https://{region_url}/api/prd/connect.json",
|
|
278
265
|
headers=headers,
|
|
279
|
-
params=
|
|
266
|
+
params={"request": json.dumps(_bodyParam, separators=(",", ":"))},
|
|
280
267
|
) as resp:
|
|
281
268
|
data = await resp.json()
|
|
282
269
|
self._connect_response = ConnectResponse.from_dict(data)
|
|
283
270
|
logger.debug(data)
|
|
284
271
|
|
|
285
272
|
async def login_by_oauth(self, country_code: str, auth_code: str):
|
|
286
|
-
"""
|
|
287
|
-
|
|
273
|
+
"""Login by OAuth."""
|
|
288
274
|
region_url = self._region.data.oaApiGatewayEndpoint
|
|
289
275
|
|
|
290
276
|
async with ClientSession() as session:
|
|
@@ -345,24 +331,17 @@ class CloudIOTGateway:
|
|
|
345
331
|
async with session.post(
|
|
346
332
|
f"https://{region_url}/api/prd/loginbyoauth.json",
|
|
347
333
|
headers=headers,
|
|
348
|
-
params=
|
|
349
|
-
loginByOauthRequest=json.dumps(_bodyParam, separators=(",", ":"))
|
|
350
|
-
),
|
|
334
|
+
params={"loginByOauthRequest": json.dumps(_bodyParam, separators=(",", ":"))},
|
|
351
335
|
) as resp:
|
|
352
336
|
data = await resp.json()
|
|
353
337
|
logger.debug(data)
|
|
354
338
|
|
|
355
339
|
self._login_by_oauth_response = LoginByOAuthResponse.from_dict(data)
|
|
356
340
|
|
|
357
|
-
# self._region = response.body.data
|
|
358
|
-
|
|
359
|
-
# return response.body
|
|
360
|
-
|
|
361
|
-
# headers require sid vid or at a minimuim vid which comes from prd/connect.json
|
|
362
|
-
|
|
363
341
|
def session_by_auth_code(self):
|
|
342
|
+
"""Create a session by auth code."""
|
|
364
343
|
config = Config(
|
|
365
|
-
app_key=self._app_key,
|
|
344
|
+
app_key=self._app_key,
|
|
366
345
|
app_secret=self._app_secret,
|
|
367
346
|
domain=self._region.data.apiGatewayEndpoint,
|
|
368
347
|
)
|
|
@@ -384,7 +363,6 @@ class CloudIOTGateway:
|
|
|
384
363
|
)
|
|
385
364
|
|
|
386
365
|
# send request
|
|
387
|
-
# possibly need to do this ourselves
|
|
388
366
|
response = client.do_request(
|
|
389
367
|
"/account/createSessionByAuthCode",
|
|
390
368
|
"https",
|
|
@@ -398,26 +376,25 @@ class CloudIOTGateway:
|
|
|
398
376
|
logger.debug(response.status_code)
|
|
399
377
|
logger.debug(response.body)
|
|
400
378
|
|
|
401
|
-
#
|
|
379
|
+
# Decode the response body
|
|
402
380
|
response_body_str = response.body.decode("utf-8")
|
|
403
381
|
|
|
404
|
-
#
|
|
382
|
+
# Load the JSON string into a dictionary
|
|
405
383
|
response_body_dict = json.loads(response_body_str)
|
|
406
384
|
|
|
407
385
|
if int(response_body_dict.get("code")) != 200:
|
|
408
386
|
raise Exception("Error in creating session: " + response_body_dict["msg"])
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
response_body_dict
|
|
412
|
-
)
|
|
387
|
+
|
|
388
|
+
self._session_by_authcode_response = SessionByAuthCodeResponse.from_dict(response_body_dict)
|
|
413
389
|
|
|
414
390
|
return response.body
|
|
415
391
|
|
|
416
392
|
def check_or_refresh_session(self):
|
|
417
|
-
|
|
393
|
+
"""Check or refresh the session."""
|
|
394
|
+
if self.load_saved_params() is False:
|
|
418
395
|
return False
|
|
419
396
|
config = Config(
|
|
420
|
-
app_key=self._app_key,
|
|
397
|
+
app_key=self._app_key,
|
|
421
398
|
app_secret=self._app_secret,
|
|
422
399
|
domain=self._region.data.apiGatewayEndpoint,
|
|
423
400
|
)
|
|
@@ -457,11 +434,12 @@ class CloudIOTGateway:
|
|
|
457
434
|
response_body_str = response.body.decode("utf-8")
|
|
458
435
|
|
|
459
436
|
# Carica la stringa JSON in un dizionario
|
|
460
|
-
|
|
437
|
+
json.loads(response_body_str)
|
|
461
438
|
|
|
462
439
|
def list_binding_by_account(self):
|
|
440
|
+
"""List bindings by account."""
|
|
463
441
|
config = Config(
|
|
464
|
-
app_key=self._app_key,
|
|
442
|
+
app_key=self._app_key,
|
|
465
443
|
app_secret=self._app_secret,
|
|
466
444
|
domain=self._region.data.apiGatewayEndpoint,
|
|
467
445
|
)
|
|
@@ -482,32 +460,27 @@ class CloudIOTGateway:
|
|
|
482
460
|
)
|
|
483
461
|
|
|
484
462
|
# send request
|
|
485
|
-
|
|
486
|
-
response = client.do_request(
|
|
487
|
-
"/uc/listBindingByAccount", "https", "POST", None, body, RuntimeOptions()
|
|
488
|
-
)
|
|
463
|
+
response = client.do_request("/uc/listBindingByAccount", "https", "POST", None, body, RuntimeOptions())
|
|
489
464
|
logger.debug(response.status_message)
|
|
490
465
|
logger.debug(response.headers)
|
|
491
466
|
logger.debug(response.status_code)
|
|
492
467
|
logger.debug(response.body)
|
|
493
468
|
|
|
494
|
-
#
|
|
495
|
-
# Decodifica il corpo della risposta
|
|
469
|
+
# Decode the response body
|
|
496
470
|
response_body_str = response.body.decode("utf-8")
|
|
497
471
|
|
|
498
|
-
#
|
|
472
|
+
# Load the JSON string into a dictionary
|
|
499
473
|
response_body_dict = json.loads(response_body_str)
|
|
500
474
|
|
|
501
475
|
if int(response_body_dict.get("code")) != 200:
|
|
502
476
|
raise Exception("Error in creating session: " + response_body_dict["msg"])
|
|
503
|
-
else:
|
|
504
|
-
self._listing_dev_by_account_response = (
|
|
505
|
-
ListingDevByAccountResponse.from_dict(response_body_dict)
|
|
506
|
-
)
|
|
507
477
|
|
|
508
|
-
|
|
478
|
+
self._listing_dev_by_account_response = ListingDevByAccountResponse.from_dict(response_body_dict)
|
|
479
|
+
|
|
480
|
+
def send_cloud_command(self, iot_id: str, command: bytes) -> str:
|
|
481
|
+
"""Send a cloud command to the specified IoT device."""
|
|
509
482
|
config = Config(
|
|
510
|
-
app_key=self._app_key,
|
|
483
|
+
app_key=self._app_key,
|
|
511
484
|
app_secret=self._app_secret,
|
|
512
485
|
domain=self._region.data.apiGatewayEndpoint,
|
|
513
486
|
)
|
|
@@ -522,30 +495,36 @@ class CloudIOTGateway:
|
|
|
522
495
|
)
|
|
523
496
|
|
|
524
497
|
# TODO move to using InvokeThingServiceRequest()
|
|
498
|
+
|
|
499
|
+
message_id = str(uuid.uuid4())
|
|
500
|
+
|
|
525
501
|
body = IoTApiRequest(
|
|
526
|
-
id=
|
|
502
|
+
id=message_id,
|
|
527
503
|
params={
|
|
528
504
|
"args": {"content": self.converter.printBase64Binary(command)},
|
|
529
505
|
"identifier": "device_protobuf_sync_service",
|
|
530
|
-
"iotId": "
|
|
506
|
+
"iotId": f"{iot_id}",
|
|
531
507
|
},
|
|
532
508
|
request=request,
|
|
533
509
|
version="1.0",
|
|
534
510
|
)
|
|
535
511
|
|
|
536
512
|
# send request
|
|
537
|
-
|
|
538
|
-
response = client.do_request(
|
|
539
|
-
"/thing/service/invoke", "https", "POST", None, body, RuntimeOptions()
|
|
540
|
-
)
|
|
513
|
+
response = client.do_request("/thing/service/invoke", "https", "POST", None, body, RuntimeOptions())
|
|
541
514
|
logger.debug(response.status_message)
|
|
542
515
|
logger.debug(response.headers)
|
|
543
516
|
logger.debug(response.status_code)
|
|
544
517
|
logger.debug(response.body)
|
|
545
518
|
|
|
546
|
-
# self._region = response.body.data
|
|
547
|
-
# Decodifica il corpo della risposta
|
|
548
519
|
response_body_str = response.body.decode("utf-8")
|
|
549
|
-
|
|
550
|
-
# Carica la stringa JSON in un dizionario
|
|
551
520
|
response_body_dict = json.loads(response_body_str)
|
|
521
|
+
|
|
522
|
+
if int(response_body_dict.get("code")) != 200:
|
|
523
|
+
logger.error(
|
|
524
|
+
"Error in sending cloud command: %s - %s",
|
|
525
|
+
str(response_body_dict.get("code")),
|
|
526
|
+
str(response_body_dict["msg"]),
|
|
527
|
+
)
|
|
528
|
+
return ""
|
|
529
|
+
|
|
530
|
+
return message_id
|
|
@@ -143,9 +143,7 @@ class tmp_constant:
|
|
|
143
143
|
URI_ALINK_SERVICE = "alink/service" # deprecated
|
|
144
144
|
URI_AUTH = "/auth" # deprecated
|
|
145
145
|
URI_AUTHEN_REGISTER = "/sys/{productKey}/{deviceName}/thing/authen/sub/register"
|
|
146
|
-
URI_AUTHEN_REGISTER_REPLY =
|
|
147
|
-
"/sys/{productKey}/{deviceName}/thing/authen/sub/register_reply"
|
|
148
|
-
)
|
|
146
|
+
URI_AUTHEN_REGISTER_REPLY = "/sys/{productKey}/{deviceName}/thing/authen/sub/register_reply"
|
|
149
147
|
URI_BLACKLIST_UPDATE_POST = "/thing/lan/blacklist/update"
|
|
150
148
|
URI_BLACKLIST_UPDATE_REPLY_POST = "/thing/lan/blacklist/update_reply"
|
|
151
149
|
URI_DEVICE = "/device/core/dev"
|
|
@@ -165,9 +163,7 @@ class tmp_constant:
|
|
|
165
163
|
URI_TOPIC_LOCALDEVICE_STATECHANGE = "group/localstatechange"
|
|
166
164
|
URI_TOPIC_REPLY_POST = "_reply"
|
|
167
165
|
URI_UPDATE_DEVICE_INFO = "/sys/{productKey}/{deviceName}/thing/deviceinfo/update"
|
|
168
|
-
URI_UPDATE_DEVICE_INFO_REPLY =
|
|
169
|
-
"/sys/{productKey}/{deviceName}/thing/deviceinfo/update_reply"
|
|
170
|
-
)
|
|
166
|
+
URI_UPDATE_DEVICE_INFO_REPLY = "/sys/{productKey}/{deviceName}/thing/deviceinfo/update_reply"
|
|
171
167
|
URI_USER = "/user"
|
|
172
168
|
VALUE_SHA256 = "sha256"
|
|
173
169
|
VERSION = "1.0"
|
|
@@ -46,15 +46,11 @@ class LubaBLE:
|
|
|
46
46
|
if self.client is not None:
|
|
47
47
|
return await self.client.disconnect()
|
|
48
48
|
|
|
49
|
-
async def notification_handler(
|
|
50
|
-
self, _characteristic: BleakGATTCharacteristic, data: bytearray
|
|
51
|
-
):
|
|
49
|
+
async def notification_handler(self, _characteristic: BleakGATTCharacteristic, data: bytearray):
|
|
52
50
|
"""Simple notification handler which prints the data received."""
|
|
53
51
|
await self._bleEvt.BleNotification(data)
|
|
54
52
|
|
|
55
|
-
def service_changed_handler(
|
|
56
|
-
self, characteristic: BleakGATTCharacteristic, data: bytearray
|
|
57
|
-
):
|
|
53
|
+
def service_changed_handler(self, characteristic: BleakGATTCharacteristic, data: bytearray):
|
|
58
54
|
"""Simple notification handler which prints the data received."""
|
|
59
55
|
print(f"Response 2 {characteristic.description}: {data}")
|
|
60
56
|
print(data.decode("utf-8"))
|
|
@@ -63,12 +59,8 @@ class LubaBLE:
|
|
|
63
59
|
|
|
64
60
|
async def notifications(self):
|
|
65
61
|
if self.client.is_connected:
|
|
66
|
-
await self.client.start_notify(
|
|
67
|
-
|
|
68
|
-
)
|
|
69
|
-
await self.client.start_notify(
|
|
70
|
-
SERVICE_CHANGED_CHARACTERISTIC, self.service_changed_handler
|
|
71
|
-
)
|
|
62
|
+
await self.client.start_notify(UUID_NOTIFICATION_CHARACTERISTIC, self.notification_handler)
|
|
63
|
+
await self.client.start_notify(SERVICE_CHANGED_CHARACTERISTIC, self.service_changed_handler)
|
|
72
64
|
|
|
73
65
|
def getClient(self):
|
|
74
66
|
return self.client
|
|
@@ -79,15 +79,11 @@ class BleMessage:
|
|
|
79
79
|
|
|
80
80
|
async def get_task(self):
|
|
81
81
|
hash_map = {"pver": 1, "subCmd": 2, "result": 0}
|
|
82
|
-
await self.messageNavigation.post_custom_data(
|
|
83
|
-
self.get_json_string(bleOrderCmd.task, hash_map)
|
|
84
|
-
)
|
|
82
|
+
await self.messageNavigation.post_custom_data(self.get_json_string(bleOrderCmd.task, hash_map))
|
|
85
83
|
|
|
86
84
|
async def send_ble_alive(self):
|
|
87
85
|
hash_map = {"ctrl": 1}
|
|
88
|
-
await self.messageNavigation.post_custom_data(
|
|
89
|
-
self.get_json_string(bleOrderCmd.bleAlive, hash_map)
|
|
90
|
-
)
|
|
86
|
+
await self.messageNavigation.post_custom_data(self.get_json_string(bleOrderCmd.bleAlive, hash_map))
|
|
91
87
|
|
|
92
88
|
def clearNotification(self):
|
|
93
89
|
self.notification = None
|
|
@@ -106,9 +102,7 @@ class BleMessage:
|
|
|
106
102
|
seqs=1,
|
|
107
103
|
version=1,
|
|
108
104
|
subtype=1,
|
|
109
|
-
net=dev_net_pb2.DevNet(
|
|
110
|
-
todev_ble_sync=1, todev_devinfo_req=dev_net_pb2.DrvDevInfoReq()
|
|
111
|
-
),
|
|
105
|
+
net=dev_net_pb2.DevNet(todev_ble_sync=1, todev_devinfo_req=dev_net_pb2.DrvDevInfoReq()),
|
|
112
106
|
)
|
|
113
107
|
byte_arr = luba_msg.SerializeToString()
|
|
114
108
|
await self.post_custom_data_bytes(byte_arr)
|
|
@@ -117,9 +111,7 @@ class BleMessage:
|
|
|
117
111
|
request = False
|
|
118
112
|
type = self.messageNavigation.getTypeValue(0, 5)
|
|
119
113
|
try:
|
|
120
|
-
request = await self.messageNavigation.post(
|
|
121
|
-
BleMessage.mEncrypted, BleMessage.mChecksum, False, type, None
|
|
122
|
-
)
|
|
114
|
+
request = await self.messageNavigation.post(BleMessage.mEncrypted, BleMessage.mChecksum, False, type, None)
|
|
123
115
|
# print(request)
|
|
124
116
|
except Exception as err:
|
|
125
117
|
# Log.w(TAG, "post requestDeviceStatus interrupted")
|
|
@@ -133,9 +125,7 @@ class BleMessage:
|
|
|
133
125
|
request = False
|
|
134
126
|
type = self.messageNavigation.getTypeValue(0, 7)
|
|
135
127
|
try:
|
|
136
|
-
request = await self.messageNavigation.post(
|
|
137
|
-
BleMessage.mEncrypted, BleMessage.mChecksum, False, type, None
|
|
138
|
-
)
|
|
128
|
+
request = await self.messageNavigation.post(BleMessage.mEncrypted, BleMessage.mChecksum, False, type, None)
|
|
139
129
|
# print(request)
|
|
140
130
|
except Exception as err:
|
|
141
131
|
# Log.w(TAG, "post requestDeviceStatus interrupted")
|
|
@@ -318,9 +308,7 @@ class BleMessage:
|
|
|
318
308
|
return
|
|
319
309
|
type_val = self.getTypeValue(1, 19)
|
|
320
310
|
try:
|
|
321
|
-
suc = await self.post(
|
|
322
|
-
self.mEncrypted, self.mChecksum, self.mRequireAck, type_val, data
|
|
323
|
-
)
|
|
311
|
+
suc = await self.post(self.mEncrypted, self.mChecksum, self.mRequireAck, type_val, data)
|
|
324
312
|
# int status = suc ? 0 : BlufiCallback.CODE_WRITE_DATA_FAILED
|
|
325
313
|
# onPostCustomDataResult(status, data)
|
|
326
314
|
# print(suc)
|
|
@@ -333,9 +321,7 @@ class BleMessage:
|
|
|
333
321
|
return
|
|
334
322
|
type_val = self.getTypeValue(1, 19)
|
|
335
323
|
try:
|
|
336
|
-
suc = await self.post(
|
|
337
|
-
self.mEncrypted, self.mChecksum, self.mRequireAck, type_val, data
|
|
338
|
-
)
|
|
324
|
+
suc = await self.post(self.mEncrypted, self.mChecksum, self.mRequireAck, type_val, data)
|
|
339
325
|
# int status = suc ? 0 : BlufiCallback.CODE_WRITE_DATA_FAILED
|
|
340
326
|
# onPostCustomDataResult(status, data)
|
|
341
327
|
except Exception as err:
|
|
@@ -352,17 +338,11 @@ class BleMessage:
|
|
|
352
338
|
if data is None:
|
|
353
339
|
return await self.post_non_data(encrypt, checksum, require_ack, type_of)
|
|
354
340
|
|
|
355
|
-
return await self.post_contains_data(
|
|
356
|
-
encrypt, checksum, require_ack, type_of, data
|
|
357
|
-
)
|
|
341
|
+
return await self.post_contains_data(encrypt, checksum, require_ack, type_of, data)
|
|
358
342
|
|
|
359
|
-
async def post_non_data(
|
|
360
|
-
self, encrypt: bool, checksum: bool, require_ack: bool, type_of: int
|
|
361
|
-
) -> bool:
|
|
343
|
+
async def post_non_data(self, encrypt: bool, checksum: bool, require_ack: bool, type_of: int) -> bool:
|
|
362
344
|
sequence = self.generateSendSequence()
|
|
363
|
-
postBytes = self.getPostBytes(
|
|
364
|
-
type_of, encrypt, checksum, require_ack, False, sequence, None
|
|
365
|
-
)
|
|
345
|
+
postBytes = self.getPostBytes(type_of, encrypt, checksum, require_ack, False, sequence, None)
|
|
366
346
|
posted = await self.gatt_write(postBytes)
|
|
367
347
|
return posted and (not require_ack or self.receiveAck(sequence))
|
|
368
348
|
|
|
@@ -385,9 +365,7 @@ class BleMessage:
|
|
|
385
365
|
for index, chunk in enumerate(chunks):
|
|
386
366
|
frag = index != len(chunks) - 1
|
|
387
367
|
sequence = self.generateSendSequence()
|
|
388
|
-
postBytes = self.getPostBytes(
|
|
389
|
-
type_of, encrypt, checksum, require_ack, frag, sequence, chunk
|
|
390
|
-
)
|
|
368
|
+
postBytes = self.getPostBytes(type_of, encrypt, checksum, require_ack, frag, sequence, chunk)
|
|
391
369
|
# print("sequence")
|
|
392
370
|
# print(sequence)
|
|
393
371
|
posted = await self.gatt_write(postBytes)
|
|
@@ -415,9 +393,7 @@ class BleMessage:
|
|
|
415
393
|
) -> bytes:
|
|
416
394
|
byteOS = BytesIO()
|
|
417
395
|
dataLength = 0 if data == None else len(data)
|
|
418
|
-
frameCtrl = FrameCtrlData.getFrameCTRLValue(
|
|
419
|
-
encrypt, checksum, 0, require_ack, hasFrag
|
|
420
|
-
)
|
|
396
|
+
frameCtrl = FrameCtrlData.getFrameCTRLValue(encrypt, checksum, 0, require_ack, hasFrag)
|
|
421
397
|
byteOS.write(type.to_bytes(1, sys.byteorder))
|
|
422
398
|
byteOS.write(frameCtrl.to_bytes(1, sys.byteorder))
|
|
423
399
|
byteOS.write(sequence.to_bytes(1, sys.byteorder))
|
|
@@ -19,9 +19,7 @@ def store_sys_data(sys):
|
|
|
19
19
|
tard_state_data_list = sys.systemTardStateTunnel.tard_state_data
|
|
20
20
|
longValue8 = tard_state_data_list[0]
|
|
21
21
|
longValue9 = tard_state_data_list[1]
|
|
22
|
-
print(
|
|
23
|
-
"Device status report,deviceState:", longValue8, ",deviceName:", "Luba..."
|
|
24
|
-
)
|
|
22
|
+
print("Device status report,deviceState:", longValue8, ",deviceName:", "Luba...")
|
|
25
23
|
chargeStateTemp = longValue9
|
|
26
24
|
longValue10 = tard_state_data_list[6]
|
|
27
25
|
longValue11 = tard_state_data_list[7]
|