pymammotion 0.3.7__py3-none-any.whl → 0.4.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.
Files changed (69) hide show
  1. pymammotion/__init__.py +2 -2
  2. pymammotion/aliyun/cloud_gateway.py +12 -9
  3. pymammotion/aliyun/model/aep_response.py +1 -2
  4. pymammotion/aliyun/model/dev_by_account_response.py +7 -8
  5. pymammotion/aliyun/model/login_by_oauth_response.py +2 -3
  6. pymammotion/aliyun/model/regions_response.py +3 -3
  7. pymammotion/aliyun/model/session_by_authcode_response.py +1 -2
  8. pymammotion/aliyun/model/stream_subscription_response.py +1 -2
  9. pymammotion/bluetooth/ble.py +5 -5
  10. pymammotion/bluetooth/ble_message.py +9 -13
  11. pymammotion/data/model/device.py +31 -228
  12. pymammotion/data/model/device_config.py +0 -10
  13. pymammotion/data/model/device_info.py +13 -0
  14. pymammotion/data/model/device_limits.py +49 -0
  15. pymammotion/data/model/generate_route_information.py +1 -1
  16. pymammotion/data/model/hash_list.py +6 -2
  17. pymammotion/data/model/plan.py +0 -3
  18. pymammotion/data/model/raw_data.py +215 -0
  19. pymammotion/data/model/region_data.py +10 -11
  20. pymammotion/data/model/report_info.py +1 -1
  21. pymammotion/data/mqtt/event.py +18 -14
  22. pymammotion/data/mqtt/properties.py +1 -1
  23. pymammotion/data/mqtt/status.py +1 -1
  24. pymammotion/data/state_manager.py +83 -23
  25. pymammotion/http/encryption.py +220 -0
  26. pymammotion/http/http.py +92 -39
  27. pymammotion/http/model/http.py +4 -2
  28. pymammotion/mammotion/commands/abstract_message.py +2 -2
  29. pymammotion/mammotion/commands/messages/driver.py +28 -21
  30. pymammotion/mammotion/commands/messages/media.py +10 -14
  31. pymammotion/mammotion/commands/messages/navigation.py +14 -11
  32. pymammotion/mammotion/commands/messages/network.py +17 -14
  33. pymammotion/mammotion/commands/messages/ota.py +9 -14
  34. pymammotion/mammotion/commands/messages/system.py +32 -29
  35. pymammotion/mammotion/commands/messages/video.py +9 -14
  36. pymammotion/mammotion/devices/base.py +7 -14
  37. pymammotion/mammotion/devices/mammotion.py +22 -13
  38. pymammotion/mammotion/devices/mammotion_bluetooth.py +15 -4
  39. pymammotion/mammotion/devices/mammotion_cloud.py +30 -12
  40. pymammotion/mqtt/linkkit/__init__.py +5 -0
  41. pymammotion/mqtt/linkkit/h2client.py +585 -0
  42. pymammotion/mqtt/linkkit/linkkit.py +3020 -0
  43. pymammotion/mqtt/mammotion_mqtt.py +13 -9
  44. pymammotion/proto/__init__.py +2176 -1
  45. pymammotion/proto/luba_mul.proto +1 -0
  46. pymammotion/proto/luba_mul_pb2.py +8 -8
  47. pymammotion/proto/luba_mul_pb2.pyi +1 -0
  48. pymammotion/proto/mctrl_nav_pb2.py +69 -67
  49. pymammotion/proto/mctrl_nav_pb2.pyi +13 -5
  50. pymammotion/proto/mctrl_sys_pb2.py +41 -37
  51. pymammotion/proto/mctrl_sys_pb2.pyi +34 -11
  52. pymammotion/utility/constant/device_constant.py +14 -5
  53. pymammotion/utility/device_config.py +754 -0
  54. pymammotion/utility/device_type.py +64 -16
  55. {pymammotion-0.3.7.dist-info → pymammotion-0.4.0.dist-info}/METADATA +9 -9
  56. {pymammotion-0.3.7.dist-info → pymammotion-0.4.0.dist-info}/RECORD +58 -62
  57. {pymammotion-0.3.7.dist-info → pymammotion-0.4.0.dist-info}/WHEEL +1 -1
  58. pymammotion/aliyun/cloud_service.py +0 -65
  59. pymammotion/proto/basestation.py +0 -59
  60. pymammotion/proto/common.py +0 -12
  61. pymammotion/proto/dev_net.py +0 -381
  62. pymammotion/proto/luba_msg.py +0 -81
  63. pymammotion/proto/luba_mul.py +0 -76
  64. pymammotion/proto/mctrl_driver.py +0 -100
  65. pymammotion/proto/mctrl_nav.py +0 -664
  66. pymammotion/proto/mctrl_ota.py +0 -48
  67. pymammotion/proto/mctrl_pept.py +0 -41
  68. pymammotion/proto/mctrl_sys.py +0 -574
  69. {pymammotion-0.3.7.dist-info → pymammotion-0.4.0.dist-info}/LICENSE +0 -0
