pymammotion 0.2.28__py3-none-any.whl → 0.2.30__py3-none-any.whl
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.
- pymammotion/__init__.py +12 -9
- pymammotion/aliyun/cloud_gateway.py +57 -39
- pymammotion/aliyun/cloud_service.py +3 -3
- pymammotion/aliyun/dataclass/dev_by_account_response.py +1 -2
- pymammotion/aliyun/dataclass/session_by_authcode_response.py +1 -0
- pymammotion/bluetooth/ble.py +6 -6
- pymammotion/bluetooth/ble_message.py +30 -16
- pymammotion/bluetooth/data/convert.py +1 -1
- pymammotion/bluetooth/data/framectrldata.py +1 -1
- pymammotion/bluetooth/data/notifydata.py +6 -6
- pymammotion/const.py +1 -0
- pymammotion/data/model/__init__.py +2 -0
- pymammotion/data/model/account.py +1 -1
- pymammotion/data/model/device.py +31 -24
- pymammotion/data/model/device_config.py +71 -0
- pymammotion/data/model/enums.py +4 -4
- pymammotion/data/model/excute_boarder_params.py +5 -5
- pymammotion/data/model/execute_boarder.py +4 -4
- pymammotion/data/model/generate_route_information.py +18 -124
- pymammotion/data/model/hash_list.py +4 -7
- pymammotion/data/model/location.py +3 -3
- pymammotion/data/model/mowing_modes.py +1 -1
- pymammotion/data/model/plan.py +4 -4
- pymammotion/data/model/region_data.py +4 -4
- pymammotion/data/model/report_info.py +1 -1
- pymammotion/data/mqtt/event.py +8 -3
- pymammotion/data/state_manager.py +13 -12
- pymammotion/event/event.py +14 -14
- pymammotion/http/http.py +33 -45
- pymammotion/http/model/http.py +75 -0
- pymammotion/mammotion/commands/messages/driver.py +20 -23
- pymammotion/mammotion/commands/messages/navigation.py +47 -48
- pymammotion/mammotion/commands/messages/network.py +17 -35
- pymammotion/mammotion/commands/messages/system.py +6 -7
- pymammotion/mammotion/control/joystick.py +11 -10
- pymammotion/mammotion/devices/__init__.py +2 -2
- pymammotion/mammotion/devices/base.py +248 -0
- pymammotion/mammotion/devices/mammotion.py +52 -1042
- pymammotion/mammotion/devices/mammotion_bluetooth.py +447 -0
- pymammotion/mammotion/devices/mammotion_cloud.py +244 -0
- pymammotion/mqtt/mammotion_future.py +3 -2
- pymammotion/mqtt/mammotion_mqtt.py +23 -23
- pymammotion/proto/__init__.py +6 -0
- pymammotion/utility/constant/__init__.py +3 -1
- pymammotion/utility/conversions.py +1 -1
- pymammotion/utility/datatype_converter.py +9 -9
- pymammotion/utility/device_type.py +47 -18
- pymammotion/utility/map.py +2 -2
- pymammotion/utility/movement.py +2 -1
- pymammotion/utility/periodic.py +5 -5
- pymammotion/utility/rocker_util.py +1 -1
- {pymammotion-0.2.28.dist-info → pymammotion-0.2.30.dist-info}/METADATA +3 -1
- {pymammotion-0.2.28.dist-info → pymammotion-0.2.30.dist-info}/RECORD +55 -51
- {pymammotion-0.2.28.dist-info → pymammotion-0.2.30.dist-info}/LICENSE +0 -0
- {pymammotion-0.2.28.dist-info → pymammotion-0.2.30.dist-info}/WHEEL +0 -0
@@ -1,12 +1,13 @@
|
|
1
1
|
from asyncio import Future
|
2
|
-
from typing import Any
|
3
2
|
|
4
3
|
import async_timeout
|
5
4
|
|
6
5
|
|
7
6
|
class MammotionFuture:
|
8
7
|
"""Create futures for each MQTT Message."""
|
9
|
-
|
8
|
+
|
9
|
+
def __init__(self, iot_id) -> None:
|
10
|
+
self.iot_id = iot_id
|
10
11
|
self.fut: Future = Future()
|
11
12
|
self.loop = self.fut.get_loop()
|
12
13
|
|
@@ -1,12 +1,15 @@
|
|
1
1
|
"""MammotionMQTT."""
|
2
|
+
|
2
3
|
import asyncio
|
4
|
+
import base64
|
3
5
|
import hashlib
|
4
6
|
import hmac
|
5
7
|
import json
|
6
8
|
import logging
|
7
9
|
from logging import getLogger
|
8
|
-
from typing import Callable, Optional
|
10
|
+
from typing import Awaitable, Callable, Optional
|
9
11
|
|
12
|
+
import betterproto
|
10
13
|
from linkkit.linkkit import LinkKit
|
11
14
|
from paho.mqtt.client import MQTTMessage
|
12
15
|
|
@@ -14,7 +17,7 @@ from pymammotion.aliyun.cloud_gateway import CloudIOTGateway
|
|
14
17
|
from pymammotion.data.mqtt.event import ThingEventMessage
|
15
18
|
from pymammotion.data.mqtt.properties import ThingPropertiesMessage
|
16
19
|
from pymammotion.data.mqtt.status import ThingStatusMessage
|
17
|
-
from pymammotion.proto import
|
20
|
+
from pymammotion.proto.luba_msg import LubaMsg
|
18
21
|
|
19
22
|
logger = getLogger(__name__)
|
20
23
|
|
@@ -29,18 +32,19 @@ class MammotionMQTT:
|
|
29
32
|
device_name: str,
|
30
33
|
device_secret: str,
|
31
34
|
iot_token: str,
|
35
|
+
cloud_client: CloudIOTGateway,
|
32
36
|
client_id: Optional[str] = None,
|
33
|
-
):
|
37
|
+
) -> None:
|
34
38
|
"""Create instance of MammotionMQTT."""
|
35
39
|
super().__init__()
|
36
|
-
self._cloud_client =
|
40
|
+
self._cloud_client = cloud_client
|
37
41
|
self.is_connected = False
|
38
42
|
self.is_ready = False
|
39
|
-
self.on_connected: Optional[Callable[[],Awaitable[None]]] = None
|
40
|
-
self.on_ready: Optional[Callable[[],Awaitable[None]]] = None
|
41
|
-
self.on_error: Optional[Callable[[str],Awaitable[None]]] = None
|
42
|
-
self.on_disconnected: Optional[Callable[[],Awaitable[None]]] = None
|
43
|
-
self.on_message: Optional[Callable[[str, str, str],Awaitable[None]]] = None
|
43
|
+
self.on_connected: Optional[Callable[[], Awaitable[None]]] = None
|
44
|
+
self.on_ready: Optional[Callable[[], Awaitable[None]]] = None
|
45
|
+
self.on_error: Optional[Callable[[str], Awaitable[None]]] = None
|
46
|
+
self.on_disconnected: Optional[Callable[[], Awaitable[None]]] = None
|
47
|
+
self.on_message: Optional[Callable[[str, str, str], Awaitable[None]]] = None
|
44
48
|
|
45
49
|
self._product_key = product_key
|
46
50
|
self._device_name = device_name
|
@@ -77,20 +81,19 @@ class MammotionMQTT:
|
|
77
81
|
self._linkkit_client.on_topic_message = self._thing_on_topic_message
|
78
82
|
self._mqtt_host = f"{self._product_key}.iot-as-mqtt.{region_id}.aliyuncs.com"
|
79
83
|
|
80
|
-
def connect_async(self):
|
84
|
+
def connect_async(self) -> None:
|
81
85
|
"""Connect async to MQTT Server."""
|
82
86
|
logger.info("Connecting...")
|
83
87
|
if self._linkkit_client.check_state() is LinkKit.LinkKitState.INITIALIZED:
|
84
88
|
self._linkkit_client.thing_setup()
|
85
89
|
self._linkkit_client.connect_async()
|
86
90
|
|
87
|
-
|
88
|
-
def disconnect(self):
|
91
|
+
def disconnect(self) -> None:
|
89
92
|
"""Disconnect from MQTT Server."""
|
90
93
|
logger.info("Disconnecting...")
|
91
94
|
self._linkkit_client.disconnect()
|
92
95
|
|
93
|
-
def _thing_on_thing_enable(self, user_data):
|
96
|
+
def _thing_on_thing_enable(self, user_data) -> None:
|
94
97
|
"""Is called when Thing is enabled."""
|
95
98
|
logger.debug("on_thing_enable")
|
96
99
|
self.is_connected = True
|
@@ -129,7 +132,7 @@ class MammotionMQTT:
|
|
129
132
|
# command = MammotionCommand(device_name="Luba")
|
130
133
|
# self._cloud_client.send_cloud_command(command.get_report_cfg())
|
131
134
|
|
132
|
-
def _thing_on_topic_message(self, topic, payload, qos, user_data):
|
135
|
+
def _thing_on_topic_message(self, topic, payload, qos, user_data) -> None:
|
133
136
|
"""Is called when thing topic comes in."""
|
134
137
|
logger.debug(
|
135
138
|
"on_topic_message, receive message, topic:%s, payload:%s, qos:%d",
|
@@ -143,8 +146,7 @@ class MammotionMQTT:
|
|
143
146
|
future = asyncio.run_coroutine_threadsafe(self.on_message(topic, payload, iot_id), self.loop)
|
144
147
|
asyncio.wrap_future(future, loop=self.loop)
|
145
148
|
|
146
|
-
|
147
|
-
def _thing_on_connect(self, session_flag, rc, user_data):
|
149
|
+
def _thing_on_connect(self, session_flag, rc, user_data) -> None:
|
148
150
|
"""Is called on thing connect."""
|
149
151
|
self.is_connected = True
|
150
152
|
if self.on_connected is not None:
|
@@ -155,7 +157,7 @@ class MammotionMQTT:
|
|
155
157
|
|
156
158
|
# self._linkkit_client.subscribe_topic(f"/sys/{self._product_key}/{self._device_name}/#")
|
157
159
|
|
158
|
-
def _on_disconnect(self, _client, _userdata):
|
160
|
+
def _on_disconnect(self, _client, _userdata) -> None:
|
159
161
|
"""Is called on disconnect."""
|
160
162
|
logger.info("Disconnected")
|
161
163
|
self.is_connected = False
|
@@ -164,8 +166,7 @@ class MammotionMQTT:
|
|
164
166
|
future = asyncio.run_coroutine_threadsafe(self.on_disconnected(), self.loop)
|
165
167
|
asyncio.wrap_future(future, loop=self.loop)
|
166
168
|
|
167
|
-
|
168
|
-
def _on_message(self, _client, _userdata, message: MQTTMessage):
|
169
|
+
def _on_message(self, _client, _userdata, message: MQTTMessage) -> None:
|
169
170
|
"""Is called when message is received."""
|
170
171
|
logger.info("Message on topic %s", message.topic)
|
171
172
|
|
@@ -174,9 +175,9 @@ class MammotionMQTT:
|
|
174
175
|
event = ThingEventMessage(**payload)
|
175
176
|
params = event.params
|
176
177
|
if params.identifier == "device_protobuf_msg_event":
|
177
|
-
content =
|
178
|
+
content = LubaMsg().parse(base64.b64decode(params.value.content.proto))
|
178
179
|
|
179
|
-
logger.info("Unhandled protobuf event: %s",
|
180
|
+
logger.info("Unhandled protobuf event: %s", betterproto.which_one_of(content, "LubaSubMsg"))
|
180
181
|
elif params.identifier == "device_warning_event":
|
181
182
|
logger.debug("identifier event: %s", params.identifier)
|
182
183
|
else:
|
@@ -191,7 +192,6 @@ class MammotionMQTT:
|
|
191
192
|
logger.debug("Unhandled topic: %s", message.topic)
|
192
193
|
logger.debug(payload)
|
193
194
|
|
194
|
-
def get_cloud_client(self) ->
|
195
|
+
def get_cloud_client(self) -> CloudIOTGateway:
|
195
196
|
"""Return internal cloud client."""
|
196
197
|
return self._cloud_client
|
197
|
-
|
pymammotion/proto/__init__.py
CHANGED
@@ -20,13 +20,13 @@ class DatatypeConverter:
|
|
20
20
|
"""
|
21
21
|
|
22
22
|
if DatatypeConverter.encode_map is None:
|
23
|
-
cArr = [0] * 64
|
24
|
-
for
|
25
|
-
cArr[
|
26
|
-
for
|
27
|
-
cArr[
|
28
|
-
for
|
29
|
-
cArr[
|
23
|
+
cArr: list[str | int] = [0] * 64
|
24
|
+
for num in range(26):
|
25
|
+
cArr[num] = chr(num + 65)
|
26
|
+
for num_2 in range(26, 52):
|
27
|
+
cArr[num_2] = chr(num_2 - 26 + 97)
|
28
|
+
for num_3 in range(52, 62):
|
29
|
+
cArr[num_3] = chr(num_3 - 52 + 48)
|
30
30
|
cArr[62] = "+"
|
31
31
|
cArr[63] = "/"
|
32
32
|
DatatypeConverter.encode_map = cArr
|
@@ -45,7 +45,7 @@ class DatatypeConverter:
|
|
45
45
|
return DatatypeConverter.encode_map[i & 63]
|
46
46
|
|
47
47
|
@staticmethod
|
48
|
-
def _printBase64Binary(bArr, i=0, i2=None):
|
48
|
+
def _printBase64Binary(bArr: bytes, i: int = 0, i2=None):
|
49
49
|
"""Print the Base64 binary representation of a byte array.
|
50
50
|
|
51
51
|
This function takes a byte array and optional start and end indices to
|
@@ -68,7 +68,7 @@ class DatatypeConverter:
|
|
68
68
|
return "".join(cArr)
|
69
69
|
|
70
70
|
@staticmethod
|
71
|
-
def _printBase64Binary_core(bArr, i, i2, cArr, i3):
|
71
|
+
def _printBase64Binary_core(bArr: bytes, i, i2, cArr, i3):
|
72
72
|
"""Encode binary data into Base64 format.
|
73
73
|
|
74
74
|
This function encodes binary data into Base64 format following the
|
@@ -11,12 +11,12 @@ class DeviceType(Enum):
|
|
11
11
|
YUKA_MINI2 = (5, "Yuka-YM", "Yuka Mini 2")
|
12
12
|
LUBA_VP = (6, "Luba-VP", "Luba VP")
|
13
13
|
|
14
|
-
def __init__(self, value: int, name: str, model: str):
|
14
|
+
def __init__(self, value: int, name: str, model: str) -> None:
|
15
15
|
self._value = value
|
16
16
|
self._name = name
|
17
17
|
self._model = model
|
18
18
|
|
19
|
-
def get_name(self):
|
19
|
+
def get_name(self) -> str:
|
20
20
|
return self._name
|
21
21
|
|
22
22
|
def get_model(self):
|
@@ -28,7 +28,7 @@ class DeviceType(Enum):
|
|
28
28
|
def get_value_str(self):
|
29
29
|
return str(self._value)
|
30
30
|
|
31
|
-
def set_value(self, value):
|
31
|
+
def set_value(self, value) -> None:
|
32
32
|
self._value = value
|
33
33
|
|
34
34
|
@staticmethod
|
@@ -54,11 +54,15 @@ class DeviceType(Enum):
|
|
54
54
|
return DeviceType.LUBA_2
|
55
55
|
elif value == 3:
|
56
56
|
return DeviceType.LUBA_YUKA
|
57
|
+
elif value == 4:
|
58
|
+
return DeviceType.YUKA_MINI
|
59
|
+
elif value == 5:
|
60
|
+
return DeviceType.YUKA_MINI2
|
57
61
|
else:
|
58
62
|
return DeviceType.UNKNOWN
|
59
63
|
|
60
64
|
@staticmethod
|
61
|
-
def value_of_str(device_name, product_key=""):
|
65
|
+
def value_of_str(device_name: str, product_key: str = ""):
|
62
66
|
"""Determine the type of device based on the provided device name and
|
63
67
|
product key.
|
64
68
|
|
@@ -78,21 +82,26 @@ class DeviceType(Enum):
|
|
78
82
|
substring = device_name[:3]
|
79
83
|
substring2 = device_name[:7]
|
80
84
|
|
81
|
-
if DeviceType.RTK.
|
85
|
+
if DeviceType.RTK.get_name() in substring or DeviceType.contain_rtk_product_key(product_key):
|
82
86
|
return DeviceType.RTK
|
83
|
-
elif DeviceType.LUBA_2.
|
87
|
+
elif DeviceType.LUBA_2.get_name() in substring2 or DeviceType.contain_luba_2_product_key(product_key):
|
84
88
|
return DeviceType.LUBA_2
|
85
|
-
elif DeviceType.LUBA_YUKA.
|
89
|
+
elif DeviceType.LUBA_YUKA.get_name() in substring2:
|
86
90
|
return DeviceType.LUBA_YUKA
|
87
|
-
elif DeviceType.
|
91
|
+
elif DeviceType.YUKA_MINI.get_name() in substring2:
|
92
|
+
return DeviceType.YUKA_MINI
|
93
|
+
elif DeviceType.YUKA_MINI2.get_name() in substring2:
|
94
|
+
return DeviceType.YUKA_MINI2
|
95
|
+
elif DeviceType.LUBA.get_name() in substring2 or DeviceType.contain_luba_product_key(product_key):
|
88
96
|
return DeviceType.LUBA
|
89
97
|
else:
|
98
|
+
print("unknown device type")
|
90
99
|
return DeviceType.UNKNOWN
|
91
100
|
except Exception:
|
92
101
|
return DeviceType.UNKNOWN
|
93
102
|
|
94
103
|
@staticmethod
|
95
|
-
def has_4g(device_name, product_key=""):
|
104
|
+
def has_4g(device_name: str, product_key: str = ""):
|
96
105
|
"""Check if the device has 4G capability based on the device name and
|
97
106
|
optional product key.
|
98
107
|
|
@@ -117,7 +126,7 @@ class DeviceType(Enum):
|
|
117
126
|
return device_type.get_value() >= DeviceType.LUBA_2.get_value()
|
118
127
|
|
119
128
|
@staticmethod
|
120
|
-
def is_luba1(device_name, product_key=""):
|
129
|
+
def is_luba1(device_name: str, product_key: str = ""):
|
121
130
|
"""Check if the given device is of type LUBA.
|
122
131
|
|
123
132
|
This function determines if the device specified by 'device_name' is of
|
@@ -141,7 +150,7 @@ class DeviceType(Enum):
|
|
141
150
|
return device_type.get_value() == DeviceType.LUBA.get_value()
|
142
151
|
|
143
152
|
@staticmethod
|
144
|
-
def is_luba_2(device_name, product_key=""):
|
153
|
+
def is_luba_2(device_name: str, product_key: str = ""):
|
145
154
|
"""Check if the device type is LUBA 2 or higher based on the device name
|
146
155
|
and optional product key.
|
147
156
|
|
@@ -162,7 +171,7 @@ class DeviceType(Enum):
|
|
162
171
|
return device_type.get_value() >= DeviceType.LUBA_2.get_value()
|
163
172
|
|
164
173
|
@staticmethod
|
165
|
-
def is_yuka(device_name):
|
174
|
+
def is_yuka(device_name: str):
|
166
175
|
"""Check if the given device name corresponds to a LUBA_YUKA device type.
|
167
176
|
|
168
177
|
Args:
|
@@ -173,10 +182,14 @@ class DeviceType(Enum):
|
|
173
182
|
|
174
183
|
"""
|
175
184
|
|
176
|
-
return
|
185
|
+
return (
|
186
|
+
DeviceType.value_of_str(device_name).get_value() == DeviceType.LUBA_YUKA.get_value()
|
187
|
+
or DeviceType.value_of_str(device_name).get_value() == DeviceType.YUKA_MINI.get_value()
|
188
|
+
or DeviceType.value_of_str(device_name).get_value() == DeviceType.YUKA_MINI2.get_value()
|
189
|
+
)
|
177
190
|
|
178
191
|
@staticmethod
|
179
|
-
def is_rtk(device_name, product_key=""):
|
192
|
+
def is_rtk(device_name: str, product_key: str = ""):
|
180
193
|
"""Check if the device type is within the range of RTK devices.
|
181
194
|
|
182
195
|
This function determines if the device type corresponding to the given
|
@@ -200,7 +213,7 @@ class DeviceType(Enum):
|
|
200
213
|
return DeviceType.RTK.get_value() <= device_type.get_value() < DeviceType.LUBA.get_value()
|
201
214
|
|
202
215
|
@staticmethod
|
203
|
-
def contain_rtk_product_key(product_key):
|
216
|
+
def contain_rtk_product_key(product_key) -> bool:
|
204
217
|
"""Check if the given product key is in a predefined list of RTK product
|
205
218
|
keys.
|
206
219
|
|
@@ -217,7 +230,7 @@ class DeviceType(Enum):
|
|
217
230
|
return product_key in ["a1qXkZ5P39W", "a1Nc68bGZzX"]
|
218
231
|
|
219
232
|
@staticmethod
|
220
|
-
def contain_luba_product_key(product_key):
|
233
|
+
def contain_luba_product_key(product_key) -> bool:
|
221
234
|
"""Check if the given product key is in the list of valid product keys.
|
222
235
|
|
223
236
|
Args:
|
@@ -245,7 +258,7 @@ class DeviceType(Enum):
|
|
245
258
|
]
|
246
259
|
|
247
260
|
@staticmethod
|
248
|
-
def contain_luba_2_product_key(product_key):
|
261
|
+
def contain_luba_2_product_key(product_key) -> bool:
|
249
262
|
"""Check if the given product key is present in a predefined list.
|
250
263
|
|
251
264
|
Args:
|
@@ -260,5 +273,21 @@ class DeviceType(Enum):
|
|
260
273
|
return False
|
261
274
|
return product_key in ["a1iMygIwxFC", "a1LLmy1zc0j", "a1LLmy1zc0j"]
|
262
275
|
|
276
|
+
@staticmethod
|
277
|
+
def contain_yuka_product_key(product_key) -> bool:
|
278
|
+
"""Check if the given product key is present in a predefined list.
|
279
|
+
|
280
|
+
Args:
|
281
|
+
product_key (str): The product key to be checked.
|
282
|
+
|
283
|
+
Returns:
|
284
|
+
bool: True if the product key is in the predefined list, False otherwise.
|
285
|
+
|
286
|
+
"""
|
287
|
+
|
288
|
+
if not product_key:
|
289
|
+
return False
|
290
|
+
return product_key in ["a1IQV0BrnXb"]
|
291
|
+
|
263
292
|
def is_support_video(self):
|
264
|
-
return self
|
293
|
+
return self != DeviceType.LUBA
|
pymammotion/utility/map.py
CHANGED
@@ -6,7 +6,7 @@ from pymammotion.data.model.location import Point
|
|
6
6
|
|
7
7
|
|
8
8
|
class CoordinateConverter:
|
9
|
-
def __init__(self, latitude_rad: float, longitude_rad: float):
|
9
|
+
def __init__(self, latitude_rad: float, longitude_rad: float) -> None:
|
10
10
|
# Initialize constants
|
11
11
|
self.WGS84A = 6378137.0
|
12
12
|
self.f_ = 3.3528106647474805e-21
|
@@ -26,7 +26,7 @@ class CoordinateConverter:
|
|
26
26
|
# Call set_init_lla with provided lat/lon
|
27
27
|
self.set_init_lla(latitude_rad, longitude_rad)
|
28
28
|
|
29
|
-
def set_init_lla(self, lat_rad, lon_rad):
|
29
|
+
def set_init_lla(self, lat_rad, lon_rad) -> None:
|
30
30
|
sin_lat = math.sin(lat_rad)
|
31
31
|
cos_lat = math.cos(lat_rad)
|
32
32
|
sin_lon = math.sin(lon_rad)
|
pymammotion/utility/movement.py
CHANGED
@@ -10,8 +10,9 @@ def transform_both_speeds(linear: float, angular: float, linear_percent: float,
|
|
10
10
|
angular_speed = int(transform4[1] * 4.5)
|
11
11
|
return linear_speed, angular_speed
|
12
12
|
|
13
|
+
|
13
14
|
def get_percent(percent: float):
|
14
15
|
if percent <= 15.0:
|
15
16
|
return 0.0
|
16
17
|
|
17
|
-
return percent - 15.0
|
18
|
+
return percent - 15.0
|
pymammotion/utility/periodic.py
CHANGED
@@ -3,13 +3,13 @@ from contextlib import suppress
|
|
3
3
|
|
4
4
|
|
5
5
|
class Periodic:
|
6
|
-
def __init__(self, func, time):
|
6
|
+
def __init__(self, func, time) -> None:
|
7
7
|
self.func = func
|
8
8
|
self.time = time
|
9
9
|
self.is_started = False
|
10
10
|
self._task = None
|
11
11
|
|
12
|
-
def start(self):
|
12
|
+
def start(self) -> None:
|
13
13
|
"""Start the task if it is not already started.
|
14
14
|
|
15
15
|
If the task is not already started, it sets the 'is_started' flag to
|
@@ -21,7 +21,7 @@ class Periodic:
|
|
21
21
|
# Start task to call func periodically:
|
22
22
|
self._task = asyncio.ensure_future(self._run())
|
23
23
|
|
24
|
-
async def stop(self):
|
24
|
+
async def stop(self) -> None:
|
25
25
|
"""Stop the task if it is currently running.
|
26
26
|
|
27
27
|
If the task is currently running, it will be cancelled and awaited until
|
@@ -35,7 +35,7 @@ class Periodic:
|
|
35
35
|
with suppress(asyncio.CancelledError):
|
36
36
|
await self._task
|
37
37
|
|
38
|
-
async def _run(self):
|
38
|
+
async def _run(self) -> None:
|
39
39
|
"""Run the specified function at regular intervals using asyncio.
|
40
40
|
|
41
41
|
This method runs the specified function at regular intervals based on
|
@@ -84,7 +84,7 @@ def periodic(period):
|
|
84
84
|
|
85
85
|
"""
|
86
86
|
|
87
|
-
async def wrapper(*args, **kwargs):
|
87
|
+
async def wrapper(*args, **kwargs) -> None:
|
88
88
|
"""Execute the given function periodically using asyncio tasks.
|
89
89
|
|
90
90
|
This function continuously creates an asyncio task to execute the
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pymammotion
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.30
|
4
4
|
Summary:
|
5
5
|
License: GNU-3.0
|
6
6
|
Author: Michael Arthur
|
@@ -18,11 +18,13 @@ Requires-Dist: alicloud-gateway-iot (>=1.0.0,<2.0.0)
|
|
18
18
|
Requires-Dist: aliyun-iot-linkkit (>=1.2.12,<2.0.0)
|
19
19
|
Requires-Dist: aliyun-python-sdk-iot (>=8.57.0,<9.0.0)
|
20
20
|
Requires-Dist: async-timeout (>=4.0.3,<5.0.0)
|
21
|
+
Requires-Dist: autotyping (>=24.3.0,<25.0.0)
|
21
22
|
Requires-Dist: betterproto (>=1.2.5,<2.0.0)
|
22
23
|
Requires-Dist: bleak (>=0.21.0)
|
23
24
|
Requires-Dist: bleak-retry-connector (>=3.5.0,<4.0.0)
|
24
25
|
Requires-Dist: jsonic (>=1.0.0,<2.0.0)
|
25
26
|
Requires-Dist: mashumaro (>=3.13,<4.0)
|
27
|
+
Requires-Dist: mypy (>=1.11.2,<2.0.0)
|
26
28
|
Requires-Dist: nest-asyncio (>=1.6.0,<2.0.0)
|
27
29
|
Requires-Dist: numpy (>=1.26.0,<2.0.0)
|
28
30
|
Requires-Dist: orjson (>=3.9.15,<4.0.0)
|
@@ -1,68 +1,72 @@
|
|
1
|
-
pymammotion/__init__.py,sha256=
|
1
|
+
pymammotion/__init__.py,sha256=jHCQrpJaG1jAoID9T4RT3g4JsZc0JpJqIcqjnA7cXd0,1605
|
2
2
|
pymammotion/aliyun/__init__.py,sha256=T1lkX7TRYiL4nqYanG4l4MImV-SlavSbuooC-W-uUGw,29
|
3
|
-
pymammotion/aliyun/cloud_gateway.py,sha256=
|
4
|
-
pymammotion/aliyun/cloud_service.py,sha256=
|
3
|
+
pymammotion/aliyun/cloud_gateway.py,sha256=d2A4F-bCZD4Oz4wdBdyFBKBvFf1GZxCKvFRcDDpczRs,22686
|
4
|
+
pymammotion/aliyun/cloud_service.py,sha256=px7dUKow5Z7VyebjYzuKkzkm77XbUXYiFiYO_2e-UQ0,2207
|
5
5
|
pymammotion/aliyun/dataclass/aep_response.py,sha256=8f6GIP58ve8gd6AL3HBoXxsy0n2q4ygWvjELGnoOnVc,452
|
6
6
|
pymammotion/aliyun/dataclass/connect_response.py,sha256=Yz-fEbDzgGPTo5Of2oAjmFkSv08T7ze80pQU4k-gKIU,824
|
7
|
-
pymammotion/aliyun/dataclass/dev_by_account_response.py,sha256=
|
7
|
+
pymammotion/aliyun/dataclass/dev_by_account_response.py,sha256=gskum11h9HPf4lKjLJKVrsxRl5BHaHJP2TPrI09SUYs,1032
|
8
8
|
pymammotion/aliyun/dataclass/login_by_oauth_response.py,sha256=IXSLZ6XnOliOnyXo5Bh0ErqFjA11puACh_9NH0sSJGQ,1262
|
9
9
|
pymammotion/aliyun/dataclass/regions_response.py,sha256=CVPpdFhDD6_emWHyLRzOdp2j3HLPtP8tlNyzGnr8AcI,690
|
10
|
-
pymammotion/aliyun/dataclass/session_by_authcode_response.py,sha256=
|
10
|
+
pymammotion/aliyun/dataclass/session_by_authcode_response.py,sha256=1K8Uu_V6flSBU8kLCh1Qj59tD9aZQSn7X3hLKeouE_g,407
|
11
11
|
pymammotion/aliyun/tmp_constant.py,sha256=M4Hq_lrGB3LZdX6R2XohRPFoK1NDnNV-pTJwJcJ9838,6650
|
12
12
|
pymammotion/bluetooth/__init__.py,sha256=LAl8jqZ1fPh-3mLmViNQsP3s814C1vsocYUa6oSaXt0,36
|
13
|
-
pymammotion/bluetooth/ble.py,sha256=
|
14
|
-
pymammotion/bluetooth/ble_message.py,sha256=
|
13
|
+
pymammotion/bluetooth/ble.py,sha256=YfkfEK3TLJ8BaidjAXfUVFv8reLCu6U_lYa3Bo0pddw,2449
|
14
|
+
pymammotion/bluetooth/ble_message.py,sha256=m-RyxHncCWrYFoeNg_G9Co5afNADZuCm32jQaqaIFc8,16211
|
15
15
|
pymammotion/bluetooth/const.py,sha256=CCqyHsYbB0BAYjwdhXt_n6eWWxmhlUrAFjvVv57mbvE,1749
|
16
16
|
pymammotion/bluetooth/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
-
pymammotion/bluetooth/data/convert.py,sha256=
|
18
|
-
pymammotion/bluetooth/data/framectrldata.py,sha256
|
19
|
-
pymammotion/bluetooth/data/notifydata.py,sha256=
|
20
|
-
pymammotion/const.py,sha256=
|
17
|
+
pymammotion/bluetooth/data/convert.py,sha256=6DMwvzVr9FWCoQFIKSI2poFXjISc_m6X59g8FlVO0-o,800
|
18
|
+
pymammotion/bluetooth/data/framectrldata.py,sha256=qxhGQsTGsfPx-CarEMLkgBn_RJ6I2-exmr9AX2U4pFg,995
|
19
|
+
pymammotion/bluetooth/data/notifydata.py,sha256=jeROpoFmaZfNTidkLLm5VYeFbeIgDSi8waJ0nVLRUTA,1995
|
20
|
+
pymammotion/const.py,sha256=lWRxvTVdXnNHuxqvRkjO5ziK0Ic-fZMM6J2dbe5M6Nc,385
|
21
21
|
pymammotion/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
-
pymammotion/data/model/__init__.py,sha256=
|
23
|
-
pymammotion/data/model/account.py,sha256=
|
24
|
-
pymammotion/data/model/device.py,sha256=
|
25
|
-
pymammotion/data/model/device_config.py,sha256=
|
26
|
-
pymammotion/data/model/enums.py,sha256=
|
27
|
-
pymammotion/data/model/excute_boarder_params.py,sha256=
|
28
|
-
pymammotion/data/model/execute_boarder.py,sha256=
|
29
|
-
pymammotion/data/model/generate_route_information.py,sha256=
|
30
|
-
pymammotion/data/model/hash_list.py,sha256
|
31
|
-
pymammotion/data/model/location.py,sha256=
|
32
|
-
pymammotion/data/model/mowing_modes.py,sha256=
|
33
|
-
pymammotion/data/model/plan.py,sha256=
|
22
|
+
pymammotion/data/model/__init__.py,sha256=aSyroxYQQS-WMRi6WmWm2js4wLa9nmsi160gx9tts4o,323
|
23
|
+
pymammotion/data/model/account.py,sha256=vJM-KTf2q6eBfVC-UlNHBSmJvqHiCawZ40vnuhXhaz8,140
|
24
|
+
pymammotion/data/model/device.py,sha256=ejIMloTHlJcBi-qNFewTDt1K0pPJYpgjtJqqqhUqR1g,11182
|
25
|
+
pymammotion/data/model/device_config.py,sha256=fsUSfYsICD7oTZm9dIaNTNSwo54A94n9VAWJcJvEz2Y,2574
|
26
|
+
pymammotion/data/model/enums.py,sha256=EpKmO8yVUZyEnTY4yH0DMMVKYNQM42zpW1maUu0i3IE,1582
|
27
|
+
pymammotion/data/model/excute_boarder_params.py,sha256=9CpUqrygcle1C_1hDW-riLmm4map4ZbE842NXjcomEI,1394
|
28
|
+
pymammotion/data/model/execute_boarder.py,sha256=9rd_h4fbcsXxgnLOd2rO2hWyD1abnTGc47QTEpp8DD0,1103
|
29
|
+
pymammotion/data/model/generate_route_information.py,sha256=MkUBoqGtCAKmiVQ4Q1pEoDVHZs5uLIo7vhfWT4nGbtY,801
|
30
|
+
pymammotion/data/model/hash_list.py,sha256=-2z_g9bhr3A7EK_J-oYrOpg6MjUnhliO__76HLUdDSo,2690
|
31
|
+
pymammotion/data/model/location.py,sha256=H1h4Rhr0z_mDplNf1CP_ZCA3zM4_FJ_nMqzkbaoh7To,787
|
32
|
+
pymammotion/data/model/mowing_modes.py,sha256=UxQrRAHQNC_lJTOA0ms2wuLAAi5UEVTkvvSZjnFpUjE,826
|
33
|
+
pymammotion/data/model/plan.py,sha256=mcadkSL7fQXy0iJ0q786I3GEQY4i6kmQXfW6Ri69lcQ,2906
|
34
34
|
pymammotion/data/model/rapid_state.py,sha256=BdJFD_DlhrVneg-PqEruqCoMty-CR7q_9Qna-hk1yd8,1171
|
35
|
-
pymammotion/data/model/region_data.py,sha256=
|
36
|
-
pymammotion/data/model/report_info.py,sha256=
|
35
|
+
pymammotion/data/model/region_data.py,sha256=FLuL6kA7lbbh_idRh1eT9EosDqh4SpAqzpqHuQRDM88,2888
|
36
|
+
pymammotion/data/model/report_info.py,sha256=gBSOmylSUdsYyIDsRms0L0nhQBx4V4LO-4tERvFpqXU,4475
|
37
37
|
pymammotion/data/mqtt/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
38
|
-
pymammotion/data/mqtt/event.py,sha256=
|
38
|
+
pymammotion/data/mqtt/event.py,sha256=omGNFYLjPKV_IY0remhEc8vcx2LkI_spZNysosPIvUM,4536
|
39
39
|
pymammotion/data/mqtt/properties.py,sha256=HkBPghr26L9_b4QaOi1DtPgb0UoPIOGSe9wb3kgnM6Y,2815
|
40
40
|
pymammotion/data/mqtt/status.py,sha256=zqnlo-MzejEQZszl0i0Wucoc3E76x6UtI9JLxoBnu54,1067
|
41
|
-
pymammotion/data/state_manager.py,sha256=
|
41
|
+
pymammotion/data/state_manager.py,sha256=OQlfLeCYFglgJZdHeqG8djaCwVDC-SqDqDeqz7Q7LR4,3171
|
42
42
|
pymammotion/event/__init__.py,sha256=mgATR6vPHACNQ-0zH5fi7NdzeTCDV1CZyaWPmtUusi8,115
|
43
|
-
pymammotion/event/event.py,sha256=
|
43
|
+
pymammotion/event/event.py,sha256=LFUhjUhlFRL2mEo1WKpn_jUJq_8K_Sw1EBWCYenWF0I,1932
|
44
44
|
pymammotion/http/_init_.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
45
|
-
pymammotion/http/http.py,sha256=
|
45
|
+
pymammotion/http/http.py,sha256=OZHjQY9ZLdlsKK6MDqqV79JIH9WYWJe3-ey-WWbe2z4,2642
|
46
|
+
pymammotion/http/model/http.py,sha256=_aVrtZZyR4EdR6GcuqMP9vH8qBLN7nKu0U2OeraCcG0,1607
|
46
47
|
pymammotion/mammotion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
48
|
pymammotion/mammotion/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
49
|
pymammotion/mammotion/commands/abstract_message.py,sha256=nw6r7694yzl7iJKqRqhLmAPRjd_TL_Xo_-JXq2_a_ug,222
|
49
50
|
pymammotion/mammotion/commands/mammotion_command.py,sha256=84XxnatnBm_5WQ_KOa2N0ltydQOhSvCme3fFqkuyEhg,1056
|
50
51
|
pymammotion/mammotion/commands/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
51
|
-
pymammotion/mammotion/commands/messages/driver.py,sha256=
|
52
|
+
pymammotion/mammotion/commands/messages/driver.py,sha256=ANIOEtjF23k7W_R_Yfgzxmc7p1KSBCF-l-tijUtw0Yg,3709
|
52
53
|
pymammotion/mammotion/commands/messages/media.py,sha256=ps0l06CXy5Ej--gTNCsyKttwo7yHLVrJUpn-wNJYecs,1150
|
53
|
-
pymammotion/mammotion/commands/messages/navigation.py,sha256
|
54
|
-
pymammotion/mammotion/commands/messages/network.py,sha256=
|
54
|
+
pymammotion/mammotion/commands/messages/navigation.py,sha256=igP_SJfZPc7g9AaqP0qqN3tgnuZiaD9nqYdJG33_JQ0,23589
|
55
|
+
pymammotion/mammotion/commands/messages/network.py,sha256=gD7NKVKg8U2KNbPvgOxvTJXbznWdpdPQo9jBsQSx4OI,8027
|
55
56
|
pymammotion/mammotion/commands/messages/ota.py,sha256=XkeuWBZtpYMMBze6r8UN7dJXbe2FxUNGNnjwBpXJKM0,1240
|
56
|
-
pymammotion/mammotion/commands/messages/system.py,sha256=
|
57
|
+
pymammotion/mammotion/commands/messages/system.py,sha256=xm9Nj3wva9leVV1tyzfS_Hf53t-j7Nk8RBlFd00CQFM,10972
|
57
58
|
pymammotion/mammotion/commands/messages/video.py,sha256=_8lJsU4sLm2CGnc7RDkueA0A51Ysui6x7SqFnhX8O2g,1007
|
58
59
|
pymammotion/mammotion/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
|
-
pymammotion/mammotion/control/joystick.py,sha256=
|
60
|
-
pymammotion/mammotion/devices/__init__.py,sha256=
|
61
|
-
pymammotion/mammotion/devices/
|
60
|
+
pymammotion/mammotion/control/joystick.py,sha256=QfBVxM_gxpWsZAGO90whtgxCI2tIZ3TTad9wHIPsU9s,5640
|
61
|
+
pymammotion/mammotion/devices/__init__.py,sha256=f2qQFPgLGmV85W2hSlMUh5BYuht9o_Ar_JEAAMD4fsE,102
|
62
|
+
pymammotion/mammotion/devices/base.py,sha256=p_YUOolzcEvJGtyPPileAvc5jwYmTtEh0TsIG1LpvQ8,10692
|
63
|
+
pymammotion/mammotion/devices/mammotion.py,sha256=am2Rpsi1SdOaABrKC3ONBkQh17gfFcWTKAmV5mZsKK8,9301
|
64
|
+
pymammotion/mammotion/devices/mammotion_bluetooth.py,sha256=3XUjhE2sb_2aZnJlevmwxd99zR_4qZOfaK86h6hKV5E,17303
|
65
|
+
pymammotion/mammotion/devices/mammotion_cloud.py,sha256=O42-jloP-emGBErgOyRCZHtqt_FntCgcqOvMoieJWI4,9791
|
62
66
|
pymammotion/mqtt/__init__.py,sha256=Ocs5e-HLJvTuDpVXyECEsWIvwsUaxzj7lZ9mSYutNDY,105
|
63
|
-
pymammotion/mqtt/mammotion_future.py,sha256=
|
64
|
-
pymammotion/mqtt/mammotion_mqtt.py,sha256=
|
65
|
-
pymammotion/proto/__init__.py,sha256=
|
67
|
+
pymammotion/mqtt/mammotion_future.py,sha256=_OWqKOlUGl2yT1xOsXFQYpGd-1zQ63OxqXgy7KRQgYc,710
|
68
|
+
pymammotion/mqtt/mammotion_mqtt.py,sha256=pugfSXAEwrA-jPzUgBH5QvoON_B1iE6_Ouib8pLi_so,8301
|
69
|
+
pymammotion/proto/__init__.py,sha256=v3_P1LOsYRBN9qCAhaWrWMX7GWHrox9XD3hdZQxcPZM,190
|
66
70
|
pymammotion/proto/basestation.proto,sha256=_x5gAz3FkZXS1jtq4GgZgaDCuRU-UV-7HTFdsfQ3zbo,1034
|
67
71
|
pymammotion/proto/basestation.py,sha256=js64_N2xQYRxWPRdVNEapO0qe7vBlfYnjW5sE8hi7hw,2026
|
68
72
|
pymammotion/proto/basestation_pb2.py,sha256=PTVlHcDLQeRV6qv7ZPjGke9MF68mpqoUeJA0Sw_AoT0,2776
|
@@ -104,16 +108,16 @@ pymammotion/proto/mctrl_sys.py,sha256=GVciaKPcp4h1qrIILHX_Pd76tKSBFlaEvFPF7FZsj8
|
|
104
108
|
pymammotion/proto/mctrl_sys_pb2.py,sha256=DYemb514mlC7c27t-k1YqqBif0xxhLmnIWk8rXtSj1c,21497
|
105
109
|
pymammotion/proto/mctrl_sys_pb2.pyi,sha256=Dj_1UM86kZ5MfcVyNC76Z0gKrfl5YFsVWP2b-bKoZvk,38912
|
106
110
|
pymammotion/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
107
|
-
pymammotion/utility/constant/__init__.py,sha256=
|
111
|
+
pymammotion/utility/constant/__init__.py,sha256=tcY0LDeD-qDDHx2LKt55KOyv9ZI0UfCNM6fknLCmm8s,110
|
108
112
|
pymammotion/utility/constant/device_constant.py,sha256=rAEK60F52VyJL31uLnq0Y60D-0VK5gVm59yi9kBfndM,7123
|
109
|
-
pymammotion/utility/conversions.py,sha256=
|
110
|
-
pymammotion/utility/datatype_converter.py,sha256=
|
111
|
-
pymammotion/utility/device_type.py,sha256=
|
112
|
-
pymammotion/utility/map.py,sha256=
|
113
|
-
pymammotion/utility/movement.py,sha256=
|
114
|
-
pymammotion/utility/periodic.py,sha256=
|
115
|
-
pymammotion/utility/rocker_util.py,sha256=
|
116
|
-
pymammotion-0.2.
|
117
|
-
pymammotion-0.2.
|
118
|
-
pymammotion-0.2.
|
119
|
-
pymammotion-0.2.
|
113
|
+
pymammotion/utility/conversions.py,sha256=v3YICy0zZwwBBzrUZgabI7GRfiDBnkiAX2qdtk3NxOY,89
|
114
|
+
pymammotion/utility/datatype_converter.py,sha256=SPM_HuaaD_XOawlqEnA8qlRRZXGba3WjA8kGOZgeBlQ,4284
|
115
|
+
pymammotion/utility/device_type.py,sha256=6Mmv8oJoJ0DQrfGhRGt3rg20f_GLwIRw4NtpAdF6wcE,9478
|
116
|
+
pymammotion/utility/map.py,sha256=GYscVMg2cX3IPlNpCBNHDW0S55yS1WGRf1iHnNZ7TfQ,2227
|
117
|
+
pymammotion/utility/movement.py,sha256=N75oAoAgFydqoaOedYIxGUHmuTCtPzAOtb-d_29tpfI,615
|
118
|
+
pymammotion/utility/periodic.py,sha256=MbeSb9cfhxzYmdT_RiE0dZe3H9IfbQW_zSqhmSX2RUc,3321
|
119
|
+
pymammotion/utility/rocker_util.py,sha256=6tX7sS87qoQC_tsxbx3NLL-HgS08wtzXiZkhDiz7uo0,7179
|
120
|
+
pymammotion-0.2.30.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
121
|
+
pymammotion-0.2.30.dist-info/METADATA,sha256=KOkVJ470-8fRi2_lwz9GDVJ7clwXavwOYcin6s30NaM,4052
|
122
|
+
pymammotion-0.2.30.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
123
|
+
pymammotion-0.2.30.dist-info/RECORD,,
|
File without changes
|
File without changes
|