pymammotion 0.4.0b8__py3-none-any.whl → 0.4.2__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.
Files changed (42) hide show
  1. pymammotion/bluetooth/ble_message.py +6 -7
  2. pymammotion/data/model/device.py +2 -7
  3. pymammotion/data/model/device_limits.py +4 -4
  4. pymammotion/data/model/hash_list.py +84 -10
  5. pymammotion/data/model/raw_data.py +1 -8
  6. pymammotion/data/state_manager.py +30 -10
  7. pymammotion/mammotion/commands/abstract_message.py +2 -2
  8. pymammotion/mammotion/commands/messages/driver.py +27 -20
  9. pymammotion/mammotion/commands/messages/media.py +13 -14
  10. pymammotion/mammotion/commands/messages/navigation.py +16 -13
  11. pymammotion/mammotion/commands/messages/network.py +13 -10
  12. pymammotion/mammotion/commands/messages/ota.py +9 -14
  13. pymammotion/mammotion/commands/messages/system.py +36 -25
  14. pymammotion/mammotion/commands/messages/video.py +8 -10
  15. pymammotion/mammotion/devices/base.py +10 -10
  16. pymammotion/mammotion/devices/mammotion.py +18 -14
  17. pymammotion/mammotion/devices/mammotion_bluetooth.py +2 -3
  18. pymammotion/mammotion/devices/mammotion_cloud.py +1 -2
  19. pymammotion/mqtt/mammotion_mqtt.py +1 -1
  20. pymammotion/proto/__init__.py +2174 -1
  21. pymammotion/proto/luba_mul_pb2.py +8 -8
  22. pymammotion/proto/luba_mul_pb2.pyi +1 -0
  23. pymammotion/proto/mctrl_nav.proto +3 -3
  24. pymammotion/proto/mctrl_nav_pb2.py +69 -67
  25. pymammotion/proto/mctrl_nav_pb2.pyi +13 -5
  26. pymammotion/proto/mctrl_sys_pb2.py +41 -37
  27. pymammotion/proto/mctrl_sys_pb2.pyi +34 -11
  28. pymammotion/utility/device_config.py +121 -121
  29. {pymammotion-0.4.0b8.dist-info → pymammotion-0.4.2.dist-info}/METADATA +1 -1
  30. {pymammotion-0.4.0b8.dist-info → pymammotion-0.4.2.dist-info}/RECORD +32 -42
  31. pymammotion/proto/basestation.py +0 -59
  32. pymammotion/proto/common.py +0 -12
  33. pymammotion/proto/dev_net.py +0 -381
  34. pymammotion/proto/luba_msg.py +0 -81
  35. pymammotion/proto/luba_mul.py +0 -77
  36. pymammotion/proto/mctrl_driver.py +0 -100
  37. pymammotion/proto/mctrl_nav.py +0 -664
  38. pymammotion/proto/mctrl_ota.py +0 -48
  39. pymammotion/proto/mctrl_pept.py +0 -41
  40. pymammotion/proto/mctrl_sys.py +0 -574
  41. {pymammotion-0.4.0b8.dist-info → pymammotion-0.4.2.dist-info}/LICENSE +0 -0
  42. {pymammotion-0.4.0b8.dist-info → pymammotion-0.4.2.dist-info}/WHEEL +0 -0
@@ -16,8 +16,7 @@ from pymammotion.bluetooth.data.framectrldata import FrameCtrlData
16
16
  from pymammotion.bluetooth.data.notifydata import BlufiNotifyData
17
17
  from pymammotion.bluetooth.model.atomic_integer import AtomicInteger
18
18
  from pymammotion.data.model.execute_boarder import ExecuteBorder
19
- from pymammotion.proto import dev_net_pb2
20
- from pymammotion.proto.luba_msg import LubaMsg, MsgAttr, MsgCmdType, MsgDevice
19
+ from pymammotion.proto import DevNet, DrvDevInfoReq, LubaMsg, MsgAttr, MsgCmdType, MsgDevice
21
20
  from pymammotion.utility.constant.device_constant import bleOrderCmd
22
21
 
23
22
  _LOGGER = logging.getLogger(__name__)
@@ -317,7 +316,7 @@ class BleMessage:
317
316
  hash_map = {"ctrl": 1}
318
317
  await self.post_custom_data(self.get_json_string(bleOrderCmd.bleAlive, hash_map))
319
318
 
320
- def get_json_string(self, cmd: int, hash_map: dict[str, object]) -> str:
319
+ def get_json_string(self, cmd: int, hash_map: dict[str, int]) -> str:
321
320
  jSONObject = {}
322
321
  try:
323
322
  jSONObject["cmd"] = cmd
