pymammotion 0.5.69__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 (154) hide show
  1. pymammotion/__init__.py +53 -0
  2. pymammotion/agora/__init__.py +0 -0
  3. pymammotion/agora/agora_api.py +755 -0
  4. pymammotion/agora/agora_rtc_capabilities.py +748 -0
  5. pymammotion/agora/agora_websockets.py +1175 -0
  6. pymammotion/aliyun/__init__.py +1 -0
  7. pymammotion/aliyun/client.py +235 -0
  8. pymammotion/aliyun/cloud_gateway.py +982 -0
  9. pymammotion/aliyun/model/aep_response.py +21 -0
  10. pymammotion/aliyun/model/connect_response.py +51 -0
  11. pymammotion/aliyun/model/dev_by_account_response.py +195 -0
  12. pymammotion/aliyun/model/login_by_oauth_response.py +64 -0
  13. pymammotion/aliyun/model/regions_response.py +29 -0
  14. pymammotion/aliyun/model/session_by_authcode_response.py +19 -0
  15. pymammotion/aliyun/model/thing_response.py +12 -0
  16. pymammotion/aliyun/regions.py +62 -0
  17. pymammotion/aliyun/tea/core.py +297 -0
  18. pymammotion/aliyun/tmp_constant.py +171 -0
  19. pymammotion/bluetooth/__init__.py +1 -0
  20. pymammotion/bluetooth/ble.py +62 -0
  21. pymammotion/bluetooth/ble_message.py +676 -0
  22. pymammotion/bluetooth/const.py +27 -0
  23. pymammotion/bluetooth/data/__init__.py +0 -0
  24. pymammotion/bluetooth/data/convert.py +25 -0
  25. pymammotion/bluetooth/data/framectrldata.py +40 -0
  26. pymammotion/bluetooth/data/notifydata.py +62 -0
  27. pymammotion/bluetooth/model/__init__.py +0 -0
  28. pymammotion/bluetooth/model/atomic_integer.py +54 -0
  29. pymammotion/const.py +13 -0
  30. pymammotion/data/__init__.py +0 -0
  31. pymammotion/data/model/__init__.py +8 -0
  32. pymammotion/data/model/account.py +8 -0
  33. pymammotion/data/model/device.py +192 -0
  34. pymammotion/data/model/device_config.py +72 -0
  35. pymammotion/data/model/device_info.py +60 -0
  36. pymammotion/data/model/device_limits.py +49 -0
  37. pymammotion/data/model/enums.py +77 -0
  38. pymammotion/data/model/errors.py +12 -0
  39. pymammotion/data/model/events.py +14 -0
  40. pymammotion/data/model/generate_geojson.py +565 -0
  41. pymammotion/data/model/generate_route_information.py +26 -0
  42. pymammotion/data/model/hash_list.py +475 -0
  43. pymammotion/data/model/location.py +36 -0
  44. pymammotion/data/model/mowing_modes.py +77 -0
  45. pymammotion/data/model/rapid_state.py +45 -0
  46. pymammotion/data/model/raw_data.py +215 -0
  47. pymammotion/data/model/region_data.py +102 -0
  48. pymammotion/data/model/report_info.py +182 -0
  49. pymammotion/data/model/work.py +27 -0
  50. pymammotion/data/mower_state_manager.py +369 -0
  51. pymammotion/data/mqtt/__init__.py +1 -0
  52. pymammotion/data/mqtt/event.py +227 -0
  53. pymammotion/data/mqtt/mammotion_properties.py +276 -0
  54. pymammotion/data/mqtt/properties.py +203 -0
  55. pymammotion/data/mqtt/status.py +57 -0
  56. pymammotion/event/__init__.py +6 -0
  57. pymammotion/event/event.py +96 -0
  58. pymammotion/homeassistant/__init__.py +3 -0
  59. pymammotion/homeassistant/mower_api.py +514 -0
  60. pymammotion/homeassistant/rtk_api.py +54 -0
  61. pymammotion/http/__init__.py +0 -0
  62. pymammotion/http/encryption.py +220 -0
  63. pymammotion/http/http.py +673 -0
  64. pymammotion/http/model/__init__.py +0 -0
  65. pymammotion/http/model/camera_stream.py +31 -0
  66. pymammotion/http/model/http.py +249 -0
  67. pymammotion/http/model/response_factory.py +61 -0
  68. pymammotion/http/model/rtk.py +16 -0
  69. pymammotion/mammotion/__init__.py +0 -0
  70. pymammotion/mammotion/commands/__init__.py +0 -0
  71. pymammotion/mammotion/commands/abstract_message.py +24 -0
  72. pymammotion/mammotion/commands/mammotion_command.py +81 -0
  73. pymammotion/mammotion/commands/messages/__init__.py +0 -0
  74. pymammotion/mammotion/commands/messages/basestation.py +43 -0
  75. pymammotion/mammotion/commands/messages/driver.py +122 -0
  76. pymammotion/mammotion/commands/messages/media.py +87 -0
  77. pymammotion/mammotion/commands/messages/navigation.py +564 -0
  78. pymammotion/mammotion/commands/messages/network.py +205 -0
  79. pymammotion/mammotion/commands/messages/ota.py +38 -0
  80. pymammotion/mammotion/commands/messages/system.py +330 -0
  81. pymammotion/mammotion/commands/messages/video.py +33 -0
  82. pymammotion/mammotion/control/__init__.py +0 -0
  83. pymammotion/mammotion/control/joystick.py +145 -0
  84. pymammotion/mammotion/devices/__init__.py +29 -0
  85. pymammotion/mammotion/devices/base.py +163 -0
  86. pymammotion/mammotion/devices/mammotion.py +571 -0
  87. pymammotion/mammotion/devices/mammotion_bluetooth.py +496 -0
  88. pymammotion/mammotion/devices/mammotion_cloud.py +355 -0
  89. pymammotion/mammotion/devices/mammotion_mower_ble.py +48 -0
  90. pymammotion/mammotion/devices/mammotion_mower_cloud.py +39 -0
  91. pymammotion/mammotion/devices/managers/managers.py +81 -0
  92. pymammotion/mammotion/devices/mower_device.py +120 -0
  93. pymammotion/mammotion/devices/mower_manager.py +107 -0
  94. pymammotion/mammotion/devices/rtk_ble.py +89 -0
  95. pymammotion/mammotion/devices/rtk_cloud.py +115 -0
  96. pymammotion/mammotion/devices/rtk_device.py +50 -0
  97. pymammotion/mammotion/devices/rtk_manager.py +125 -0
  98. pymammotion/mqtt/__init__.py +6 -0
  99. pymammotion/mqtt/aliyun_mqtt.py +237 -0
  100. pymammotion/mqtt/linkkit/__init__.py +5 -0
  101. pymammotion/mqtt/linkkit/h2client.py +585 -0
  102. pymammotion/mqtt/linkkit/linkkit.py +3025 -0
  103. pymammotion/mqtt/mammotion_future.py +26 -0
  104. pymammotion/mqtt/mammotion_mqtt.py +214 -0
  105. pymammotion/mqtt/mqtt_models.py +66 -0
  106. pymammotion/proto/__init__.py +4841 -0
  107. pymammotion/proto/basestation.proto +51 -0
  108. pymammotion/proto/basestation_pb2.py +35 -0
  109. pymammotion/proto/basestation_pb2.pyi +89 -0
  110. pymammotion/proto/common.proto +7 -0
  111. pymammotion/proto/common_pb2.py +25 -0
  112. pymammotion/proto/common_pb2.pyi +13 -0
  113. pymammotion/proto/dev_net.proto +321 -0
  114. pymammotion/proto/dev_net_pb2.py +111 -0
  115. pymammotion/proto/dev_net_pb2.pyi +515 -0
  116. pymammotion/proto/luba_msg.proto +76 -0
  117. pymammotion/proto/luba_msg_pb2.py +41 -0
  118. pymammotion/proto/luba_msg_pb2.pyi +97 -0
  119. pymammotion/proto/luba_mul.proto +129 -0
  120. pymammotion/proto/luba_mul_pb2.py +61 -0
  121. pymammotion/proto/luba_mul_pb2.pyi +178 -0
  122. pymammotion/proto/mctrl_driver.proto +107 -0
  123. pymammotion/proto/mctrl_driver_pb2.py +57 -0
  124. pymammotion/proto/mctrl_driver_pb2.pyi +167 -0
  125. pymammotion/proto/mctrl_nav.proto +591 -0
  126. pymammotion/proto/mctrl_nav_pb2.py +136 -0
  127. pymammotion/proto/mctrl_nav_pb2.pyi +1067 -0
  128. pymammotion/proto/mctrl_ota.proto +80 -0
  129. pymammotion/proto/mctrl_ota_pb2.py +45 -0
  130. pymammotion/proto/mctrl_ota_pb2.pyi +128 -0
  131. pymammotion/proto/mctrl_pept.proto +34 -0
  132. pymammotion/proto/mctrl_pept_pb2.py +33 -0
  133. pymammotion/proto/mctrl_pept_pb2.pyi +58 -0
  134. pymammotion/proto/mctrl_sys.proto +741 -0
  135. pymammotion/proto/mctrl_sys_pb2.py +206 -0
  136. pymammotion/proto/mctrl_sys_pb2.pyi +1213 -0
  137. pymammotion/proto/message_pool.py +3 -0
  138. pymammotion/proto/py.typed +0 -0
  139. pymammotion/py.typed +0 -0
  140. pymammotion/utility/constant/__init__.py +3 -0
  141. pymammotion/utility/constant/device_constant.py +315 -0
  142. pymammotion/utility/conversions.py +5 -0
  143. pymammotion/utility/datatype_converter.py +124 -0
  144. pymammotion/utility/device_config.py +755 -0
  145. pymammotion/utility/device_type.py +489 -0
  146. pymammotion/utility/map.py +259 -0
  147. pymammotion/utility/movement.py +18 -0
  148. pymammotion/utility/mur_mur_hash.py +159 -0
  149. pymammotion/utility/periodic.py +106 -0
  150. pymammotion/utility/rocker_util.py +194 -0
  151. pymammotion-0.5.69.dist-info/METADATA +93 -0
  152. pymammotion-0.5.69.dist-info/RECORD +154 -0
  153. pymammotion-0.5.69.dist-info/WHEEL +4 -0
  154. pymammotion-0.5.69.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,276 @@