@@ -1,11 +1,11 @@
1
1
  # === sendOrderMsg_Net ===
2
- import time
3
2
  from abc import ABC
3
+ import time
4
4
 
5
5
  from pymammotion import logger
6
6
  from pymammotion.mammotion.commands.abstract_message import AbstractMessage
7
7
  from pymammotion.mammotion.commands.messages.navigation import MessageNavigation
8
- from pymammotion.proto.dev_net import (
8
+ from pymammotion.proto import (
9
9
  DevNet,
10
10
  DrvDebugDdsZmq,
11
11
  DrvDevInfoReq,
@@ -18,11 +18,14 @@ from pymammotion.proto.dev_net import (
18
18
  DrvWifiUpload,
19
19
  GetNetworkInfoReq,
20
20
  IotConctrlType,
21
+ LubaMsg,
21
22
  MnetCfg,
23
+ MsgAttr,
24
+ MsgCmdType,
25
+ MsgDevice,
22
26
  NetType,
23
27
  SetMnetCfgReq,
24
28
  )
25
- from pymammotion.proto.luba_msg import LubaMsg, MsgAttr, MsgCmdType, MsgDevice
26
29
 
27
30
 
28
31
  class MessageNetwork(AbstractMessage, ABC):
@@ -31,10 +34,10 @@ class MessageNetwork(AbstractMessage, ABC):
31
34
  @staticmethod
32
35
  def send_order_msg_net(build: DevNet) -> bytes:
33
36
  luba_msg = LubaMsg(
34
- msgtype=MsgCmdType.MSG_CMD_TYPE_ESP,
37
+ msgtype=MsgCmdType.ESP,
35
38
  sender=MsgDevice.DEV_MOBILEAPP,
36
39
  rcver=MsgDevice.DEV_COMM_ESP,
37
- msgattr=MsgAttr.MSG_ATTR_REQ,
40
+ msgattr=MsgAttr.REQ,
38
41
  seqs=1,
39
42
  version=1,
40
43
  subtype=1,
@@ -48,13 +51,13 @@ class MessageNetwork(AbstractMessage, ABC):
48
51
  comm_esp = DevNet(todev_ble_sync=sync_type)
49
52
  return self.send_order_msg_net(comm_esp)
50
53
 
51
- def get_device_base_info(self) -> bytes:
54
+ def get_device_version_main(self) -> bytes:
52
55
  net = DevNet(todev_devinfo_req=DrvDevInfoReq())
53
56
  net.todev_devinfo_req.req_ids.append(DrvDevInfoReqId(id=1, type=6))
54
57
 
55
58
  return self.send_order_msg_net(net)
56
59
 
57
- def get_device_version_main(self) -> bytes:
60
+ def get_device_base_info(self) -> bytes:
58
61
  net = DevNet(todev_devinfo_req=DrvDevInfoReq())
59
62
 
60
63
  for i in range(1, 8):
@@ -76,7 +79,7 @@ class MessageNetwork(AbstractMessage, ABC):
76
79
 
77
80
  def set_zmq_enable(self) -> bytes:
78
81
  build = DevNet(
79
- todev_set_dds2zmq=DrvDebugDdsZmq(
82
+ todev_set_dds2_zmq=DrvDebugDdsZmq(
80
83
  is_enable=True,
81
84
  rx_topic_name="perception_post_result",
82
85
  tx_zmq_url="tcp://0.0.0.0:5555",
@@ -164,7 +167,7 @@ class MessageNetwork(AbstractMessage, ABC):
164
167
  todev_ble_sync=1,
165
168
  todev_set_mnet_cfg_req=SetMnetCfgReq(
166
169
  cfg=MnetCfg(
167
- type=NetType.NET_TYPE_WIFI,
170
+ type=NetType.WIFI,
168
171
  inet_enable=new_4g_status,
169
172
  mnet_enable=new_4g_status,
170
173
  )
@@ -177,7 +180,7 @@ class MessageNetwork(AbstractMessage, ABC):
177
180
  def set_device_wifi_enable_status(self, new_wifi_status: bool) -> bytes:
178
181
  build = DevNet(
179
182
  todev_ble_sync=1,
180
- todev__wifi__configuration=DrvWifiSet(config_param=4, wifi_enable=new_wifi_status),
183
+ todev_wifi_configuration=DrvWifiSet(config_param=4, wifi_enable=new_wifi_status),
181
184
  )
182
185
  logger.debug(f"szNetwork: Send command - set network (on/off status). newWifiStatus={new_wifi_status}")
183
186
  return self.send_order_msg_net(build)
@@ -185,7 +188,7 @@ class MessageNetwork(AbstractMessage, ABC):
185
188
  def wifi_connectinfo_update(self) -> bytes:
186
189
  build = DevNet(
187
190
  todev_ble_sync=1,
188
- todev__wifi_msg_upload=DrvWifiUpload(wifi_msg_upload=1),
191
+ todev_wifi_msg_upload=DrvWifiUpload(wifi_msg_upload=1),
189
192
  )
190
193
  logger.debug("Send command - get Wifi connection information")
191
194
  return self.send_order_msg_net(build)
@@ -193,17 +196,17 @@ class MessageNetwork(AbstractMessage, ABC):
193
196
  def wifi_connectinfo_update2(self) -> None:
194
197
  hash_map = {"getMsgCmd": 1}
195
198
  # self.post_custom_data(self.get_json_string(
196
- # 68, hash_map)) # ToDo: Fix this
199
+ # 68, hash_map)) # TODO: Fix this
197
200
 
198
201
  def get_record_wifi_list(self) -> bytes:
199
- build = DevNet(todev_ble_sync=1, todev__wifi_list_upload=DrvWifiList())
202
+ build = DevNet(todev_ble_sync=1, todev_wifi_list_upload=DrvWifiList())
200
203
  logger.debug("Send command - get memorized WiFi list upload command")
201
204
  return self.send_order_msg_net(build)
202
205
 
203
206
  def close_clear_connect_current_wifi(self, ssid: str, status: int) -> bytes:
204
207
  build = DevNet(
205
208
  todev_ble_sync=1,
206
- todev__wifi__configuration=DrvWifiSet(config_param=status, confssid=ssid),
209
+ todev_wifi_configuration=DrvWifiSet(config_param=status, confssid=ssid),
207
210
  )
208
211
  logger.debug(
209
212
  f"Send command - set network (disconnect, direct connect, forget, no operation reconnect) operation command (downlink ssid={ssid}, status={status})"
@@ -2,17 +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, mctrl_ota_pb2
6
- from pymammotion.proto.luba_msg import MsgCmdType, MsgDevice
5
+ from pymammotion.proto import GetInfoReq, InfoType, LubaMsg, MctlOta, MsgAttr, MsgCmdType, MsgDevice
7
6
 
8
7
 
9
8
  class MessageOta(AbstractMessage, ABC):
10
9
  def send_order_msg_ota(self, ota):
11
- luba_msg = luba_msg_pb2.LubaMsg(
12
- msgtype=luba_msg_pb2.MSG_CMD_TYPE_EMBED_OTA,
13
- sender=luba_msg_pb2.DEV_MOBILEAPP,
14
- rcver=self.get_msg_device(MsgCmdType.MSG_CMD_TYPE_EMBED_OTA, MsgDevice.DEV_MAINCTL),
15
- msgattr=luba_msg_pb2.MSG_ATTR_REQ,
10
+ luba_msg = LubaMsg(
11
+ msgtype=MsgCmdType.EMBED_OTA,
12
+ sender=MsgDevice.DEV_MOBILEAPP,
13
+ rcver=self.get_msg_device(MsgCmdType.EMBED_OTA, MsgDevice.DEV_MAINCTL),
14
+ msgattr=MsgAttr.MSG_ATTR_REQ,
16
15
  seqs=1,
17
16
  version=1,
18
17
  subtype=1,
@@ -22,17 +21,13 @@ class MessageOta(AbstractMessage, ABC):
22
21
  return luba_msg.SerializeToString()
23
22
 
24
23
  def get_device_ota_info(self, log_type: int):
25
- todev_get_info_req = mctrl_ota_pb2.MctlOta(
26
- todev_get_info_req=mctrl_ota_pb2.getInfoReq(type=mctrl_ota_pb2.IT_OTA)
27
- )
24
+ todev_get_info_req = MctlOta(todev_get_info_req=GetInfoReq(type=InfoType.IT_OTA))
28
25
 
29
26
  print("===Send command to get upgrade details===logType:" + str(log_type))
30
27
  return self.send_order_msg_ota(todev_get_info_req)
31
28
 
32
- def get_device_info_new(self):
29
+ def get_device_info_new(self) -> bytes:
33
30
  """New device call for OTA upgrade information."""
34
- todev_get_info_req = mctrl_ota_pb2.MctlOta(
35
- todev_get_info_req=mctrl_ota_pb2.getInfoReq(type=mctrl_ota_pb2.IT_BASE)
36
- )
31
+ todev_get_info_req = MctlOta(todev_get_info_req=GetInfoReq(type=InfoType.IT_BASE))
37
32
  print("Send to get OTA upgrade information", "Get device information")
38
33
  return self.send_order_msg_ota(todev_get_info_req)
@@ -1,17 +1,20 @@
1
1
  # === sendOrderMsg_Sys ===
2
+ from abc import ABC
2
3
  import datetime
3
4
  import time
4
- from abc import ABC
5
5
 
6
6
  from pymammotion import logger
7
7
  from pymammotion.mammotion.commands.abstract_message import AbstractMessage
8
8
  from pymammotion.mammotion.commands.messages.navigation import MessageNavigation
9
- from pymammotion.proto.luba_msg import LubaMsg, MsgAttr, MsgCmdType, MsgDevice
10
- from pymammotion.proto.mctrl_sys import (
9
+ from pymammotion.proto import (
11
10
  DeviceProductTypeInfoT,
12
11
  LoraCfgReq,
12
+ LubaMsg,
13
13
  MctlSys,
14
14
  MCtrlSimulationCmdData,
15
+ MsgAttr,
16
+ MsgCmdType,
17
+ MsgDevice,
15
18
  ReportInfoCfg,
16
19
  RptAct,
17
20
  RptInfoType,
@@ -26,12 +29,12 @@ from pymammotion.utility.device_type import DeviceType
26
29
  class MessageSystem(AbstractMessage, ABC):
27
30
  messageNavigation: MessageNavigation = MessageNavigation()
28
31
 
29
- def send_order_msg_sys(self, sys):
32
+ def send_order_msg_sys(self, sys) -> bytes:
30
33
  luba_msg = LubaMsg(
31
- msgtype=MsgCmdType.MSG_CMD_TYPE_EMBED_SYS,
32
- msgattr=MsgAttr.MSG_ATTR_REQ,
34
+ msgtype=MsgCmdType.EMBED_SYS,
35
+ msgattr=MsgAttr.REQ,
33
36
  sender=MsgDevice.DEV_MOBILEAPP,
34
- rcver=self.get_msg_device(MsgCmdType.MSG_CMD_TYPE_EMBED_SYS, MsgDevice.DEV_MAINCTL),
37
+ rcver=self.get_msg_device(MsgCmdType.EMBED_SYS, MsgDevice.DEV_MAINCTL),
35
38
  sys=sys,
36
39
  seqs=1,
37
40
  version=1,
@@ -42,10 +45,10 @@ class MessageSystem(AbstractMessage, ABC):
42
45
  return luba_msg.SerializeToString()
43
46
 
44
47
  @staticmethod
45
- def send_order_msg_sys_legacy(sys):
48
+ def send_order_msg_sys_legacy(sys) -> bytes:
46
49
  luba_msg = LubaMsg(
47
- msgtype=MsgCmdType.MSG_CMD_TYPE_EMBED_SYS,
48
- msgattr=MsgAttr.MSG_ATTR_REQ,
50
+ msgtype=MsgCmdType.EMBED_SYS,
51
+ msgattr=MsgAttr.REQ,
49
52
  sender=MsgDevice.DEV_MOBILEAPP,
50
53
  rcver=MsgDevice.DEV_MAINCTL,
51
54
  sys=sys,
@@ -57,12 +60,12 @@ class MessageSystem(AbstractMessage, ABC):
57
60
 
58
61
  return luba_msg.SerializeToString()
59
62
 
60
- def reset_system(self):
63
+ def reset_system(self) -> bytes:
61
64
  build = MctlSys(todev_reset_system=1)
62
65
  logger.debug("Send command - send factory reset")
63
66
  return self.send_order_msg_sys(build)
64
67
 
65
- def set_blade_control(self, on_off: int):
68
+ def set_blade_control(self, on_off: int) -> bytes:
66
69
  mctlsys = MctlSys()
67
70
  sys_knife_control = SysKnifeControl()
68
71
  sys_knife_control.knife_status = on_off
@@ -70,10 +73,10 @@ class MessageSystem(AbstractMessage, ABC):
70
73
 
71
74
  return self.send_order_msg_sys(mctlsys)
72
75
 
73
- def get_device_product_model(self):
76
+ def get_device_product_model(self) -> bytes:
74
77
  return self.send_order_msg_sys(MctlSys(device_product_type_info=DeviceProductTypeInfoT(result=1)))
75
78
 
76
- def read_and_set_sidelight(self, is_sidelight: bool, operate: int):
79
+ def read_and_set_sidelight(self, is_sidelight: bool, operate: int) -> bytes:
77
80
  """Read state of sidelight as well as set it."""
78
81
  if is_sidelight:
79
82
  build = TimeCtrlLight(
@@ -102,7 +105,7 @@ class MessageSystem(AbstractMessage, ABC):
102
105
  is_sidelight}, operate:{operate}, timeCtrlLight:{build}")
103
106
  return self.send_order_msg_sys(build2)
104
107
 
105
- def test_tool_order_to_sys(self, sub_cmd: int, param_id: int, param_value: list[int]):
108
+ def test_tool_order_to_sys(self, sub_cmd: int, param_id: int, param_value: list[int]) -> bytes:
106
109
  build = MCtrlSimulationCmdData(sub_cmd=sub_cmd, param_id=param_id, param_value=param_value)
107
110
  logger.debug(f"Send tool test command: subCmd={sub_cmd}, param_id:{
108
111
  param_id}, param_value={param_value}")
@@ -111,20 +114,20 @@ class MessageSystem(AbstractMessage, ABC):
111
114
  param_id}, param_value={param_value}")
112
115
  return self.send_order_msg_sys(build2)
113
116
 
114
- def read_and_set_rtk_paring_code(self, op: int, cgf: str | None = None):
117
+ def read_and_set_rtk_paring_code(self, op: int, cgf: str | None = None) -> bytes:
115
118
  logger.debug(f"Send read and write base station configuration quality op:{
116
119
  op}, cgf:{cgf}")
117
120
  return self.send_order_msg_sys(MctlSys(todev_lora_cfg_req=LoraCfgReq(op=op, cfg=cgf)))
118
121
 
119
- def allpowerfull_rw(self, id: int, context: int, rw: int) -> bytes:
120
- if (id == 6 or id == 3 or id == 7) and DeviceType.is_luba_2(self.get_device_name()):
121
- return self.messageNavigation.allpowerfull_rw_adapter_x3(id, context, rw)
122
- build = MctlSys(bidire_comm_cmd=SysCommCmd(id=id, context=context, rw=rw))
123
- logger.debug(f"Send command - 9 general read and write command id={id}, context={context}, rw={rw}")
124
- if id == 5:
122
+ def allpowerfull_rw(self, rw_id: int, context: int, rw: int) -> bytes:
123
+ if (rw_id == 6 or rw_id == 3 or rw_id == 7) and DeviceType.is_luba_2(self.get_device_name()):
124
+ return self.messageNavigation.allpowerfull_rw_adapter_x3(rw_id, context, rw)
125
+ build = MctlSys(bidire_comm_cmd=SysCommCmd(id=rw_id, context=context, rw=rw))
126
+ logger.debug(f"Send command - 9 general read and write command id={rw_id}, context={context}, rw={rw}")
127
+ if rw_id == 5:
125
128
  # TODO investigate if the original code makes any difference to this call.
126
129
  """
127
- LubaMsgOuterClass.LubaMsg.Builder protoBufBuilderSet = getProtoBufBuilderSet(LubaMsgOuterClass.MsgCmdType.MSG_CMD_TYPE_EMBED_SYS, LubaMsgOuterClass.MsgDevice.DEV_MAINCTL, LubaMsgOuterClass.MsgAttr.MSG_ATTR_REQ);
130
+ LubaMsgOuterClass.LubaMsg.Builder protoBufBuilderSet = getProtoBufBuilderSet(LubaMsgOuterClass.MsgCmdType.EMBED_SYS, LubaMsgOuterClass.MsgDevice.DEV_MAINCTL, LubaMsgOuterClass.MsgAttr.REQ);
128
131
  protoBufBuilderSet.setSys(build);
129
132
  sendMsg(protoBufBuilderSet, 122, true, "发送指令--9通用读写命令id=" + i + ",context=" + i2 + ",rw=" + i3);
130
133
  """
@@ -197,7 +200,7 @@ class MessageSystem(AbstractMessage, ABC):
197
200
  # test_id}, testDuration={test_duration}", "Factory tool logger.debug222", True)
198
201
  # return self.send_order_msg_sys(build2)
199
202
 
200
- def send_sys_set_date_time(self):
203
+ def send_sys_set_date_time(self) -> bytes:
201
204
  calendar = datetime.datetime.now()
202
205
  i = calendar.year
203
206
  i2 = calendar.month
@@ -231,7 +234,7 @@ class MessageSystem(AbstractMessage, ABC):
231
234
  )
232
235
  return self.send_order_msg_sys(build)
233
236
 
234
- def get_device_version_info(self):
237
+ def get_device_version_info(self) -> bytes:
235
238
  return self.send_order_msg_sys(MctlSys(todev_get_dev_fw_info=1))
236
239
 
237
240
  def read_and_set_rtk_pairing_code(self, op: int, cfg: str) -> bytes:
@@ -298,10 +301,10 @@ class MessageSystem(AbstractMessage, ABC):
298
301
  mctl_sys.todev_report_cfg.sub.append(RptInfoType.RIT_VISION_STATISTIC)
299
302
 
300
303
  luba_msg = LubaMsg(
301
- msgtype=MsgCmdType.MSG_CMD_TYPE_EMBED_SYS,
304
+ msgtype=MsgCmdType.EMBED_SYS,
302
305
  sender=MsgDevice.DEV_MOBILEAPP,
303
306
  rcver=MsgDevice.DEV_MAINCTL,
304
- msgattr=MsgAttr.MSG_ATTR_REQ,
307
+ msgattr=MsgAttr.REQ,
305
308
  seqs=1,
306
309
  version=1,
307
310
  subtype=1,
@@ -334,10 +337,10 @@ class MessageSystem(AbstractMessage, ABC):
334
337
  mctl_sys.todev_report_cfg.sub.append(RptInfoType.RIT_BASESTATION_INFO)
335
338
 
336
339
  luba_msg = LubaMsg(
337
- msgtype=MsgCmdType.MSG_CMD_TYPE_EMBED_SYS,
340
+ msgtype=MsgCmdType.EMBED_SYS,
338
341
  sender=MsgDevice.DEV_MOBILEAPP,
339
342
  rcver=MsgDevice.DEV_MAINCTL,
340
- msgattr=MsgAttr.MSG_ATTR_REQ,
343
+ msgattr=MsgAttr.REQ,
341
344
  seqs=1,
342
345
  version=1,
343
346
  subtype=1,
@@ -1,20 +1,19 @@
1
1
  # === sendOrderMsg_Video ===
2
- import time
3
2
  from abc import ABC
3
+ import time
4
4
 
5
5
  from pymammotion.mammotion.commands.abstract_message import AbstractMessage
6
- from pymammotion.proto import luba_msg_pb2, luba_mul_pb2
7
- from pymammotion.proto.luba_msg import MsgAttr, MsgCmdType, MsgDevice
6
+ from pymammotion.proto import LubaMsg, MsgAttr, MsgCmdType, MsgDevice, MulCameraPosition, MulSetVideo, SocMul
8
7
  from pymammotion.utility.device_type import DeviceType
9
8
 
10
9
 
11
10
  class MessageVideo(AbstractMessage, ABC):
12
11
  async def send_order_msg_video(self, mul):
13
- luba_msg = luba_msg_pb2.LubaMsg(
14
- msgtype=luba_msg_pb2.MSG_CMD_TYPE_MUL,
15
- msgattr=MsgAttr.MSG_ATTR_REQ,
16
- sender=luba_msg_pb2.DEV_MOBILEAPP,
17
- rcver=self.get_msg_device(MsgCmdType.MSG_CMD_TYPE_MUL, MsgDevice.SOC_MODULE_MULTIMEDIA),
12
+ luba_msg = LubaMsg(
13
+ msgtype=MsgCmdType.MUL,
14
+ msgattr=MsgAttr.REQ,
15
+ sender=MsgDevice.DEV_MOBILEAPP,
16
+ rcver=self.get_msg_device(MsgCmdType.MUL, MsgDevice.SOC_MODULE_MULTIMEDIA),
18
17
  mul=mul,
19
18
  seqs=1,
20
19
  version=1,
@@ -25,10 +24,6 @@ class MessageVideo(AbstractMessage, ABC):
25
24
  return luba_msg.SerializeToString()
26
25
 
27
26
  def device_agora_join_channel_with_position(self, enter_state: int):
28
- position = (
29
- luba_mul_pb2.MUL_CAMERA_POSITION.ALL
30
- if DeviceType.is_yuka(self.get_device_name())
31
- else luba_mul_pb2.MUL_CAMERA_POSITION.LEFT
32
- )
33
- mctl_sys = luba_mul_pb2.SocMul(set_video=luba_mul_pb2.MulSetVideo(position=position, vi_switch=enter_state))
27
+ position = MulCameraPosition.ALL if DeviceType.is_yuka(self.get_device_name()) else MulCameraPosition.LEFT
28
+ mctl_sys = SocMul(set_video=MulSetVideo(position=position, vi_switch=enter_state))
34
29
  return self.send_order_msg_video(mctl_sys)
@@ -1,16 +1,16 @@
1
+ from abc import abstractmethod
1
2
  import asyncio
2
3
  import logging
3
- from abc import abstractmethod
4
- from typing import Any, Awaitable, Callable
4
+ from typing import Any
5
5
 
6
6
  import betterproto
7
7
 
8
8
  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
+ from pymammotion.data.model.raw_data import RawMowerData
11
12
  from pymammotion.data.state_manager import StateManager
12
- from pymammotion.proto.luba_msg import LubaMsg
13
- from pymammotion.proto.mctrl_nav import NavGetCommDataAck, NavGetHashListAck, SvgMessageAckT
13
+ from pymammotion.proto import LubaMsg, NavGetCommDataAck, NavGetHashListAck, SvgMessageAckT
14
14
 
15
15
  _LOGGER = logging.getLogger(__name__)
16
16
 
@@ -36,19 +36,12 @@ class MammotionBaseDevice:
36
36
  def __init__(self, state_manager: StateManager, cloud_device: Device | None = None) -> None:
37
37
  """Initialize MammotionBaseDevice."""
38
38
  self.loop = asyncio.get_event_loop()
39
- self._raw_data = LubaMsg().to_dict(casing=betterproto.Casing.SNAKE)
40
39
  self._state_manager = state_manager
41
- self._state_manager.gethash_ack_callback = self.datahash_response
42
- self._state_manager.get_commondata_ack_callback = self.commdata_response
40
+ self._raw_data = dict()
41
+ self._raw_mower_data: RawMowerData = RawMowerData()
43
42
  self._notify_future: asyncio.Future[bytes] | None = None
44
43
  self._cloud_device = cloud_device
45
44
 
46
- def set_notification_callback(self, func: Callable[[tuple[str, Any | None]], Awaitable[None]]) -> None:
47
- self._state_manager.on_notification_callback = func
48
-
49
- def set_queue_callback(self, func: Callable[[str, dict[str, Any]], Awaitable[bytes]]) -> None:
50
- self._state_manager.queue_command_callback = func
51
-
52
45
  async def datahash_response(self, hash_ack: NavGetHashListAck) -> None:
53
46
  """Handle datahash responses."""
54
47
  current_frame = hash_ack.current_frame
@@ -108,7 +101,7 @@ class MammotionBaseDevice:
108
101
  case "ota":
109
102
  self._update_ota_data(tmp_msg)
110
103
 
111
- self.mower.update_raw(self._raw_data)
104
+ self._raw_mower_data.update_raw(self._raw_data)
112
105
 
113
106
  def _update_nav_data(self, tmp_msg) -> None:
114
107
  """Update navigation data."""
@@ -3,8 +3,8 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import asyncio
6
- import logging
7
6
  from enum import Enum
7
+ import logging
8
8
  from typing import Any
9
9
 
10
10
  from bleak.backends.device import BLEDevice
@@ -14,7 +14,7 @@ from pymammotion.aliyun.model.dev_by_account_response import Device
14
14
  from pymammotion.data.model.account import Credentials
15
15
  from pymammotion.data.model.device import MowingDevice
16
16
  from pymammotion.data.state_manager import StateManager
17
- from pymammotion.http.http import connect_http
17
+ from pymammotion.http.http import MammotionHTTP
18
18
  from pymammotion.mammotion.devices.mammotion_bluetooth import MammotionBaseBLEDevice
19
19
  from pymammotion.mammotion.devices.mammotion_cloud import MammotionBaseCloudDevice, MammotionCloud
20
20
  from pymammotion.mqtt import MammotionMQTT
@@ -84,9 +84,15 @@ class MammotionMixedDeviceManager:
84
84
  def replace_cloud(self, cloud_device: MammotionBaseCloudDevice) -> None:
85
85
  self._cloud_device = cloud_device
86
86
 
87
+ def remove_cloud(self) -> None:
88
+ del self._cloud_device
89
+
87
90
  def replace_ble(self, ble_device: MammotionBaseBLEDevice) -> None:
88
91
  self._ble_device = ble_device
89
92
 
93
+ def remove_ble(self) -> None:
94
+ del self._ble_device
95
+
90
96
  def replace_mqtt(self, mqtt: MammotionCloud) -> None:
91
97
  device = self._cloud_device.device
92
98
  self._cloud_device = MammotionBaseCloudDevice(mqtt, cloud_device=device, state_manager=self._state_manager)
@@ -98,7 +104,7 @@ class MammotionMixedDeviceManager:
98
104
  return self._ble_device is not None
99
105
 
100
106
 
101
- class MammotionDevices:
107
+ class MammotionDeviceManager:
102
108
  devices: dict[str, MammotionMixedDeviceManager] = {}
103
109
 
104
110
  def add_device(self, mammotion_device: MammotionMixedDeviceManager) -> None:
@@ -151,10 +157,10 @@ async def create_devices(
151
157
  class Mammotion:
152
158
  """Represents a Mammotion account and its devices."""
153
159
 
154
- devices = MammotionDevices()
160
+ device_manager = MammotionDeviceManager()
155
161
  mqtt_list: dict[str, MammotionCloud] = dict()
156
162
 
157
- _instance: Mammotion = None
163
+ _instance: Mammotion | None = None
158
164
 
159
165
  def __new__(cls, *args: Any, **kwargs: Any):
160
166
  if not cls._instance:
@@ -169,7 +175,7 @@ class Mammotion:
169
175
  self, ble_device: BLEDevice, preference: ConnectionPreference = ConnectionPreference.BLUETOOTH
170
176
  ) -> None:
171
177
  if ble_device:
172
- self.devices.add_device(
178
+ self.device_manager.add_device(
173
179
  MammotionMixedDeviceManager(name=ble_device.name, ble_device=ble_device, preference=preference)
174
180
  )
175
181
 
@@ -205,9 +211,9 @@ class Mammotion:
205
211
 
206
212
  def add_cloud_devices(self, mqtt_client: MammotionCloud) -> None:
207
213
  for device in mqtt_client.cloud_client.devices_by_account_response.data.data:
208
- mower_device = self.devices.get_device(device.deviceName)
214
+ mower_device = self.device_manager.get_device(device.deviceName)
209
215
  if device.deviceName.startswith(("Luba-", "Yuka-")) and mower_device is None:
210
- self.devices.add_device(
216
+ self.device_manager.add_device(
211
217
  MammotionMixedDeviceManager(
212
218
  name=device.deviceName,
213
219
  cloud_device=device,
@@ -222,7 +228,7 @@ class Mammotion:
222
228
  mower_device.replace_mqtt(mqtt_client)
223
229
 
224
230
  def set_disconnect_strategy(self, disconnect: bool) -> None:
225
- for device_name, device in self.devices.devices.items():
231
+ for device_name, device in self.device_manager.devices.items():
226
232
  if device.ble() is not None:
227
233
  ble_device: MammotionBaseBLEDevice = device.ble()
228
234
  ble_device.set_disconnect_strategy(disconnect)
@@ -230,7 +236,8 @@ class Mammotion:
230
236
  async def login(self, account: str, password: str) -> CloudIOTGateway:
231
237
  """Login to mammotion cloud."""
232
238
  cloud_client = CloudIOTGateway()
233
- mammotion_http = await connect_http(account, password)
239
+ mammotion_http = MammotionHTTP()
240
+ await mammotion_http.login(account, password)
234
241
  country_code = mammotion_http.login_info.userInformation.domainAbbreviation
235
242
  _LOGGER.debug("CountryCode: " + country_code)
236
243
  _LOGGER.debug("AuthCode: " + mammotion_http.login_info.authorization_code)
@@ -248,10 +255,10 @@ class Mammotion:
248
255
  return cloud_client
249
256
 
250
257
  async def remove_device(self, name: str) -> None:
251
- await self.devices.remove_device(name)
258
+ await self.device_manager.remove_device(name)
252
259
 
253
260
  def get_device_by_name(self, name: str) -> MammotionMixedDeviceManager:
254
- return self.devices.get_device(name)
261
+ return self.device_manager.get_device(name)
255
262
 
256
263
  async def send_command(self, name: str, key: str):
257
264
  """Send a command to the device."""
@@ -295,7 +302,9 @@ class Mammotion:
295
302
  device = self.get_device_by_name(name)
296
303
  if device.preference is ConnectionPreference.WIFI:
297
304
  if device.has_cloud():
298
- _stream_response = await device.cloud().mqtt.cloud_client.get_stream_subscription(device.cloud().iot_id)
305
+ _stream_response = await device.cloud().mqtt.cloud_client.mammotion_http.get_stream_subscription(
306
+ device.cloud().iot_id
307
+ )
299
308
  _LOGGER.debug(_stream_response)
300
309
  return _stream_response
301
310
 
@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ from collections.abc import Awaitable, Callable
2
3
  import logging
3
4
  from typing import Any, cast
4
5
  from uuid import UUID
@@ -17,8 +18,7 @@ from pymammotion.bluetooth import BleMessage
17
18
  from pymammotion.data.state_manager import StateManager
18
19
  from pymammotion.mammotion.commands.mammotion_command import MammotionCommand
19
20
  from pymammotion.mammotion.devices.base import MammotionBaseDevice
20
- from pymammotion.proto import has_field
21
- from pymammotion.proto.luba_msg import LubaMsg
21
+ from pymammotion.proto import LubaMsg, has_field
22
22
 
23
23
  DBUS_ERROR_BACKOFF_TIME = 0.25
24
24
 
@@ -89,9 +89,17 @@ class MammotionBaseBLEDevice(MammotionBaseDevice):
89
89
  self._operation_lock = asyncio.Lock()
90
90
  self._key: str | None = None
91
91
  self.set_queue_callback(self.queue_command)
92
+ self._state_manager.ble_gethash_ack_callback = self.datahash_response
93
+ self._state_manager.ble_get_commondata_ack_callback = self.commdata_response
92
94
  loop = asyncio.get_event_loop()
93
95
  loop.create_task(self.process_queue())
94
96
 
97
+ def set_notification_callback(self, func: Callable[[tuple[str, Any | None]], Awaitable[None]]) -> None:
98
+ self._state_manager.ble_on_notification_callback = func
99
+
100
+ def set_queue_callback(self, func: Callable[[str, dict[str, Any]], Awaitable[bytes]]) -> None:
101
+ self._state_manager.ble_queue_command_callback = func
102
+
95
103
  def update_device(self, device: BLEDevice) -> None:
96
104
  """Update the BLE device."""
97
105
  self.ble_device = device
@@ -325,7 +333,7 @@ class MammotionBaseBLEDevice(MammotionBaseDevice):
325
333
  _LOGGER.exception("Error parsing message %s", data)
326
334
  data = b""
327
335
  finally:
328
- self._message.clearNotification()
336
+ self._message.clear_notification()
329
337
 
330
338
  _LOGGER.debug("%s: Received notification: %s", self.name, data)
331
339
  else:
@@ -338,12 +346,15 @@ class MammotionBaseBLEDevice(MammotionBaseDevice):
338
346
 
339
347
  return
340
348
 
349
+ await self._state_manager.notification(new_msg)
341
350
  # may or may not be correct, some work could be done here to correctly match responses
342
351
  if self._notify_future and not self._notify_future.done():
343
352
  self._notify_future.set_result(data)
344
353
 
354
+ if self._execute_timed_disconnect is None:
355
+ await self._execute_forced_disconnect()
356
+
345
357
  self._reset_disconnect_timer()
346
- await self._state_manager.notification(new_msg)
347
358
 
348
359
  async def _start_notify(self) -> None:
349
360
  """Start notification."""