@@ -331,7 +330,7 @@ class BleMessage:
331
330
  print(e)
332
331
  return ""
333
332
 
334
- def clearNotification(self) -> None:
333
+ def clear_notification(self) -> None:
335
334
  self.notification = None
336
335
  self.notification = BlufiNotifyData()
337
336
 
@@ -341,14 +340,14 @@ class BleMessage:
341
340
  async def send_device_info(self) -> None:
342
341
  """Currently not called"""
343
342
  luba_msg = LubaMsg(
344
- msgtype=MsgCmdType.MSG_CMD_TYPE_ESP,
343
+ msgtype=MsgCmdType.ESP,
345
344
  sender=MsgDevice.DEV_MOBILEAPP,
346
345
  rcver=MsgDevice.DEV_COMM_ESP,
347
- msgattr=MsgAttr.MSG_ATTR_REQ,
346
+ msgattr=MsgAttr.REQ,
348
347
  seqs=1,
349
348
  version=1,
350
349
  subtype=1,
351
- net=dev_net_pb2.DevNet(todev_ble_sync=1, todev_devinfo_req=dev_net_pb2.DrvDevInfoReq()),
350
+ net=DevNet(todev_ble_sync=1, todev_devinfo_req=DrvDevInfoReq()),
352
351
  )
353
352
  byte_arr = luba_msg.SerializeToString()
354
353
  await self.post_custom_data_bytes(byte_arr)
@@ -12,13 +12,7 @@ from pymammotion.data.model.report_info import ReportData
12
12
  from pymammotion.data.mqtt.properties import ThingPropertiesMessage
13
13
  from pymammotion.data.mqtt.status import ThingStatusMessage
14
14
  from pymammotion.http.model.http import ErrorInfo
15
- from pymammotion.proto.mctrl_sys import (
16
- DeviceFwInfo,
17
- MowToAppInfoT,
18
- ReportInfoData,
19
- SystemRapidStateTunnelMsg,
20
- SystemUpdateBufMsg,
21
- )
15
+ from pymammotion.proto import DeviceFwInfo, MowToAppInfoT, ReportInfoData, SystemRapidStateTunnelMsg, SystemUpdateBufMsg
22
16
  from pymammotion.utility.constant import WorkMode
23
17
  from pymammotion.utility.conversions import parse_double
24
18
  from pymammotion.utility.map import CoordinateConverter
@@ -28,6 +22,7 @@ from pymammotion.utility.map import CoordinateConverter
28
22
  class MowingDevice(DataClassORJSONMixin):
29
23
  """Wraps the betterproto dataclasses, so we can bypass the groups for keeping all data."""
30
24
 
25
+ name: str = ""
31
26
  online: bool = True
32
27
  mower_state: MowerInfo = field(default_factory=MowerInfo)
33
28
  mqtt_properties: ThingPropertiesMessage | None = None
@@ -9,7 +9,7 @@ class RangeLimit:
9
9
 
10
10
  @dataclass
11
11
  class DeviceLimits:
12
- cutter_height: RangeLimit = field(default_factory=RangeLimit)
12
+ blade_height: RangeLimit = field(default_factory=RangeLimit)
13
13
  working_speed: RangeLimit = field(default_factory=RangeLimit)
14
14
  working_path: RangeLimit = field(default_factory=RangeLimit)
15
15
  work_area_num_max: int = 60
@@ -18,7 +18,7 @@ class DeviceLimits:
18
18
  def to_dict(self) -> dict:
19
19
  """Convert the device limits to a dictionary format."""
