pymammotion 0.2.97__tar.gz → 0.2.99__tar.gz

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