pymammotion 0.2.98__py3-none-any.whl → 0.3.0__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/aliyun/cloud_gateway.py +2 -2
- pymammotion/bluetooth/ble_message.py +335 -46
- pymammotion/bluetooth/model/__init__.py +0 -0
- pymammotion/bluetooth/model/atomic_integer.py +54 -0
- pymammotion/data/model/mowing_modes.py +7 -0
- pymammotion/data/model/report_info.py +7 -0
- pymammotion/mammotion/commands/messages/system.py +9 -0
- pymammotion/mammotion/devices/base.py +14 -1
- {pymammotion-0.2.98.dist-info → pymammotion-0.3.0.dist-info}/METADATA +1 -1
- {pymammotion-0.2.98.dist-info → pymammotion-0.3.0.dist-info}/RECORD +12 -10
- {pymammotion-0.2.98.dist-info → pymammotion-0.3.0.dist-info}/LICENSE +0 -0
- {pymammotion-0.2.98.dist-info → pymammotion-0.3.0.dist-info}/WHEEL +0 -0
@@ -478,7 +478,7 @@ class CloudIOTGateway:
|
|
478
478
|
|
479
479
|
def check_or_refresh_session(self):
|
480
480
|
"""Check or refresh the session."""
|
481
|
-
logger.debug("
|
481
|
+
logger.debug("Trying to refresh token")
|
482
482
|
config = Config(
|
483
483
|
app_key=self._app_key,
|
484
484
|
app_secret=self._app_secret,
|
@@ -684,7 +684,7 @@ class CloudIOTGateway:
|
|
684
684
|
logger.error(
|
685
685
|
"Error in sending cloud command: %s - %s",
|
686
686
|
str(response_body_dict.get("code")),
|
687
|
-
str(response_body_dict.get("
|
687
|
+
str(response_body_dict.get("message")),
|
688
688
|
)
|
689
689
|
if response_body_dict.get("code") == 29003:
|
690
690
|
logger.debug(self._session_by_authcode_response.data.identityId)
|
@@ -6,6 +6,7 @@ import sys
|
|
6
6
|
import time
|
7
7
|
from asyncio import sleep
|
8
8
|
from io import BytesIO
|
9
|
+
from typing import Union
|
9
10
|
|
10
11
|
from bleak import BleakClient
|
11
12
|
from jsonic.serializable import serialize
|
@@ -14,6 +15,7 @@ from pymammotion.aliyun.tmp_constant import tmp_constant
|
|
14
15
|
from pymammotion.bluetooth.const import UUID_WRITE_CHARACTERISTIC
|
15
16
|
from pymammotion.bluetooth.data.framectrldata import FrameCtrlData
|
16
17
|
from pymammotion.bluetooth.data.notifydata import BlufiNotifyData
|
18
|
+
from pymammotion.bluetooth.model.atomic_integer import AtomicInteger
|
17
19
|
from pymammotion.data.model.execute_boarder import ExecuteBorder
|
18
20
|
from pymammotion.proto import (
|
19
21
|
dev_net_pb2,
|
@@ -23,6 +25,265 @@ from pymammotion.utility.constant.device_constant import bleOrderCmd
|
|
23
25
|
|
24
26
|
_LOGGER = logging.getLogger(__name__)
|
25
27
|
|
28
|
+
CRC_TB = [
|
29
|
+
0x0000,
|
30
|
+
0x1021,
|
31
|
+
0x2042,
|
32
|
+
0x3063,
|
33
|
+
0x4084,
|
34
|
+
0x50A5,
|
35
|
+
0x60C6,
|
36
|
+
0x70E7,
|
37
|
+
0x8108,
|
38
|
+
0x9129,
|
39
|
+
0xA14A,
|
40
|
+
0xB16B,
|
41
|
+
0xC18C,
|
42
|
+
0xD1AD,
|
43
|
+
0xE1CE,
|
44
|
+
0xF1EF,
|
45
|
+
0x1231,
|
46
|
+
0x0210,
|
47
|
+
0x3273,
|
48
|
+
0x2252,
|
49
|
+
0x52B5,
|
50
|
+
0x4294,
|
51
|
+
0x72F7,
|
52
|
+
0x62D6,
|
53
|
+
0x9339,
|
54
|
+
0x8318,
|
55
|
+
0xB37B,
|
56
|
+
0xA35A,
|
57
|
+
0xD3BD,
|
58
|
+
0xC39C,
|
59
|
+
0xF3FF,
|
60
|
+
0xE3DE,
|
61
|
+
0x2462,
|
62
|
+
0x3443,
|
63
|
+
0x0420,
|
64
|
+
0x1401,
|
65
|
+
0x64E6,
|
66
|
+
0x74C7,
|
67
|
+
0x44A4,
|
68
|
+
0x5485,
|
69
|
+
0xA56A,
|
70
|
+
0xB54B,
|
71
|
+
0x8528,
|
72
|
+
0x9509,
|
73
|
+
0xE5EE,
|
74
|
+
0xF5CF,
|
75
|
+
0xC5AC,
|
76
|
+
0xD58D,
|
77
|
+
0x3653,
|
78
|
+
0x2672,
|
79
|
+
0x1611,
|
80
|
+
0x0630,
|
81
|
+
0x76D7,
|
82
|
+
0x66F6,
|
83
|
+
0x5695,
|
84
|
+
0x46B4,
|
85
|
+
0xB75B,
|
86
|
+
0xA77A,
|
87
|
+
0x9719,
|
88
|
+
0x8738,
|
89
|
+
0xF7DF,
|
90
|
+
0xE7FE,
|
91
|
+
0xD79D,
|
92
|
+
0xC7BC,
|
93
|
+
0x48C4,
|
94
|
+
0x58E5,
|
95
|
+
0x6886,
|
96
|
+
0x78A7,
|
97
|
+
0x0840,
|
98
|
+
0x1861,
|
99
|
+
0x2802,
|
100
|
+
0x3823,
|
101
|
+
0xC9CC,
|
102
|
+
0xD9ED,
|
103
|
+
0xE98E,
|
104
|
+
0xF9AF,
|
105
|
+
0x8948,
|
106
|
+
0x9969,
|
107
|
+
0xA90A,
|
108
|
+
0xB92B,
|
109
|
+
0x5AF5,
|
110
|
+
0x4AD4,
|
111
|
+
0x7AB7,
|
112
|
+
0x6A96,
|
113
|
+
0x1A71,
|
114
|
+
0x0A50,
|
115
|
+
0x3A33,
|
116
|
+
0x2A12,
|
117
|
+
0xDBFD,
|
118
|
+
0xCBDC,
|
119
|
+
0xFBBF,
|
120
|
+
0xEB9E,
|
121
|
+
0x9B79,
|
122
|
+
0x8B58,
|
123
|
+
0xBB3B,
|
124
|
+
0xAB1A,
|
125
|
+
0x6CA6,
|
126
|
+
0x7C87,
|
127
|
+
0x4CE4,
|
128
|
+
0x5CC5,
|
129
|
+
0x2C22,
|
130
|
+
0x3C03,
|
131
|
+
0x0C60,
|
132
|
+
0x1C41,
|
133
|
+
0xEDAE,
|
134
|
+
0xFD8F,
|
135
|
+
0xCDEC,
|
136
|
+
0xDDCD,
|
137
|
+
0xAD2A,
|
138
|
+
0xBD0B,
|
139
|
+
0x8D68,
|
140
|
+
0x9D49,
|
141
|
+
0x7E97,
|
142
|
+
0x6EB6,
|
143
|
+
0x5ED5,
|
144
|
+
0x4EF4,
|
145
|
+
0x3E13,
|
146
|
+
0x2E32,
|
147
|
+
0x1E51,
|
148
|
+
0x0E70,
|
149
|
+
0xFF9F,
|
150
|
+
0xEFBE,
|
151
|
+
0xDFDD,
|
152
|
+
0xCFFC,
|
153
|
+
0xBF1B,
|
154
|
+
0xAF3A,
|
155
|
+
0x9F59,
|
156
|
+
0x8F78,
|
157
|
+
0x9188,
|
158
|
+
0x81A9,
|
159
|
+
0xB1CA,
|
160
|
+
0xA1EB,
|
161
|
+
0xD10C,
|
162
|
+
0xC12D,
|
163
|
+
0xF14E,
|
164
|
+
0xE16F,
|
165
|
+
0x1080,
|
166
|
+
0x00A1,
|
167
|
+
0x30C2,
|
168
|
+
0x20E3,
|
169
|
+
0x5004,
|
170
|
+
0x4025,
|
171
|
+
0x7046,
|
172
|
+
0x6067,
|
173
|
+
0x83B9,
|
174
|
+
0x9398,
|
175
|
+
0xA3FB,
|
176
|
+
0xB3DA,
|
177
|
+
0xC33D,
|
178
|
+
0xD31C,
|
179
|
+
0xE37F,
|
180
|
+
0xF35E,
|
181
|
+
0x02B1,
|
182
|
+
0x1290,
|
183
|
+
0x22F3,
|
184
|
+
0x32D2,
|
185
|
+
0x4235,
|
186
|
+
0x5214,
|
187
|
+
0x6277,
|
188
|
+
0x7256,
|
189
|
+
0xB5EA,
|
190
|
+
0xA5CB,
|
191
|
+
0x95A8,
|
192
|
+
0x8589,
|
193
|
+
0xF56E,
|
194
|
+
0xE54F,
|
195
|
+
0xD52C,
|
196
|
+
0xC50D,
|
197
|
+
0x34E2,
|
198
|
+
0x24C3,
|
199
|
+
0x14A0,
|
200
|
+
0x0481,
|
201
|
+
0x7466,
|
202
|
+
0x6447,
|
203
|
+
0x5424,
|
204
|
+
0x4405,
|
205
|
+
0xA7DB,
|
206
|
+
0xB7FA,
|
207
|
+
0x8799,
|
208
|
+
0x97B8,
|
209
|
+
0xE75F,
|
210
|
+
0xF77E,
|
211
|
+
0xC71D,
|
212
|
+
0xD73C,
|
213
|
+
0x26D3,
|
214
|
+
0x36F2,
|
215
|
+
0x0691,
|
216
|
+
0x16B0,
|
217
|
+
0x6657,
|
218
|
+
0x7676,
|
219
|
+
0x4615,
|
220
|
+
0x5634,
|
221
|
+
0xD94C,
|
222
|
+
0xC96D,
|
223
|
+
0xF90E,
|
224
|
+
0xE92F,
|
225
|
+
0x99C8,
|
226
|
+
0x89E9,
|
227
|
+
0xB98A,
|
228
|
+
0xA9AB,
|
229
|
+
0x5844,
|
230
|
+
0x4865,
|
231
|
+
0x7806,
|
232
|
+
0x6827,
|
233
|
+
0x18C0,
|
234
|
+
0x08E1,
|
235
|
+
0x3882,
|
236
|
+
0x28A3,
|
237
|
+
0xCB7D,
|
238
|
+
0xDB5C,
|
239
|
+
0xEB3F,
|
240
|
+
0xFB1E,
|
241
|
+
0x8BF9,
|
242
|
+
0x9BD8,
|
243
|
+
0xABBB,
|
244
|
+
0xBB9A,
|
245
|
+
0x4A75,
|
246
|
+
0x5A54,
|
247
|
+
0x6A37,
|
248
|
+
0x7A16,
|
249
|
+
0x0AF1,
|
250
|
+
0x1AD0,
|
251
|
+
0x2AB3,
|
252
|
+
0x3A92,
|
253
|
+
0xFD2E,
|
254
|
+
0xED0F,
|
255
|
+
0xDD6C,
|
256
|
+
0xCD4D,
|
257
|
+
0xBDAA,
|
258
|
+
0xAD8B,
|
259
|
+
0x9DE8,
|
260
|
+
0x8DC9,
|
261
|
+
0x7C26,
|
262
|
+
0x6C07,
|
263
|
+
0x5C64,
|
264
|
+
0x4C45,
|
265
|
+
0x3CA2,
|
266
|
+
0x2C83,
|
267
|
+
0x1CE0,
|
268
|
+
0x0CC1,
|
269
|
+
0xEF1F,
|
270
|
+
0xFF3E,
|
271
|
+
0xCF5D,
|
272
|
+
0xDF7C,
|
273
|
+
0xAF9B,
|
274
|
+
0xBFBA,
|
275
|
+
0x8FD9,
|
276
|
+
0x9FF8,
|
277
|
+
0x6E17,
|
278
|
+
0x7E36,
|
279
|
+
0x4E55,
|
280
|
+
0x5E74,
|
281
|
+
0x2E93,
|
282
|
+
0x3EB2,
|
283
|
+
0x0ED1,
|
284
|
+
0x1EF0,
|
285
|
+
]
|
286
|
+
|
26
287
|
|
27
288
|
class BleMessage:
|
28
289
|
"""Class for sending and recieving messages from Luba"""
|
@@ -43,15 +304,11 @@ class BleMessage:
|
|
43
304
|
mChecksum = False
|
44
305
|
mRequireAck = False
|
45
306
|
mConnectState = 0
|
46
|
-
mSendSequence: iter
|
47
|
-
mReadSequence: iter
|
48
|
-
mAck: queue
|
49
|
-
notification: BlufiNotifyData
|
50
307
|
|
51
308
|
def __init__(self, client: BleakClient) -> None:
|
52
309
|
self.client = client
|
53
|
-
self.mSendSequence =
|
54
|
-
self.mReadSequence =
|
310
|
+
self.mSendSequence = AtomicInteger(-1)
|
311
|
+
self.mReadSequence = AtomicInteger(-1)
|
55
312
|
self.mAck = queue.Queue()
|
56
313
|
self.notification = BlufiNotifyData()
|
57
314
|
|
@@ -131,7 +388,7 @@ class BleMessage:
|
|
131
388
|
await self.client.write_gatt_char(UUID_WRITE_CHARACTERISTIC, data, True)
|
132
389
|
|
133
390
|
def parseNotification(self, response: bytearray):
|
134
|
-
|
391
|
+
"""Parse notification data from BLE device."""
|
135
392
|
if response is None:
|
136
393
|
# Log.w(TAG, "parseNotification null data");
|
137
394
|
return -1
|
@@ -144,17 +401,20 @@ class BleMessage:
|
|
144
401
|
return -2
|
145
402
|
|
146
403
|
sequence = int(response[2]) # toInt
|
404
|
+
current_sequence = self.mReadSequence.get() & 255
|
405
|
+
if sequence == current_sequence:
|
406
|
+
_LOGGER.debug(f"Received bluetooth data 1: {response.hex()}, object: {self}")
|
407
|
+
return 2
|
147
408
|
|
148
409
|
# Compare with the second counter, mod 255
|
149
|
-
if sequence != (
|
410
|
+
if sequence != (self.mReadSequence.increment_and_get() & 255):
|
150
411
|
_LOGGER.debug(
|
151
412
|
"parseNotification read sequence wrong %s %s",
|
152
413
|
sequence,
|
153
|
-
self.mReadSequence,
|
414
|
+
self.mReadSequence.get(),
|
154
415
|
)
|
155
|
-
|
156
416
|
# Set the value for mReadSequence manually
|
157
|
-
self.mReadSequence
|
417
|
+
self.mReadSequence.set(sequence)
|
158
418
|
|
159
419
|
# LogUtil.m7773e(self.mGatt.getDevice().getName() + "打印丢包率", self.mReadSequence_2 + "/" + self.mReadSequence_1);
|
160
420
|
pkt_type = int(response[0]) # toInt
|
@@ -180,36 +440,27 @@ class BleMessage:
|
|
180
440
|
# dataBytes = aes.decrypt(dataBytes);
|
181
441
|
# }
|
182
442
|
if frameCtrlData.isChecksum():
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
if frameCtrlData.hasFrag():
|
200
|
-
dataOffset = 2
|
201
|
-
else:
|
202
|
-
dataOffset = 0
|
203
|
-
|
204
|
-
self.notification.addData(dataBytes, dataOffset)
|
443
|
+
respChecksum1 = int(response[-1])
|
444
|
+
respChecksum2 = int(response[-2])
|
445
|
+
crc = self.calc_crc(self.calc_crc(0, bytes([sequence, dataLen])), dataBytes)
|
446
|
+
calcChecksum1 = (crc >> 8) & 255
|
447
|
+
calcChecksum2 = crc & 255
|
448
|
+
|
449
|
+
if respChecksum1 != calcChecksum1 or respChecksum2 != calcChecksum2:
|
450
|
+
_LOGGER.debug(
|
451
|
+
f"expect checksum: {respChecksum1}, {respChecksum2}\n"
|
452
|
+
f"received checksum: {calcChecksum1}, {calcChecksum2}"
|
453
|
+
)
|
454
|
+
return -4
|
455
|
+
|
456
|
+
data_offset = 2 if frameCtrlData.hasFrag() else 0
|
457
|
+
|
458
|
+
self.notification.addData(dataBytes, data_offset)
|
205
459
|
return 1 if frameCtrlData.hasFrag() else 0
|
206
460
|
except Exception as e:
|
207
461
|
_LOGGER.debug(e)
|
208
462
|
return -100
|
209
463
|
|
210
|
-
# Log.w(TAG, "parseNotification data length less than 4");
|
211
|
-
return -2
|
212
|
-
|
213
464
|
async def parseBlufiNotifyData(self, return_bytes: bool = False):
|
214
465
|
pkgType = self.notification.getPkgType()
|
215
466
|
subType = self.notification.getSubType()
|
@@ -284,17 +535,17 @@ class BleMessage:
|
|
284
535
|
|
285
536
|
def receiveAck(self, expectAck: int) -> bool:
|
286
537
|
try:
|
287
|
-
ack =
|
538
|
+
ack = self.mAck.get()
|
288
539
|
return ack == expectAck
|
289
540
|
except Exception as err:
|
290
541
|
_LOGGER.debug(err)
|
291
542
|
return False
|
292
543
|
|
293
|
-
def
|
294
|
-
return
|
544
|
+
def generate_send_sequence(self) -> int:
|
545
|
+
return self.mSendSequence.increment_and_get() & 255
|
295
546
|
|
296
547
|
async def post_custom_data_bytes(self, data: bytes) -> None:
|
297
|
-
if data
|
548
|
+
if data is None:
|
298
549
|
return
|
299
550
|
type_val = self.getTypeValue(1, 19)
|
300
551
|
try:
|
@@ -336,7 +587,7 @@ class BleMessage:
|
|
336
587
|
return await self.post_contains_data(encrypt, checksum, require_ack, type_of, data)
|
337
588
|
|
338
589
|
async def post_non_data(self, encrypt: bool, checksum: bool, require_ack: bool, type_of: int) -> bool:
|
339
|
-
sequence = self.
|
590
|
+
sequence = self.generate_send_sequence()
|
340
591
|
postBytes = self.getPostBytes(type_of, encrypt, checksum, require_ack, False, sequence, None)
|
341
592
|
posted = await self.gatt_write(postBytes)
|
342
593
|
return posted and (not require_ack or self.receiveAck(sequence))
|
@@ -359,22 +610,26 @@ class BleMessage:
|
|
359
610
|
chunks.append(data[i : i + chunk_size])
|
360
611
|
for index, chunk in enumerate(chunks):
|
361
612
|
frag = index != len(chunks) - 1
|
362
|
-
sequence = self.
|
613
|
+
sequence = self.generate_send_sequence()
|
363
614
|
postBytes = self.getPostBytes(type_of, encrypt, checksum, require_ack, frag, sequence, chunk)
|
364
615
|
# _LOGGER.debug("sequence")
|
365
616
|
# _LOGGER.debug(sequence)
|
366
617
|
posted = await self.gatt_write(postBytes)
|
367
|
-
if posted
|
618
|
+
if posted is not None:
|
368
619
|
return False
|
369
620
|
|
370
621
|
if not frag:
|
371
622
|
return not require_ack or self.receiveAck(sequence)
|
372
623
|
|
624
|
+
if require_ack and not self.receiveAck(sequence):
|
625
|
+
return False
|
626
|
+
|
627
|
+
_LOGGER.debug("sleeping 0.01")
|
628
|
+
await sleep(0.01)
|
373
629
|
if require_ack and not self.receiveAck(sequence):
|
374
630
|
return False
|
375
631
|
else:
|
376
|
-
|
377
|
-
await sleep(0.01)
|
632
|
+
return True
|
378
633
|
|
379
634
|
def getPostBytes(
|
380
635
|
self,
|
@@ -394,8 +649,42 @@ class BleMessage:
|
|
394
649
|
byteOS.write(sequence.to_bytes(1, sys.byteorder))
|
395
650
|
byteOS.write(dataLength.to_bytes(1, sys.byteorder))
|
396
651
|
|
397
|
-
if data
|
652
|
+
if data is not None:
|
398
653
|
byteOS.write(data)
|
399
654
|
|
400
655
|
_LOGGER.debug(byteOS.getvalue())
|
401
656
|
return byteOS.getvalue()
|
657
|
+
|
658
|
+
@staticmethod
|
659
|
+
def calc_crc(initial: int, data: Union[bytes, bytearray]) -> int:
|
660
|
+
"""Calculate CRC value for given initial value and byte array.
|
661
|
+
|
662
|
+
Args:
|
663
|
+
initial: Initial CRC value
|
664
|
+
data: Bytes to calculate CRC for
|
665
|
+
|
666
|
+
Returns:
|
667
|
+
Calculated CRC value (16-bit)
|
668
|
+
|
669
|
+
Raises:
|
670
|
+
TypeError: If data is not bytes or bytearray
|
671
|
+
ValueError: If initial value is out of valid range
|
672
|
+
|
673
|
+
"""
|
674
|
+
if not isinstance(data, (bytes, bytearray)):
|
675
|
+
raise TypeError("Data must be bytes or bytearray")
|
676
|
+
|
677
|
+
if not 0 <= initial <= 0xFFFF:
|
678
|
+
raise ValueError("Initial value must be between 0 and 65535")
|
679
|
+
|
680
|
+
try:
|
681
|
+
crc = (~initial) & 0xFFFF
|
682
|
+
|
683
|
+
for byte in data:
|
684
|
+
crc = ((crc << 8) ^ CRC_TB[byte ^ (crc >> 8)]) & 0xFFFF
|
685
|
+
|
686
|
+
return (~crc) & 0xFFFF
|
687
|
+
|
688
|
+
except Exception as e:
|
689
|
+
_LOGGER.error("Error calculating CRC: %s", str(e))
|
690
|
+
raise
|
File without changes
|
@@ -0,0 +1,54 @@
|
|
1
|
+
from threading import Lock
|
2
|
+
|
3
|
+
|
4
|
+
class AtomicInteger:
|
5
|
+
"""Thread-safe atomic integer implementation."""
|
6
|
+
|
7
|
+
def __init__(self, initial_value: int = 0) -> None:
|
8
|
+
"""Initialize atomic integer with given value."""
|
9
|
+
self._value = initial_value
|
10
|
+
self._lock = Lock()
|
11
|
+
|
12
|
+
def get(self) -> int:
|
13
|
+
"""Get the current value."""
|
14
|
+
with self._lock:
|
15
|
+
return self._value
|
16
|
+
|
17
|
+
def set(self, value: int) -> None:
|
18
|
+
"""Set a new value."""
|
19
|
+
with self._lock:
|
20
|
+
self._value = value
|
21
|
+
|
22
|
+
def increment_and_get(self) -> int:
|
23
|
+
"""Increment the value and return the new value."""
|
24
|
+
with self._lock:
|
25
|
+
self._value += 1
|
26
|
+
return self._value
|
27
|
+
|
28
|
+
def decrement_and_get(self) -> int:
|
29
|
+
"""Decrement the value and return the new value."""
|
30
|
+
with self._lock:
|
31
|
+
self._value -= 1
|
32
|
+
return self._value
|
33
|
+
|
34
|
+
def add_and_get(self, delta: int) -> int:
|
35
|
+
"""Add delta to value and return the new value."""
|
36
|
+
with self._lock:
|
37
|
+
self._value += delta
|
38
|
+
return self._value
|
39
|
+
|
40
|
+
def compare_and_set(self, expect: int, update: int) -> bool:
|
41
|
+
"""Compare value with expected and set to update if they match."""
|
42
|
+
with self._lock:
|
43
|
+
if self._value == expect:
|
44
|
+
self._value = update
|
45
|
+
return True
|
46
|
+
return False
|
47
|
+
|
48
|
+
def __str__(self) -> str:
|
49
|
+
"""Returns string representation of the atomic integer."""
|
50
|
+
return str(self.get())
|
51
|
+
|
52
|
+
def __repr__(self) -> str:
|
53
|
+
"""Detailed string representation of the atomic integer."""
|
54
|
+
return f"AtomicInteger({self.get()})"
|
@@ -23,6 +23,11 @@ class MnetInfo(DataClassORJSONMixin):
|
|
23
23
|
imei: str = ""
|
24
24
|
|
25
25
|
|
26
|
+
@dataclass
|
27
|
+
class LockStateT(DataClassORJSONMixin):
|
28
|
+
lock_state: int = 0
|
29
|
+
|
30
|
+
|
26
31
|
@dataclass
|
27
32
|
class DeviceData(DataClassORJSONMixin):
|
28
33
|
sys_status: int = 0
|
@@ -30,9 +35,11 @@ class DeviceData(DataClassORJSONMixin):
|
|
30
35
|
battery_val: int = 0
|
31
36
|
sensor_status: int = 0
|
32
37
|
last_status: int = 0
|
38
|
+
vslam_status: int = 0
|
33
39
|
sys_time_stamp: str = ""
|
34
40
|
collector_status: CollectorStatus = field(default_factory=CollectorStatus)
|
35
41
|
mnet_info: MnetInfo = field(default_factory=MnetInfo)
|
42
|
+
lock_state: LockStateT = field(default_factory=LockStateT)
|
36
43
|
|
37
44
|
|
38
45
|
@dataclass
|
@@ -127,6 +127,12 @@ class MessageSystem(AbstractMessage, ABC):
|
|
127
127
|
return self.send_order_msg_sys(build)
|
128
128
|
return self.send_order_msg_sys(build)
|
129
129
|
|
130
|
+
def traverse_mode(self, id: int) -> None:
|
131
|
+
"""Sets the traversal mode back to charger."""
|
132
|
+
# 0 direct
|
133
|
+
# 1 follow the perimeter
|
134
|
+
self.allpowerfull_rw(7, id, 1)
|
135
|
+
|
130
136
|
# Commented out as not needed and too many refs to try fix up
|
131
137
|
# def factory_test_order(self, test_id: int, test_duration: int, expect: str):
|
132
138
|
# new_builder = mow_to_app_qctools_info_t.Builder()
|
@@ -224,6 +230,9 @@ class MessageSystem(AbstractMessage, ABC):
|
|
224
230
|
def get_device_version_info(self):
|
225
231
|
return self.send_order_msg_sys(MctlSys(todev_get_dev_fw_info=1))
|
226
232
|
|
233
|
+
def read_and_set_rtk_pairing_code(self, op: int, cfg: str) -> bytes:
|
234
|
+
return self.send_order_msg_sys(MctlSys(todev_lora_cfg_req=LoraCfgReq(op=op, cfg=cfg)))
|
235
|
+
|
227
236
|
# === sendOrderMsg_Sys2 ===
|
228
237
|
|
229
238
|
def request_iot_sys(
|
@@ -204,7 +204,8 @@ class MammotionBaseDevice:
|
|
204
204
|
await self.queue_command("get_device_product_model")
|
205
205
|
await self.queue_command("get_report_cfg")
|
206
206
|
"""RTK and dock location."""
|
207
|
-
await self.queue_command("allpowerfull_rw", id=5,
|
207
|
+
await self.queue_command("allpowerfull_rw", id=5, context=1, rw=1)
|
208
|
+
await self.async_read_settings()
|
208
209
|
|
209
210
|
async def start_map_sync(self) -> None:
|
210
211
|
"""Start sync of map data."""
|
@@ -225,6 +226,18 @@ class MammotionBaseDevice:
|
|
225
226
|
# jobs list
|
226
227
|
# hash_list_result = await self._send_command_with_args("get_all_boundary_hash_list", sub_cmd=3)
|
227
228
|
|
229
|
+
async def async_read_settings(self) -> None:
|
230
|
+
"""Read settings from device."""
|
231
|
+
await self.queue_command("allpowerfull_rw", id=3, context=1, rw=0)
|
232
|
+
await self.queue_command("allpowerfull_rw", id=4, context=1, rw=0)
|
233
|
+
await self.queue_command("allpowerfull_rw", id=6, context=1, rw=0)
|
234
|
+
# traversal mode
|
235
|
+
await self.queue_command("allpowerfull_rw", id=7, context=1, rw=0)
|
236
|
+
|
237
|
+
await self.queue_command("read_and_set_sidelight", is_sidelight=True, operate=1)
|
238
|
+
|
239
|
+
await self.queue_command("read_and_set_rtk_pairing_code", op=1, cfg="")
|
240
|
+
|
228
241
|
async def async_get_errors(self) -> None:
|
229
242
|
"""Error codes."""
|
230
243
|
await self.queue_command("allpowerfull_rw", id=5, rw=1, context=2)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
pymammotion/__init__.py,sha256=BcwrItywpSECTxrTPwEuBExi_ekOrG2M2tbphuotIlE,1617
|
2
2
|
pymammotion/aliyun/__init__.py,sha256=T1lkX7TRYiL4nqYanG4l4MImV-SlavSbuooC-W-uUGw,29
|
3
|
-
pymammotion/aliyun/cloud_gateway.py,sha256=
|
3
|
+
pymammotion/aliyun/cloud_gateway.py,sha256=pv3Ag9U0OKk0vBzGJCklS59mbUb4O6sDjLM329uaBho,25791
|
4
4
|
pymammotion/aliyun/cloud_service.py,sha256=px7dUKow5Z7VyebjYzuKkzkm77XbUXYiFiYO_2e-UQ0,2207
|
5
5
|
pymammotion/aliyun/model/aep_response.py,sha256=8f6GIP58ve8gd6AL3HBoXxsy0n2q4ygWvjELGnoOnVc,452
|
6
6
|
pymammotion/aliyun/model/connect_response.py,sha256=Yz-fEbDzgGPTo5Of2oAjmFkSv08T7ze80pQU4k-gKIU,824
|
@@ -12,12 +12,14 @@ pymammotion/aliyun/model/stream_subscription_response.py,sha256=po765WASQDboVCos
|
|
12
12
|
pymammotion/aliyun/tmp_constant.py,sha256=M4Hq_lrGB3LZdX6R2XohRPFoK1NDnNV-pTJwJcJ9838,6650
|
13
13
|
pymammotion/bluetooth/__init__.py,sha256=LAl8jqZ1fPh-3mLmViNQsP3s814C1vsocYUa6oSaXt0,36
|
14
14
|
pymammotion/bluetooth/ble.py,sha256=Z2cO1EV2ndORKoJMzc2RdUdYbUe_PIzxCZICJg0_V24,2404
|
15
|
-
pymammotion/bluetooth/ble_message.py,sha256=
|
15
|
+
pymammotion/bluetooth/ble_message.py,sha256=toiUjfrH9VXPgYSUdufoCT2ZKGO0QoXoFZLea1t-Vdg,18911
|
16
16
|
pymammotion/bluetooth/const.py,sha256=CCqyHsYbB0BAYjwdhXt_n6eWWxmhlUrAFjvVv57mbvE,1749
|
17
17
|
pymammotion/bluetooth/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
18
|
pymammotion/bluetooth/data/convert.py,sha256=6DMwvzVr9FWCoQFIKSI2poFXjISc_m6X59g8FlVO0-o,800
|
19
19
|
pymammotion/bluetooth/data/framectrldata.py,sha256=qxhGQsTGsfPx-CarEMLkgBn_RJ6I2-exmr9AX2U4pFg,995
|
20
20
|
pymammotion/bluetooth/data/notifydata.py,sha256=jeROpoFmaZfNTidkLLm5VYeFbeIgDSi8waJ0nVLRUTA,1995
|
21
|
+
pymammotion/bluetooth/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
+
pymammotion/bluetooth/model/atomic_integer.py,sha256=jtSqeqd6It3TvzZN7TJyYHQNRuItuw0Bg-cL0AUEBhY,1666
|
21
23
|
pymammotion/const.py,sha256=lWRxvTVdXnNHuxqvRkjO5ziK0Ic-fZMM6J2dbe5M6Nc,385
|
22
24
|
pymammotion/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
25
|
pymammotion/data/model/__init__.py,sha256=aSyroxYQQS-WMRi6WmWm2js4wLa9nmsi160gx9tts4o,323
|
@@ -31,11 +33,11 @@ pymammotion/data/model/execute_boarder.py,sha256=9rd_h4fbcsXxgnLOd2rO2hWyD1abnTG
|
|
31
33
|
pymammotion/data/model/generate_route_information.py,sha256=tCF3-HDm4O30hy8BJrTOaMpP3ArHbI9i9ZG7ARc5eLg,777
|
32
34
|
pymammotion/data/model/hash_list.py,sha256=ZPg5d1hy4bPMgPw5JkHujT06LIoEmXn7qSdQW79FF3A,6257
|
33
35
|
pymammotion/data/model/location.py,sha256=PwmITejfI4pm7PI4rzqSuuHetwle6IJr_CV95435s2M,871
|
34
|
-
pymammotion/data/model/mowing_modes.py,sha256=
|
36
|
+
pymammotion/data/model/mowing_modes.py,sha256=87R4T-hs6tZ0baPvdYII9Fd6ZbJRqkXj7MRFZ7nIPOY,941
|
35
37
|
pymammotion/data/model/plan.py,sha256=mcadkSL7fQXy0iJ0q786I3GEQY4i6kmQXfW6Ri69lcQ,2906
|
36
38
|
pymammotion/data/model/rapid_state.py,sha256=mIdhAG_LZXpVcybxqTLgLXkNOmVmDTn04B9PGIDA8Ls,1251
|
37
39
|
pymammotion/data/model/region_data.py,sha256=OTV15vRyn9JORXsQPjWMNF1ZujuNhsOKl25KeqwMObA,3007
|
38
|
-
pymammotion/data/model/report_info.py,sha256=
|
40
|
+
pymammotion/data/model/report_info.py,sha256=9sPPfhBv8f0K-xuHRkKrbez-7nZ_oCND2vZYLuKvkBA,3436
|
39
41
|
pymammotion/data/mqtt/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
40
42
|
pymammotion/data/mqtt/event.py,sha256=pEOQcjnv5XKosSPD8UmVAgCAaI8vLuIhGECZcU4xKjk,5055
|
41
43
|
pymammotion/data/mqtt/properties.py,sha256=kvphcjrDuJHuX8Az98-wKeFv_rSmu2Fz9YKLGodGSj0,3759
|
@@ -56,12 +58,12 @@ pymammotion/mammotion/commands/messages/media.py,sha256=l-m4l2Vp1ZOHPHyJTceuLaLv
|
|
56
58
|
pymammotion/mammotion/commands/messages/navigation.py,sha256=Z6RQK-pMh8o7_K_1yTENx3lkNBFQTU_ojunolSre0oM,23241
|
57
59
|
pymammotion/mammotion/commands/messages/network.py,sha256=AErasUL7U4lbFKRJPVzUZMHegP5K2Jo9wGmeWruOtUg,7623
|
58
60
|
pymammotion/mammotion/commands/messages/ota.py,sha256=g937HT_-OQXV6A3zUiZ53b45cOX6y-rzs5m-4b0IcTk,1473
|
59
|
-
pymammotion/mammotion/commands/messages/system.py,sha256=
|
61
|
+
pymammotion/mammotion/commands/messages/system.py,sha256=dk-4UL0P1efDimO939qXX9XhhaoKLz9rHrWRAPi8-YM,13607
|
60
62
|
pymammotion/mammotion/commands/messages/video.py,sha256=xili9khz4Op5NwjXfvIkeRYzQlQPIf8o8bnoYx-Ylpw,1319
|
61
63
|
pymammotion/mammotion/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
62
64
|
pymammotion/mammotion/control/joystick.py,sha256=QfBVxM_gxpWsZAGO90whtgxCI2tIZ3TTad9wHIPsU9s,5640
|
63
65
|
pymammotion/mammotion/devices/__init__.py,sha256=f2qQFPgLGmV85W2hSlMUh5BYuht9o_Ar_JEAAMD4fsE,102
|
64
|
-
pymammotion/mammotion/devices/base.py,sha256=
|
66
|
+
pymammotion/mammotion/devices/base.py,sha256=RlXFBcvC92lI-YvHJsmilDLfgpiXojKnHTYC3q3CAJo,10658
|
65
67
|
pymammotion/mammotion/devices/mammotion.py,sha256=r3G13Wi1szQ1rq6J-Rwl_cddZDyp5DqkZ9BbjF5Kxpg,12538
|
66
68
|
pymammotion/mammotion/devices/mammotion_bluetooth.py,sha256=HUOKnjYUWTGjksyQDCPKF_u3dWo2ddgrWCBXnJ2VkwA,18963
|
67
69
|
pymammotion/mammotion/devices/mammotion_cloud.py,sha256=a9fB0ZCYElRxrjnwCM81RXCbxo5kJKhGa-BGck9U3-A,12949
|
@@ -119,7 +121,7 @@ pymammotion/utility/map.py,sha256=GYscVMg2cX3IPlNpCBNHDW0S55yS1WGRf1iHnNZ7TfQ,22
|
|
119
121
|
pymammotion/utility/movement.py,sha256=N75oAoAgFydqoaOedYIxGUHmuTCtPzAOtb-d_29tpfI,615
|
120
122
|
pymammotion/utility/periodic.py,sha256=MbeSb9cfhxzYmdT_RiE0dZe3H9IfbQW_zSqhmSX2RUc,3321
|
121
123
|
pymammotion/utility/rocker_util.py,sha256=6tX7sS87qoQC_tsxbx3NLL-HgS08wtzXiZkhDiz7uo0,7179
|
122
|
-
pymammotion-0.
|
123
|
-
pymammotion-0.
|
124
|
-
pymammotion-0.
|
125
|
-
pymammotion-0.
|
124
|
+
pymammotion-0.3.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
125
|
+
pymammotion-0.3.0.dist-info/METADATA,sha256=N1mvd5oSRS6F5PncM4cee1BCKEivhOxY6WbCxz9ECtk,3895
|
126
|
+
pymammotion-0.3.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
127
|
+
pymammotion-0.3.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|