20
20
  return {
21
- "cutter_height": {"min": self.cutter_height.min, "max": self.cutter_height.max},
21
+ "blade_height": {"min": self.blade_height.min, "max": self.blade_height.max},
22
22
  "working_speed": {"min": self.working_speed.min, "max": self.working_speed.max},
23
23
  "working_path": {"min": self.working_path.min, "max": self.working_path.max},
24
24
  "work_area_num_max": self.work_area_num_max,
@@ -29,7 +29,7 @@ class DeviceLimits:
29
29
  def from_dict(cls, data: dict) -> "DeviceLimits":
30
30
  """Create a DeviceLimits instance from a dictionary."""
31
31
  return cls(
32
- cutter_height=RangeLimit(min=data["cutter_height"]["min"], max=data["cutter_height"]["max"]),
32
+ blade_height=RangeLimit(min=data["blade_height"]["min"], max=data["blade_height"]["max"]),
33
33
  working_speed=RangeLimit(min=data["working_speed"]["min"], max=data["working_speed"]["max"]),
34
34
  working_path=RangeLimit(min=data["working_path"]["min"], max=data["working_path"]["max"]),
35
35
  work_area_num_max=data["work_area_num_max"],
@@ -40,7 +40,7 @@ class DeviceLimits:
40
40
  """Validate that all ranges are logical (min <= max)."""
41
41
  return all(
42
42
  [
43
- self.cutter_height.min <= self.cutter_height.max,
43
+ self.blade_height.min <= self.blade_height.max,
44
44
  self.working_speed.min <= self.working_speed.max,
45
45
  self.working_path.min <= self.working_path.max,
46
46
  self.work_area_num_max > 0,
@@ -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 NavGetCommDataAck, NavGetHashListAck, SvgMessageAckT
6
+ from pymammotion.proto import NavGetCommDataAck, SvgMessageAckT
7
7
 
8
8
 
9
9
  class PathType(IntEnum):
@@ -16,21 +16,91 @@ class PathType(IntEnum):
16
16
  SVG = 13
17
17
 
18
18
 
19
+ @dataclass
20
+ class CommDataCouple:
21
+ x: float = 0.0
22
+ y: float = 0.0
23
+
24
+
25
+ @dataclass
26
+ class AreaLabelName(DataClassORJSONMixin):
27
+ label: str = ""
28
+
29
+
30
+ @dataclass
31
+ class NavGetCommData(DataClassORJSONMixin):
32
+ pver: int = 0
33
+ sub_cmd: int = 0
34
+ result: int = 0
35
+ action: int = 0
36
+ type: int = 0
37
+ hash: int = 0
38
+ paternal_hash_a: int = 0
39
+ paternal_hash_b: int = 0
40
+ total_frame: int = 0
41
+ current_frame: int = 0
42
+ data_hash: int = 0
43
+ data_len: int = 0
44
+ data_couple: list["CommDataCouple"] = field(default_factory=list)
45
+ reserved: str = ""
46
+ area_label: "AreaLabelName" = field(default_factory=AreaLabelName)
47
+
48
+
49
+ @dataclass
50
+ class SvgMessageData(DataClassORJSONMixin):
51
+ x_move: float = 0.0
52
+ y_move: float = 0.0
53
+ scale: float = 0.0
54
+ rotate: float = 0.0
55
+ base_width_m: float = 0.0
56
+ base_width_pix: int = 0
57
+ base_height_m: float = 0.0
58
+ base_height_pix: int = 0
59
+ data_count: int = 0
60
+ hide_svg: bool = False
61
+ name_count: int = 0
62
+ svg_file_name: str = ""
63
+ svg_file_data: str = ""
64
+
65
+
66
+ @dataclass
67
+ class SvgMessage(DataClassORJSONMixin):
68
+ pver: int = 0
69
+ sub_cmd: int = 0
70
+ total_frame: int = 0
71
+ current_frame: int = 0
72
+ data_hash: int = 0
73
+ paternal_hash_a: int = 0
74
+ type: int = 0
75
+ result: int = 0
76
+ svg_message: "SvgMessageData" = field(default_factory=SvgMessageData)
77
+
78
+
19
79
  @dataclass
20
80
  class FrameList(DataClassORJSONMixin):
21
81
  total_frame: int
22
- data: list[NavGetCommDataAck | SvgMessageAckT]
82
+ data: list[NavGetCommData | SvgMessage]
23
83
 
24
84
 
25
- @dataclass
26
- class NavGetHashListData(DataClassORJSONMixin, NavGetHashListAck):
85
+ @dataclass(eq=False, repr=False)
86
+ class NavGetHashListData(DataClassORJSONMixin):
27
87
  """Dataclass for NavGetHashListData."""
28
88
 
89
+ pver: int = 0
90
+ sub_cmd: int = 0
91
+ total_frame: int = 0
92
+ current_frame: int = 0
93
+ data_hash: int = 0
94
+ hash_len: int = 0
95
+ reserved: str = ""
96
+ result: int = 0
97
+ data_couple: list[int] = field(default_factory=list)
98
+
29
99
 
30
100
  @dataclass
31
101
  class RootHashList(DataClassORJSONMixin):
32
102
  total_frame: int = 0
33
- data: list[NavGetHashListAck] = field(default_factory=list)
103
+ data: list[NavGetHashListData] = field(default_factory=list)
34
104
 
35
105
 
36
106
  @dataclass
@@ -81,7 +151,7 @@ class HashList(DataClassORJSONMixin):
81
151
  )
82
152
  ]
83
153
 
84
- def update_root_hash_list(self, hash_list: NavGetHashListAck) -> None:
154
+ def update_root_hash_list(self, hash_list: NavGetHashListData) -> None:
85
155
  self.root_hash_list.total_frame = hash_list.total_frame
86
156
 
87
157
  for index, obj in enumerate(self.root_hash_list.data):
@@ -93,7 +163,7 @@ class HashList(DataClassORJSONMixin):
93
163
  # If no match was found, append the new item
94
164
  self.root_hash_list.data.append(hash_list)
95
165
 
96
- def missing_hash_frame(self):
166
+ def missing_hash_frame(self) -> list[int]:
97
167
  return self._find_missing_frames(self.root_hash_list)
98
168
 
99
169
  def missing_frame(self, hash_data: NavGetCommDataAck | SvgMessageAckT) -> list[int]:
@@ -112,7 +182,9 @@ class HashList(DataClassORJSONMixin):
112
182
  if hash_data.type == PathType.SVG:
113
183
  return self._find_missing_frames(self.svg.get(hash_data.data_hash))
114
184
 
115
- def update(self, hash_data: NavGetCommDataAck | SvgMessageAckT) -> bool:
185
+ return []
186
+
187
+ def update(self, hash_data: NavGetCommData | SvgMessage) -> bool:
116
188
  """Update the map data."""
117
189
  if hash_data.type == PathType.AREA:
118
190
  existing_name = next((area for area in self.area_name if area.hash == hash_data.hash), None)
@@ -133,6 +205,8 @@ class HashList(DataClassORJSONMixin):
133
205
  if hash_data.type == PathType.SVG:
134
206
  return self._add_hash_data(self.svg, hash_data)
135
207
 
208
+ return False
209
+
136
210
  @staticmethod
137
211
  def _find_missing_frames(frame_list: FrameList | RootHashList) -> list[int]:
138
212
  if frame_list.total_frame == len(frame_list.data):
@@ -144,8 +218,8 @@ class HashList(DataClassORJSONMixin):
144
218
  return missing_numbers
145
219
 
146
220
  @staticmethod
147
- def _add_hash_data(hash_dict: dict, hash_data: NavGetCommDataAck | SvgMessageAckT) -> bool:
148
- if isinstance(hash_data, SvgMessageAckT):
221
+ def _add_hash_data(hash_dict: dict, hash_data: NavGetCommData | SvgMessage) -> bool:
222
+ if isinstance(hash_data, SvgMessage):
149
223
  if hash_dict.get(hash_data.data_hash) is None:
150
224
  hash_dict[hash_data.data_hash] = FrameList(total_frame=hash_data.total_frame, data=[hash_data])
151
225
  return True
@@ -2,14 +2,7 @@ from dataclasses import dataclass, field
2
2
 
3
3
  from mashumaro.mixins.orjson import DataClassORJSONMixin
4
4
 
5
- from pymammotion.proto.dev_net import DevNet
6
- from pymammotion.proto.luba_msg import LubaMsg
7
- from pymammotion.proto.luba_mul import SocMul
8
- from pymammotion.proto.mctrl_driver import MctlDriver
9
- from pymammotion.proto.mctrl_nav import MctlNav
10
- from pymammotion.proto.mctrl_ota import MctlOta
11
- from pymammotion.proto.mctrl_pept import MctlPept
12
- from pymammotion.proto.mctrl_sys import MctlSys
5
+ from pymammotion.proto import DevNet, LubaMsg, MctlDriver, MctlNav, MctlOta, MctlPept, MctlSys, SocMul
13
6
 
14
7
 
15
8
  @dataclass
@@ -9,13 +9,22 @@ import betterproto
9
9
 
10
10
  from pymammotion.data.model.device import MowingDevice
11
11
  from pymammotion.data.model.device_info import SideLight
12
- from pymammotion.data.model.hash_list import AreaHashNameList
12
+ from pymammotion.data.model.hash_list import AreaHashNameList, NavGetCommData, NavGetHashListData, SvgMessage
13
13
  from pymammotion.data.mqtt.properties import ThingPropertiesMessage
14
14
  from pymammotion.data.mqtt.status import ThingStatusMessage
15
- from pymammotion.proto.dev_net import DrvDevInfoResp, DrvDevInfoResult, WifiIotStatusReport
16
- from pymammotion.proto.luba_msg import LubaMsg
17
- from pymammotion.proto.mctrl_nav import AppGetAllAreaHashName, NavGetCommDataAck, NavGetHashListAck, SvgMessageAckT
18
- from pymammotion.proto.mctrl_sys import DeviceFwInfo, DeviceProductTypeInfoT, TimeCtrlLight
15
+ from pymammotion.proto import (
16
+ AppGetAllAreaHashName,
17
+ DeviceFwInfo,
18
+ DeviceProductTypeInfoT,
19
+ DrvDevInfoResp,
20
+ DrvDevInfoResult,
21
+ LubaMsg,
22
+ NavGetCommDataAck,
23
+ NavGetHashListAck,
24
+ SvgMessageAckT,
25
+ TimeCtrlLight,
26
+ WifiIotStatusReport,
27
+ )
19
28
 
20
29
  logger = logging.getLogger(__name__)
21
30
 
@@ -59,6 +68,8 @@ class StateManager:
59
68
  if not self._device.online:
60
69
  self._device.online = True
61
70
  self._device.status_properties = thing_status
71
+ if self._device.mower_state.product_key == "":
72
+ self._device.mower_state.product_key = thing_status.params.productKey
62
73
 
63
74
  @property
64
75
  def online(self) -> bool:
@@ -90,6 +101,9 @@ class StateManager:
90
101
  """Handle protobuf notifications."""
91
102
  res = betterproto.which_one_of(message, "LubaSubMsg")
92
103
  self.last_updated_at = datetime.now()
104
+ # additional catch all if we don't get a status update
105
+ if not self._device.online:
106
+ self._device.online = True
93
107
 
94
108
  match res[0]:
95
109
  case "nav":
@@ -113,18 +127,24 @@ class StateManager:
113
127
  match nav_msg[0]:
114
128
  case "toapp_gethash_ack":
115
129
  hashlist_ack: NavGetHashListAck = nav_msg[1]
116
- self._device.map.update_root_hash_list(hashlist_ack)
130
+ self._device.map.update_root_hash_list(
131
+ NavGetHashListData.from_dict(hashlist_ack.to_dict(casing=betterproto.Casing.SNAKE))
132
+ )
117
133
  await self.gethash_ack_callback(nav_msg[1])
118
134
  case "toapp_get_commondata_ack":
119
135
  common_data: NavGetCommDataAck = nav_msg[1]
120
- updated = self._device.map.update(common_data)
136
+ updated = self._device.map.update(
137
+ NavGetCommData.from_dict(common_data.to_dict(casing=betterproto.Casing.SNAKE))
138
+ )
121
139
  if updated:
122
140
  await self.get_commondata_ack_callback(common_data)
123
141
  case "toapp_svg_msg":
124
- common_data: SvgMessageAckT = nav_msg[1]
125
- updated = self._device.map.update(common_data)
142
+ common_svg_data: SvgMessageAckT = nav_msg[1]
143
+ updated = self._device.map.update(
144
+ SvgMessage.from_dict(common_svg_data.to_dict(casing=betterproto.Casing.SNAKE))
145
+ )
126
146
  if updated:
127
- await self.get_commondata_ack_callback(common_data)
147
+ await self.get_commondata_ack_callback(common_svg_data)
128
148
 
129
149
  case "toapp_all_hash_name":
130
150
  hash_names: AppGetAllAreaHashName = nav_msg[1]
@@ -1,6 +1,6 @@
1
1
  from abc import abstractmethod
2
2
 
3
- from pymammotion.proto.luba_msg import MsgCmdType, MsgDevice
3
+ from pymammotion.proto import MsgCmdType, MsgDevice
4
4
  from pymammotion.utility.device_type import DeviceType
5
5
 
6
6
 
@@ -16,7 +16,7 @@ class AbstractMessage:
16
16
  """Changes the rcver name if it's not a luba1."""
17
17
  if (
18
18
  not DeviceType.is_luba1(self.get_device_name(), self.get_device_product_key())
19
- and msg_type == MsgCmdType.MSG_CMD_TYPE_NAV
19
+ and msg_type == MsgCmdType.NAV
20
20
  ):
21
21
  return MsgDevice.DEV_NAVIGATION
22
22
  return msg_device
@@ -4,8 +4,19 @@ from logging import getLogger
4
4
  import time
5
5
 
6
6
  from pymammotion.mammotion.commands.abstract_message import AbstractMessage
7
- from pymammotion.proto import mctrl_driver
8
- from pymammotion.proto.luba_msg import LubaMsg, MsgAttr, MsgCmdType, MsgDevice
7
+ from pymammotion.proto import (
8
+ DrvKnifeHeight,
9
+ DrvMotionCtrl,
10
+ DrvMowCtrlByHand,
11
+ DrvSrSpeed,
12
+ LubaMsg,
13
+ MctlDriver,
14
+ MsgAttr,
15
+ MsgCmdType,
16
+ MsgDevice,
17
+ RtkCfgReqT,
18
+ RtkSysMaskQueryT,
19
+ )
9
20
 
10
21
  logger = getLogger(__name__)
11
22
 
@@ -13,10 +24,10 @@ logger = getLogger(__name__)
13
24
  class MessageDriver(AbstractMessage, ABC):
14
25
  def send_order_msg_driver(self, driver) -> bytes:
15
26
  return LubaMsg(
16
- msgtype=MsgCmdType.MSG_CMD_TYPE_EMBED_DRIVER,
27
+ msgtype=MsgCmdType.EMBED_DRIVER,
17
28
  sender=MsgDevice.DEV_MOBILEAPP,
18
- rcver=self.get_msg_device(MsgCmdType.MSG_CMD_TYPE_EMBED_DRIVER, MsgDevice.DEV_MAINCTL),
19
- msgattr=MsgAttr.MSG_ATTR_REQ,
29
+ rcver=self.get_msg_device(MsgCmdType.EMBED_DRIVER, MsgDevice.DEV_MAINCTL),
30
+ msgattr=MsgAttr.REQ,
20
31
  timestamp=round(time.time() * 1000),
21
32
  seqs=1,
22
33
  version=1,
@@ -26,25 +37,23 @@ class MessageDriver(AbstractMessage, ABC):
26
37
 
27
38
  def set_blade_height(self, height: int):
28
39
  logger.debug(f"Send knife height height={height}")
29
- build = mctrl_driver.MctlDriver(todev_knife_height_set=mctrl_driver.DrvKnifeHeight(knife_height=height))
40
+ build = MctlDriver(todev_knife_height_set=DrvKnifeHeight(knife_height=height))
30
41
  logger.debug(f"Send command--Knife motor height setting height={height}")
31
42
  return self.send_order_msg_driver(build)
32
43
 
33
44
  def set_speed(self, speed: float):
34
45
  logger.debug(f"{self.get_device_name()} set speed, {speed}")
35
- build = mctrl_driver.MctlDriver(bidire_speed_read_set=mctrl_driver.DrvSrSpeed(speed=speed, rw=1))
46
+ build = MctlDriver(bidire_speed_read_set=DrvSrSpeed(speed=speed, rw=1))
36
47
  logger.debug(f"Send command--Speed setting speed={speed}")
37
48
  return self.send_order_msg_driver(build)
38
49
 
39
50
  def syn_nav_star_point_data(self, sat_system: int):
40
- build = mctrl_driver.MctlDriver(rtk_sys_mask_query=mctrl_driver.RtkSysMaskQueryT(sat_system=sat_system))
51
+ build = MctlDriver(rtk_sys_mask_query=RtkSysMaskQueryT(sat_system=sat_system))
41
52
  logger.debug(f"Send command--Navigation satellite frequency point synchronization={sat_system}")
42
53
  return self.send_order_msg_driver(build)
43
54
 
44
55
  def set_nav_star_point(self, cmd_req: str):
45
- build = mctrl_driver.MctlDriver(
46
- rtk_cfg_req=mctrl_driver.RtkCfgReqT(cmd_req=cmd_req, cmd_length=len(cmd_req) - 1)
47
- )
56
+ build = MctlDriver(rtk_cfg_req=RtkCfgReqT(cmd_req=cmd_req, cmd_length=len(cmd_req) - 1))
48
57
  logger.debug(f"Send command--Navigation satellite frequency point setting={cmd_req}")
49
58
  logger.debug(
50
59
  f"Navigation satellite setting, Send command--Navigation satellite frequency point setting={cmd_req}"
@@ -52,7 +61,7 @@ class MessageDriver(AbstractMessage, ABC):
52
61
  return self.send_order_msg_driver(build)
53
62
 
54
63
  def get_speed(self):
55
- build = mctrl_driver.MctlDriver(bidire_speed_read_set=mctrl_driver.DrvSrSpeed(rw=0))
64
+ build = MctlDriver(bidire_speed_read_set=DrvSrSpeed(rw=0))
56
65
  logger.debug("Send command--Get speed value")
57
66
  return self.send_order_msg_driver(build)
58
67
 
@@ -63,12 +72,12 @@ class MessageDriver(AbstractMessage, ABC):
63
72
  cut_knife_height: int,
64
73
  max_run_speed: float,
65
74
  ):
66
- build = mctrl_driver.MctlDriver(
67
- mow_ctrl_by_hand=mctrl_driver.DrvMowCtrlByHand(
75
+ build = MctlDriver(
76
+ mow_ctrl_by_hand=DrvMowCtrlByHand(
68
77
  main_ctrl=main_ctrl,
69
78
  cut_knife_ctrl=cut_knife_ctrl,
70
79
  cut_knife_height=cut_knife_height,
71
- max_run__speed=max_run_speed,
80
+ max_run_speed=max_run_speed,
72
81
  )
73
82
  )
74
83
  logger.debug(
@@ -78,13 +87,11 @@ class MessageDriver(AbstractMessage, ABC):
78
87
 
79
88
  return self.send_order_msg_driver(build)
80
89
 
81
- def send_movement(self, linear_speed: int, angular_speed: int):
90
+ def send_movement(self, linear_speed: int, angular_speed: int) -> bytes:
82
91
  logger.debug(f"Control command print, linearSpeed={
83
92
  linear_speed} // angularSpeed={angular_speed}")
84
93
  return self.send_order_msg_driver(
85
- mctrl_driver.MctlDriver(
86
- todev_devmotion_ctrl=mctrl_driver.DrvMotionCtrl(
87
- set_linear_speed=linear_speed, set_angular_speed=angular_speed
88
- )
94
+ MctlDriver(
95
+ todev_devmotion_ctrl=DrvMotionCtrl(set_linear_speed=linear_speed, set_angular_speed=angular_speed)
89
96
  )
90
97
  )
@@ -2,18 +2,16 @@
2
2
  from abc import ABC
3
3
 
4
4
  from pymammotion.mammotion.commands.abstract_message import AbstractMessage
5
- from pymammotion.proto import luba_msg_pb2, luba_mul_pb2
6
- from pymammotion.proto.luba_msg import MsgCmdType, MsgDevice
7
- from pymammotion.proto.luba_mul import MUL_LANGUAGE
5
+ from pymammotion.proto import LubaMsg, MsgAttr, MsgCmdType, MsgDevice, MulLanguage, MulSetAudio, MulSetWiper, SocMul
8
6
 
9
7
 
10
8
  class MessageMedia(AbstractMessage, ABC):
11
9
  def send_order_msg_media(self, mul):
12
- luba_msg = luba_msg_pb2.LubaMsg(
13
- msgtype=luba_msg_pb2.MSG_CMD_TYPE_MUL,
14
- sender=luba_msg_pb2.DEV_MOBILEAPP,
15
- rcver=self.get_msg_device(MsgCmdType.MSG_CMD_TYPE_MUL, MsgDevice.SOC_MODULE_MULTIMEDIA),
16
- msgattr=luba_msg_pb2.MSG_ATTR_REQ,
10
+ luba_msg = LubaMsg(
11
+ msgtype=MsgCmdType.MUL,
12
+ sender=MsgDevice.DEV_MOBILEAPP,
13
+ rcver=self.get_msg_device(MsgCmdType.MUL, MsgDevice.SOC_MODULE_MULTIMEDIA),
14
+ msgattr=MsgAttr.REQ,
17
15
  seqs=1,
18
16
  version=1,
19
17
  subtype=1,
@@ -23,12 +21,13 @@ class MessageMedia(AbstractMessage, ABC):
23
21
  return luba_msg.SerializeToString()
24
22
 
25
23
  def set_car_volume(self, volume: int):
26
- return self.send_order_msg_media(luba_mul_pb2.SocMul(set_audio=luba_mul_pb2.MulSetAudio(at_switch=volume)))
24
+ """Set the car volume. 0 - 100"""
25
+ return self.send_order_msg_media(SocMul(set_audio=MulSetAudio(at_switch=volume)))
27
26
 
28
- def set_car_voice_language(self, language_type: MUL_LANGUAGE | str | None):
29
- return self.send_order_msg_media(
30
- luba_mul_pb2.SocMul(set_audio=luba_mul_pb2.MulSetAudio(au_language=language_type))
31
- )
27
+ def set_car_voice_language(self, language_type: MulLanguage | str | None):
28
+ return self.send_order_msg_media(SocMul(set_audio=MulSetAudio(au_language=language_type)))
32
29
 
33
30
  def set_car_wiper(self, round_num: int):
34
- return self.send_order_msg_media(luba_mul_pb2.SocMul(set_wiper=luba_mul_pb2.MulSetWiper(round=round_num)))
31
+ """Set mower wiper."""
32
+ # 2
33
+ return self.send_order_msg_media(SocMul(set_wiper=MulSetWiper(round=round_num)))
@@ -7,10 +7,13 @@ from pymammotion.data.model import GenerateRouteInformation
7
7
  from pymammotion.data.model.plan import Plan
8
8
  from pymammotion.data.model.region_data import RegionData
9
9
  from pymammotion.mammotion.commands.abstract_message import AbstractMessage
10
- from pymammotion.proto.luba_msg import LubaMsg, MsgAttr, MsgCmdType, MsgDevice
11
- from pymammotion.proto.mctrl_nav import (
10
+ from pymammotion.proto import (
12
11
  AppRequestCoverPathsT,
12
+ LubaMsg,
13
13
  MctlNav,
14
+ MsgAttr,
15
+ MsgCmdType,
16
+ MsgDevice,
14
17
  NavGetCommData,
15
18
  NavGetHashList,
16
19
  NavMapNameMsg,
@@ -32,10 +35,10 @@ logger = logging.getLogger(__name__)
32
35
  class MessageNavigation(AbstractMessage, ABC):
33
36
  def send_order_msg_nav(self, build) -> bytes:
34
37
  luba_msg = LubaMsg(
35
- msgtype=MsgCmdType.MSG_CMD_TYPE_NAV,
38
+ msgtype=MsgCmdType.NAV,
36
39
  sender=MsgDevice.DEV_MOBILEAPP,
37
- rcver=self.get_msg_device(MsgCmdType.MSG_CMD_TYPE_NAV, MsgDevice.DEV_MAINCTL),
38
- msgattr=MsgAttr.MSG_ATTR_REQ,
40
+ rcver=self.get_msg_device(MsgCmdType.NAV, MsgDevice.DEV_MAINCTL),
41
+ msgattr=MsgAttr.REQ,
39
42
  seqs=1,
40
43
  version=1,
41
44
  subtype=1,
@@ -45,8 +48,8 @@ class MessageNavigation(AbstractMessage, ABC):
45
48
 
46
49
  return luba_msg.SerializeToString()
47
50
 
48
- def allpowerfull_rw_adapter_x3(self, id: int, context: int, rw: int) -> bytes:
49
- build = MctlNav(nav_sys_param_cmd=NavSysParamMsg(id=id, context=context, rw=rw))
51
+ def allpowerfull_rw_adapter_x3(self, rw_id: int, context: int, rw: int) -> bytes:
52
+ build = MctlNav(nav_sys_param_cmd=NavSysParamMsg(id=rw_id, context=context, rw=rw))
50
53
  logger.debug(f"Send command--9 general read and write command id={id}, context={context}, rw={rw}")
51
54
  return self.send_order_msg_nav(build)
52
55
 
@@ -268,7 +271,7 @@ class MessageNavigation(AbstractMessage, ABC):
268
271
  logger.debug("Send command--Get area name list")
269
272
  return self.send_order_msg_nav(mctl_nav)
270
273
 
271
- def set_area_name(self, device_id, hash_id: int, name: str) -> bytes:
274
+ def set_area_name(self, device_id: str, hash_id: int, name: str) -> bytes:
272
275
  # Build the NavMapNameMsg with the specified parameters
273
276
  mctl_nav = MctlNav(
274
277
  toapp_map_name_msg=NavMapNameMsg(hash=hash_id, name=name, result=0, device_id=device_id, rw=1)
@@ -280,7 +283,7 @@ class MessageNavigation(AbstractMessage, ABC):
280
283
 
281
284
  def get_all_boundary_hash_list(self, sub_cmd: int) -> bytes:
282
285
  build = MctlNav(todev_gethash=NavGetHashList(pver=1, sub_cmd=sub_cmd))
283
- logger.debug(f"Area loading=====================:Get area hash list++Bluetooth:{sub_cmd}")
286
+ logger.debug(f"Area loading=====================:Get area hash list:{sub_cmd}")
284
287
  return self.send_order_msg_nav(build)
285
288
 
286
289
  def get_hash_response(self, total_frame: int, current_frame: int) -> bytes:
@@ -327,9 +330,9 @@ class MessageNavigation(AbstractMessage, ABC):
327
330
  logger.debug(f"Send command--Send tool command id={param_id},values={values}")
328
331
  return self.send_order_msg_nav(build)
329
332
 
330
- def end_draw_border(self, type: int) -> bytes:
333
+ def end_draw_border(self, type: int) -> bytes | None:
331
334
  if type == -1:
332
- return
335
+ return None
333
336
  build = MctlNav(todev_get_commondata=NavGetCommData(pver=1, action=1, type=type))
334
337
  logger.debug(f"Send command--End drawing boundary, obstacle, channel command type={type}")
335
338
  return self.send_order_msg_nav(build)
@@ -339,9 +342,9 @@ class MessageNavigation(AbstractMessage, ABC):
339
342
  logger.debug("Send command--Cancel current recording (boundary, obstacle)")
340
343
  return self.send_order_msg_nav(build)
341
344
 
342
- def delete_map_elements(self, type: int, hash_num: int) -> bytes:
345
+ def delete_map_elements(self, type: int, hash_num: int) -> bytes | None:
343
346
  if type == -1:
344
- return
347
+ return None
345
348
  build = MctlNav(todev_get_commondata=NavGetCommData(pver=1, action=6, type=type, hash=hash_num))
346
349
  logger.debug(f"Send command--Delete boundary or obstacle or channel command type={type},hash={hash}")
347
350
  return self.send_order_msg_nav(build)