pymammotion 0.5.0__py3-none-any.whl → 0.5.1__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 +15 -1
- pymammotion/data/state_manager.py +3 -2
- pymammotion/http/http.py +12 -9
- pymammotion/http/model/response_factory.py +16 -0
- {pymammotion-0.5.0.dist-info → pymammotion-0.5.1.dist-info}/METADATA +1 -1
- {pymammotion-0.5.0.dist-info → pymammotion-0.5.1.dist-info}/RECORD +8 -8
- {pymammotion-0.5.0.dist-info → pymammotion-0.5.1.dist-info}/LICENSE +0 -0
- {pymammotion-0.5.0.dist-info → pymammotion-0.5.1.dist-info}/WHEEL +0 -0
|
@@ -691,8 +691,22 @@ class CloudIOTGateway:
|
|
|
691
691
|
return self._devices_by_account_response
|
|
692
692
|
|
|
693
693
|
async def send_cloud_command(self, iot_id: str, command: bytes) -> str:
|
|
694
|
-
"""Send a cloud command to the specified IoT device."""
|
|
695
694
|
|
|
695
|
+
"""Sends a cloud command to a specified IoT device.
|
|
696
|
+
|
|
697
|
+
This function checks if the IoT token is expired and attempts to refresh it if
|
|
698
|
+
possible. It then constructs a request using the provided command and sends it
|
|
699
|
+
to the IoT device via an asynchronous HTTP POST request. The function handles
|
|
700
|
+
various error codes and exceptions based on the response from the cloud
|
|
701
|
+
service.
|
|
702
|
+
|
|
703
|
+
Args:
|
|
704
|
+
iot_id (str): The unique identifier of the IoT device.
|
|
705
|
+
command (bytes): The command to be sent to the IoT device in binary format.
|
|
706
|
+
|
|
707
|
+
Returns:
|
|
708
|
+
str: A unique message ID for the sent command.
|
|
709
|
+
"""
|
|
696
710
|
if command is None:
|
|
697
711
|
raise Exception("Command is missing / None")
|
|
698
712
|
|
|
@@ -105,16 +105,17 @@ class StateManager:
|
|
|
105
105
|
await self.ble_on_notification_callback.data_event(res)
|
|
106
106
|
|
|
107
107
|
async def on_properties_callback(self, thing_properties: ThingPropertiesMessage) -> None:
|
|
108
|
-
"""
|
|
108
|
+
"""Call properties callback if it exists."""
|
|
109
109
|
if self.properties_callback:
|
|
110
110
|
await self.properties_callback.data_event(thing_properties)
|
|
111
111
|
|
|
112
112
|
async def on_status_callback(self, thing_status: ThingStatusMessage) -> None:
|
|
113
|
-
"""
|
|
113
|
+
"""Execute the status callback if it is set."""
|
|
114
114
|
if self.status_callback:
|
|
115
115
|
await self.status_callback.data_event(thing_status)
|
|
116
116
|
|
|
117
117
|
async def get_commondata_ack_callback(self, comm_data: NavGetCommDataAck | SvgMessageAckT) -> None:
|
|
118
|
+
"""Asynchronously calls the appropriate callback based on available handlers."""
|
|
118
119
|
if self.cloud_get_commondata_ack_callback:
|
|
119
120
|
await self.cloud_get_commondata_ack_callback(comm_data)
|
|
120
121
|
elif self.ble_get_commondata_ack_callback:
|
pymammotion/http/http.py
CHANGED
|
@@ -18,7 +18,7 @@ class MammotionHTTP:
|
|
|
18
18
|
self._password = None
|
|
19
19
|
self.response: Response | None = None
|
|
20
20
|
self.login_info: LoginResponseData | None = None
|
|
21
|
-
self._headers = {"User-Agent": "okhttp/4.9.3", "App-Version": "
|
|
21
|
+
self._headers = {"User-Agent": "okhttp/4.9.3", "App-Version": "Home Assistant,1.14.2.29"}
|
|
22
22
|
self.encryption_utils = EncryptionUtils()
|
|
23
23
|
|
|
24
24
|
@staticmethod
|
|
@@ -93,12 +93,13 @@ class MammotionHTTP:
|
|
|
93
93
|
print(data)
|
|
94
94
|
|
|
95
95
|
async def get_stream_subscription(self, iot_id: str) -> Response[StreamSubscriptionResponse]:
|
|
96
|
-
"""
|
|
96
|
+
"""Fetches stream subscription data from agora.io for a given IoT device."""
|
|
97
97
|
async with ClientSession(MAMMOTION_API_DOMAIN) as session:
|
|
98
98
|
async with session.post(
|
|
99
99
|
"/device-server/v1/stream/subscription",
|
|
100
100
|
json={"deviceId": iot_id},
|
|
101
101
|
headers={
|
|
102
|
+
**self._headers,
|
|
102
103
|
"Authorization": f"Bearer {self.login_info.access_token}",
|
|
103
104
|
"Content-Type": "application/json",
|
|
104
105
|
"User-Agent": "okhttp/4.9.3",
|
|
@@ -116,9 +117,8 @@ class MammotionHTTP:
|
|
|
116
117
|
async def get_stream_subscription_mini_or_x_series(
|
|
117
118
|
self, iot_id: str, is_yuka: bool
|
|
118
119
|
) -> Response[StreamSubscriptionResponse]:
|
|
119
|
-
"""Get agora.io data for view camera stream (New models 2025)"""
|
|
120
|
-
|
|
121
120
|
# Prepare the payload with cameraStates based on is_yuka flag
|
|
121
|
+
"""Fetches stream subscription data for a given IoT device."""
|
|
122
122
|
payload = {"deviceId": iot_id, "mode": 0, "cameraStates": []}
|
|
123
123
|
|
|
124
124
|
# Add appropriate cameraStates based on the is_yuka flag
|
|
@@ -132,6 +132,7 @@ class MammotionHTTP:
|
|
|
132
132
|
"/device-server/v1/stream/token",
|
|
133
133
|
json=payload,
|
|
134
134
|
headers={
|
|
135
|
+
**self._headers,
|
|
135
136
|
"Authorization": f"Bearer {self.login_info.access_token}",
|
|
136
137
|
"Content-Type": "application/json",
|
|
137
138
|
"User-Agent": "okhttp/4.9.3",
|
|
@@ -147,7 +148,7 @@ class MammotionHTTP:
|
|
|
147
148
|
return response
|
|
148
149
|
|
|
149
150
|
async def get_video_resource(self, iot_id: str) -> Response[VideoResourceResponse]:
|
|
150
|
-
"""
|
|
151
|
+
"""Fetch video resource for a given IoT ID."""
|
|
151
152
|
async with ClientSession(MAMMOTION_API_DOMAIN) as session:
|
|
152
153
|
async with session.get(
|
|
153
154
|
f"/device-server/v1/video-resource/{iot_id}",
|
|
@@ -167,12 +168,13 @@ class MammotionHTTP:
|
|
|
167
168
|
return response
|
|
168
169
|
|
|
169
170
|
async def get_device_ota_firmware(self, iot_ids: list[str]) -> Response[list[CheckDeviceVersion]]:
|
|
170
|
-
"""
|
|
171
|
+
"""Checks device firmware versions for a list of IoT IDs."""
|
|
171
172
|
async with ClientSession(MAMMOTION_API_DOMAIN) as session:
|
|
172
173
|
async with session.post(
|
|
173
174
|
"/device-server/v1/devices/version/check",
|
|
174
175
|
json={"deviceIds": iot_ids},
|
|
175
176
|
headers={
|
|
177
|
+
**self._headers,
|
|
176
178
|
"Authorization": f"Bearer {self.login_info.access_token}",
|
|
177
179
|
"Content-Type": "application/json",
|
|
178
180
|
"User-Agent": "okhttp/4.9.3",
|
|
@@ -184,12 +186,13 @@ class MammotionHTTP:
|
|
|
184
186
|
return response_factory(Response[list[CheckDeviceVersion]], data)
|
|
185
187
|
|
|
186
188
|
async def start_ota_upgrade(self, iot_id: str, version: str) -> Response[str]:
|
|
187
|
-
"""
|
|
189
|
+
"""Initiates an OTA upgrade for a device."""
|
|
188
190
|
async with ClientSession(MAMMOTION_API_DOMAIN) as session:
|
|
189
191
|
async with session.post(
|
|
190
192
|
"/device-server/v1/ota/device/upgrade",
|
|
191
193
|
json={"deviceId": iot_id, "version": version},
|
|
192
194
|
headers={
|
|
195
|
+
**self._headers,
|
|
193
196
|
"Authorization": f"Bearer {self.login_info.access_token}",
|
|
194
197
|
"Content-Type": "application/json",
|
|
195
198
|
"User-Agent": "okhttp/4.9.3",
|
|
@@ -208,14 +211,14 @@ class MammotionHTTP:
|
|
|
208
211
|
return await self.login(account, self._password)
|
|
209
212
|
|
|
210
213
|
async def login(self, account: str, password: str) -> Response[LoginResponseData]:
|
|
214
|
+
"""Logs in to the service using provided account and password."""
|
|
211
215
|
self.account = account
|
|
212
216
|
self._password = password
|
|
213
217
|
async with ClientSession(MAMMOTION_DOMAIN) as session:
|
|
214
218
|
async with session.post(
|
|
215
219
|
"/oauth/token",
|
|
216
220
|
headers={
|
|
217
|
-
|
|
218
|
-
"App-Version": "google Pixel 2 XL taimen-Android 11,1.11.332",
|
|
221
|
+
**self._headers,
|
|
219
222
|
"Encrypt-Key": self.encryption_utils.encrypt_by_public_key(),
|
|
220
223
|
"Decrypt-Type": "3",
|
|
221
224
|
"Ec-Version": "v1",
|
|
@@ -6,6 +6,21 @@ T = TypeVar("T")
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def deserialize_data(value, target_type):
|
|
9
|
+
"""Deserialize data into a specified target type.
|
|
10
|
+
|
|
11
|
+
The function handles deserialization of basic types, lists, and unions. It
|
|
12
|
+
recursively processes list elements and supports optional types by handling
|
|
13
|
+
Union[T, None]. For custom types with a `from_dict` method, it calls this
|
|
14
|
+
method for deserialization. If the target type is unknown or unsupported, it
|
|
15
|
+
returns the value unchanged.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
value: The data to be deserialized.
|
|
19
|
+
target_type (type): The desired type into which the data should be deserialized.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
The deserialized data in the specified target type.
|
|
23
|
+
"""
|
|
9
24
|
if value is None:
|
|
10
25
|
return None
|
|
11
26
|
|
|
@@ -30,6 +45,7 @@ def deserialize_data(value, target_type):
|
|
|
30
45
|
|
|
31
46
|
def response_factory(response_cls: type[Response[T]], raw_dict: dict) -> Response[T]:
|
|
32
47
|
# Extract the type of the generic `data` field
|
|
48
|
+
"""Create a Response instance from a dictionary."""
|
|
33
49
|
data_type = get_args(response_cls)[0] if get_args(response_cls) else None
|
|
34
50
|
|
|
35
51
|
if data_type:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
pymammotion/__init__.py,sha256=H-U94bNLp0LPC6hkRopVEUlUsZSR97n7WfKGPjK1GMg,1638
|
|
2
2
|
pymammotion/aliyun/__init__.py,sha256=T1lkX7TRYiL4nqYanG4l4MImV-SlavSbuooC-W-uUGw,29
|
|
3
3
|
pymammotion/aliyun/client.py,sha256=GCpAnLOVWW_W0c8UvdRpWVzZH5oLto8JZnb82stJi-8,9662
|
|
4
|
-
pymammotion/aliyun/cloud_gateway.py,sha256=
|
|
4
|
+
pymammotion/aliyun/cloud_gateway.py,sha256=dRsxFOm_ou1X0VjU-i5B5hee3ay3q6HK1bqEP0oK0EE,29717
|
|
5
5
|
pymammotion/aliyun/model/aep_response.py,sha256=EY4uMTJ4F9rvbcXnAOc5YKi7q__9kIVgfDwfyr65Gk0,421
|
|
6
6
|
pymammotion/aliyun/model/connect_response.py,sha256=Yz-fEbDzgGPTo5Of2oAjmFkSv08T7ze80pQU4k-gKIU,824
|
|
7
7
|
pymammotion/aliyun/model/dev_by_account_response.py,sha256=P9yYy4Z2tLkJSqXA_5XGaCUliSSVa5ILl7VoMtL_tCA,977
|
|
@@ -45,17 +45,17 @@ pymammotion/data/mqtt/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdr
|
|
|
45
45
|
pymammotion/data/mqtt/event.py,sha256=C8TGRJs9wNxwg9FFmr9qcsweDnl5v5kcVcwiHxtYzJw,5384
|
|
46
46
|
pymammotion/data/mqtt/properties.py,sha256=FMZHDwKO-vZeaMP0ewVZ22wgBVhi244l2ZAWb9wFANQ,4259
|
|
47
47
|
pymammotion/data/mqtt/status.py,sha256=SgdrpE1Uldb01hybO6hYhgU1Sp1eILghC0UhMZMHrdQ,1091
|
|
48
|
-
pymammotion/data/state_manager.py,sha256=
|
|
48
|
+
pymammotion/data/state_manager.py,sha256=Y3doVfn-ahzSZoC-0h0fMAyyGfrixDPMtXOcyNONnHE,11484
|
|
49
49
|
pymammotion/event/__init__.py,sha256=mgATR6vPHACNQ-0zH5fi7NdzeTCDV1CZyaWPmtUusi8,115
|
|
50
50
|
pymammotion/event/event.py,sha256=Z8WYxv_-5khEqKjL1w4c_Et24G1Kdm8QFuIBylD3h3U,3021
|
|
51
51
|
pymammotion/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
52
52
|
pymammotion/http/_init_.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
53
|
pymammotion/http/encryption.py,sha256=lzXu3WwBdQlzjXxWnlJuRgkCrKdPbxx5drhMitVKIEk,8287
|
|
54
|
-
pymammotion/http/http.py,sha256=
|
|
54
|
+
pymammotion/http/http.py,sha256=_Umuj6DKnTiDZ_y6C6DqPvHMRxKvqHqM0G_1QlsmHN8,12103
|
|
55
55
|
pymammotion/http/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
56
|
pymammotion/http/model/camera_stream.py,sha256=ilxQNny_w9Frwt-m8kbHinvyjDv4Bx8C2swfZ2lTEDE,600
|
|
57
57
|
pymammotion/http/model/http.py,sha256=VDBmi9nyY5Y2ns_HYvKIyzbkKRxhZ5elpq0lWXWzbGw,4123
|
|
58
|
-
pymammotion/http/model/response_factory.py,sha256=
|
|
58
|
+
pymammotion/http/model/response_factory.py,sha256=f5_ZR0-4sLOU-q28BVy5sQOReSoND2A8UvpOOwnwrzA,1936
|
|
59
59
|
pymammotion/mammotion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
60
|
pymammotion/mammotion/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
61
|
pymammotion/mammotion/commands/abstract_message.py,sha256=P5FcjGkfoQ1O4Q9JKdq306TisQnJ40xDXufR-juNn8k,792
|
|
@@ -124,7 +124,7 @@ pymammotion/utility/movement.py,sha256=N75oAoAgFydqoaOedYIxGUHmuTCtPzAOtb-d_29tp
|
|
|
124
124
|
pymammotion/utility/mur_mur_hash.py,sha256=xEfOZVbqRawJj66eLgtnZ85OauDR47oIPr29OHelzPI,4468
|
|
125
125
|
pymammotion/utility/periodic.py,sha256=MbeSb9cfhxzYmdT_RiE0dZe3H9IfbQW_zSqhmSX2RUc,3321
|
|
126
126
|
pymammotion/utility/rocker_util.py,sha256=6tX7sS87qoQC_tsxbx3NLL-HgS08wtzXiZkhDiz7uo0,7179
|
|
127
|
-
pymammotion-0.5.
|
|
128
|
-
pymammotion-0.5.
|
|
129
|
-
pymammotion-0.5.
|
|
130
|
-
pymammotion-0.5.
|
|
127
|
+
pymammotion-0.5.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
128
|
+
pymammotion-0.5.1.dist-info/METADATA,sha256=xxLNaAy_fpnXzUHLfWVbN5Ts9VMkfKiPeDuc_OtGhPo,3870
|
|
129
|
+
pymammotion-0.5.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
130
|
+
pymammotion-0.5.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|