pymammotion 0.5.28__py3-none-any.whl → 0.5.30__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.
Potentially problematic release.
This version of pymammotion might be problematic. Click here for more details.
- pymammotion/http/http.py +40 -2
- pymammotion/mammotion/commands/mammotion_command.py +14 -0
- pymammotion/mammotion/commands/messages/system.py +0 -14
- pymammotion/mammotion/devices/base.py +7 -7
- {pymammotion-0.5.28.dist-info → pymammotion-0.5.30.dist-info}/METADATA +2 -1
- {pymammotion-0.5.28.dist-info → pymammotion-0.5.30.dist-info}/RECORD +8 -8
- {pymammotion-0.5.28.dist-info → pymammotion-0.5.30.dist-info}/LICENSE +0 -0
- {pymammotion-0.5.28.dist-info → pymammotion-0.5.30.dist-info}/WHEEL +0 -0
pymammotion/http/http.py
CHANGED
|
@@ -26,6 +26,11 @@ class MammotionHTTP:
|
|
|
26
26
|
def generate_headers(token: str) -> dict:
|
|
27
27
|
return {"Authorization": f"Bearer {token}"}
|
|
28
28
|
|
|
29
|
+
async def handle_expiry(self, resp: Response) -> Response:
|
|
30
|
+
if resp.code == 401:
|
|
31
|
+
return await self.login(self.account, self._password)
|
|
32
|
+
return resp
|
|
33
|
+
|
|
29
34
|
async def login_by_email(self, email: str, password: str) -> Response[LoginResponseData]:
|
|
30
35
|
return await self.login(email, password)
|
|
31
36
|
|
|
@@ -54,11 +59,37 @@ class MammotionHTTP:
|
|
|
54
59
|
|
|
55
60
|
Returns 401 if token is invalid. We then need to re-authenticate, can try to refresh token first
|
|
56
61
|
"""
|
|
57
|
-
async with ClientSession(
|
|
58
|
-
async with session.post(
|
|
62
|
+
async with ClientSession(MAMMOTION_DOMAIN) as session:
|
|
63
|
+
async with session.post(
|
|
64
|
+
"/user-server/v1/user/oauth/check",
|
|
65
|
+
headers={
|
|
66
|
+
**self._headers,
|
|
67
|
+
"Authorization": f"Bearer {self.login_info.access_token}",
|
|
68
|
+
"Content-Type": "application/json",
|
|
69
|
+
"User-Agent": "okhttp/4.9.3",
|
|
70
|
+
},
|
|
71
|
+
) as resp:
|
|
59
72
|
data = await resp.json()
|
|
60
73
|
return Response.from_dict(data)
|
|
61
74
|
|
|
75
|
+
async def refresh_token(self) -> Response:
|
|
76
|
+
"""Refresh token."""
|
|
77
|
+
async with ClientSession(MAMMOTION_DOMAIN) as session:
|
|
78
|
+
async with session.post(
|
|
79
|
+
"/authorization/code",
|
|
80
|
+
headers={
|
|
81
|
+
**self._headers,
|
|
82
|
+
"Authorization": f"Bearer {self.login_info.access_token}",
|
|
83
|
+
"Content-Type": "application/json",
|
|
84
|
+
"User-Agent": "okhttp/4.9.3",
|
|
85
|
+
},
|
|
86
|
+
json={"clientId": MAMMOTION_CLIENT_ID},
|
|
87
|
+
) as resp:
|
|
88
|
+
data = await resp.json()
|
|
89
|
+
|
|
90
|
+
self.login_info.authorization_code = data["data"].get("code", self.login_info.authorization_code)
|
|
91
|
+
return Response.from_dict(data)
|
|
92
|
+
|
|
62
93
|
async def pair_devices_mqtt(self, mower_name: str, rtk_name: str) -> Response:
|
|
63
94
|
async with ClientSession(MAMMOTION_API_DOMAIN) as session:
|
|
64
95
|
async with session.post(
|
|
@@ -72,6 +103,7 @@ class MammotionHTTP:
|
|
|
72
103
|
return Response.from_dict(data)
|
|
73
104
|
else:
|
|
74
105
|
print(data)
|
|
106
|
+
return Response.from_dict(data)
|
|
75
107
|
|
|
76
108
|
async def unpair_devices_mqtt(self, mower_name: str, rtk_name: str) -> Response:
|
|
77
109
|
async with ClientSession(MAMMOTION_API_DOMAIN) as session:
|
|
@@ -86,6 +118,7 @@ class MammotionHTTP:
|
|
|
86
118
|
return Response.from_dict(data)
|
|
87
119
|
else:
|
|
88
120
|
print(data)
|
|
121
|
+
return Response.from_dict(data)
|
|
89
122
|
|
|
90
123
|
async def net_rtk_enable(self, device_id: str) -> Response:
|
|
91
124
|
async with ClientSession(MAMMOTION_API_DOMAIN) as session:
|
|
@@ -98,6 +131,7 @@ class MammotionHTTP:
|
|
|
98
131
|
return Response.from_dict(data)
|
|
99
132
|
else:
|
|
100
133
|
print(data)
|
|
134
|
+
return Response.from_dict(data)
|
|
101
135
|
|
|
102
136
|
async def get_stream_subscription(self, iot_id: str) -> Response[StreamSubscriptionResponse]:
|
|
103
137
|
"""Fetches stream subscription data from agora.io for a given IoT device."""
|
|
@@ -116,6 +150,7 @@ class MammotionHTTP:
|
|
|
116
150
|
# TODO catch errors from mismatch like token expire etc
|
|
117
151
|
# Assuming the data format matches the expected structure
|
|
118
152
|
response = Response[StreamSubscriptionResponse].from_dict(data)
|
|
153
|
+
await self.handle_expiry(response)
|
|
119
154
|
if response.code != 0:
|
|
120
155
|
return response
|
|
121
156
|
response.data = StreamSubscriptionResponse.from_dict(data.get("data", {}))
|
|
@@ -231,6 +266,9 @@ class MammotionHTTP:
|
|
|
231
266
|
self._password = password
|
|
232
267
|
if self._password is None:
|
|
233
268
|
raise ValueError("Password is required for refresh login")
|
|
269
|
+
res = await self.refresh_token()
|
|
270
|
+
if res.code == 0:
|
|
271
|
+
return res
|
|
234
272
|
return await self.login(account, self._password)
|
|
235
273
|
|
|
236
274
|
async def login(self, account: str, password: str) -> Response[LoginResponseData]:
|
|
@@ -30,6 +30,20 @@ class MammotionCommand(
|
|
|
30
30
|
return self.allpowerfull_rw_adapter_x3(rw_id, context, rw)
|
|
31
31
|
return self.allpowerfull_rw(rw_id, context, rw)
|
|
32
32
|
|
|
33
|
+
def traverse_mode(self, context: int) -> bytes:
|
|
34
|
+
"""Sets the traversal mode back to charger."""
|
|
35
|
+
# setReChargeMode
|
|
36
|
+
# 0 direct
|
|
37
|
+
# 1 follow the perimeter
|
|
38
|
+
return self.read_write_device(7, context, 1)
|
|
39
|
+
|
|
40
|
+
def turning_mode(self, context: int) -> bytes:
|
|
41
|
+
"""Sets the traversal mode back to charger."""
|
|
42
|
+
# setTurnAroundMode
|
|
43
|
+
# 0 zero turn
|
|
44
|
+
# 1 multipoint turn
|
|
45
|
+
return self.read_write_device(6, context, 1)
|
|
46
|
+
|
|
33
47
|
def get_device_product_key(self) -> str:
|
|
34
48
|
return self._product_key
|
|
35
49
|
|
|
@@ -119,20 +119,6 @@ class MessageSystem(AbstractMessage, ABC):
|
|
|
119
119
|
logger.debug(f"Send command - 9 general read and write command id={rw_id}, context={context}, rw={rw}")
|
|
120
120
|
return self.send_order_msg_sys(build)
|
|
121
121
|
|
|
122
|
-
def traverse_mode(self, context: int) -> bytes:
|
|
123
|
-
"""Sets the traversal mode back to charger."""
|
|
124
|
-
# setReChargeMode
|
|
125
|
-
# 0 direct
|
|
126
|
-
# 1 follow the perimeter
|
|
127
|
-
return self.allpowerfull_rw(7, context, 1)
|
|
128
|
-
|
|
129
|
-
def turning_mode(self, context: int) -> bytes:
|
|
130
|
-
"""Sets the traversal mode back to charger."""
|
|
131
|
-
# setTurnAroundMode
|
|
132
|
-
# 0 zero turn
|
|
133
|
-
# 1 multipoint turn
|
|
134
|
-
return self.allpowerfull_rw(6, context, 1)
|
|
135
|
-
|
|
136
122
|
# Commented out as not needed and too many refs to try fix up
|
|
137
123
|
# def factory_test_order(self, test_id: int, test_duration: int, expect: str):
|
|
138
124
|
# new_builder = mow_to_app_qctools_info_t.Builder()
|
|
@@ -210,7 +210,7 @@ class MammotionBaseDevice:
|
|
|
210
210
|
await self.queue_command("get_device_product_model")
|
|
211
211
|
await self.queue_command("get_report_cfg")
|
|
212
212
|
"""RTK and dock location."""
|
|
213
|
-
await self.queue_command("
|
|
213
|
+
await self.queue_command("read_write_device", rw_id=5, context=1, rw=1)
|
|
214
214
|
await self.async_read_settings()
|
|
215
215
|
|
|
216
216
|
async def start_map_sync(self) -> None:
|
|
@@ -261,13 +261,13 @@ class MammotionBaseDevice:
|
|
|
261
261
|
async def async_read_settings(self) -> None:
|
|
262
262
|
"""Read settings from device."""
|
|
263
263
|
# no cutting in rain nav_sys_param_cmd (id 3 context 1/0)
|
|
264
|
-
await self.queue_command("
|
|
264
|
+
await self.queue_command("read_write_device", rw_id=3, context=1, rw=0)
|
|
265
265
|
# ??
|
|
266
|
-
await self.queue_command("
|
|
266
|
+
await self.queue_command("read_write_device", rw_id=4, context=1, rw=0)
|
|
267
267
|
# turning mode nav_sys_param_cmd (id 6, context 1/0)
|
|
268
|
-
await self.queue_command("
|
|
268
|
+
await self.queue_command("read_write_device", rw_id=6, context=1, rw=0)
|
|
269
269
|
# traversal mode
|
|
270
|
-
await self.queue_command("
|
|
270
|
+
await self.queue_command("read_write_device", rw_id=7, context=1, rw=0)
|
|
271
271
|
|
|
272
272
|
await self.queue_command("read_and_set_sidelight", is_sidelight=True, operate=1)
|
|
273
273
|
|
|
@@ -275,8 +275,8 @@ class MammotionBaseDevice:
|
|
|
275
275
|
|
|
276
276
|
async def async_get_errors(self) -> None:
|
|
277
277
|
"""Error codes."""
|
|
278
|
-
await self.queue_command("
|
|
279
|
-
await self.queue_command("
|
|
278
|
+
await self.queue_command("read_write_device", rw_id=5, rw=1, context=2)
|
|
279
|
+
await self.queue_command("read_write_device", rw_id=5, rw=1, context=3)
|
|
280
280
|
|
|
281
281
|
async def command(self, key: str, **kwargs):
|
|
282
282
|
"""Send a command to the device."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pymammotion
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.30
|
|
4
4
|
Summary:
|
|
5
5
|
License: GPL-3.0
|
|
6
6
|
Author: Michael Arthur
|
|
@@ -21,6 +21,7 @@ Requires-Dist: bleak (>=0.21.0)
|
|
|
21
21
|
Requires-Dist: bleak-retry-connector (>=3.5.0)
|
|
22
22
|
Requires-Dist: crcmod (>=1.7,<2.0)
|
|
23
23
|
Requires-Dist: cryptography (>=43.0.1)
|
|
24
|
+
Requires-Dist: grpclib (>=0.4.8,<0.5.0)
|
|
24
25
|
Requires-Dist: jsonic (>=1.0.0,<2.0.0)
|
|
25
26
|
Requires-Dist: mashumaro (>=3.13,<4.0)
|
|
26
27
|
Requires-Dist: numpy (>=1.26.0)
|
|
@@ -53,7 +53,7 @@ pymammotion/event/event.py,sha256=Z8WYxv_-5khEqKjL1w4c_Et24G1Kdm8QFuIBylD3h3U,30
|
|
|
53
53
|
pymammotion/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
54
|
pymammotion/http/_init_.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
55
|
pymammotion/http/encryption.py,sha256=lzXu3WwBdQlzjXxWnlJuRgkCrKdPbxx5drhMitVKIEk,8287
|
|
56
|
-
pymammotion/http/http.py,sha256=
|
|
56
|
+
pymammotion/http/http.py,sha256=K30JryDOmxmqUfAmvVchhemKKe_E5lr0XMifbzW9XMs,14670
|
|
57
57
|
pymammotion/http/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
58
|
pymammotion/http/model/camera_stream.py,sha256=ilxQNny_w9Frwt-m8kbHinvyjDv4Bx8C2swfZ2lTEDE,600
|
|
59
59
|
pymammotion/http/model/http.py,sha256=VDBmi9nyY5Y2ns_HYvKIyzbkKRxhZ5elpq0lWXWzbGw,4123
|
|
@@ -62,7 +62,7 @@ pymammotion/http/model/rtk.py,sha256=pR2mi6_Y8oTPlqDXWLk7oaUqmcgcrBQ0f3MJdC0_CUg
|
|
|
62
62
|
pymammotion/mammotion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
63
|
pymammotion/mammotion/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
64
64
|
pymammotion/mammotion/commands/abstract_message.py,sha256=M4qL-Yw5g3fTgS9jB9LUSgJSAqpUf7MME-2mfv471Sk,808
|
|
65
|
-
pymammotion/mammotion/commands/mammotion_command.py,sha256
|
|
65
|
+
pymammotion/mammotion/commands/mammotion_command.py,sha256=-TOdikRS0x9gCpXmBZblzKoOd4Zy1zODGiA5KoF0OCc,3468
|
|
66
66
|
pymammotion/mammotion/commands/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
67
|
pymammotion/mammotion/commands/messages/basestation.py,sha256=a1LEF4C25ynILeQLx-FOOU4d-N_vMkXSh_etojJjIDM,1442
|
|
68
68
|
pymammotion/mammotion/commands/messages/driver.py,sha256=tJUM1WhlWFs92PbZW5QSG-TMo6nemAUkcUDzI_6gETU,4695
|
|
@@ -70,12 +70,12 @@ pymammotion/mammotion/commands/messages/media.py,sha256=KJyMzSZkwQrHWjAWfAI88Y7-
|
|
|
70
70
|
pymammotion/mammotion/commands/messages/navigation.py,sha256=yI-B5HHGuZJXn9iYrxhYZ5BArde6wB_j9bUc5IcSIJE,23261
|
|
71
71
|
pymammotion/mammotion/commands/messages/network.py,sha256=7K6aqt29ymTSUG0iEv4kIRD0Dv6rfHNctE00UvuMpG4,7264
|
|
72
72
|
pymammotion/mammotion/commands/messages/ota.py,sha256=Nk3Tlp6n7hkbkuy355BlqbozHIHzsYnrH2cDO8QGaLk,1446
|
|
73
|
-
pymammotion/mammotion/commands/messages/system.py,sha256=
|
|
73
|
+
pymammotion/mammotion/commands/messages/system.py,sha256=1Xchdx7Y0-kbrM-knSEUhwELu9PyF7DjtsCFt7_BCXw,13343
|
|
74
74
|
pymammotion/mammotion/commands/messages/video.py,sha256=5D5Azt6Q63K-OeC2eSPmmrGgFLmGIi21jPuESCYVgnE,1296
|
|
75
75
|
pymammotion/mammotion/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
76
|
pymammotion/mammotion/control/joystick.py,sha256=QfBVxM_gxpWsZAGO90whtgxCI2tIZ3TTad9wHIPsU9s,5640
|
|
77
77
|
pymammotion/mammotion/devices/__init__.py,sha256=f2qQFPgLGmV85W2hSlMUh5BYuht9o_Ar_JEAAMD4fsE,102
|
|
78
|
-
pymammotion/mammotion/devices/base.py,sha256
|
|
78
|
+
pymammotion/mammotion/devices/base.py,sha256=3-7-xZLgs4xXWRt9vDDgfv7Rlno7Ce6LolPDXLaV4GI,12065
|
|
79
79
|
pymammotion/mammotion/devices/mammotion.py,sha256=uk0mM6JSOzr84qkf8lECvlmTLX0UEQDXyowSeHZydek,15801
|
|
80
80
|
pymammotion/mammotion/devices/mammotion_bluetooth.py,sha256=lVqGice3fv-Xura10PuWUCMdtNXf84gtf3S1STw2hr4,19345
|
|
81
81
|
pymammotion/mammotion/devices/mammotion_cloud.py,sha256=ligdszu1KsHe0b0ZyyIibN_uXpxoSNp7ytNmsumidHY,16489
|
|
@@ -130,7 +130,7 @@ pymammotion/utility/movement.py,sha256=N75oAoAgFydqoaOedYIxGUHmuTCtPzAOtb-d_29tp
|
|
|
130
130
|
pymammotion/utility/mur_mur_hash.py,sha256=xEfOZVbqRawJj66eLgtnZ85OauDR47oIPr29OHelzPI,4468
|
|
131
131
|
pymammotion/utility/periodic.py,sha256=MbeSb9cfhxzYmdT_RiE0dZe3H9IfbQW_zSqhmSX2RUc,3321
|
|
132
132
|
pymammotion/utility/rocker_util.py,sha256=6tX7sS87qoQC_tsxbx3NLL-HgS08wtzXiZkhDiz7uo0,7179
|
|
133
|
-
pymammotion-0.5.
|
|
134
|
-
pymammotion-0.5.
|
|
135
|
-
pymammotion-0.5.
|
|
136
|
-
pymammotion-0.5.
|
|
133
|
+
pymammotion-0.5.30.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
134
|
+
pymammotion-0.5.30.dist-info/METADATA,sha256=wG2W00B9kT2MCxiKPbKgu08ostwFfNmyD_ycfBS5TJ0,3912
|
|
135
|
+
pymammotion-0.5.30.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
136
|
+
pymammotion-0.5.30.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|