1
+ from dataclasses import dataclass
2
+ from typing import Annotated
3
+
4
+ from mashumaro.config import BaseConfig
5
+ from mashumaro.mixins.orjson import DataClassORJSONMixin
6
+ from mashumaro.types import Alias
7
+
8
+
9
+ @dataclass
10
+ class FirmwareInfo(DataClassORJSONMixin):
11
+ t: str
12
+ c: str
13
+ v: str
14
+
15
+
16
+ @dataclass
17
+ class DeviceVersionInfo(DataClassORJSONMixin):
18
+ dev_ver: Annotated[str, Alias("devVer")]
19
+ whole: int
20
+ fw_info: Annotated[list[FirmwareInfo], Alias("fwInfo")]
21
+
22
+ class Config(BaseConfig):
23
+ allow_deserialization_not_by_alias = True
24
+
25
+
26
+ @dataclass
27
+ class Coordinate(DataClassORJSONMixin):
28
+ lon: float
29
+ lat: float
30
+
31
+
32
+ @dataclass
33
+ class InternalNavigation(DataClassORJSONMixin):
34
+ nav: Annotated[str, Alias("NAV")]
35
+ pau: Annotated[str, Alias("Pau")]
36
+ r_pau: Annotated[str, Alias("rPau")]
37
+ mcu: Annotated[str, Alias("MCU")]
38
+ app: Annotated[str, Alias("APP")]
39
+ w_slp: Annotated[str, Alias("wSlp")]
40
+ i_slp: Annotated[str, Alias("iSlp")]
41
+
42
+ class Config(BaseConfig):
43
+ allow_deserialization_not_by_alias = True
44
+
45
+
46
+ @dataclass
47
+ class BandwidthTraffic(DataClassORJSONMixin):
48
+ iot: Annotated[str, Alias("IoT")]
49
+ roi: Annotated[str, Alias("RoI")]
50
+ fpv: Annotated[str, Alias("FPV")]
51
+ inav: InternalNavigation
52
+
53
+ class Config(BaseConfig):
54
+ allow_deserialization_not_by_alias = True
55
+
56
+
57
+ @dataclass
58
+ class TrafficPeriod(DataClassORJSONMixin):
59
+ r: str
60
+ t: str
61
+ s: str
62
+
63
+
64
+ @dataclass
65
+ class TrafficData(DataClassORJSONMixin):
66
+ upt: str
67
+ hour: Annotated[dict[str, TrafficPeriod], Alias("Hour")]
68
+ day: Annotated[dict[str, TrafficPeriod], Alias("Day")]
69
+ mon: Annotated[dict[str, TrafficPeriod], Alias("Mon")]
70
+
71
+ class Config(BaseConfig):
72
+ allow_deserialization_not_by_alias = True
73
+
74
+
75
+ @dataclass
76
+ class NetworkInfo(DataClassORJSONMixin):
77
+ ssid: str
78
+ ip: str
79
+ wifi_sta_mac: str
80
+ wifi_rssi: int
81
+ wifi_available: int
82
+ bt_mac: str
83
+ mnet_model: str
84
+ imei: str
85
+ fw_ver: str
86
+ sim: str
87
+ imsi: str
88
+ iccid: str
89
+ sim_source: str
90
+ mnet_rssi: int
91
+ signal: int
92
+ mnet_link: int
93
+ mnet_option: str
94
+ mnet_ip: str
95
+ mnet_reg: str
96
+ mnet_rsrp: str
97
+ mnet_snr: str
98
+ mnet_enable: int
99
+ apn_num: int
100
+ apn_info: str
101
+ apn_cid: int
102
+ used_net: int
103
+ hub_reset: int
104
+ mnet_dis: int
105
+ airplane_times: int
106
+ lsusb_num: int
107
+ b_tra: Annotated[BandwidthTraffic, Alias("bTra")]
108
+ bw_tra: Annotated[BandwidthTraffic, Alias("bwTra")]
109
+ mnet_rx: str
110
+ mnet_tx: str
111
+ m_tra: Annotated[TrafficData, Alias("mTra")]
112
+ mnet_uniot: int
113
+ mnet_un_getiot: int
114
+ ssh_flag: str
115
+ mileage: str
116
+ work_time: str
117
+ wt_sec: int
118
+ bat_cycles: str
119
+
120
+
121
+ @dataclass
122
+ class DeviceOtherInfo(DataClassORJSONMixin):
123
+ soc_up_time: Annotated[int, Alias("socUpTime")]
124
+ mcu_up_time: Annotated[int, Alias("mcuUpTime")]
125
+ soc_loads: Annotated[str, Alias("socLoads")]
126
+ soc_mem_free: Annotated[int, Alias("socMemFree")]
127
+ soc_mem_total: Annotated[int, Alias("socMemTotal")]
128
+ soc_mmc_life_time: Annotated[int, Alias("socMmcLifeTime")]
129
+ usb_dis_cnt: Annotated[int, Alias("usbDisCnt")]
130
+ soc_pstore: Annotated[int, Alias("socPstore")]
131
+ soc_coredump: Annotated[int, Alias("socCoredump")]
132
+ soc_tmp: Annotated[int, Alias("socTmp")]
133
+ mc_mcu: Annotated[str, Alias("mcMcu")]
134
+ tilt_degree: str
135
+ i_msg_free: Annotated[int, Alias("iMsgFree")]
136
+ i_msg_limit: Annotated[int, Alias("iMsgLimit")]
137
+ i_msg_raw: Annotated[int, Alias("iMsgRaw")]
138
+ i_msg_prop: Annotated[int, Alias("iMsgprop")]
139
+ i_msg_serv: Annotated[int, Alias("iMsgServ")]
140
+ i_msg_info: Annotated[int, Alias("iMsgInfo")]
141
+ i_msg_warn: Annotated[int, Alias("iMsgWarn")]
142
+ i_msg_fault: Annotated[int, Alias("iMsgFault")]
143
+ i_msg_ota_stage: Annotated[int, Alias("iMsgOtaStage")]
144
+ i_msg_protobuf: Annotated[int, Alias("iMsgProtobuf")]
145
+ i_msg_notify: Annotated[int, Alias("iMsgNotify")]
146
+ i_msg_log_prog: Annotated[int, Alias("iMsgLogProg")]
147
+ i_msg_biz_req: Annotated[int, Alias("iMsgBizReq")]
148
+ i_msg_cfg_req: Annotated[int, Alias("iMsgCfgReq")]
149
+ i_msg_voice: Annotated[int, Alias("iMsgVoice")]
150
+ i_msg_warn_code: Annotated[int, Alias("iMsgWarnCode")]
151
+ pb_net: Annotated[int, Alias("pbNet")]
152
+ pb_sys: Annotated[int, Alias("pbSys")]
153
+ pb_nav: Annotated[int, Alias("pbNav")]
154
+ pb_local: Annotated[int, Alias("pbLocal")]
155
+ pb_plan: Annotated[int, Alias("pbPlan")]
156
+ pb_e_drv: Annotated[int, Alias("pbEDrv")]
157
+ pb_e_sys: Annotated[int, Alias("pbESys")]
158
+ pb_midware: Annotated[int, Alias("pbMidware")]
159
+ pb_ota: Annotated[int, Alias("pbOta")]
160
+ pb_appl: Annotated[int, Alias("pbAppl")]
161
+ pb_mul: Annotated[int, Alias("pbMul")]
162
+ pb_other: Annotated[int, Alias("pbOther")]
163
+ lora_connect: Annotated[int, Alias("loraConnect")]
164
+ base_status: Annotated[int, Alias("Basestatus")]
165
+ mqtt_rtk_switch: int
166
+ mqtt_rtk_channel: int
167
+ mqtt_rtk_status: int
168
+ mqtt_rtcm_cnt: int
169
+ mqtt_conn_cnt: int
170
+ mqtt_disconn_cnt: int
171
+ mqtt_rtk_hb_flag: int
172
+ mqtt_rtk_hb_count: int
173
+ mqtt_start_cnt: int
174
+ mqtt_close_cnt: int
175
+ mqtt_rtk_ssl_fail: int
176
+ mqtt_rtk_wifi_config: int
177
+ nrtk_svc_prov: int
178
+ nrtk_svc_err: int
179
+ base_stn_id: int
180
+ rtk_status: int
181
+ charge_status: int
182
+ chassis_state: int
183
+ nav: str
184
+ ins_fusion: str
185
+ perception: str
186
+ vision_proxy: str
187
+ vslam_vio: str
188
+ iot_con_timeout: int
189
+ iot_con: int
190
+ iot_con_fail_max: str
191
+ iot_con_fail_min: Annotated[str, Alias("iot_con__fail_min")]
192
+ iot_url_count: int
193
+ iot_url_max: str
194
+ iot_url_min: str
195
+ iot_cn: int
196
+ iot_ap: int
197
+ iot_us: int
198
+ iot_eu: int
199
+ task_area: float
200
+ task_count: int
201
+ task_hash: str
202
+ systemio_boot_time: Annotated[str, Alias("systemioBootTime")]
203
+ dds_no_gdc: int
204
+
205
+ class Config(BaseConfig):
206
+ allow_deserialization_not_by_alias = True
207
+
208
+
209
+ @dataclass
210
+ class CheckData(DataClassORJSONMixin):
211
+ result: str
212
+ error: Annotated[list[int], Alias("Error")]
213
+ warn: Annotated[list[int], Alias("Warn")]
214
+ ok: Annotated[list[int], Alias("OK")]
215
+
216
+ class Config(BaseConfig):
217
+ allow_deserialization_not_by_alias = True
218
+
219
+
220
+ @dataclass
221
+ class DeviceProperties(DataClassORJSONMixin):
222
+ device_state: Annotated[int, Alias("deviceState")]
223
+ battery_percentage: Annotated[int, Alias("batteryPercentage")]
224
+ device_version: Annotated[str, Alias("deviceVersion")]
225
+ knife_height: Annotated[int, Alias("knifeHeight")]
226
+ lora_general_config: Annotated[str, Alias("loraGeneralConfig")]
227
+ ext_mod: Annotated[str, Alias("extMod")]
228
+ int_mod: Annotated[str, Alias("intMod")]
229
+ iot_state: Annotated[int, Alias("iotState")]
230
+ iot_msg_total: Annotated[int, Alias("iotMsgTotal")]
231
+ iot_msg_hz: Annotated[int, Alias("iotMsgHz")]
232
+ lt_mr_mod: Annotated[str, Alias("ltMrMod")]
233
+ rt_mr_mod: Annotated[str, Alias("rtMrMod")]
234
+ bms_hardware_version: Annotated[str, Alias("bmsHardwareVersion")]
235
+ stm32_h7_version: Annotated[str, Alias("stm32H7Version")]
236
+ left_motor_version: Annotated[str, Alias("leftMotorVersion")]
237
+ right_motor_version: Annotated[str, Alias("rightMotorVersion")]
238
+ rtk_version: Annotated[str, Alias("rtkVersion")]
239
+ bms_version: Annotated[str, Alias("bmsVersion")]
240
+ mc_boot_version: Annotated[str, Alias("mcBootVersion")]
241
+ left_motor_boot_version: Annotated[str, Alias("leftMotorBootVersion")]
242
+ right_motor_boot_version: Annotated[str, Alias("rightMotorBootVersion")]
243
+
244
+ # Nested JSON objects
245
+ device_version_info: Annotated[DeviceVersionInfo, Alias("deviceVersionInfo")]
246
+ coordinate: Coordinate
247
+ device_other_info: Annotated[DeviceOtherInfo, Alias("deviceOtherInfo")]
248
+ network_info: Annotated[NetworkInfo, Alias("networkInfo")]
249
+ check_data: Annotated[CheckData, Alias("checkData")]
250
+ iot_id: str = ""
251
+
252
+ class Config(BaseConfig):
253
+ allow_deserialization_not_by_alias = True
254
+ # Custom deserializer for nested JSON strings
255
+ serialization_strategy = {
256
+ DeviceVersionInfo: {
257
+ "deserialize": lambda x: DeviceVersionInfo.from_json(x) if isinstance(x, str) else x,
258
+ "serialize": lambda x: x.to_json() if hasattr(x, "to_json") else x,
259
+ },
260
+ Coordinate: {
261
+ "deserialize": lambda x: Coordinate.from_json(x) if isinstance(x, str) else x,
262
+ "serialize": lambda x: x.to_json() if hasattr(x, "to_json") else x,
263
+ },
264
+ DeviceOtherInfo: {
265
+ "deserialize": lambda x: DeviceOtherInfo.from_json(x) if isinstance(x, str) else x,
266
+ "serialize": lambda x: x.to_json() if hasattr(x, "to_json") else x,
267
+ },
268
+ NetworkInfo: {
269
+ "deserialize": lambda x: NetworkInfo.from_json(x) if isinstance(x, str) else x,
270
+ "serialize": lambda x: x.to_json() if hasattr(x, "to_json") else x,
271
+ },
272
+ CheckData: {
273
+ "deserialize": lambda x: CheckData.from_json(x) if isinstance(x, str) else x,
274
+ "serialize": lambda x: x.to_json() if hasattr(x, "to_json") else x,
275
+ },
276
+ }
@@ -0,0 +1,203 @@
1
+ from dataclasses import dataclass
2
+ from typing import Annotated, Any, Literal, Union
3
+
4
+ from mashumaro import DataClassDictMixin
5
+ from mashumaro.config import BaseConfig
6
+ from mashumaro.mixins.orjson import DataClassORJSONMixin
7
+ from mashumaro.types import Alias
8
+
9
+ from pymammotion.data.mqtt.mammotion_properties import DeviceProperties
10
+
11
+
12
+ @dataclass
13
+ class BatteryPercentageItems(DataClassORJSONMixin):
14
+ batteryPercentage: int
15
+
16
+
17
+ @dataclass
18
+ class BMSHardwareVersionItems(DataClassORJSONMixin):
19
+ bmsHardwareVersion: str
20
+
21
+
22
+ @dataclass
23
+ class CoordinateItems(DataClassORJSONMixin):
24
+ coordinate: str # '{"lon":0.303903,"lat":1.051868}'
25
+
26
+
27
+ @dataclass
28
+ class DeviceStateItems(DataClassORJSONMixin):
29
+ deviceState: int
30
+
31
+
32
+ @dataclass
33
+ class DeviceVersionItems(DataClassORJSONMixin):
34
+ deviceVersion: str
35
+
36
+
37
+ @dataclass
38
+ class DeviceVersionInfoItems(DataClassORJSONMixin):
39
+ deviceVersionInfo: str
40
+
41
+
42
+ @dataclass
43
+ class ESP32VersionItems(DataClassORJSONMixin):
44
+ esp32Version: str
45
+
46
+
47
+ @dataclass
48
+ class LeftMotorBootVersionItems(DataClassORJSONMixin):
49
+ leftMotorBootVersion: str
50
+
51
+
52
+ @dataclass
53
+ class LeftMotorVersionItems(DataClassORJSONMixin):
54
+ leftMotorVersion: str
55
+
56
+
57
+ @dataclass
58
+ class MCBootVersionItems(DataClassORJSONMixin):
59
+ mcBootVersion: str
60
+
61
+
62
+ @dataclass
63
+ class NetworkInfoItems(DataClassORJSONMixin):
64
+ networkInfo: str
65
+
66
+
67
+ @dataclass
68
+ class RightMotorBootVersionItems(DataClassORJSONMixin):
69
+ rightMotorBootVersion: str
70
+
71
+
72
+ @dataclass
73
+ class RightMotorVersionItems(DataClassORJSONMixin):
74
+ rightMotorVersion: str
75
+
76
+
77
+ @dataclass
78
+ class RTKVersionItems(DataClassORJSONMixin):
79
+ rtkVersion: str
80
+
81
+
82
+ @dataclass
83
+ class StationRTKVersionItems(DataClassORJSONMixin):
84
+ stationRtkVersion: str
85
+
86
+
87
+ @dataclass
88
+ class STM32H7VersionItems(DataClassORJSONMixin):
89
+ stm32H7Version: str
90
+
91
+
92
+ @dataclass
93
+ class OTAProgressItems(DataClassORJSONMixin):
94
+ result: int
95
+ otaId: str
96
+ progress: int
97
+ message: str
98
+ version: str
99
+ properties: str
100
+
101
+
102
+ ItemTypes = Union[
103
+ BatteryPercentageItems,
104
+ BMSHardwareVersionItems,
105
+ CoordinateItems,
106
+ DeviceStateItems,
107
+ DeviceVersionItems,
108
+ DeviceVersionInfoItems,
109
+ ESP32VersionItems,
110
+ LeftMotorBootVersionItems,
111
+ LeftMotorVersionItems,
112
+ MCBootVersionItems,
113
+ NetworkInfoItems,
114
+ RightMotorBootVersionItems,
115
+ RightMotorVersionItems,
116
+ RTKVersionItems,
117
+ StationRTKVersionItems,
118
+ STM32H7VersionItems,
119
+ OTAProgressItems,
120
+ ]
121
+
122
+
123
+ @dataclass
124
+ class Item(DataClassDictMixin):
125
+ time: int
126
+ value: int | float | str | dict[str, Any] | ItemTypes # Depending on the type of value
127
+
128
+
129
+ @dataclass
130
+ class Items(DataClassDictMixin):
131
+ iotState: Item | None = None
132
+ extMod: Item | None = None
133
+ deviceVersionInfo: Item | None = None
134
+ leftMotorBootVersion: Item | None = None
135
+ knifeHeight: Item | None = None
136
+ rtMrMod: Item | None = None
137
+ iotMsgHz: Item | None = None
138
+ iotMsgTotal: Item | None = None
139
+ loraRawConfig: Item | None = None
140
+ loraGeneralConfig: Item | None = None
141
+ leftMotorVersion: Item | None = None
142
+ intMod: Item | None = None
143
+ coordinate: Item | None = None
144
+ bmsVersion: Item | None = None
145
+ rightMotorVersion: Item | None = None
146
+ stm32H7Version: Item | None = None
147
+ rightMotorBootVersion: Item | None = None
148
+ deviceVersion: Item | None = None
149
+ rtkVersion: Item | None = None
150
+ ltMrMod: Item | None = None
151
+ networkInfo: Item | None = None
152
+ bmsHardwareVersion: Item | None = None
153
+ batteryPercentage: Item | None = None
154
+ deviceState: Item | None = None
155
+ deviceOtherInfo: Item | None = None
156
+ mcBootVersion: Item | None = None
157
+ otaProgress: Item | None = None
158
+
159
+
160
+ @dataclass
161
+ class Params(DataClassORJSONMixin):
162
+ device_type: Annotated[Literal["LawnMower", "Tracker"], Alias("deviceType")]
163
+ check_failed_data: Annotated[dict[str, Any], Alias("checkFailedData")]
164
+ group_id_list: Annotated[list[str], Alias("groupIdList")]
165
+ _tenant_id: Annotated[str, Alias("_tenantId")]
166
+ group_id: Annotated[str, Alias("groupId")]
167
+ category_key: Annotated[Literal["LawnMower", "Tracker"], Alias("categoryKey")]
168
+ batch_id: Annotated[str, Alias("batchId")]
169
+ gmt_create: Annotated[int, Alias("gmtCreate")]
170
+ product_key: Annotated[str, Alias("productKey")]
171
+ generate_time: Annotated[int, Alias("generateTime")]
172
+ device_name: Annotated[str, Alias("deviceName")]
173
+ _trace_id: Annotated[str, Alias("_traceId")]
174
+ iot_id: Annotated[str, Alias("iotId")]
175
+ jmsx_delivery_count: Annotated[int, Alias("JMSXDeliveryCount")]
176
+ check_level: Annotated[int, Alias("checkLevel")]
177
+ qos: int
178
+ request_id: Annotated[str, Alias("requestId")]
179
+ _category_key: Annotated[str, Alias("_categoryKey")]
180
+ namespace: str
181
+ tenant_id: Annotated[str, Alias("tenantId")]
182
+ thing_type: Annotated[Literal["DEVICE"], Alias("thingType")]
183
+ items: Annotated["Items", Alias("items")]
184
+ tenant_instance_id: Annotated[str, Alias("tenantInstanceId")]
185
+
186
+ class Config(BaseConfig):
187
+ allow_deserialization_not_by_alias = True
188
+
189
+
190
+ @dataclass
191
+ class ThingPropertiesMessage(DataClassORJSONMixin):
192
+ method: Literal["thing.properties"]
193
+ id: str
194
+ params: Params
195
+ version: Literal["1.0"]
196
+
197
+
198
+ @dataclass
199
+ class MammotionPropertiesMessage(DataClassORJSONMixin):
200
+ id: str
201
+ version: str
202
+ sys: dict
203
+ params: DeviceProperties
@@ -0,0 +1,57 @@
1
+ from dataclasses import dataclass
2
+ from enum import Enum
3
+ from typing import Annotated, Literal
4
+
5
+ from mashumaro.config import BaseConfig
6
+ from mashumaro.mixins.orjson import DataClassORJSONMixin
7
+ from mashumaro.types import Alias
8
+
9
+
10
+ @dataclass
11
+ class GroupIdListItem(DataClassORJSONMixin):
12
+ groupId: str
13
+ groupType: Literal["ISOLATION", "ILOP_APP"]
14
+
15
+
16
+ # are there other values?
17
+ class StatusType(Enum):
18
+ CONNECTED = 1
19
+ DISCONNECTED = 3
20
+
21
+
22
+ @dataclass
23
+ class Status(DataClassORJSONMixin):
24
+ time: int
25
+ value: StatusType
26
+
27
+
28
+ @dataclass
29
+ class Params(DataClassORJSONMixin):
30
+ group_id_list: Annotated[list[GroupIdListItem], Alias("groupIdList")]
31
+ net_type: Annotated[Literal["NET_WIFI", "NET_MNET"], Alias("netType")]
32
+ active_time: Annotated[int, Alias("activeTime")]
33
+ ip: str
34
+ aliyun_commodity_code: Annotated[Literal["iothub_senior"], Alias("aliyunCommodityCode")]
35
+ category_key: Annotated[Literal["LawnMower", "Tracker"], Alias("categoryKey")]
36
+ node_type: Annotated[Literal["DEVICE"], Alias("nodeType")]
37
+ product_key: Annotated[str, Alias("productKey")]
38
+ status_last: Annotated[int, Alias("statusLast")]
39
+ device_name: Annotated[str, Alias("deviceName")]
40
+ iot_id: Annotated[str, Alias("iotId")]
41
+ namespace: str
42
+ tenant_id: Annotated[str, Alias("tenantId")]
43
+ thing_type: Annotated[Literal["DEVICE"], Alias("thingType")]
44
+ tenant_instance_id: Annotated[str, Alias("tenantInstanceId")]
45
+ category_id: Annotated[int, Alias("categoryId")]
46
+ status: Annotated[Status, Alias("status")]
47
+
48
+ class Config(BaseConfig):
49
+ allow_deserialization_not_by_alias = True
50
+
51
+
52
+ @dataclass
53
+ class ThingStatusMessage(DataClassORJSONMixin):
54
+ method: Literal["thing.status"]
55
+ id: str
56
+ params: Params
57
+ version: Literal["1.0"]
@@ -0,0 +1,6 @@
1
+ # __init__.py
2
+
3
+ # version of Luba Desktop
4
+ __version__ = "0.0.1"
5
+
6
+ from .event import BleNotificationEvent, MoveEvent
@@ -0,0 +1,96 @@
1
+ import asyncio
2
+ from collections.abc import Callable
3
+ from types import MethodType
4
+ from typing import Any
5
+ import weakref
6
+
7
+
8
+ class Event:
9
+ def __init__(self) -> None:
10
+ self.__eventhandlers: list[weakref.ReferenceType] = []
11
+
12
+ def __iadd__(self, handler: Callable) -> "Event":
13
+ if isinstance(handler, MethodType):
14
+ # Instance method, use WeakMethod
15
+ ref = weakref.WeakMethod(handler)
16
+ else:
17
+ # Function or static method, use weakref.ref
18
+ ref = weakref.ref(handler)
19
+ self.__eventhandlers.append(ref)
20
+ return self
21
+
22
+ def __isub__(self, handler: Callable) -> "Event":
23
+ self.__eventhandlers = [ref for ref in self.__eventhandlers if ref() is not handler]
24
+ return self
25
+
26
+ async def __call__(self, *args: Any, **kwargs: Any) -> None:
27
+ live_handlers = []
28
+ for ref in self.__eventhandlers:
29
+ func = ref()
30
+ if func is not None:
31
+ live_handlers.append(func(*args, **kwargs))
32
+ await asyncio.gather(*live_handlers)
33
+
34
+ # Clean up dead references
35
+ self.__eventhandlers = [ref for ref in self.__eventhandlers if ref() is not None]
36
+
37
+ def has_dead_handlers(self) -> bool:
38
+ """Check if any handlers have been garbage collected."""
39
+ return any(ref() is None for ref in self.__eventhandlers)
40
+
41
+
42
+ class MoveEvent:
43
+ def __init__(self) -> None:
44
+ self.OnMoveFinished = Event()
45
+
46
+ async def MoveFinished(self) -> None:
47
+ # This function will be executed once blufi finishes after a movement command and will
48
+ # raise an event
49
+ await self.OnMoveFinished()
50
+
51
+ def AddSubscribersForMoveFinishedEvent(self, objMethod) -> None:
52
+ self.OnMoveFinished += objMethod
53
+
54
+ def RemoveSubscribersForMoveFinishedEvent(self, objMethod) -> None:
55
+ self.OnMoveFinished -= objMethod
56
+
57
+
58
+ class BleNotificationEvent:
59
+ def __init__(self) -> None:
60
+ self.OnBleNotification = Event()
61
+
62
+ async def BleNotification(self, data: bytearray) -> None:
63
+ # This function will be executed when data is received.
64
+ await self.OnBleNotification(data)
65
+
66
+ def AddSubscribersForBleNotificationEvent(self, objMethod) -> None:
67
+ self.OnBleNotification += objMethod
68
+
69
+ def RemoveSubscribersForBleNotificationEvent(self, objMethod) -> None:
70
+ self.OnBleNotification -= objMethod
71
+
72
+
73
+ class DataEvent:
74
+ """Callbacks for data events."""
75
+
76
+ def __init__(self) -> None:
77
+ self.on_data_event = Event()
78
+
79
+ async def data_event(self, data: Any) -> None:
80
+ """Execute the data event callback."""
81
+ # This function will be executed when data is received.
82
+ if data:
83
+ await self.on_data_event(data)
84
+ else:
85
+ await self.on_data_event()
86
+
87
+ def add_subscribers(self, obj_method: Callable) -> None:
88
+ """Add subscribers."""
89
+ self.on_data_event += obj_method
90
+
91
+ def remove_subscribers(self, obj_method: Callable) -> None:
92
+ """Remove subscribers."""
93
+ try:
94
+ self.on_data_event -= obj_method
95
+ except ValueError:
96
+ """Subscription object no longer there."""
@@ -0,0 +1,3 @@
1
+ from pymammotion.homeassistant.mower_api import HomeAssistantMowerApi
2
+
3
+ __all__ = ["HomeAssistantMowerApi"]