pymammotion 0.2.47__py3-none-any.whl → 0.2.49__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.
@@ -3,7 +3,7 @@ from enum import IntEnum
3
3
 
4
4
  from mashumaro.mixins.orjson import DataClassORJSONMixin
5
5
 
6
- from pymammotion.proto.mctrl_nav import AreaHashName, NavGetCommDataAck
6
+ from pymammotion.proto.mctrl_nav import NavGetCommDataAck, NavGetHashListAck
7
7
 
8
8
 
9
9
  class PathType(IntEnum):
@@ -20,6 +20,12 @@ class FrameList(DataClassORJSONMixin):
20
20
  data: list[NavGetCommDataAck]
21
21
 
22
22
 
23
+ @dataclass
24
+ class RootHashList(DataClassORJSONMixin):
25
+ total_frame: int = 1
26
+ data: list[NavGetHashListAck] = field(default_factory=list)
27
+
28
+
23
29
  @dataclass
24
30
  class AreaHashNameList(DataClassORJSONMixin):
25
31
  """Wrapper so we can serialize to and from dict."""
@@ -35,18 +41,38 @@ class HashList(DataClassORJSONMixin):
35
41
  hashlist for all our hashIDs for verification
36
42
  """
37
43
 
44
+ root_hash_list: RootHashList = field(default_factory=RootHashList)
38
45
  area: dict = field(default_factory=dict) # type 0
39
46
  path: dict = field(default_factory=dict) # type 2
40
47
  obstacle: dict = field(default_factory=dict) # type 1
41
- hashlist: list[int] = field(default_factory=list)
42
48
  area_name: list[AreaHashNameList] = field(default_factory=list)
43
49
 
44
- def set_hashlist(self, hashlist: list[int]) -> None:
45
- self.hashlist = [x for x in hashlist if not (x in self.hashlist or self.hashlist.append(x))]
50
+ def update_hash_lists(self, hashlist: list[int]) -> None:
46
51
  self.area = {hash_id: frames for hash_id, frames in self.area.items() if hash_id in hashlist}
47
52
  self.path = {hash_id: frames for hash_id, frames in self.path.items() if hash_id in hashlist}
48
53
  self.obstacle = {hash_id: frames for hash_id, frames in self.obstacle.items() if hash_id in hashlist}
49
54
 
55
+ @property
56
+ def hashlist(self) -> list[int]:
57
+ return [i for obj in self.root_hash_list.data for i in obj.data_couple]
58
+
59
+ def update_root_hash_list(self, hash_list: NavGetHashListAck) -> None:
60
+ self.root_hash_list.total_frame = hash_list.total_frame
61
+
62
+ for index, obj in enumerate(self.root_hash_list.data):
63
+ if obj.current_frame == hash_list.current_frame:
64
+ # Replace the item if current_frame matches
65
+ self.root_hash_list.data[index] = hash_list
66
+ self.update_hash_lists(self.hashlist)
67
+ return
68
+
69
+ # If no match was found, append the new item
70
+ self.root_hash_list.data.append(hash_list)
71
+ self.update_hash_lists(self.hashlist)
72
+
73
+ def missing_hash_frame(self):
74
+ return self._find_missing_frames(self.root_hash_list)
75
+
50
76
  def missing_frame(self, hash_data: NavGetCommDataAck) -> list[int]:
51
77
  if hash_data.type == PathType.AREA:
52
78
  return self._find_missing_frames(self.area.get(hash_data.hash))
@@ -62,7 +88,7 @@ class HashList(DataClassORJSONMixin):
62
88
  if hash_data.type == PathType.AREA:
63
89
  existing_name = next((area for area in self.area_name if area.hash == hash_data.hash), None)
64
90
  if not existing_name:
65
- self.area_name.append(AreaHashName(name=f"area {len(self.area_name)+1}", hash=hash_data.hash))
91
+ self.area_name.append(AreaHashNameList(name=f"area {len(self.area_name)+1}", hash=hash_data.hash))
66
92
  return self._add_hash_data(self.area, hash_data)
67
93
 
68
94
  if hash_data.type == PathType.OBSTACLE:
@@ -72,7 +98,7 @@ class HashList(DataClassORJSONMixin):
72
98
  return self._add_hash_data(self.path, hash_data)
73
99
 
74
100
  @staticmethod
75
- def _find_missing_frames(frame_list: FrameList) -> list[int]:
101
+ def _find_missing_frames(frame_list: FrameList | RootHashList) -> list[int]:
76
102
  if frame_list.total_frame == len(frame_list.data):
77
103
  return []
78
104
  number_list = list(range(1, frame_list.total_frame + 1))
@@ -62,7 +62,7 @@ class StateManager:
62
62
  match nav_msg[0]:
63
63
  case "toapp_gethash_ack":
64
64
  hashlist_ack: NavGetHashListAck = nav_msg[1]
65
- self._device.map.set_hashlist(hashlist_ack.data_couple)
65
+ self._device.map.update_root_hash_list(hashlist_ack)
66
66
  await self.gethash_ack_callback(nav_msg[1])
67
67
  case "toapp_get_commondata_ack":
68
68
  common_data: NavGetCommDataAck = nav_msg[1]
@@ -9,7 +9,6 @@ from pymammotion.aliyun.model.dev_by_account_response import Device
9
9
  from pymammotion.data.model import RegionData
10
10
  from pymammotion.data.model.device import MowingDevice
11
11
  from pymammotion.data.state_manager import StateManager
12
- from pymammotion.proto import has_field
13
12
  from pymammotion.proto.luba_msg import LubaMsg
14
13
  from pymammotion.proto.mctrl_nav import NavGetCommDataAck, NavGetHashListAck
15
14
 
@@ -55,7 +54,15 @@ class MammotionBaseDevice:
55
54
 
56
55
  async def datahash_response(self, hash_ack: NavGetHashListAck) -> None:
57
56
  """Handle datahash responses."""
58
- await self.queue_command("synchronize_hash_data", hash_num=hash_ack.data_couple[0])
57
+ current_frame = hash_ack.current_frame
58
+
59
+ missing_frames = self.mower.map.missing_hash_frame()
60
+ if len(missing_frames) == 0:
61
+ return await self.queue_command("synchronize_hash_data", hash_num=self.mower.map.hashlist)
62
+
63
+ if current_frame != missing_frames[0] - 1:
64
+ current_frame = missing_frames[0] - 1
65
+ await self.queue_command("get_hash_response", total_frame=hash_ack.total_frame, current_frame=current_frame)
59
66
 
60
67
  async def commdata_response(self, common_data: NavGetCommDataAck) -> None:
61
68
  """Handle common data responses."""
@@ -66,7 +73,7 @@ class MammotionBaseDevice:
66
73
  if len(missing_frames) == 0:
67
74
  # get next in hash ack list
68
75
 
69
- data_hash = find_next_integer(self.mower.nav.toapp_gethash_ack.data_couple, common_data.hash)
76
+ data_hash = find_next_integer(self.mower.map.hashlist, common_data.hash)
70
77
  if data_hash is None:
71
78
  return
72
79
 
@@ -201,22 +208,16 @@ class MammotionBaseDevice:
201
208
 
202
209
  async def start_map_sync(self) -> None:
203
210
  """Start sync of map data."""
204
- try:
205
- # work out why this crashes sometimes for better proto
206
211
 
207
- if self._cloud_device and len(self.mower.map.area_name) == 0:
208
- await self.queue_command("get_area_name_list", device_id=self._cloud_device.iotId)
209
- except Exception:
210
- """Do nothing for now."""
212
+ if self._cloud_device and len(self.mower.map.area_name) == 0:
213
+ await self.queue_command("get_area_name_list", device_id=self._cloud_device.iotId)
211
214
 
212
215
  await self.queue_command("read_plan", sub_cmd=2, plan_index=0)
213
216
 
214
- if not has_field(self.mower.nav.toapp_gethash_ack):
215
- await self.queue_command("get_all_boundary_hash_list", sub_cmd=0)
216
- await self.queue_command("get_hash_response", total_frame=1, current_frame=1)
217
- else:
218
- for data_hash in self.mower.nav.toapp_gethash_ack.data_couple:
219
- await self.queue_command("synchronize_hash_data", hash_num=data_hash)
217
+ await self.queue_command("get_all_boundary_hash_list", sub_cmd=0)
218
+ await self.queue_command("get_hash_response", total_frame=1, current_frame=1)
219
+ for data_hash in self.mower.map.hashlist:
220
+ await self.queue_command("synchronize_hash_data", hash_num=data_hash)
220
221
 
221
222
  # sub_cmd 3 is job hashes??
222
223
  # sub_cmd 4 is dump location (yuka)
@@ -247,8 +247,8 @@ class Mammotion:
247
247
  await loop.run_in_executor(None, cloud_client.list_binding_by_account)
248
248
  return cloud_client
249
249
 
250
- def remove_device(self, name: str) -> None:
251
- self.devices.remove_device(name)
250
+ async def remove_device(self, name: str) -> None:
251
+ await self.devices.remove_device(name)
252
252
 
253
253
  def get_device_by_name(self, name: str) -> MammotionMixedDeviceManager:
254
254
  return self.devices.get_device(name)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pymammotion
3
- Version: 0.2.47
3
+ Version: 0.2.49
4
4
  Summary:
5
5
  License: GNU-3.0
6
6
  Author: Michael Arthur
@@ -28,7 +28,7 @@ pymammotion/data/model/enums.py,sha256=EpKmO8yVUZyEnTY4yH0DMMVKYNQM42zpW1maUu0i3
28
28
  pymammotion/data/model/excute_boarder_params.py,sha256=9CpUqrygcle1C_1hDW-riLmm4map4ZbE842NXjcomEI,1394
29
29
  pymammotion/data/model/execute_boarder.py,sha256=9rd_h4fbcsXxgnLOd2rO2hWyD1abnTGc47QTEpp8DD0,1103
30
30
  pymammotion/data/model/generate_route_information.py,sha256=MkUBoqGtCAKmiVQ4Q1pEoDVHZs5uLIo7vhfWT4nGbtY,801
31
- pymammotion/data/model/hash_list.py,sha256=Tj4yYOr4jlOj5oU1rw-ypUNsx3Q76QCwM6M_PZrAgaI,3463
31
+ pymammotion/data/model/hash_list.py,sha256=WMnXddqHGWz3Htiof2xhcXMcHLvqjNcsDWuXAQlllVo,4394
32
32
  pymammotion/data/model/location.py,sha256=PwmITejfI4pm7PI4rzqSuuHetwle6IJr_CV95435s2M,871
33
33
  pymammotion/data/model/mowing_modes.py,sha256=5TrHSijUyPtIDWpNtgzx_vFQukRJWRz4gIrUaXggKPw,827
34
34
  pymammotion/data/model/plan.py,sha256=mcadkSL7fQXy0iJ0q786I3GEQY4i6kmQXfW6Ri69lcQ,2906
@@ -39,7 +39,7 @@ pymammotion/data/mqtt/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdr
39
39
  pymammotion/data/mqtt/event.py,sha256=plt53w3kHulB_MfbkxK9j7AfdQ5ahVU2s4kiQMoLio4,4612
40
40
  pymammotion/data/mqtt/properties.py,sha256=HkBPghr26L9_b4QaOi1DtPgb0UoPIOGSe9wb3kgnM6Y,2815
41
41
  pymammotion/data/mqtt/status.py,sha256=zqnlo-MzejEQZszl0i0Wucoc3E76x6UtI9JLxoBnu54,1067
42
- pymammotion/data/state_manager.py,sha256=sP-y5jUFpL19sRwuaaSZcdGCn8jNOJhLg5sEkOTJhEw,4104
42
+ pymammotion/data/state_manager.py,sha256=bGZXaiIosNTrN0L8DmddLqL2MRKbixKmyd2XFiZMCTE,4101
43
43
  pymammotion/event/__init__.py,sha256=mgATR6vPHACNQ-0zH5fi7NdzeTCDV1CZyaWPmtUusi8,115
44
44
  pymammotion/event/event.py,sha256=UzYnxV5DfvMDK3E06UvSzvzuBbaXOOUwO6xYt_zn9To,2034
45
45
  pymammotion/http/_init_.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -60,8 +60,8 @@ pymammotion/mammotion/commands/messages/video.py,sha256=_8lJsU4sLm2CGnc7RDkueA0A
60
60
  pymammotion/mammotion/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
61
  pymammotion/mammotion/control/joystick.py,sha256=QfBVxM_gxpWsZAGO90whtgxCI2tIZ3TTad9wHIPsU9s,5640
62
62
  pymammotion/mammotion/devices/__init__.py,sha256=f2qQFPgLGmV85W2hSlMUh5BYuht9o_Ar_JEAAMD4fsE,102
63
- pymammotion/mammotion/devices/base.py,sha256=6g0q94h1RZDtmYEL85SsFkn1F5BegQy_WC5a9hn8kqQ,9665
64
- pymammotion/mammotion/devices/mammotion.py,sha256=UyIPKY7XMy7zlfwKXmZetIw70bY5Ob8crhF6A-pU5Wo,12283
63
+ pymammotion/mammotion/devices/base.py,sha256=o3G-A6JciBq2AUZaPdHtp6q9pp3blOxYb1ySI3Fg_Gk,9717
64
+ pymammotion/mammotion/devices/mammotion.py,sha256=ForzwnQu1IRxtwsFMHAudFCtOAUJC01BcX5RK7dYYcs,12295
65
65
  pymammotion/mammotion/devices/mammotion_bluetooth.py,sha256=nyO7pkKgAoRPs-28ESf6ee-y3G5JTYRO-MCp4wKPMlE,17476
66
66
  pymammotion/mammotion/devices/mammotion_cloud.py,sha256=Q1Il0nCxH-8utg_9AKAY3HxuuhB78uHZV4yVpZ4k1TI,11282
67
67
  pymammotion/mqtt/__init__.py,sha256=Ocs5e-HLJvTuDpVXyECEsWIvwsUaxzj7lZ9mSYutNDY,105
@@ -118,7 +118,7 @@ pymammotion/utility/map.py,sha256=GYscVMg2cX3IPlNpCBNHDW0S55yS1WGRf1iHnNZ7TfQ,22
118
118
  pymammotion/utility/movement.py,sha256=N75oAoAgFydqoaOedYIxGUHmuTCtPzAOtb-d_29tpfI,615
119
119
  pymammotion/utility/periodic.py,sha256=MbeSb9cfhxzYmdT_RiE0dZe3H9IfbQW_zSqhmSX2RUc,3321
120
120
  pymammotion/utility/rocker_util.py,sha256=6tX7sS87qoQC_tsxbx3NLL-HgS08wtzXiZkhDiz7uo0,7179
121
- pymammotion-0.2.47.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
122
- pymammotion-0.2.47.dist-info/METADATA,sha256=bNQeK12Z3_33er6aQINFxdnR5vdbKoD35Jqg612MCrI,4052
123
- pymammotion-0.2.47.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
124
- pymammotion-0.2.47.dist-info/RECORD,,
121
+ pymammotion-0.2.49.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
122
+ pymammotion-0.2.49.dist-info/METADATA,sha256=Qw3Jl5LZDfCw9TOlEParI4X8ZffLGJiJdlHyWSRo2fQ,4052
123
+ pymammotion-0.2.49.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
124
+ pymammotion-0.2.49.dist-info/RECORD,,