wyzeapy 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.
- wyzeapy/__init__.py +277 -45
- wyzeapy/const.py +9 -4
- wyzeapy/crypto.py +31 -2
- wyzeapy/exceptions.py +11 -8
- wyzeapy/payload_factory.py +205 -170
- wyzeapy/services/__init__.py +3 -0
- wyzeapy/services/base_service.py +406 -212
- wyzeapy/services/bulb_service.py +67 -63
- wyzeapy/services/camera_service.py +136 -50
- wyzeapy/services/hms_service.py +8 -17
- wyzeapy/services/irrigation_service.py +189 -0
- wyzeapy/services/lock_service.py +5 -3
- wyzeapy/services/sensor_service.py +32 -11
- wyzeapy/services/switch_service.py +6 -2
- wyzeapy/services/thermostat_service.py +29 -15
- wyzeapy/services/update_manager.py +38 -11
- wyzeapy/services/wall_switch_service.py +18 -8
- wyzeapy/tests/test_irrigation_service.py +536 -0
- wyzeapy/types.py +29 -12
- wyzeapy/utils.py +98 -17
- wyzeapy/wyze_auth_lib.py +195 -37
- wyzeapy-0.5.30.dist-info/METADATA +13 -0
- wyzeapy-0.5.30.dist-info/RECORD +24 -0
- {wyzeapy-0.5.28.dist-info → wyzeapy-0.5.30.dist-info}/WHEEL +1 -1
- wyzeapy/tests/test_bulb_service.py +0 -135
- wyzeapy/tests/test_camera_service.py +0 -180
- wyzeapy/tests/test_hms_service.py +0 -90
- wyzeapy/tests/test_lock_service.py +0 -114
- wyzeapy/tests/test_sensor_service.py +0 -159
- wyzeapy/tests/test_switch_service.py +0 -138
- wyzeapy/tests/test_thermostat_service.py +0 -136
- wyzeapy/tests/test_wall_switch_service.py +0 -161
- wyzeapy-0.5.28.dist-info/LICENSES/GPL-3.0-only.txt +0 -232
- wyzeapy-0.5.28.dist-info/METADATA +0 -16
- wyzeapy-0.5.28.dist-info/RECORD +0 -31
wyzeapy/services/base_service.py
CHANGED
|
@@ -12,49 +12,163 @@ from typing import List, Tuple, Any, Dict, Optional
|
|
|
12
12
|
import aiohttp
|
|
13
13
|
|
|
14
14
|
from .update_manager import DeviceUpdater, UpdateManager
|
|
15
|
-
from ..const import
|
|
15
|
+
from ..const import (
|
|
16
|
+
PHONE_SYSTEM_TYPE,
|
|
17
|
+
APP_VERSION,
|
|
18
|
+
APP_VER,
|
|
19
|
+
PHONE_ID,
|
|
20
|
+
APP_NAME,
|
|
21
|
+
OLIVE_APP_ID,
|
|
22
|
+
APP_INFO,
|
|
23
|
+
SC,
|
|
24
|
+
SV,
|
|
25
|
+
APP_PLATFORM,
|
|
26
|
+
SOURCE,
|
|
27
|
+
)
|
|
16
28
|
from ..crypto import olive_create_signature
|
|
17
|
-
from ..payload_factory import
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
from ..payload_factory import (
|
|
30
|
+
olive_create_hms_patch_payload,
|
|
31
|
+
olive_create_hms_payload,
|
|
32
|
+
olive_create_hms_get_payload,
|
|
33
|
+
ford_create_payload,
|
|
34
|
+
olive_create_get_payload,
|
|
35
|
+
olive_create_post_payload,
|
|
36
|
+
olive_create_user_info_payload,
|
|
37
|
+
devicemgmt_create_capabilities_payload,
|
|
38
|
+
devicemgmt_get_iot_props_list,
|
|
39
|
+
olive_create_get_payload_irrigation,
|
|
40
|
+
olive_create_post_payload_irrigation_stop,
|
|
41
|
+
olive_create_post_payload_irrigation_quickrun,
|
|
42
|
+
)
|
|
20
43
|
from ..types import PropertyIDs, Device, DeviceMgmtToggleType
|
|
21
|
-
from ..utils import
|
|
22
|
-
|
|
44
|
+
from ..utils import (
|
|
45
|
+
check_for_errors_standard,
|
|
46
|
+
check_for_errors_hms,
|
|
47
|
+
check_for_errors_lock,
|
|
48
|
+
check_for_errors_iot,
|
|
49
|
+
wyze_encrypt,
|
|
50
|
+
check_for_errors_devicemgmt,
|
|
51
|
+
)
|
|
23
52
|
from ..wyze_auth_lib import WyzeAuthLib
|
|
24
53
|
|
|
54
|
+
"""
|
|
55
|
+
BaseService provides shared functionality for Wyze device services,
|
|
56
|
+
including authentication, device discovery, and automatic updates.
|
|
57
|
+
"""
|
|
58
|
+
|
|
25
59
|
_LOGGER = logging.getLogger(__name__)
|
|
26
60
|
|
|
27
61
|
|
|
28
62
|
class BaseService:
|
|
63
|
+
"""Base service class providing common functionality for all Wyze device services.
|
|
64
|
+
|
|
65
|
+
This abstract base class provides shared infrastructure for interacting with Wyze devices
|
|
66
|
+
including authentication, API communication, device discovery, and automatic updates.
|
|
67
|
+
All device-specific service classes (BulbService, SwitchService, etc.) inherit from this class.
|
|
68
|
+
|
|
69
|
+
**Key Features:**
|
|
70
|
+
* Device discovery and caching via `get_object_list()`
|
|
71
|
+
* Automatic device updates with configurable intervals
|
|
72
|
+
* Authentication token management and refresh
|
|
73
|
+
* Common API endpoint wrappers for device properties and actions
|
|
74
|
+
* Error handling and validation for API responses
|
|
75
|
+
* Support for both cloud and local device communication
|
|
76
|
+
|
|
77
|
+
**Common Usage Patterns:**
|
|
78
|
+
```python
|
|
79
|
+
# Device services inherit from BaseService
|
|
80
|
+
bulb_service = await wyze.bulb_service
|
|
81
|
+
|
|
82
|
+
# Get all devices (cached after first call)
|
|
83
|
+
devices = await bulb_service.get_object_list()
|
|
84
|
+
|
|
85
|
+
# Register for automatic updates
|
|
86
|
+
bulb_service.register_updater(device, interval=30)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Note:** This class is not meant to be instantiated directly - use device-specific services instead.
|
|
90
|
+
"""
|
|
91
|
+
|
|
29
92
|
_devices: Optional[List[Device]] = None
|
|
30
|
-
_last_updated_time: time =
|
|
93
|
+
_last_updated_time: time = (
|
|
94
|
+
0 # preload a value of 0 so that comparison will succeed on the first run
|
|
95
|
+
)
|
|
31
96
|
_min_update_time = 1200 # lets let the device_params update every 20 minutes for now. This could probably reduced signicficantly.
|
|
32
|
-
_update_lock: asyncio.Lock = asyncio.Lock()
|
|
97
|
+
_update_lock: asyncio.Lock = asyncio.Lock() # fmt: skip
|
|
33
98
|
_update_manager: UpdateManager = UpdateManager()
|
|
34
99
|
_update_loop = None
|
|
35
100
|
_updater: DeviceUpdater = None
|
|
36
101
|
_updater_dict = {}
|
|
37
102
|
|
|
38
103
|
def __init__(self, auth_lib: WyzeAuthLib):
|
|
104
|
+
"""Initialize the base service with authentication.
|
|
105
|
+
|
|
106
|
+
**Args:**
|
|
107
|
+
* `auth_lib` (WyzeAuthLib): The authentication library for API access
|
|
108
|
+
"""
|
|
39
109
|
self._auth_lib = auth_lib
|
|
40
110
|
|
|
41
111
|
@staticmethod
|
|
42
112
|
async def start_update_manager():
|
|
113
|
+
"""Start the global update manager for automatic device state updates.
|
|
114
|
+
|
|
115
|
+
This initializes the background update system that handles periodic
|
|
116
|
+
device state refreshes for all registered devices.
|
|
117
|
+
|
|
118
|
+
**Example:**
|
|
119
|
+
```python
|
|
120
|
+
await BaseService.start_update_manager()
|
|
121
|
+
```
|
|
122
|
+
"""
|
|
43
123
|
if BaseService._update_loop is None:
|
|
44
124
|
BaseService._update_loop = asyncio.get_event_loop()
|
|
45
|
-
BaseService._update_loop.create_task(
|
|
125
|
+
BaseService._update_loop.create_task(
|
|
126
|
+
BaseService._update_manager.update_next()
|
|
127
|
+
)
|
|
46
128
|
|
|
47
129
|
def register_updater(self, device: Device, interval):
|
|
130
|
+
"""Register a device for automatic status updates at a specified interval.
|
|
131
|
+
|
|
132
|
+
This enables automatic background updates for a device, periodically refreshing
|
|
133
|
+
its state from the Wyze servers. Useful for keeping device status current.
|
|
134
|
+
|
|
135
|
+
**Args:**
|
|
136
|
+
* `device` (Device): The device to register for automatic updates
|
|
137
|
+
* `interval` (int): Update interval in seconds
|
|
138
|
+
|
|
139
|
+
**Example:**
|
|
140
|
+
```python
|
|
141
|
+
# Update device state every 30 seconds
|
|
142
|
+
service.register_updater(device, 30)
|
|
143
|
+
```
|
|
144
|
+
"""
|
|
48
145
|
self._updater = DeviceUpdater(self, device, interval)
|
|
49
146
|
BaseService._update_manager.add_updater(self._updater)
|
|
50
147
|
self._updater_dict[self._updater.device] = self._updater
|
|
51
148
|
|
|
52
149
|
def unregister_updater(self, device: Device):
|
|
150
|
+
"""Stop automatic updates for a device.
|
|
151
|
+
|
|
152
|
+
This removes a device from the automatic update system to stop
|
|
153
|
+
background status refreshes.
|
|
154
|
+
|
|
155
|
+
**Args:**
|
|
156
|
+
* `device` (Device): The device to stop updating automatically
|
|
157
|
+
|
|
158
|
+
**Example:**
|
|
159
|
+
```python
|
|
160
|
+
service.unregister_updater(device)
|
|
161
|
+
```
|
|
162
|
+
"""
|
|
53
163
|
if self._updater:
|
|
54
164
|
BaseService._update_manager.del_updater(self._updater_dict[device])
|
|
55
165
|
del self._updater_dict[device]
|
|
56
166
|
|
|
57
|
-
async def set_push_info(self, on: bool)
|
|
167
|
+
async def set_push_info(self, on: bool):
|
|
168
|
+
"""Set push info for the user.
|
|
169
|
+
|
|
170
|
+
:param on: Whether to enable or disable push notifications.
|
|
171
|
+
"""
|
|
58
172
|
await self._auth_lib.refresh_if_should()
|
|
59
173
|
|
|
60
174
|
url = "https://api.wyzecam.com/app/user/set_push_info"
|
|
@@ -68,7 +182,7 @@ class BaseService:
|
|
|
68
182
|
"sv": SV,
|
|
69
183
|
"access_token": self._auth_lib.token.access_token,
|
|
70
184
|
"phone_id": PHONE_ID,
|
|
71
|
-
"app_name": APP_NAME
|
|
185
|
+
"app_name": APP_NAME,
|
|
72
186
|
}
|
|
73
187
|
|
|
74
188
|
response_json = await self._auth_lib.post(url, json=payload)
|
|
@@ -76,31 +190,49 @@ class BaseService:
|
|
|
76
190
|
check_for_errors_standard(self, response_json)
|
|
77
191
|
|
|
78
192
|
async def get_user_profile(self) -> Dict[Any, Any]:
|
|
193
|
+
"""Get user profile.
|
|
194
|
+
|
|
195
|
+
:return: User profile.
|
|
196
|
+
"""
|
|
79
197
|
await self._auth_lib.refresh_if_should()
|
|
80
198
|
|
|
81
199
|
payload = olive_create_user_info_payload()
|
|
82
200
|
signature = olive_create_signature(payload, self._auth_lib.token.access_token)
|
|
83
201
|
headers = {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
202
|
+
"Accept-Encoding": "gzip",
|
|
203
|
+
"User-Agent": "myapp",
|
|
204
|
+
"appid": OLIVE_APP_ID,
|
|
205
|
+
"appinfo": APP_INFO,
|
|
206
|
+
"phoneid": PHONE_ID,
|
|
207
|
+
"access_token": self._auth_lib.token.access_token,
|
|
208
|
+
"signature2": signature,
|
|
91
209
|
}
|
|
92
210
|
|
|
93
|
-
url =
|
|
211
|
+
url = (
|
|
212
|
+
"https://wyze-platform-service.wyzecam.com/app/v2/platform/get_user_profile"
|
|
213
|
+
)
|
|
94
214
|
|
|
95
215
|
response_json = await self._auth_lib.get(url, headers=headers, params=payload)
|
|
96
216
|
|
|
97
217
|
return response_json
|
|
98
218
|
|
|
99
219
|
async def get_object_list(self) -> List[Device]:
|
|
100
|
-
"""
|
|
101
|
-
|
|
220
|
+
"""Discover and retrieve all devices associated with the Wyze account.
|
|
221
|
+
|
|
222
|
+
This method fetches all devices from the Wyze API and caches them for
|
|
223
|
+
efficient subsequent access. Results are shared across all service instances.
|
|
224
|
+
|
|
225
|
+
**Returns:**
|
|
226
|
+
* `List[Device]`: List of all discovered Wyze devices
|
|
227
|
+
|
|
228
|
+
**Example:**
|
|
229
|
+
```python
|
|
230
|
+
devices = await service.get_object_list()
|
|
231
|
+
for device in devices:
|
|
232
|
+
print(f"Device: {device.nickname} ({device.product_model})")
|
|
233
|
+
```
|
|
102
234
|
|
|
103
|
-
|
|
235
|
+
**Note:** Results are cached and shared across all BaseService instances
|
|
104
236
|
"""
|
|
105
237
|
await self._auth_lib.refresh_if_should()
|
|
106
238
|
|
|
@@ -113,19 +245,29 @@ class BaseService:
|
|
|
113
245
|
"sv": "9d74946e652647e9b6c9d59326aef104",
|
|
114
246
|
"access_token": self._auth_lib.token.access_token,
|
|
115
247
|
"phone_id": PHONE_ID,
|
|
116
|
-
"app_name": APP_NAME
|
|
248
|
+
"app_name": APP_NAME,
|
|
117
249
|
}
|
|
118
250
|
|
|
119
|
-
response_json = await self._auth_lib.post(
|
|
120
|
-
|
|
251
|
+
response_json = await self._auth_lib.post(
|
|
252
|
+
"https://api.wyzecam.com/app/v2/home_page/get_object_list", json=payload
|
|
253
|
+
)
|
|
121
254
|
|
|
122
255
|
check_for_errors_standard(self, response_json)
|
|
123
256
|
# Cache the devices so that update calls can pull more recent device_params
|
|
124
|
-
BaseService._devices = [
|
|
257
|
+
BaseService._devices = [
|
|
258
|
+
Device(device) for device in response_json["data"]["device_list"]
|
|
259
|
+
]
|
|
125
260
|
|
|
126
261
|
return BaseService._devices
|
|
127
262
|
|
|
128
|
-
async def get_updated_params(
|
|
263
|
+
async def get_updated_params(
|
|
264
|
+
self, device_mac: str = None
|
|
265
|
+
) -> Dict[str, Optional[Any]]:
|
|
266
|
+
"""Get updated params for a device.
|
|
267
|
+
|
|
268
|
+
:param device_mac: The device mac to get updated params for.
|
|
269
|
+
:return: Updated params for the device.
|
|
270
|
+
"""
|
|
129
271
|
if time.time() - BaseService._last_updated_time >= BaseService._min_update_time:
|
|
130
272
|
await self.get_object_list()
|
|
131
273
|
BaseService._last_updated_time = time.time()
|
|
@@ -136,8 +278,7 @@ class BaseService:
|
|
|
136
278
|
return ret_params
|
|
137
279
|
|
|
138
280
|
async def _get_property_list(self, device: Device) -> List[Tuple[PropertyIDs, Any]]:
|
|
139
|
-
"""
|
|
140
|
-
Wraps the api.wyzecam.com/app/v2/device/get_property_list endpoint
|
|
281
|
+
"""Wraps the api.wyzecam.com/app/v2/device/get_property_list endpoint
|
|
141
282
|
|
|
142
283
|
:param device: Device to get properties for
|
|
143
284
|
:return: List of PropertyIDs and values
|
|
@@ -157,34 +298,30 @@ class BaseService:
|
|
|
157
298
|
"app_name": APP_NAME,
|
|
158
299
|
"device_model": device.product_model,
|
|
159
300
|
"device_mac": device.mac,
|
|
160
|
-
"target_pid_list": []
|
|
301
|
+
"target_pid_list": [],
|
|
161
302
|
}
|
|
162
303
|
|
|
163
|
-
response_json = await self._auth_lib.post(
|
|
164
|
-
|
|
304
|
+
response_json = await self._auth_lib.post(
|
|
305
|
+
"https://api.wyzecam.com/app/v2/device/get_property_list", json=payload
|
|
306
|
+
)
|
|
165
307
|
|
|
166
308
|
check_for_errors_standard(self, response_json)
|
|
167
|
-
properties = response_json[
|
|
309
|
+
properties = response_json["data"]["property_list"]
|
|
168
310
|
property_list = []
|
|
169
311
|
for prop in properties:
|
|
170
312
|
try:
|
|
171
|
-
property_id = PropertyIDs(prop[
|
|
172
|
-
property_list.append((
|
|
173
|
-
property_id,
|
|
174
|
-
prop['value']
|
|
175
|
-
))
|
|
313
|
+
property_id = PropertyIDs(prop["pid"])
|
|
314
|
+
property_list.append((property_id, prop["value"]))
|
|
176
315
|
except ValueError:
|
|
177
316
|
pass
|
|
178
317
|
|
|
179
318
|
return property_list
|
|
180
319
|
|
|
181
|
-
async def _set_property_list(self, device: Device, plist: List[Dict[str, str]])
|
|
182
|
-
"""
|
|
183
|
-
Wraps the api.wyzecam.com/app/v2/device/set_property_list endpoint
|
|
320
|
+
async def _set_property_list(self, device: Device, plist: List[Dict[str, str]]):
|
|
321
|
+
"""Wraps the api.wyzecam.com/app/v2/device/set_property_list endpoint
|
|
184
322
|
|
|
185
323
|
:param device: The device for which to set the property(ies)
|
|
186
324
|
:param plist: A list of properties [{"pid": pid, "pvalue": pvalue},...]
|
|
187
|
-
:return:
|
|
188
325
|
"""
|
|
189
326
|
|
|
190
327
|
await self._auth_lib.refresh_if_should()
|
|
@@ -201,17 +338,17 @@ class BaseService:
|
|
|
201
338
|
"app_name": APP_NAME,
|
|
202
339
|
"property_list": plist,
|
|
203
340
|
"device_model": device.product_model,
|
|
204
|
-
"device_mac": device.mac
|
|
341
|
+
"device_mac": device.mac,
|
|
205
342
|
}
|
|
206
343
|
|
|
207
|
-
response_json = await self._auth_lib.post(
|
|
208
|
-
|
|
344
|
+
response_json = await self._auth_lib.post(
|
|
345
|
+
"https://api.wyzecam.com/app/v2/device/set_property_list", json=payload
|
|
346
|
+
)
|
|
209
347
|
|
|
210
348
|
check_for_errors_standard(self, response_json)
|
|
211
349
|
|
|
212
|
-
async def _run_action_list(self, device: Device, plist: List[Dict[Any, Any]])
|
|
213
|
-
"""
|
|
214
|
-
Wraps the api.wyzecam.com/app/v2/auto/run_action_list endpoint
|
|
350
|
+
async def _run_action_list(self, device: Device, plist: List[Dict[Any, Any]]):
|
|
351
|
+
"""Wraps the api.wyzecam.com/app/v2/auto/run_action_list endpoint
|
|
215
352
|
|
|
216
353
|
:param device: The device for which to run the action list
|
|
217
354
|
:param plist: A list of properties [{"pid": pid, "pvalue": pvalue},...]
|
|
@@ -231,31 +368,24 @@ class BaseService:
|
|
|
231
368
|
"action_list": [
|
|
232
369
|
{
|
|
233
370
|
"instance_id": device.mac,
|
|
234
|
-
"action_params": {
|
|
235
|
-
"list": [
|
|
236
|
-
{
|
|
237
|
-
"mac": device.mac,
|
|
238
|
-
"plist": plist
|
|
239
|
-
}
|
|
240
|
-
]
|
|
241
|
-
},
|
|
371
|
+
"action_params": {"list": [{"mac": device.mac, "plist": plist}]},
|
|
242
372
|
"provider_key": device.product_model,
|
|
243
|
-
"action_key": "set_mesh_property"
|
|
373
|
+
"action_key": "set_mesh_property",
|
|
244
374
|
}
|
|
245
|
-
]
|
|
375
|
+
],
|
|
246
376
|
}
|
|
247
377
|
|
|
248
|
-
response_json = await self._auth_lib.post(
|
|
249
|
-
|
|
378
|
+
response_json = await self._auth_lib.post(
|
|
379
|
+
"https://api.wyzecam.com/app/v2/auto/run_action_list", json=payload
|
|
380
|
+
)
|
|
250
381
|
|
|
251
382
|
check_for_errors_standard(self, response_json)
|
|
252
383
|
|
|
253
384
|
async def _get_event_list(self, count: int) -> Dict[Any, Any]:
|
|
254
|
-
"""
|
|
255
|
-
Wraps the api.wyzecam.com/app/v2/device/get_event_list endpoint
|
|
385
|
+
"""Wraps the api.wyzecam.com/app/v2/device/get_event_list endpoint
|
|
256
386
|
|
|
257
387
|
:param count: Number of events to gather
|
|
258
|
-
:return: Response from the server
|
|
388
|
+
:return: Response from the server after being validated
|
|
259
389
|
"""
|
|
260
390
|
|
|
261
391
|
await self._auth_lib.refresh_if_should()
|
|
@@ -268,12 +398,7 @@ class BaseService:
|
|
|
268
398
|
"count": count,
|
|
269
399
|
"app_version": APP_VERSION,
|
|
270
400
|
"order_by": 2,
|
|
271
|
-
"event_value_list": [
|
|
272
|
-
"1",
|
|
273
|
-
"13",
|
|
274
|
-
"10",
|
|
275
|
-
"12"
|
|
276
|
-
],
|
|
401
|
+
"event_value_list": ["1", "13", "10", "12"],
|
|
277
402
|
"sc": "9f275790cab94a72bd206c8876429f3c",
|
|
278
403
|
"device_mac_list": [],
|
|
279
404
|
"event_tag_list": [],
|
|
@@ -283,22 +408,21 @@ class BaseService:
|
|
|
283
408
|
"app_ver": APP_VER,
|
|
284
409
|
"ts": 1623612037763,
|
|
285
410
|
"device_mac": "",
|
|
286
|
-
"access_token": self._auth_lib.token.access_token
|
|
411
|
+
"access_token": self._auth_lib.token.access_token,
|
|
287
412
|
}
|
|
288
413
|
|
|
289
|
-
response_json = await self._auth_lib.post(
|
|
290
|
-
|
|
414
|
+
response_json = await self._auth_lib.post(
|
|
415
|
+
"https://api.wyzecam.com/app/v2/device/get_event_list", json=payload
|
|
416
|
+
)
|
|
291
417
|
|
|
292
418
|
check_for_errors_standard(self, response_json)
|
|
293
419
|
return response_json
|
|
294
420
|
|
|
295
|
-
async def _run_action(self, device: Device, action: str)
|
|
296
|
-
"""
|
|
297
|
-
Wraps the api.wyzecam.com/app/v2/auto/run_action endpoint
|
|
421
|
+
async def _run_action(self, device: Device, action: str):
|
|
422
|
+
"""Wraps the api.wyzecam.com/app/v2/auto/run_action endpoint
|
|
298
423
|
|
|
299
424
|
:param device: The device for which to run the action
|
|
300
425
|
:param action: The action to run
|
|
301
|
-
:return:
|
|
302
426
|
"""
|
|
303
427
|
|
|
304
428
|
await self._auth_lib.refresh_if_should()
|
|
@@ -320,18 +444,18 @@ class BaseService:
|
|
|
320
444
|
"custom_string": "",
|
|
321
445
|
}
|
|
322
446
|
|
|
323
|
-
response_json = await self._auth_lib.post(
|
|
324
|
-
|
|
447
|
+
response_json = await self._auth_lib.post(
|
|
448
|
+
"https://api.wyzecam.com/app/v2/auto/run_action", json=payload
|
|
449
|
+
)
|
|
325
450
|
|
|
326
451
|
check_for_errors_standard(self, response_json)
|
|
327
|
-
|
|
328
|
-
async def _run_action_devicemgmt(self, device: Device, type: str, value: str)
|
|
329
|
-
"""
|
|
330
|
-
Wraps the devicemgmt-service-beta.wyze.com/device-management/api/action/run_action endpoint
|
|
452
|
+
|
|
453
|
+
async def _run_action_devicemgmt(self, device: Device, type: str, value: str):
|
|
454
|
+
"""Wraps the devicemgmt-service-beta.wyze.com/device-management/api/action/run_action endpoint
|
|
331
455
|
|
|
332
456
|
:param device: The device for which to run the action
|
|
333
|
-
:param
|
|
334
|
-
:
|
|
457
|
+
:param type: The type of action to run
|
|
458
|
+
:param value: The value of the action to run
|
|
335
459
|
"""
|
|
336
460
|
|
|
337
461
|
await self._auth_lib.refresh_if_should()
|
|
@@ -339,30 +463,32 @@ class BaseService:
|
|
|
339
463
|
capabilities = devicemgmt_create_capabilities_payload(type, value)
|
|
340
464
|
|
|
341
465
|
payload = {
|
|
342
|
-
"capabilities": [
|
|
343
|
-
capabilities
|
|
344
|
-
],
|
|
466
|
+
"capabilities": [capabilities],
|
|
345
467
|
"nonce": int(time.time() * 1000),
|
|
346
468
|
"targetInfo": {
|
|
347
469
|
"id": device.mac,
|
|
348
470
|
"productModel": device.product_model,
|
|
349
|
-
"type": "DEVICE"
|
|
471
|
+
"type": "DEVICE",
|
|
350
472
|
},
|
|
351
|
-
"transactionId": "0a5b20591fedd4du1b93f90743ba0csd"
|
|
473
|
+
"transactionId": "0a5b20591fedd4du1b93f90743ba0csd", # OG cam needs this (doesn't matter what the value is)
|
|
352
474
|
}
|
|
353
475
|
|
|
354
476
|
headers = {
|
|
355
477
|
"authorization": self._auth_lib.token.access_token,
|
|
356
478
|
}
|
|
357
479
|
|
|
358
|
-
response_json = await self._auth_lib.post(
|
|
359
|
-
|
|
480
|
+
response_json = await self._auth_lib.post(
|
|
481
|
+
"https://devicemgmt-service-beta.wyze.com/device-management/api/action/run_action",
|
|
482
|
+
json=payload,
|
|
483
|
+
headers=headers,
|
|
484
|
+
)
|
|
360
485
|
|
|
361
486
|
check_for_errors_iot(self, response_json)
|
|
362
|
-
|
|
363
|
-
async def _set_toggle(
|
|
364
|
-
|
|
365
|
-
|
|
487
|
+
|
|
488
|
+
async def _set_toggle(
|
|
489
|
+
self, device: Device, toggleType: DeviceMgmtToggleType, state: str
|
|
490
|
+
):
|
|
491
|
+
"""Wraps the ai-subscription-service-beta.wyzecam.com/v4/subscription-service/toggle-management endpoint
|
|
366
492
|
|
|
367
493
|
:param device: The device for which to get the state
|
|
368
494
|
:param toggleType: Enum for the toggle type
|
|
@@ -377,21 +503,15 @@ class BaseService:
|
|
|
377
503
|
"device_firmware": "1234567890",
|
|
378
504
|
"device_id": device.mac,
|
|
379
505
|
"device_model": device.product_model,
|
|
380
|
-
"page_id": [
|
|
381
|
-
toggleType.pageId
|
|
382
|
-
],
|
|
506
|
+
"page_id": [toggleType.pageId],
|
|
383
507
|
"toggle_update": [
|
|
384
|
-
{
|
|
385
|
-
|
|
386
|
-
"toggle_status": state
|
|
387
|
-
}
|
|
388
|
-
]
|
|
508
|
+
{"toggle_id": toggleType.toggleId, "toggle_status": state}
|
|
509
|
+
],
|
|
389
510
|
}
|
|
390
511
|
],
|
|
391
|
-
"nonce": str(int(time.time() * 1000))
|
|
512
|
+
"nonce": str(int(time.time() * 1000)),
|
|
392
513
|
}
|
|
393
514
|
|
|
394
|
-
|
|
395
515
|
signature = olive_create_signature(payload, self._auth_lib.token.access_token)
|
|
396
516
|
headers = {
|
|
397
517
|
"access_token": self._auth_lib.token.access_token,
|
|
@@ -401,20 +521,22 @@ class BaseService:
|
|
|
401
521
|
"signature2": signature,
|
|
402
522
|
"appplatform": APP_PLATFORM,
|
|
403
523
|
"appversion": APP_VERSION,
|
|
404
|
-
"requestid": "35374158s4s313b9a2be7c057f2da5d1"
|
|
524
|
+
"requestid": "35374158s4s313b9a2be7c057f2da5d1",
|
|
405
525
|
}
|
|
406
526
|
|
|
407
|
-
response_json = await self._auth_lib.put(
|
|
408
|
-
|
|
409
|
-
|
|
527
|
+
response_json = await self._auth_lib.put(
|
|
528
|
+
"https://ai-subscription-service-beta.wyzecam.com/v4/subscription-service/toggle-management",
|
|
529
|
+
json=payload,
|
|
530
|
+
headers=headers,
|
|
531
|
+
)
|
|
532
|
+
|
|
410
533
|
check_for_errors_devicemgmt(self, response_json)
|
|
411
|
-
|
|
534
|
+
|
|
412
535
|
async def _get_iot_prop_devicemgmt(self, device: Device) -> Dict[str, Any]:
|
|
413
|
-
"""
|
|
414
|
-
Wraps the devicemgmt-service-beta.wyze.com/device-management/api/device-property/get_iot_prop endpoint
|
|
536
|
+
"""Wraps the devicemgmt-service-beta.wyze.com/device-management/api/device-property/get_iot_prop endpoint
|
|
415
537
|
|
|
416
538
|
:param device: The device for which to get the state
|
|
417
|
-
:return:
|
|
539
|
+
:return: Response from the server after being validated
|
|
418
540
|
"""
|
|
419
541
|
|
|
420
542
|
await self._auth_lib.refresh_if_should()
|
|
@@ -425,24 +547,26 @@ class BaseService:
|
|
|
425
547
|
"targetInfo": {
|
|
426
548
|
"id": device.mac,
|
|
427
549
|
"productModel": device.product_model,
|
|
428
|
-
"type": "DEVICE"
|
|
429
|
-
}
|
|
550
|
+
"type": "DEVICE",
|
|
551
|
+
},
|
|
430
552
|
}
|
|
431
553
|
|
|
432
554
|
headers = {
|
|
433
555
|
"authorization": self._auth_lib.token.access_token,
|
|
434
556
|
}
|
|
435
557
|
|
|
436
|
-
response_json = await self._auth_lib.post(
|
|
437
|
-
|
|
438
|
-
|
|
558
|
+
response_json = await self._auth_lib.post(
|
|
559
|
+
"https://devicemgmt-service-beta.wyze.com/device-management/api/device-property/get_iot_prop",
|
|
560
|
+
json=payload,
|
|
561
|
+
headers=headers,
|
|
562
|
+
)
|
|
563
|
+
|
|
439
564
|
check_for_errors_iot(self, response_json)
|
|
440
565
|
|
|
441
566
|
return response_json
|
|
442
567
|
|
|
443
|
-
async def _set_property(self, device: Device, pid: str, pvalue: str)
|
|
444
|
-
"""
|
|
445
|
-
Wraps the api.wyzecam.com/app/v2/device/set_property endpoint
|
|
568
|
+
async def _set_property(self, device: Device, pid: str, pvalue: str):
|
|
569
|
+
"""Wraps the api.wyzecam.com/app/v2/device/set_property endpoint
|
|
446
570
|
|
|
447
571
|
:param device: The device for which to set the property
|
|
448
572
|
:param pid: The property id
|
|
@@ -463,22 +587,21 @@ class BaseService:
|
|
|
463
587
|
"pvalue": pvalue,
|
|
464
588
|
"pid": pid,
|
|
465
589
|
"device_model": device.product_model,
|
|
466
|
-
"device_mac": device.mac
|
|
590
|
+
"device_mac": device.mac,
|
|
467
591
|
}
|
|
468
592
|
|
|
469
|
-
response_json = await self._auth_lib.post(
|
|
470
|
-
|
|
593
|
+
response_json = await self._auth_lib.post(
|
|
594
|
+
"https://api.wyzecam.com/app/v2/device/set_property", json=payload
|
|
595
|
+
)
|
|
471
596
|
|
|
472
597
|
check_for_errors_standard(self, response_json)
|
|
473
598
|
|
|
474
|
-
async def _monitoring_profile_active(self, hms_id: str, home: int, away: int)
|
|
475
|
-
"""
|
|
476
|
-
Wraps the hms.api.wyze.com/api/v1/monitoring/v1/profile/active endpoint
|
|
599
|
+
async def _monitoring_profile_active(self, hms_id: str, home: int, away: int):
|
|
600
|
+
"""Wraps the hms.api.wyze.com/api/v1/monitoring/v1/profile/active endpoint
|
|
477
601
|
|
|
478
602
|
:param hms_id: The hms id
|
|
479
603
|
:param home: 1 for home 0 for not
|
|
480
604
|
:param away: 1 for away 0 for not
|
|
481
|
-
:return:
|
|
482
605
|
"""
|
|
483
606
|
await self._auth_lib.refresh_if_should()
|
|
484
607
|
|
|
@@ -486,31 +609,23 @@ class BaseService:
|
|
|
486
609
|
query = olive_create_hms_patch_payload(hms_id)
|
|
487
610
|
signature = olive_create_signature(query, self._auth_lib.token.access_token)
|
|
488
611
|
headers = {
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
612
|
+
"Accept-Encoding": "gzip",
|
|
613
|
+
"User-Agent": "myapp",
|
|
614
|
+
"appid": OLIVE_APP_ID,
|
|
615
|
+
"appinfo": APP_INFO,
|
|
616
|
+
"phoneid": PHONE_ID,
|
|
617
|
+
"access_token": self._auth_lib.token.access_token,
|
|
618
|
+
"signature2": signature,
|
|
619
|
+
"Authorization": self._auth_lib.token.access_token,
|
|
497
620
|
}
|
|
498
|
-
payload = [
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
},
|
|
503
|
-
{
|
|
504
|
-
"state": "away",
|
|
505
|
-
"active": away
|
|
506
|
-
}
|
|
507
|
-
]
|
|
508
|
-
response_json = await self._auth_lib.patch(url, headers=headers, params=query, json=payload)
|
|
621
|
+
payload = [{"state": "home", "active": home}, {"state": "away", "active": away}]
|
|
622
|
+
response_json = await self._auth_lib.patch(
|
|
623
|
+
url, headers=headers, params=query, json=payload
|
|
624
|
+
)
|
|
509
625
|
check_for_errors_hms(self, response_json)
|
|
510
626
|
|
|
511
627
|
async def _get_plan_binding_list_by_user(self) -> Dict[Any, Any]:
|
|
512
|
-
"""
|
|
513
|
-
Wraps the wyze-membership-service.wyzecam.com/platform/v2/membership/get_plan_binding_list_by_user endpoint
|
|
628
|
+
"""Wraps the wyze-membership-service.wyzecam.com/platform/v2/membership/get_plan_binding_list_by_user endpoint
|
|
514
629
|
|
|
515
630
|
:return: The response to gathering the plan for the current user
|
|
516
631
|
"""
|
|
@@ -522,13 +637,13 @@ class BaseService:
|
|
|
522
637
|
payload = olive_create_hms_payload()
|
|
523
638
|
signature = olive_create_signature(payload, self._auth_lib.token.access_token)
|
|
524
639
|
headers = {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
640
|
+
"Accept-Encoding": "gzip",
|
|
641
|
+
"User-Agent": "myapp",
|
|
642
|
+
"appid": OLIVE_APP_ID,
|
|
643
|
+
"appinfo": APP_INFO,
|
|
644
|
+
"phoneid": PHONE_ID,
|
|
645
|
+
"access_token": self._auth_lib.token.access_token,
|
|
646
|
+
"signature2": signature,
|
|
532
647
|
}
|
|
533
648
|
|
|
534
649
|
response_json = await self._auth_lib.get(url, headers=headers, params=payload)
|
|
@@ -544,13 +659,8 @@ class BaseService:
|
|
|
544
659
|
await self._auth_lib.refresh_if_should()
|
|
545
660
|
|
|
546
661
|
url = "https://hms.api.wyze.com/api/v1/reme-alarm"
|
|
547
|
-
payload = {
|
|
548
|
-
|
|
549
|
-
"remediation_id": "emergency"
|
|
550
|
-
}
|
|
551
|
-
headers = {
|
|
552
|
-
"Authorization": self._auth_lib.token.access_token
|
|
553
|
-
}
|
|
662
|
+
payload = {"hms_id": hms_id, "remediation_id": "emergency"}
|
|
663
|
+
headers = {"Authorization": self._auth_lib.token.access_token}
|
|
554
664
|
|
|
555
665
|
response_json = await self._auth_lib.delete(url, headers=headers, json=payload)
|
|
556
666
|
|
|
@@ -570,14 +680,14 @@ class BaseService:
|
|
|
570
680
|
query = olive_create_hms_get_payload(hms_id)
|
|
571
681
|
signature = olive_create_signature(query, self._auth_lib.token.access_token)
|
|
572
682
|
headers = {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
683
|
+
"User-Agent": "myapp",
|
|
684
|
+
"appid": OLIVE_APP_ID,
|
|
685
|
+
"appinfo": APP_INFO,
|
|
686
|
+
"phoneid": PHONE_ID,
|
|
687
|
+
"access_token": self._auth_lib.token.access_token,
|
|
688
|
+
"signature2": signature,
|
|
689
|
+
"Authorization": self._auth_lib.token.access_token,
|
|
690
|
+
"Content-Type": "application/json",
|
|
581
691
|
}
|
|
582
692
|
|
|
583
693
|
response_json = await self._auth_lib.get(url, headers=headers, params=query)
|
|
@@ -594,9 +704,11 @@ class BaseService:
|
|
|
594
704
|
|
|
595
705
|
payload = {
|
|
596
706
|
"uuid": device_uuid,
|
|
597
|
-
"action": action # "remoteLock" or "remoteUnlock"
|
|
707
|
+
"action": action, # "remoteLock" or "remoteUnlock"
|
|
598
708
|
}
|
|
599
|
-
payload = ford_create_payload(
|
|
709
|
+
payload = ford_create_payload(
|
|
710
|
+
self._auth_lib.token.access_token, payload, url_path, "post"
|
|
711
|
+
)
|
|
600
712
|
|
|
601
713
|
url = "https://yd-saas-toc.wyzecam.com/openapi/lock/v1/control"
|
|
602
714
|
|
|
@@ -611,12 +723,11 @@ class BaseService:
|
|
|
611
723
|
|
|
612
724
|
device_uuid = device.mac.split(".")[-1]
|
|
613
725
|
|
|
614
|
-
payload = {
|
|
615
|
-
"uuid": device_uuid,
|
|
616
|
-
"with_keypad": "1"
|
|
617
|
-
}
|
|
726
|
+
payload = {"uuid": device_uuid, "with_keypad": "1"}
|
|
618
727
|
|
|
619
|
-
payload = ford_create_payload(
|
|
728
|
+
payload = ford_create_payload(
|
|
729
|
+
self._auth_lib.token.access_token, payload, url_path, "get"
|
|
730
|
+
)
|
|
620
731
|
|
|
621
732
|
url = "https://yd-saas-toc.wyzecam.com/openapi/lock/v1/info"
|
|
622
733
|
|
|
@@ -631,11 +742,11 @@ class BaseService:
|
|
|
631
742
|
|
|
632
743
|
url_path = "/openapi/lock/v1/ble/token"
|
|
633
744
|
|
|
634
|
-
payload = {
|
|
635
|
-
"uuid": device.mac
|
|
636
|
-
}
|
|
745
|
+
payload = {"uuid": device.mac}
|
|
637
746
|
|
|
638
|
-
payload = ford_create_payload(
|
|
747
|
+
payload = ford_create_payload(
|
|
748
|
+
self._auth_lib.token.access_token, payload, url_path, "get"
|
|
749
|
+
)
|
|
639
750
|
|
|
640
751
|
url = f"https://yd-saas-toc.wyzecam.com{url_path}"
|
|
641
752
|
|
|
@@ -659,29 +770,32 @@ class BaseService:
|
|
|
659
770
|
"sv": "c86fa16fc99d4d6580f82ef3b942e586",
|
|
660
771
|
"access_token": self._auth_lib.token.access_token,
|
|
661
772
|
"phone_id": PHONE_ID,
|
|
662
|
-
"app_name": APP_NAME
|
|
773
|
+
"app_name": APP_NAME,
|
|
663
774
|
}
|
|
664
775
|
|
|
665
|
-
response_json = await self._auth_lib.post(
|
|
666
|
-
|
|
776
|
+
response_json = await self._auth_lib.post(
|
|
777
|
+
"https://api.wyzecam.com/app/v2/device/get_device_Info", json=payload
|
|
778
|
+
)
|
|
667
779
|
|
|
668
780
|
check_for_errors_standard(self, response_json)
|
|
669
781
|
|
|
670
782
|
return response_json
|
|
671
783
|
|
|
672
|
-
async def _get_iot_prop(
|
|
784
|
+
async def _get_iot_prop(
|
|
785
|
+
self, url: str, device: Device, keys: str
|
|
786
|
+
) -> Dict[Any, Any]:
|
|
673
787
|
await self._auth_lib.refresh_if_should()
|
|
674
788
|
|
|
675
789
|
payload = olive_create_get_payload(device.mac, keys)
|
|
676
790
|
signature = olive_create_signature(payload, self._auth_lib.token.access_token)
|
|
677
791
|
headers = {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
792
|
+
"Accept-Encoding": "gzip",
|
|
793
|
+
"User-Agent": "myapp",
|
|
794
|
+
"appid": OLIVE_APP_ID,
|
|
795
|
+
"appinfo": APP_INFO,
|
|
796
|
+
"phoneid": PHONE_ID,
|
|
797
|
+
"access_token": self._auth_lib.token.access_token,
|
|
798
|
+
"signature2": signature,
|
|
685
799
|
}
|
|
686
800
|
|
|
687
801
|
response_json = await self._auth_lib.get(url, headers=headers, params=payload)
|
|
@@ -690,26 +804,34 @@ class BaseService:
|
|
|
690
804
|
|
|
691
805
|
return response_json
|
|
692
806
|
|
|
693
|
-
async def _set_iot_prop(
|
|
807
|
+
async def _set_iot_prop(
|
|
808
|
+
self, url: str, device: Device, prop_key: str, value: Any
|
|
809
|
+
) -> None:
|
|
694
810
|
await self._auth_lib.refresh_if_should()
|
|
695
811
|
|
|
696
|
-
payload = olive_create_post_payload(
|
|
697
|
-
|
|
698
|
-
|
|
812
|
+
payload = olive_create_post_payload(
|
|
813
|
+
device.mac, device.product_model, prop_key, value
|
|
814
|
+
)
|
|
815
|
+
signature = olive_create_signature(
|
|
816
|
+
json.dumps(payload, separators=(",", ":")),
|
|
817
|
+
self._auth_lib.token.access_token,
|
|
818
|
+
)
|
|
699
819
|
headers = {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
820
|
+
"Accept-Encoding": "gzip",
|
|
821
|
+
"Content-Type": "application/json",
|
|
822
|
+
"User-Agent": "myapp",
|
|
823
|
+
"appid": OLIVE_APP_ID,
|
|
824
|
+
"appinfo": APP_INFO,
|
|
825
|
+
"phoneid": PHONE_ID,
|
|
826
|
+
"access_token": self._auth_lib.token.access_token,
|
|
827
|
+
"signature2": signature,
|
|
708
828
|
}
|
|
709
829
|
|
|
710
|
-
payload_str = json.dumps(payload, separators=(
|
|
830
|
+
payload_str = json.dumps(payload, separators=(",", ":"))
|
|
711
831
|
|
|
712
|
-
response_json = await self._auth_lib.post(
|
|
832
|
+
response_json = await self._auth_lib.post(
|
|
833
|
+
url, headers=headers, data=payload_str
|
|
834
|
+
)
|
|
713
835
|
|
|
714
836
|
check_for_errors_iot(self, response_json)
|
|
715
837
|
|
|
@@ -720,20 +842,20 @@ class BaseService:
|
|
|
720
842
|
"mac": bulb.mac.upper(),
|
|
721
843
|
"index": "1",
|
|
722
844
|
"ts": str(int(time.time_ns() // 1000000)),
|
|
723
|
-
"plist": plist
|
|
845
|
+
"plist": plist,
|
|
724
846
|
}
|
|
725
847
|
|
|
726
|
-
characteristics_str = json.dumps(characteristics, separators=(
|
|
848
|
+
characteristics_str = json.dumps(characteristics, separators=(",", ":"))
|
|
727
849
|
characteristics_enc = wyze_encrypt(bulb.enr, characteristics_str)
|
|
728
850
|
|
|
729
851
|
payload = {
|
|
730
852
|
"request": "set_status",
|
|
731
853
|
"isSendQueue": 0,
|
|
732
|
-
"characteristics": characteristics_enc
|
|
854
|
+
"characteristics": characteristics_enc,
|
|
733
855
|
}
|
|
734
856
|
|
|
735
857
|
# JSON likes to add a second \ so we have to remove it for the bulb to be happy
|
|
736
|
-
payload_str = json.dumps(payload, separators=(
|
|
858
|
+
payload_str = json.dumps(payload, separators=(",", ":")).replace("\\\\", "\\")
|
|
737
859
|
|
|
738
860
|
url = "http://%s:88/device_request" % bulb.ip
|
|
739
861
|
|
|
@@ -742,7 +864,9 @@ class BaseService:
|
|
|
742
864
|
async with session.post(url, data=payload_str) as response:
|
|
743
865
|
print(await response.text())
|
|
744
866
|
except aiohttp.ClientConnectionError:
|
|
745
|
-
_LOGGER.warning(
|
|
867
|
+
_LOGGER.warning(
|
|
868
|
+
"Failed to connect to bulb %s, reverting to cloud." % bulb.mac
|
|
869
|
+
)
|
|
746
870
|
await self._run_action_list(bulb, plist)
|
|
747
871
|
bulb.cloud_fallback = True
|
|
748
872
|
|
|
@@ -775,3 +899,73 @@ class BaseService:
|
|
|
775
899
|
check_for_errors_standard(self, response_json)
|
|
776
900
|
|
|
777
901
|
return response_json["data"]["usage_record_list"]
|
|
902
|
+
|
|
903
|
+
async def _get_zone_by_device(self, url: str, device: Device) -> Dict[Any, Any]:
|
|
904
|
+
await self._auth_lib.refresh_if_should()
|
|
905
|
+
|
|
906
|
+
payload = olive_create_get_payload_irrigation(device.mac)
|
|
907
|
+
signature = olive_create_signature(payload, self._auth_lib.token.access_token)
|
|
908
|
+
headers = {
|
|
909
|
+
'Accept-Encoding': 'gzip',
|
|
910
|
+
'User-Agent': 'myapp',
|
|
911
|
+
'appid': OLIVE_APP_ID,
|
|
912
|
+
'appinfo': APP_INFO,
|
|
913
|
+
'phoneid': PHONE_ID,
|
|
914
|
+
'access_token': self._auth_lib.token.access_token,
|
|
915
|
+
'signature2': signature
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
response_json = await self._auth_lib.get(url, headers=headers, params=payload)
|
|
919
|
+
|
|
920
|
+
check_for_errors_iot(self, response_json)
|
|
921
|
+
|
|
922
|
+
return response_json
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
async def _stop_running_schedule(self, url: str, device: Device, action: str) -> Dict[Any, Any]:
|
|
926
|
+
await self._auth_lib.refresh_if_should()
|
|
927
|
+
|
|
928
|
+
payload = olive_create_post_payload_irrigation_stop(device.mac, action)
|
|
929
|
+
signature = olive_create_signature(json.dumps(payload, separators=(',', ':')),
|
|
930
|
+
self._auth_lib.token.access_token)
|
|
931
|
+
headers = {
|
|
932
|
+
'Accept-Encoding': 'gzip',
|
|
933
|
+
'Content-Type': 'application/json',
|
|
934
|
+
'User-Agent': 'myapp',
|
|
935
|
+
'appid': OLIVE_APP_ID,
|
|
936
|
+
'appinfo': APP_INFO,
|
|
937
|
+
'phoneid': PHONE_ID,
|
|
938
|
+
'access_token': self._auth_lib.token.access_token,
|
|
939
|
+
'signature2': signature
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
payload_str = json.dumps(payload, separators=(',', ':'))
|
|
943
|
+
response_json = await self._auth_lib.post(url, headers=headers, data=payload_str)
|
|
944
|
+
|
|
945
|
+
check_for_errors_iot(self, response_json)
|
|
946
|
+
|
|
947
|
+
return response_json
|
|
948
|
+
|
|
949
|
+
async def _start_zone(self, url: str, device: Device, zone_number: int, duration: int) -> Dict[Any, Any]:
|
|
950
|
+
await self._auth_lib.refresh_if_should()
|
|
951
|
+
|
|
952
|
+
payload = olive_create_post_payload_irrigation_quickrun(device.mac, zone_number, duration)
|
|
953
|
+
signature = olive_create_signature(json.dumps(payload, separators=(',', ':')),
|
|
954
|
+
self._auth_lib.token.access_token)
|
|
955
|
+
headers = {
|
|
956
|
+
'Accept-Encoding': 'gzip',
|
|
957
|
+
'Content-Type': 'application/json',
|
|
958
|
+
'User-Agent': 'myapp',
|
|
959
|
+
'appid': OLIVE_APP_ID,
|
|
960
|
+
'appinfo': APP_INFO,
|
|
961
|
+
'phoneid': PHONE_ID,
|
|
962
|
+
'access_token': self._auth_lib.token.access_token,
|
|
963
|
+
'signature2': signature
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
payload_str = json.dumps(payload, separators=(',', ':'))
|
|
967
|
+
response_json = await self._auth_lib.post(url, headers=headers, data=payload_str)
|
|
968
|
+
|
|
969
|
+
check_for_errors_iot(self, response_json)
|
|
970
|
+
|
|
971
|
+
return response_json
|