pymammotion 0.2.16__py3-none-any.whl → 0.2.18__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/aliyun/cloud_gateway.py +13 -7
- pymammotion/aliyun/dataclass/login_by_oauth_response.py +1 -1
- pymammotion/const.py +2 -2
- pymammotion/data/mqtt/event.py +17 -5
- pymammotion/data/state_manager.py +4 -0
- pymammotion/http/http.py +1 -1
- pymammotion/mammotion/devices/mammotion.py +6 -4
- {pymammotion-0.2.16.dist-info → pymammotion-0.2.18.dist-info}/METADATA +1 -1
- {pymammotion-0.2.16.dist-info → pymammotion-0.2.18.dist-info}/RECORD +11 -11
- {pymammotion-0.2.16.dist-info → pymammotion-0.2.18.dist-info}/LICENSE +0 -0
- {pymammotion-0.2.16.dist-info → pymammotion-0.2.18.dist-info}/WHEEL +0 -0
|
@@ -11,6 +11,7 @@ import time
|
|
|
11
11
|
import uuid
|
|
12
12
|
from logging import getLogger, exception
|
|
13
13
|
from datetime import datetime
|
|
14
|
+
from urllib.parse import urlencode
|
|
14
15
|
|
|
15
16
|
from aiohttp import ClientSession
|
|
16
17
|
from alibabacloud_iot_api_gateway.client import Client
|
|
@@ -241,6 +242,7 @@ class CloudIOTGateway:
|
|
|
241
242
|
async def connect(self):
|
|
242
243
|
"""Connect to the Aliyun Cloud IoT Gateway."""
|
|
243
244
|
region_url = "sdk.openaccount.aliyun.com"
|
|
245
|
+
time_now = time.time()
|
|
244
246
|
async with ClientSession() as session:
|
|
245
247
|
headers = {
|
|
246
248
|
"host": region_url,
|
|
@@ -323,7 +325,7 @@ class CloudIOTGateway:
|
|
|
323
325
|
"x-ca-key": self._app_key,
|
|
324
326
|
"x-ca-signaturemethod": "HmacSHA256",
|
|
325
327
|
"accept": "application/json",
|
|
326
|
-
"content-type": "application/x-www-form-urlencoded",
|
|
328
|
+
"content-type": "application/x-www-form-urlencoded; charset=utf-8",
|
|
327
329
|
"user-agent": UtilClient.get_user_agent(None),
|
|
328
330
|
"vid": self._connect_response.data.vid,
|
|
329
331
|
}
|
|
@@ -331,14 +333,16 @@ class CloudIOTGateway:
|
|
|
331
333
|
_bodyParam = {
|
|
332
334
|
"country": country_code,
|
|
333
335
|
"authCode": auth_code,
|
|
334
|
-
"oauthPlateform":
|
|
336
|
+
"oauthPlateform": 23,
|
|
335
337
|
"oauthAppKey": self._app_key,
|
|
336
|
-
"appAuthToken": self._device_sn,
|
|
337
338
|
"riskControlInfo": {
|
|
338
339
|
"appID": "com.agilexrobotics",
|
|
340
|
+
"appAuthToken": "",
|
|
339
341
|
"signType": "RSA",
|
|
342
|
+
"sdkVersion": "3.4.2",
|
|
340
343
|
"utdid": self._utdid,
|
|
341
344
|
"umidToken": self._utdid,
|
|
345
|
+
"deviceId": self._connect_response.data.data.device.data.deviceId,
|
|
342
346
|
"USE_OA_PWD_ENCRYPT": "true",
|
|
343
347
|
"USE_H5_NC": "true",
|
|
344
348
|
},
|
|
@@ -354,12 +358,12 @@ class CloudIOTGateway:
|
|
|
354
358
|
header = "".join(f"{k}:{dic[k]}\n" for k in keys).strip()
|
|
355
359
|
|
|
356
360
|
headers["x-ca-signature-headers"] = sign_headers
|
|
357
|
-
string_to_sign = "POST\n{}\n\n{}\n{}\n{}\n/api/prd/loginbyoauth.json?
|
|
361
|
+
string_to_sign = "POST\n{}\n\n{}\n{}\n{}\n/api/prd/loginbyoauth.json?{}".format(
|
|
358
362
|
headers["accept"],
|
|
359
363
|
headers["content-type"],
|
|
360
364
|
headers["date"],
|
|
361
365
|
header,
|
|
362
|
-
json.dumps(_bodyParam, separators=(",", ":")),
|
|
366
|
+
f"loginByOauthRequest={json.dumps(_bodyParam, separators=(",", ":"))}",
|
|
363
367
|
)
|
|
364
368
|
|
|
365
369
|
hash_val = hmac.new(
|
|
@@ -369,12 +373,14 @@ class CloudIOTGateway:
|
|
|
369
373
|
).digest()
|
|
370
374
|
signature = base64.b64encode(hash_val).decode("utf-8")
|
|
371
375
|
headers["x-ca-signature"] = signature
|
|
372
|
-
|
|
373
376
|
async with session.post(
|
|
374
377
|
f"https://{region_url}/api/prd/loginbyoauth.json",
|
|
375
378
|
headers=headers,
|
|
376
|
-
|
|
379
|
+
data={
|
|
380
|
+
'loginByOauthRequest': json.dumps(_bodyParam, separators=(",", ":"))
|
|
381
|
+
}
|
|
377
382
|
) as resp:
|
|
383
|
+
|
|
378
384
|
data = await resp.json()
|
|
379
385
|
logger.debug(data)
|
|
380
386
|
if resp.status == 200:
|
pymammotion/const.py
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
APP_KEY = "34231230"
|
|
4
4
|
APP_SECRET = "1ba85698bb10e19c6437413b61ba3445"
|
|
5
|
-
APP_VERSION = "1.11.
|
|
5
|
+
APP_VERSION = "1.11.130"
|
|
6
6
|
ALIYUN_DOMAIN = "api.link.aliyun.com"
|
|
7
|
-
MAMMOTION_DOMAIN = "https://
|
|
7
|
+
MAMMOTION_DOMAIN = "https://id.mammotion.com"
|
|
8
8
|
MAMMOTION_CLIENT_ID = "MADKALUBAS"
|
|
9
9
|
MAMMOTION_CLIENT_SECRET = "GshzGRZJjuMUgd2sYHM7"
|
pymammotion/data/mqtt/event.py
CHANGED
|
@@ -45,10 +45,15 @@ class DeviceWarningEventValue(DataClassORJSONMixin):
|
|
|
45
45
|
# (see resources/res/values-en-rUS/strings.xml in APK)
|
|
46
46
|
code: int
|
|
47
47
|
|
|
48
|
+
@dataclass
|
|
49
|
+
class DeviceConfigurationRequestValue(DataClassORJSONMixin):
|
|
50
|
+
code: int
|
|
51
|
+
bizId: str
|
|
52
|
+
params: str
|
|
53
|
+
|
|
48
54
|
|
|
49
55
|
@dataclass
|
|
50
56
|
class GeneralParams(DataClassORJSONMixin):
|
|
51
|
-
identifier: str
|
|
52
57
|
groupIdList: list[str]
|
|
53
58
|
groupId: str
|
|
54
59
|
categoryKey: Literal["LawnMower"]
|
|
@@ -67,7 +72,7 @@ class GeneralParams(DataClassORJSONMixin):
|
|
|
67
72
|
tenantInstanceId: str
|
|
68
73
|
value: Any
|
|
69
74
|
|
|
70
|
-
|
|
75
|
+
identifier: Optional[str] = None
|
|
71
76
|
checkFailedData: Optional[dict] = None
|
|
72
77
|
_tenantId: Optional[str] = None
|
|
73
78
|
generateTime: Optional[int] = None
|
|
@@ -92,6 +97,11 @@ class DeviceWarningEventParams(GeneralParams):
|
|
|
92
97
|
type: Literal["alert"]
|
|
93
98
|
value: DeviceWarningEventValue
|
|
94
99
|
|
|
100
|
+
@dataclass
|
|
101
|
+
class DeviceConfigurationRequestEvent(GeneralParams):
|
|
102
|
+
type: Literal["info"]
|
|
103
|
+
value: DeviceConfigurationRequestValue
|
|
104
|
+
|
|
95
105
|
|
|
96
106
|
@dataclass
|
|
97
107
|
class ThingEventMessage(DataClassORJSONMixin):
|
|
@@ -102,7 +112,7 @@ class ThingEventMessage(DataClassORJSONMixin):
|
|
|
102
112
|
|
|
103
113
|
@classmethod
|
|
104
114
|
def from_dicts(cls, payload: dict) -> "ThingEventMessage":
|
|
105
|
-
"""
|
|
115
|
+
"""Deserialize payload JSON ThingEventMessage."""
|
|
106
116
|
method = payload.get("method")
|
|
107
117
|
event_id = payload.get("id")
|
|
108
118
|
params_dict = payload.get("params", {})
|
|
@@ -110,7 +120,10 @@ class ThingEventMessage(DataClassORJSONMixin):
|
|
|
110
120
|
|
|
111
121
|
# Determina quale classe usare per i parametri
|
|
112
122
|
identifier = params_dict.get("identifier")
|
|
113
|
-
if identifier
|
|
123
|
+
if identifier is None:
|
|
124
|
+
"""Request configuration event."""
|
|
125
|
+
params_obj = DeviceConfigurationRequestEvent(**params_dict)
|
|
126
|
+
elif identifier == "device_protobuf_msg_event":
|
|
114
127
|
params_obj = DeviceProtobufMsgEventParams(**params_dict)
|
|
115
128
|
elif identifier == "device_warning_event":
|
|
116
129
|
params_obj = DeviceWarningEventParams(**params_dict)
|
|
@@ -119,5 +132,4 @@ class ThingEventMessage(DataClassORJSONMixin):
|
|
|
119
132
|
else:
|
|
120
133
|
raise ValueError(f"Unknown identifier: {identifier}")
|
|
121
134
|
|
|
122
|
-
# Crea e restituisce l'istanza di ThingEventMessage
|
|
123
135
|
return cls(method=method, id=event_id, params=params_obj, version=version)
|
|
@@ -17,6 +17,7 @@ class StateManager:
|
|
|
17
17
|
self._device = device
|
|
18
18
|
self.gethash_ack_callback: Optional[Callable[[NavGetHashListAck],Awaitable[None]]] = None
|
|
19
19
|
self.get_commondata_ack_callback: Optional[Callable[[NavGetCommDataAck],Awaitable[None]]] = None
|
|
20
|
+
self.on_notification_callback: Optional[Callable[[],Awaitable[None]]] = None
|
|
20
21
|
|
|
21
22
|
def get_device(self) -> MowingDevice:
|
|
22
23
|
"""Get device."""
|
|
@@ -44,6 +45,9 @@ class StateManager:
|
|
|
44
45
|
case "ota":
|
|
45
46
|
self._update_ota_data(message)
|
|
46
47
|
|
|
48
|
+
if self.on_notification_callback:
|
|
49
|
+
await self.on_notification_callback()
|
|
50
|
+
|
|
47
51
|
async def _update_nav_data(self, message):
|
|
48
52
|
"""Update nav data."""
|
|
49
53
|
nav_msg = betterproto.which_one_of(message.nav, "SubNavMsg")
|
pymammotion/http/http.py
CHANGED
|
@@ -55,7 +55,7 @@ class MammotionHTTP:
|
|
|
55
55
|
@classmethod
|
|
56
56
|
async def login(cls, session: ClientSession, username: str, password: str) -> Response[LoginResponseData]:
|
|
57
57
|
async with session.post(
|
|
58
|
-
"/
|
|
58
|
+
"/oauth/token",
|
|
59
59
|
params=dict(
|
|
60
60
|
username=username,
|
|
61
61
|
password=password,
|
|
@@ -346,6 +346,9 @@ class MammotionBaseDevice:
|
|
|
346
346
|
self._notify_future: asyncio.Future[bytes] | None = None
|
|
347
347
|
self._cloud_device = cloud_device
|
|
348
348
|
|
|
349
|
+
def set_notifiction_callback(self, func: Callable[[],Awaitable[None]]):
|
|
350
|
+
self._state_manager.on_notification_callback = func
|
|
351
|
+
|
|
349
352
|
async def datahash_response(self, hash_ack: NavGetHashListAck):
|
|
350
353
|
"""Handle datahash responses."""
|
|
351
354
|
result_hash = 0
|
|
@@ -1147,10 +1150,9 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
|
1147
1150
|
_LOGGER.debug("Thing event received")
|
|
1148
1151
|
event = ThingEventMessage.from_dicts(payload)
|
|
1149
1152
|
params = event.params
|
|
1150
|
-
if
|
|
1151
|
-
_LOGGER.debug("config event %s", str)
|
|
1153
|
+
if params.identifier is None:
|
|
1152
1154
|
return
|
|
1153
|
-
if params.identifier == "device_protobuf_msg_event" and
|
|
1155
|
+
if params.identifier == "device_protobuf_msg_event" and event.method == "thing.events":
|
|
1154
1156
|
_LOGGER.debug("Protobuf event")
|
|
1155
1157
|
binary_data = base64.b64decode(params.value.get("content", ""))
|
|
1156
1158
|
self._update_raw_data(cast(bytes, binary_data))
|
|
@@ -1171,7 +1173,7 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
|
1171
1173
|
if not fut.fut.cancelled():
|
|
1172
1174
|
fut.resolve(cast(bytes, binary_data))
|
|
1173
1175
|
await self._state_manager.notification(new_msg)
|
|
1174
|
-
if
|
|
1176
|
+
if event.method == "thing.properties":
|
|
1175
1177
|
_LOGGER.debug(event)
|
|
1176
1178
|
|
|
1177
1179
|
async def _handle_mqtt_message(self, topic: str, payload: dict) -> None:
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
pymammotion/__init__.py,sha256=kmnjdt3AEMejIz5JK7h1tTJj5ZriAgKwZBa3ScA4-Ao,1516
|
|
2
2
|
pymammotion/aliyun/__init__.py,sha256=T1lkX7TRYiL4nqYanG4l4MImV-SlavSbuooC-W-uUGw,29
|
|
3
|
-
pymammotion/aliyun/cloud_gateway.py,sha256=
|
|
3
|
+
pymammotion/aliyun/cloud_gateway.py,sha256=ra7m3CgP6mIoc0RhRFk-rySdcEWOjbZcDBwvfNvMpM8,22461
|
|
4
4
|
pymammotion/aliyun/cloud_service.py,sha256=YWcKuKK6iRWy5mTnBYgHxcCusiRGGzQt3spSf7dGDss,2183
|
|
5
5
|
pymammotion/aliyun/dataclass/aep_response.py,sha256=8f6GIP58ve8gd6AL3HBoXxsy0n2q4ygWvjELGnoOnVc,452
|
|
6
6
|
pymammotion/aliyun/dataclass/connect_response.py,sha256=Yz-fEbDzgGPTo5Of2oAjmFkSv08T7ze80pQU4k-gKIU,824
|
|
7
7
|
pymammotion/aliyun/dataclass/dev_by_account_response.py,sha256=YV7I1Gd3RyHXi369AzEKa604VOV5bmtjD1mVElg9wOw,1033
|
|
8
|
-
pymammotion/aliyun/dataclass/login_by_oauth_response.py,sha256=
|
|
8
|
+
pymammotion/aliyun/dataclass/login_by_oauth_response.py,sha256=IXSLZ6XnOliOnyXo5Bh0ErqFjA11puACh_9NH0sSJGQ,1262
|
|
9
9
|
pymammotion/aliyun/dataclass/regions_response.py,sha256=CVPpdFhDD6_emWHyLRzOdp2j3HLPtP8tlNyzGnr8AcI,690
|
|
10
10
|
pymammotion/aliyun/dataclass/session_by_authcode_response.py,sha256=_5vsyIxocoecEqygPTmhOQnzjwaK845ssIqbTeaLcmk,406
|
|
11
11
|
pymammotion/aliyun/tmp_constant.py,sha256=M4Hq_lrGB3LZdX6R2XohRPFoK1NDnNV-pTJwJcJ9838,6650
|
|
@@ -17,7 +17,7 @@ pymammotion/bluetooth/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
|
17
17
|
pymammotion/bluetooth/data/convert.py,sha256=tlctvRODoYypy4FpMD_UBwB1bIn5hG0QdQQdNI0e1R8,792
|
|
18
18
|
pymammotion/bluetooth/data/framectrldata.py,sha256=-qRmbHBXDLDEPOp-N9e44C9l3SUcJX7vyEvACx5DpDA,987
|
|
19
19
|
pymammotion/bluetooth/data/notifydata.py,sha256=N1bphpueWUWbsWUcpZmMGt2CyCgLcKAFAIHG4RCnqBU,1947
|
|
20
|
-
pymammotion/const.py,sha256=
|
|
20
|
+
pymammotion/const.py,sha256=EEmZ1v4MqN2nPiNpS_mJQqaCkSNEa1EXUmtwZBUhXIg,329
|
|
21
21
|
pymammotion/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
pymammotion/data/model/__init__.py,sha256=d8FlIgCcWqoH3jJSpnm-IY-25RM-l2nbRwLtWjSHo74,222
|
|
23
23
|
pymammotion/data/model/account.py,sha256=stWLDtWPw1vOPp3xNdX-jWziMmdCvww4IYl00UUGKuI,139
|
|
@@ -35,14 +35,14 @@ pymammotion/data/model/rapid_state.py,sha256=_e9M-65AbkvIqXyMYzLKBxbNvpso42qD8R-
|
|
|
35
35
|
pymammotion/data/model/region_data.py,sha256=75xOTM1qeRbSROp53eIczw3yCmYM9DgMjMh8qE9xkKo,2880
|
|
36
36
|
pymammotion/data/model/report_info.py,sha256=1Rj_yRZ9apWX296QHae5prdObDbs32bsQf9rzMz2KEQ,4458
|
|
37
37
|
pymammotion/data/mqtt/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
38
|
-
pymammotion/data/mqtt/event.py,sha256=
|
|
38
|
+
pymammotion/data/mqtt/event.py,sha256=ywlMEMVapuV-h6WE_miBq7lE10kcZBiNBJ3Taq2UP3k,3886
|
|
39
39
|
pymammotion/data/mqtt/properties.py,sha256=HkBPghr26L9_b4QaOi1DtPgb0UoPIOGSe9wb3kgnM6Y,2815
|
|
40
40
|
pymammotion/data/mqtt/status.py,sha256=zqnlo-MzejEQZszl0i0Wucoc3E76x6UtI9JLxoBnu54,1067
|
|
41
|
-
pymammotion/data/state_manager.py,sha256=
|
|
41
|
+
pymammotion/data/state_manager.py,sha256=jkedK5qAVDTGqIzlPNCmPpE-Pc1V4e-ZHW6Ds1ihJ50,3004
|
|
42
42
|
pymammotion/event/__init__.py,sha256=mgATR6vPHACNQ-0zH5fi7NdzeTCDV1CZyaWPmtUusi8,115
|
|
43
43
|
pymammotion/event/event.py,sha256=Fy5-I1p92AO_D67VW4eHQqA4pOt7MZsrP--tVfIVUz8,1820
|
|
44
44
|
pymammotion/http/_init_.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
|
-
pymammotion/http/http.py,sha256=
|
|
45
|
+
pymammotion/http/http.py,sha256=is0PNnglB4hdOMxLi1w5nyOrz3i4N3_jk0XzF_BbAZY,2346
|
|
46
46
|
pymammotion/mammotion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
47
|
pymammotion/mammotion/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
48
|
pymammotion/mammotion/commands/abstract_message.py,sha256=nw6r7694yzl7iJKqRqhLmAPRjd_TL_Xo_-JXq2_a_ug,222
|
|
@@ -58,7 +58,7 @@ pymammotion/mammotion/commands/messages/video.py,sha256=_8lJsU4sLm2CGnc7RDkueA0A
|
|
|
58
58
|
pymammotion/mammotion/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
59
59
|
pymammotion/mammotion/control/joystick.py,sha256=EWV20MMzQuhbLlNlXbsyZKSEpeM7x1CQL7saU4Pn0-g,6165
|
|
60
60
|
pymammotion/mammotion/devices/__init__.py,sha256=T72jt0ejtMjo1rPmn_FeMF3pmp0LLeRRpc9WcDKEYYY,126
|
|
61
|
-
pymammotion/mammotion/devices/mammotion.py,sha256=
|
|
61
|
+
pymammotion/mammotion/devices/mammotion.py,sha256=vPRVIV82c6Q25GHAG98kLihuPdwGgKJzPh9Kz4AGLqU,47945
|
|
62
62
|
pymammotion/mqtt/__init__.py,sha256=Ocs5e-HLJvTuDpVXyECEsWIvwsUaxzj7lZ9mSYutNDY,105
|
|
63
63
|
pymammotion/mqtt/mammotion_future.py,sha256=WKnHqeHiS2Ut-SaDBNOxqh1jDLeTiyLTsJ7PNUexrjk,687
|
|
64
64
|
pymammotion/mqtt/mammotion_mqtt.py,sha256=7V0JW2N9dshUJAGlg6d6Y5LKWYoXvlQd0o-9l6idPNg,8071
|
|
@@ -111,7 +111,7 @@ pymammotion/utility/device_type.py,sha256=KYawu2glZMVlPmxRbA4kVFujXz3miHp3rJiOWR
|
|
|
111
111
|
pymammotion/utility/map.py,sha256=aoi-Luzuph02hKynTofMoq3mnPstanx75MDAVv49CuY,2211
|
|
112
112
|
pymammotion/utility/periodic.py,sha256=9wJMfwXPlx6Mbp3Fws7LLTI34ZDKphH1bva_Ggyk32g,3281
|
|
113
113
|
pymammotion/utility/rocker_util.py,sha256=syPL0QN4zMzHiTIkUKS7RXBBptjdbkfNlPddwUD5V3A,7171
|
|
114
|
-
pymammotion-0.2.
|
|
115
|
-
pymammotion-0.2.
|
|
116
|
-
pymammotion-0.2.
|
|
117
|
-
pymammotion-0.2.
|
|
114
|
+
pymammotion-0.2.18.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
115
|
+
pymammotion-0.2.18.dist-info/METADATA,sha256=i4YzclEryvuMkLzPWQQC54c1gSgT2sWN2svPJKfyq04,3969
|
|
116
|
+
pymammotion-0.2.18.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
117
|
+
pymammotion-0.2.18.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|