pymammotion 0.4.11b1__py3-none-any.whl → 0.4.12__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/bluetooth/ble.py +2 -4
- pymammotion/data/model/hash_list.py +52 -16
- pymammotion/mammotion/commands/abstract_message.py +4 -0
- pymammotion/mammotion/commands/mammotion_command.py +2 -1
- pymammotion/mammotion/commands/messages/driver.py +2 -2
- pymammotion/mammotion/commands/messages/media.py +2 -2
- pymammotion/mammotion/commands/messages/navigation.py +2 -2
- pymammotion/mammotion/commands/messages/network.py +3 -4
- pymammotion/mammotion/commands/messages/ota.py +5 -3
- pymammotion/mammotion/commands/messages/system.py +9 -10
- pymammotion/mammotion/commands/messages/video.py +2 -2
- pymammotion/mammotion/devices/base.py +16 -11
- pymammotion/mammotion/devices/mammotion_bluetooth.py +1 -1
- pymammotion/mammotion/devices/mammotion_cloud.py +6 -3
- pymammotion/proto/__init__.py +1 -1
- {pymammotion-0.4.11b1.dist-info → pymammotion-0.4.12.dist-info}/METADATA +1 -2
- {pymammotion-0.4.11b1.dist-info → pymammotion-0.4.12.dist-info}/RECORD +19 -19
- {pymammotion-0.4.11b1.dist-info → pymammotion-0.4.12.dist-info}/WHEEL +1 -1
- {pymammotion-0.4.11b1.dist-info → pymammotion-0.4.12.dist-info}/LICENSE +0 -0
pymammotion/bluetooth/ble.py
CHANGED
@@ -36,12 +36,10 @@ class MammotionBLE:
|
|
36
36
|
return await self.connect()
|
37
37
|
|
38
38
|
async def connect(self) -> bool:
|
39
|
-
if self.client is not None
|
40
|
-
return await self.client.connect()
|
39
|
+
return await self.client.connect() if self.client is not None else False
|
41
40
|
|
42
41
|
async def disconnect(self) -> bool:
|
43
|
-
if self.client is not None
|
44
|
-
return await self.client.disconnect()
|
42
|
+
return await self.client.disconnect() if self.client is not None else False
|
45
43
|
|
46
44
|
async def notification_handler(self, _characteristic: BleakGATTCharacteristic, data: bytearray) -> None:
|
47
45
|
"""Simple notification handler which prints the data received."""
|
@@ -3,7 +3,7 @@ from enum import IntEnum
|
|
3
3
|
|
4
4
|
from mashumaro.mixins.orjson import DataClassORJSONMixin
|
5
5
|
|
6
|
-
from pymammotion.proto import NavGetCommDataAck, SvgMessageAckT
|
6
|
+
from pymammotion.proto import NavGetCommDataAck, NavGetHashListAck, SvgMessageAckT
|
7
7
|
|
8
8
|
|
9
9
|
class PathType(IntEnum):
|
@@ -78,8 +78,9 @@ class SvgMessage(DataClassORJSONMixin):
|
|
78
78
|
|
79
79
|
@dataclass
|
80
80
|
class FrameList(DataClassORJSONMixin):
|
81
|
-
total_frame: int
|
82
|
-
|
81
|
+
total_frame: int = 0
|
82
|
+
sub_cmd: int = 0
|
83
|
+
data: list[NavGetCommData | SvgMessage] = field(default_factory=list)
|
83
84
|
|
84
85
|
|
85
86
|
@dataclass(eq=False, repr=False)
|
@@ -100,6 +101,7 @@ class NavGetHashListData(DataClassORJSONMixin):
|
|
100
101
|
@dataclass
|
101
102
|
class RootHashList(DataClassORJSONMixin):
|
102
103
|
total_frame: int = 0
|
104
|
+
sub_cmd: int = 0
|
103
105
|
data: list[NavGetHashListData] = field(default_factory=list)
|
104
106
|
|
105
107
|
|
@@ -119,11 +121,11 @@ class HashList(DataClassORJSONMixin):
|
|
119
121
|
"""
|
120
122
|
|
121
123
|
root_hash_lists: list[RootHashList] = field(default_factory=list)
|
122
|
-
area: dict = field(default_factory=dict) # type 0
|
123
|
-
path: dict = field(default_factory=dict) # type 2
|
124
|
-
obstacle: dict = field(default_factory=dict) # type 1
|
125
|
-
dump: dict = field(default_factory=dict) # type 12?
|
126
|
-
svg: dict = field(default_factory=dict) # type 13
|
124
|
+
area: dict[int, FrameList] = field(default_factory=dict) # type 0
|
125
|
+
path: dict[int, FrameList] = field(default_factory=dict) # type 2
|
126
|
+
obstacle: dict[int, FrameList] = field(default_factory=dict) # type 1
|
127
|
+
dump: dict[int, FrameList] = field(default_factory=dict) # type 12?
|
128
|
+
svg: dict[int, FrameList] = field(default_factory=dict) # type 13
|
127
129
|
area_name: list[AreaHashNameList] = field(default_factory=list)
|
128
130
|
|
129
131
|
def update_hash_lists(self, hashlist: list[int]) -> None:
|
@@ -132,6 +134,11 @@ class HashList(DataClassORJSONMixin):
|
|
132
134
|
self.obstacle = {hash_id: frames for hash_id, frames in self.obstacle.items() if hash_id in hashlist}
|
133
135
|
self.dump = {hash_id: frames for hash_id, frames in self.dump.items() if hash_id in hashlist}
|
134
136
|
self.svg = {hash_id: frames for hash_id, frames in self.svg.items() if hash_id in hashlist}
|
137
|
+
self.area_name = [
|
138
|
+
area_item
|
139
|
+
for area_item in self.area_name
|
140
|
+
if area_item.hash in self.area.keys() or area_item.hash in self.hashlist
|
141
|
+
]
|
135
142
|
|
136
143
|
@property
|
137
144
|
def hashlist(self) -> list[int]:
|
@@ -140,8 +147,7 @@ class HashList(DataClassORJSONMixin):
|
|
140
147
|
# Combine data_couple from all RootHashLists
|
141
148
|
return [i for root_list in self.root_hash_lists for obj in root_list.data for i in obj.data_couple]
|
142
149
|
|
143
|
-
|
144
|
-
def missing_hashlist(self) -> list[int]:
|
150
|
+
def missing_hashlist(self, sub_cmd: int = 0) -> list[int]:
|
145
151
|
"""Return missing hashlist."""
|
146
152
|
all_hash_ids = set(self.area.keys()).union(
|
147
153
|
self.path.keys(), self.obstacle.keys(), self.dump.keys(), self.svg.keys()
|
@@ -150,16 +156,39 @@ class HashList(DataClassORJSONMixin):
|
|
150
156
|
i
|
151
157
|
for root_list in self.root_hash_lists
|
152
158
|
for obj in root_list.data
|
159
|
+
if root_list.sub_cmd == sub_cmd
|
153
160
|
for i in obj.data_couple
|
154
|
-
if
|
161
|
+
if i not in all_hash_ids
|
155
162
|
]
|
156
163
|
|
164
|
+
def missing_root_hash_frame(self, hash_list: NavGetHashListAck) -> list[int]:
|
165
|
+
"""Return missing root hash frame."""
|
166
|
+
target_root_list = next(
|
167
|
+
(
|
168
|
+
rhl
|
169
|
+
for rhl in self.root_hash_lists
|
170
|
+
if rhl.total_frame == hash_list.total_frame and rhl.sub_cmd == hash_list.sub_cmd
|
171
|
+
),
|
172
|
+
None,
|
173
|
+
)
|
174
|
+
if target_root_list is None:
|
175
|
+
return []
|
176
|
+
|
177
|
+
return self._find_missing_frames(target_root_list)
|
178
|
+
|
157
179
|
def update_root_hash_list(self, hash_list: NavGetHashListData) -> None:
|
158
|
-
target_root_list = next(
|
180
|
+
target_root_list = next(
|
181
|
+
(
|
182
|
+
rhl
|
183
|
+
for rhl in self.root_hash_lists
|
184
|
+
if rhl.total_frame == hash_list.total_frame and rhl.sub_cmd == hash_list.sub_cmd
|
185
|
+
),
|
186
|
+
None,
|
187
|
+
)
|
159
188
|
|
160
189
|
if target_root_list is None:
|
161
190
|
# Create new RootHashList if none exists for this total_frame
|
162
|
-
new_root_list = RootHashList(total_frame=hash_list.total_frame, data=[hash_list])
|
191
|
+
new_root_list = RootHashList(total_frame=hash_list.total_frame, sub_cmd=hash_list.sub_cmd, data=[hash_list])
|
163
192
|
self.root_hash_lists.append(new_root_list)
|
164
193
|
return
|
165
194
|
|
@@ -172,10 +201,11 @@ class HashList(DataClassORJSONMixin):
|
|
172
201
|
# If no match was found, append the new item
|
173
202
|
target_root_list.data.append(hash_list)
|
174
203
|
|
175
|
-
def missing_hash_frame(self) -> list[int]:
|
204
|
+
def missing_hash_frame(self, hash_ack: NavGetHashListAck) -> list[int]:
|
176
205
|
"""Returns a combined list of all missing frames across all RootHashLists."""
|
177
206
|
missing_frames = []
|
178
|
-
for
|
207
|
+
filtered_lists = [rl for rl in self.root_hash_lists if rl.sub_cmd == hash_ack.sub_cmd]
|
208
|
+
for root_list in filtered_lists:
|
179
209
|
missing = self._find_missing_frames(root_list)
|
180
210
|
if missing:
|
181
211
|
missing_frames.extend(missing)
|
@@ -201,12 +231,15 @@ class HashList(DataClassORJSONMixin):
|
|
201
231
|
|
202
232
|
def update(self, hash_data: NavGetCommData | SvgMessage) -> bool:
|
203
233
|
"""Update the map data."""
|
234
|
+
|
204
235
|
if hash_data.type == PathType.AREA:
|
205
236
|
existing_name = next((area for area in self.area_name if area.hash == hash_data.hash), None)
|
206
237
|
if not existing_name:
|
207
238
|
name = f"area {len(self.area_name)+1}" if hash_data.area_label is None else hash_data.area_label.label
|
208
239
|
self.area_name.append(AreaHashNameList(name=name, hash=hash_data.hash))
|
209
|
-
|
240
|
+
result = self._add_hash_data(self.area, hash_data)
|
241
|
+
self.update_hash_lists(self.hashlist)
|
242
|
+
return result
|
210
243
|
|
211
244
|
if hash_data.type == PathType.OBSTACLE:
|
212
245
|
return self._add_hash_data(self.obstacle, hash_data)
|
@@ -224,6 +257,9 @@ class HashList(DataClassORJSONMixin):
|
|
224
257
|
|
225
258
|
@staticmethod
|
226
259
|
def _find_missing_frames(frame_list: FrameList | RootHashList) -> list[int]:
|
260
|
+
if frame_list is None:
|
261
|
+
return []
|
262
|
+
|
227
263
|
if frame_list.total_frame == len(frame_list.data):
|
228
264
|
return []
|
229
265
|
number_list = list(range(1, frame_list.total_frame + 1))
|
@@ -1,10 +1,14 @@
|
|
1
1
|
from abc import abstractmethod
|
2
2
|
|
3
|
+
from pymammotion.bluetooth.model.atomic_integer import AtomicInteger
|
3
4
|
from pymammotion.proto import MsgCmdType, MsgDevice
|
4
5
|
from pymammotion.utility.device_type import DeviceType
|
5
6
|
|
6
7
|
|
7
8
|
class AbstractMessage:
|
9
|
+
seqs = AtomicInteger(0)
|
10
|
+
user_account: int = 1
|
11
|
+
|
8
12
|
@abstractmethod
|
9
13
|
def get_device_name(self) -> str:
|
10
14
|
"""Get device name."""
|
@@ -13,9 +13,10 @@ class MammotionCommand(
|
|
13
13
|
):
|
14
14
|
"""MQTT commands for Luba."""
|
15
15
|
|
16
|
-
def __init__(self, device_name: str) -> None:
|
16
|
+
def __init__(self, device_name: str, user_account: int) -> None:
|
17
17
|
self._device_name = device_name
|
18
18
|
self._product_key = ""
|
19
|
+
self.user_account = user_account
|
19
20
|
|
20
21
|
def get_device_name(self) -> str:
|
21
22
|
"""Get device name."""
|
@@ -29,9 +29,9 @@ class MessageDriver(AbstractMessage, ABC):
|
|
29
29
|
rcver=self.get_msg_device(MsgCmdType.EMBED_DRIVER, MsgDevice.DEV_MAINCTL),
|
30
30
|
msgattr=MsgAttr.REQ,
|
31
31
|
timestamp=round(time.time() * 1000),
|
32
|
-
seqs=
|
32
|
+
seqs=self.seqs.increment_and_get() & 255,
|
33
33
|
version=1,
|
34
|
-
subtype=
|
34
|
+
subtype=self.user_account,
|
35
35
|
driver=driver,
|
36
36
|
).SerializeToString()
|
37
37
|
|
@@ -12,9 +12,9 @@ class MessageMedia(AbstractMessage, ABC):
|
|
12
12
|
sender=MsgDevice.DEV_MOBILEAPP,
|
13
13
|
rcver=self.get_msg_device(MsgCmdType.MUL, MsgDevice.SOC_MODULE_MULTIMEDIA),
|
14
14
|
msgattr=MsgAttr.REQ,
|
15
|
-
seqs=
|
15
|
+
seqs=self.seqs.increment_and_get() & 255,
|
16
16
|
version=1,
|
17
|
-
subtype=
|
17
|
+
subtype=self.user_account,
|
18
18
|
mul=mul,
|
19
19
|
)
|
20
20
|
|
@@ -39,9 +39,9 @@ class MessageNavigation(AbstractMessage, ABC):
|
|
39
39
|
sender=MsgDevice.DEV_MOBILEAPP,
|
40
40
|
rcver=self.get_msg_device(MsgCmdType.NAV, MsgDevice.DEV_MAINCTL),
|
41
41
|
msgattr=MsgAttr.REQ,
|
42
|
-
seqs=
|
42
|
+
seqs=self.seqs.increment_and_get() & 255,
|
43
43
|
version=1,
|
44
|
-
subtype=
|
44
|
+
subtype=self.user_account,
|
45
45
|
nav=build,
|
46
46
|
timestamp=round(time.time() * 1000),
|
47
47
|
)
|
@@ -31,16 +31,15 @@ from pymammotion.proto import (
|
|
31
31
|
class MessageNetwork(AbstractMessage, ABC):
|
32
32
|
messageNavigation: MessageNavigation = MessageNavigation()
|
33
33
|
|
34
|
-
|
35
|
-
def send_order_msg_net(build: DevNet) -> bytes:
|
34
|
+
def send_order_msg_net(self, build: DevNet) -> bytes:
|
36
35
|
luba_msg = LubaMsg(
|
37
36
|
msgtype=MsgCmdType.ESP,
|
38
37
|
sender=MsgDevice.DEV_MOBILEAPP,
|
39
38
|
rcver=MsgDevice.DEV_COMM_ESP,
|
40
39
|
msgattr=MsgAttr.REQ,
|
41
|
-
seqs=
|
40
|
+
seqs=self.seqs.increment_and_get() & 255,
|
42
41
|
version=1,
|
43
|
-
subtype=
|
42
|
+
subtype=self.user_account,
|
44
43
|
net=build,
|
45
44
|
timestamp=round(time.time() * 1000),
|
46
45
|
)
|
@@ -6,15 +6,17 @@ from pymammotion.proto import GetInfoReq, InfoType, LubaMsg, MctlOta, MsgAttr, M
|
|
6
6
|
|
7
7
|
|
8
8
|
class MessageOta(AbstractMessage, ABC):
|
9
|
+
"""Message OTA class."""
|
10
|
+
|
9
11
|
def send_order_msg_ota(self, ota):
|
10
12
|
luba_msg = LubaMsg(
|
11
13
|
msgtype=MsgCmdType.EMBED_OTA,
|
12
14
|
sender=MsgDevice.DEV_MOBILEAPP,
|
13
15
|
rcver=self.get_msg_device(MsgCmdType.EMBED_OTA, MsgDevice.DEV_MAINCTL),
|
14
|
-
msgattr=MsgAttr.
|
15
|
-
seqs=
|
16
|
+
msgattr=MsgAttr.REQ,
|
17
|
+
seqs=self.seqs.increment_and_get() & 255,
|
16
18
|
version=1,
|
17
|
-
subtype=
|
19
|
+
subtype=self.user_account,
|
18
20
|
ota=ota,
|
19
21
|
)
|
20
22
|
|
@@ -36,25 +36,24 @@ class MessageSystem(AbstractMessage, ABC):
|
|
36
36
|
sender=MsgDevice.DEV_MOBILEAPP,
|
37
37
|
rcver=self.get_msg_device(MsgCmdType.EMBED_SYS, MsgDevice.DEV_MAINCTL),
|
38
38
|
sys=sys,
|
39
|
-
seqs=
|
39
|
+
seqs=self.seqs.increment_and_get() & 255,
|
40
40
|
version=1,
|
41
|
-
subtype=
|
41
|
+
subtype=self.user_account,
|
42
42
|
timestamp=round(time.time() * 1000),
|
43
43
|
)
|
44
44
|
|
45
45
|
return luba_msg.SerializeToString()
|
46
46
|
|
47
|
-
|
48
|
-
def send_order_msg_sys_legacy(sys) -> bytes:
|
47
|
+
def send_order_msg_sys_legacy(self, sys) -> bytes:
|
49
48
|
luba_msg = LubaMsg(
|
50
49
|
msgtype=MsgCmdType.EMBED_SYS,
|
51
50
|
msgattr=MsgAttr.REQ,
|
52
51
|
sender=MsgDevice.DEV_MOBILEAPP,
|
53
52
|
rcver=MsgDevice.DEV_MAINCTL,
|
54
53
|
sys=sys,
|
55
|
-
seqs=
|
54
|
+
seqs=self.seqs.increment_and_get() & 255,
|
56
55
|
version=1,
|
57
|
-
subtype=
|
56
|
+
subtype=self.user_account,
|
58
57
|
timestamp=round(time.time() * 1000),
|
59
58
|
)
|
60
59
|
|
@@ -315,9 +314,9 @@ class MessageSystem(AbstractMessage, ABC):
|
|
315
314
|
sender=MsgDevice.DEV_MOBILEAPP,
|
316
315
|
rcver=MsgDevice.DEV_MAINCTL,
|
317
316
|
msgattr=MsgAttr.REQ,
|
318
|
-
seqs=
|
317
|
+
seqs=self.seqs.increment_and_get() & 255,
|
319
318
|
version=1,
|
320
|
-
subtype=
|
319
|
+
subtype=self.user_account,
|
321
320
|
sys=mctl_sys,
|
322
321
|
timestamp=round(time.time() * 1000),
|
323
322
|
)
|
@@ -351,9 +350,9 @@ class MessageSystem(AbstractMessage, ABC):
|
|
351
350
|
sender=MsgDevice.DEV_MOBILEAPP,
|
352
351
|
rcver=MsgDevice.DEV_MAINCTL,
|
353
352
|
msgattr=MsgAttr.REQ,
|
354
|
-
seqs=
|
353
|
+
seqs=self.seqs.increment_and_get() & 255,
|
355
354
|
version=1,
|
356
|
-
subtype=
|
355
|
+
subtype=self.user_account,
|
357
356
|
sys=mctl_sys,
|
358
357
|
timestamp=round(time.time() * 1000),
|
359
358
|
)
|
@@ -15,9 +15,9 @@ class MessageVideo(AbstractMessage, ABC):
|
|
15
15
|
sender=MsgDevice.DEV_MOBILEAPP,
|
16
16
|
rcver=self.get_msg_device(MsgCmdType.MUL, MsgDevice.SOC_MODULE_MULTIMEDIA),
|
17
17
|
mul=mul,
|
18
|
-
seqs=
|
18
|
+
seqs=self.seqs.increment_and_get() & 255,
|
19
19
|
version=1,
|
20
|
-
subtype=
|
20
|
+
subtype=self.user_account,
|
21
21
|
timestamp=round(time.time() * 1000),
|
22
22
|
)
|
23
23
|
|
@@ -45,18 +45,18 @@ class MammotionBaseDevice:
|
|
45
45
|
|
46
46
|
async def datahash_response(self, hash_ack: NavGetHashListAck) -> None:
|
47
47
|
"""Handle datahash responses."""
|
48
|
-
current_frame = hash_ack.current_frame
|
49
48
|
|
50
|
-
missing_frames = self.mower.map.
|
49
|
+
missing_frames = self.mower.map.missing_root_hash_frame(hash_ack)
|
51
50
|
if len(missing_frames) == 0:
|
52
|
-
if len(self.mower.map.missing_hashlist) > 0:
|
53
|
-
data_hash = self.mower.map.missing_hashlist.pop()
|
51
|
+
if len(self.mower.map.missing_hashlist(hash_ack.sub_cmd)) > 0:
|
52
|
+
data_hash = self.mower.map.missing_hashlist(hash_ack.sub_cmd).pop()
|
54
53
|
return await self.queue_command("synchronize_hash_data", hash_num=data_hash)
|
55
54
|
return
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
for frame in missing_frames:
|
57
|
+
await self.queue_command(
|
58
|
+
"get_hash_response", sub_cmd=hash_ack.sub_cmd, total_frame=hash_ack.total_frame, current_frame=frame - 1
|
59
|
+
)
|
60
60
|
|
61
61
|
async def commdata_response(self, common_data: NavGetCommDataAck | SvgMessageAckT) -> None:
|
62
62
|
"""Handle common data responses."""
|
@@ -67,7 +67,11 @@ class MammotionBaseDevice:
|
|
67
67
|
if len(missing_frames) == 0:
|
68
68
|
# get next in hash ack list
|
69
69
|
|
70
|
-
data_hash =
|
70
|
+
data_hash = (
|
71
|
+
self.mower.map.missing_hashlist(common_data.sub_cmd).pop()
|
72
|
+
if len(self.mower.map.missing_hashlist(common_data.sub_cmd)) > 0
|
73
|
+
else None
|
74
|
+
)
|
71
75
|
if data_hash is None:
|
72
76
|
return
|
73
77
|
|
@@ -80,6 +84,7 @@ class MammotionBaseDevice:
|
|
80
84
|
region_data.hash = common_data.data_hash if isinstance(common_data, SvgMessageAckT) else common_data.hash
|
81
85
|
region_data.action = common_data.action if isinstance(common_data, NavGetCommDataAck) else None
|
82
86
|
region_data.type = common_data.type
|
87
|
+
region_data.sub_cmd = common_data.sub_cmd
|
83
88
|
region_data.total_frame = total_frame
|
84
89
|
region_data.current_frame = current_frame
|
85
90
|
await self.queue_command("get_regional_data", regional_data=region_data)
|
@@ -210,14 +215,14 @@ class MammotionBaseDevice:
|
|
210
215
|
await self.queue_command("read_plan", sub_cmd=2, plan_index=0)
|
211
216
|
|
212
217
|
await self.queue_command("get_all_boundary_hash_list", sub_cmd=0)
|
213
|
-
|
214
|
-
|
215
|
-
data_hash = self.mower.map.missing_hashlist.pop()
|
218
|
+
if len(self.mower.map.missing_hashlist()) > 0:
|
219
|
+
data_hash = self.mower.map.missing_hashlist().pop()
|
216
220
|
await self.queue_command("synchronize_hash_data", hash_num=data_hash)
|
217
221
|
|
218
222
|
# sub_cmd 3 is job hashes??
|
219
223
|
# sub_cmd 4 is dump location (yuka)
|
220
224
|
# jobs list
|
225
|
+
#
|
221
226
|
# hash_list_result = await self._send_command_with_args("get_all_boundary_hash_list", sub_cmd=3)
|
222
227
|
|
223
228
|
async def async_read_settings(self) -> None:
|
@@ -82,7 +82,7 @@ class MammotionBaseBLEDevice(MammotionBaseDevice):
|
|
82
82
|
self._write_char: BleakGATTCharacteristic | int | str | UUID = 0
|
83
83
|
self._disconnect_timer: asyncio.TimerHandle | None = None
|
84
84
|
self._message: BleMessage | None = None
|
85
|
-
self._commands: MammotionCommand = MammotionCommand(device.name)
|
85
|
+
self._commands: MammotionCommand = MammotionCommand(device.name, 1)
|
86
86
|
self.command_queue = asyncio.Queue()
|
87
87
|
self._expected_disconnect = False
|
88
88
|
self._connect_lock = asyncio.Lock()
|
@@ -164,7 +164,10 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
164
164
|
self.iot_id = cloud_device.iotId
|
165
165
|
self.device = cloud_device
|
166
166
|
self._command_futures = {}
|
167
|
-
self._commands: MammotionCommand = MammotionCommand(
|
167
|
+
self._commands: MammotionCommand = MammotionCommand(
|
168
|
+
cloud_device.deviceName,
|
169
|
+
int(mqtt.cloud_client.mammotion_http.response.data.get("userInformation").get("userAccount")),
|
170
|
+
)
|
168
171
|
self.currentID = ""
|
169
172
|
self._mqtt.mqtt_message_event.add_subscribers(self._parse_message_for_device)
|
170
173
|
self._mqtt.mqtt_properties_event.add_subscribers(self._parse_message_properties_for_device)
|
@@ -329,9 +332,9 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
329
332
|
fut: MammotionFuture = self.dequeue_by_iot_id(self._mqtt.waiting_queue, self.iot_id)
|
330
333
|
if fut is None:
|
331
334
|
return
|
332
|
-
while fut.fut.cancelled() and len(self._mqtt.waiting_queue) > 0:
|
335
|
+
while fut is None or fut.fut.cancelled() and len(self._mqtt.waiting_queue) > 0:
|
333
336
|
fut = self.dequeue_by_iot_id(self._mqtt.waiting_queue, self.iot_id)
|
334
|
-
if not fut.fut.cancelled():
|
337
|
+
if fut is not None and not fut.fut.cancelled():
|
335
338
|
fut.resolve(cast(bytes, binary_data))
|
336
339
|
|
337
340
|
@property
|
pymammotion/proto/__init__.py
CHANGED
@@ -892,7 +892,7 @@ class NavGetCommData(betterproto.Message):
|
|
892
892
|
sub_cmd: int = betterproto.int32_field(2)
|
893
893
|
action: int = betterproto.int32_field(3)
|
894
894
|
type: int = betterproto.int32_field(4)
|
895
|
-
hash: int = betterproto.
|
895
|
+
hash: int = betterproto.int64_field(5)
|
896
896
|
paternal_hash_a: int = betterproto.int64_field(6)
|
897
897
|
paternal_hash_b: int = betterproto.int64_field(7)
|
898
898
|
total_frame: int = betterproto.int32_field(8)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: pymammotion
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.12
|
4
4
|
Summary:
|
5
5
|
License: GPL-3.0
|
6
6
|
Author: Michael Arthur
|
@@ -8,7 +8,6 @@ Author-email: michael@jumblesoft.co.nz
|
|
8
8
|
Requires-Python: >=3.10
|
9
9
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
11
|
-
Classifier: Programming Language :: Python :: 3.10
|
12
11
|
Classifier: Programming Language :: Python :: 3.11
|
13
12
|
Classifier: Programming Language :: Python :: 3.12
|
14
13
|
Requires-Dist: aiohttp (>=3.9.1,<4.0.0)
|
@@ -10,7 +10,7 @@ pymammotion/aliyun/model/session_by_authcode_response.py,sha256=naMDigtvmpf-Ikf5
|
|
10
10
|
pymammotion/aliyun/model/stream_subscription_response.py,sha256=7d0i8cNMAMX7aQjd2yebMDdqQkugcCzk-SD6oVtf18M,333
|
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=
|
13
|
+
pymammotion/bluetooth/ble.py,sha256=XQWJBpSzeIawCrLTsVrq9LI6jmM_ALVTttUkosK2BRM,2480
|
14
14
|
pymammotion/bluetooth/ble_message.py,sha256=47xoj22Kw5XF9VT965J_BxpvTdOgSXy4opqkbsojvDo,18795
|
15
15
|
pymammotion/bluetooth/const.py,sha256=CCqyHsYbB0BAYjwdhXt_n6eWWxmhlUrAFjvVv57mbvE,1749
|
16
16
|
pymammotion/bluetooth/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -31,7 +31,7 @@ pymammotion/data/model/enums.py,sha256=EpKmO8yVUZyEnTY4yH0DMMVKYNQM42zpW1maUu0i3
|
|
31
31
|
pymammotion/data/model/excute_boarder_params.py,sha256=9CpUqrygcle1C_1hDW-riLmm4map4ZbE842NXjcomEI,1394
|
32
32
|
pymammotion/data/model/execute_boarder.py,sha256=9rd_h4fbcsXxgnLOd2rO2hWyD1abnTGc47QTEpp8DD0,1103
|
33
33
|
pymammotion/data/model/generate_route_information.py,sha256=pgjqURwmEIzjCMbl4Z5JDDkfxyUAdry1KhPfyir3-mU,777
|
34
|
-
pymammotion/data/model/hash_list.py,sha256=
|
34
|
+
pymammotion/data/model/hash_list.py,sha256=xbvve9t-VcsN_ezrWjkZyLKCdji4Ii0ota9R1fhrr4g,9926
|
35
35
|
pymammotion/data/model/location.py,sha256=PwmITejfI4pm7PI4rzqSuuHetwle6IJr_CV95435s2M,871
|
36
36
|
pymammotion/data/model/mowing_modes.py,sha256=bBbRhDe-imZsXDR0TN0emQv6BiIkAlXJFb5isPEjgDk,1078
|
37
37
|
pymammotion/data/model/plan.py,sha256=wGlcJT-w0EdbWK9jI838TCOm_MABFg7WoR664VB8RWg,2880
|
@@ -52,30 +52,30 @@ pymammotion/http/http.py,sha256=t4GWoF8qfCvFCVDR5-koIwSq-rEq-vYmQYLNbpwIDQ4,6871
|
|
52
52
|
pymammotion/http/model/http.py,sha256=tM5ikwVkWhRdXc2xi1NOLmWPH2mQEQelpaVgMlAEmlI,2333
|
53
53
|
pymammotion/mammotion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
54
|
pymammotion/mammotion/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
55
|
-
pymammotion/mammotion/commands/abstract_message.py,sha256=
|
56
|
-
pymammotion/mammotion/commands/mammotion_command.py,sha256=
|
55
|
+
pymammotion/mammotion/commands/abstract_message.py,sha256=C1teY4Bd_BpBhAWWzKokoeXm7bjvDeV0sDL5CVpoyhI,829
|
56
|
+
pymammotion/mammotion/commands/mammotion_command.py,sha256=3OFXQjF7HFwPd_j6utHVI2Kfwh7t6_6ff_9MKAWGTlk,2570
|
57
57
|
pymammotion/mammotion/commands/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
58
|
-
pymammotion/mammotion/commands/messages/driver.py,sha256=
|
59
|
-
pymammotion/mammotion/commands/messages/media.py,sha256=
|
60
|
-
pymammotion/mammotion/commands/messages/navigation.py,sha256=
|
61
|
-
pymammotion/mammotion/commands/messages/network.py,sha256=
|
62
|
-
pymammotion/mammotion/commands/messages/ota.py,sha256=
|
63
|
-
pymammotion/mammotion/commands/messages/system.py,sha256=
|
64
|
-
pymammotion/mammotion/commands/messages/video.py,sha256=
|
58
|
+
pymammotion/mammotion/commands/messages/driver.py,sha256=7lVfk3bHymgNf3toVhqYmCq8KrLTk_OaNz3oTmT_xY8,3647
|
59
|
+
pymammotion/mammotion/commands/messages/media.py,sha256=NUmd6W5171sOZZ08GhUCqzpGMptVqXC36t-H3i42tOQ,1282
|
60
|
+
pymammotion/mammotion/commands/messages/navigation.py,sha256=05ZstacaIqTcuSkDox-EVbt5aUIbuajflros_Tmm8I4,23248
|
61
|
+
pymammotion/mammotion/commands/messages/network.py,sha256=oO3PK6TKY563Jw-ZRpNmIzGCgkuk2SQm0BhcDL5claM,7595
|
62
|
+
pymammotion/mammotion/commands/messages/ota.py,sha256=ZHLQRE5ETvLEIu2Vbj3m2XidIWT8uorYSHxkZd3pkRc,1376
|
63
|
+
pymammotion/mammotion/commands/messages/system.py,sha256=ScXlurQAy8Z9WntXBRrxThnsVHFWfiNNltEWh-SVcvQ,14811
|
64
|
+
pymammotion/mammotion/commands/messages/video.py,sha256=YQGIxKx2prA0X01ovNmMkX6YfjuQKlq1KF5z_eRwfws,1195
|
65
65
|
pymammotion/mammotion/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
66
66
|
pymammotion/mammotion/control/joystick.py,sha256=QfBVxM_gxpWsZAGO90whtgxCI2tIZ3TTad9wHIPsU9s,5640
|
67
67
|
pymammotion/mammotion/devices/__init__.py,sha256=f2qQFPgLGmV85W2hSlMUh5BYuht9o_Ar_JEAAMD4fsE,102
|
68
|
-
pymammotion/mammotion/devices/base.py,sha256=
|
68
|
+
pymammotion/mammotion/devices/base.py,sha256=nzXpybSLX7o7ASVt85WYrmi0ycsATeQe-8ePMaQXXFY,10415
|
69
69
|
pymammotion/mammotion/devices/mammotion.py,sha256=Zz2tUIdGA-jFSHLM3aO8tBMvVl7sBIBiqC9Kg7f-lm8,13190
|
70
|
-
pymammotion/mammotion/devices/mammotion_bluetooth.py,sha256=
|
71
|
-
pymammotion/mammotion/devices/mammotion_cloud.py,sha256=
|
70
|
+
pymammotion/mammotion/devices/mammotion_bluetooth.py,sha256=0c-HXawLQVHz28s0HKaSCNq4wmLWJZZ3ATDVnCXdSrc,19579
|
71
|
+
pymammotion/mammotion/devices/mammotion_cloud.py,sha256=gLdxaD759QphR10LsQchTTOHZi6jvnI2EHlbhMfsXvE,14373
|
72
72
|
pymammotion/mqtt/__init__.py,sha256=Ocs5e-HLJvTuDpVXyECEsWIvwsUaxzj7lZ9mSYutNDY,105
|
73
73
|
pymammotion/mqtt/linkkit/__init__.py,sha256=ENgc3ynd2kd9gMQR3-kgmCu6Ed9Y6XCIzU0zFReUlkk,80
|
74
74
|
pymammotion/mqtt/linkkit/h2client.py,sha256=w9Nvi_nY4CLD_fw-pHtYChwQf7e2TiAGeqkY_sF4cf0,19659
|
75
75
|
pymammotion/mqtt/linkkit/linkkit.py,sha256=NzFpdtfxNHQ6xNu-POyp45fTK7AWUAWV7RavFevX4m4,132772
|
76
76
|
pymammotion/mqtt/mammotion_future.py,sha256=_OWqKOlUGl2yT1xOsXFQYpGd-1zQ63OxqXgy7KRQgYc,710
|
77
77
|
pymammotion/mqtt/mammotion_mqtt.py,sha256=urqhTIXabJ8QGAkArPZZQAm7CJQiA00912mviotTSds,10194
|
78
|
-
pymammotion/proto/__init__.py,sha256=
|
78
|
+
pymammotion/proto/__init__.py,sha256=qKfF78NyD__2p1URDpzhCHa9EsIxKbXHUhTuep7esWQ,72200
|
79
79
|
pymammotion/proto/basestation.proto,sha256=_x5gAz3FkZXS1jtq4GgZgaDCuRU-UV-7HTFdsfQ3zbo,1034
|
80
80
|
pymammotion/proto/basestation_pb2.py,sha256=PTVlHcDLQeRV6qv7ZPjGke9MF68mpqoUeJA0Sw_AoT0,2776
|
81
81
|
pymammotion/proto/basestation_pb2.pyi,sha256=eeYW9l_5OsokGzP9OE_lg6TdJwXGAFvPiojQ3tipcak,3970
|
@@ -117,7 +117,7 @@ pymammotion/utility/map.py,sha256=GYscVMg2cX3IPlNpCBNHDW0S55yS1WGRf1iHnNZ7TfQ,22
|
|
117
117
|
pymammotion/utility/movement.py,sha256=N75oAoAgFydqoaOedYIxGUHmuTCtPzAOtb-d_29tpfI,615
|
118
118
|
pymammotion/utility/periodic.py,sha256=MbeSb9cfhxzYmdT_RiE0dZe3H9IfbQW_zSqhmSX2RUc,3321
|
119
119
|
pymammotion/utility/rocker_util.py,sha256=6tX7sS87qoQC_tsxbx3NLL-HgS08wtzXiZkhDiz7uo0,7179
|
120
|
-
pymammotion-0.4.
|
121
|
-
pymammotion-0.4.
|
122
|
-
pymammotion-0.4.
|
123
|
-
pymammotion-0.4.
|
120
|
+
pymammotion-0.4.12.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
121
|
+
pymammotion-0.4.12.dist-info/METADATA,sha256=7OOHH8HQ2IzfLTBV7avw8fyUMUBu_i72OoQGDWkeXSg,3834
|
122
|
+
pymammotion-0.4.12.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
123
|
+
pymammotion-0.4.12.dist-info/RECORD,,
|
File without changes
|