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 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(MAMMOTION_API_DOMAIN) as session:
58
- async with session.post("/user-server/v1/user/oauth/check", headers=self._headers) as resp:
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("allpowerfull_rw", rw_id=5, context=1, rw=1)
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("allpowerfull_rw", rw_id=3, context=1, rw=0)
264
+ await self.queue_command("read_write_device", rw_id=3, context=1, rw=0)
265
265
  # ??
266
- await self.queue_command("allpowerfull_rw", rw_id=4, context=1, rw=0)
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("allpowerfull_rw", rw_id=6, context=1, rw=0)
268
+ await self.queue_command("read_write_device", rw_id=6, context=1, rw=0)
269
269
  # traversal mode
270
- await self.queue_command("allpowerfull_rw", rw_id=7, context=1, rw=0)
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("allpowerfull_rw", rw_id=5, rw=1, context=2)
279
- await self.queue_command("allpowerfull_rw", rw_id=5, rw=1, context=3)
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.28
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=a-EGTagL2wAdTYbDpQSoRciCdGoWky6Qbrl2U5XOXVg,13157
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=AMOx6nEbPa0HijbENomPLLuJummS1q-23BzgetBAuOI,2991
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=620kzRgX_ee9ATRgxQ1fwog4hN_-ijGNxGUH-wwlIIU,13816
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=-AYurMM70CFxrtm-YelttYAWdOGta4p4Cxg_5eD5cXY,12051
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.28.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
134
- pymammotion-0.5.28.dist-info/METADATA,sha256=0LkGDYjPd8jt78p1jzAj6zkJoqgF1STchdjs39wMCns,3872
135
- pymammotion-0.5.28.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
136
- pymammotion-0.5.28.dist-info/RECORD,,
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,,