wyzeapy 0.5.23__py3-none-any.whl → 0.5.24__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/const.py +3 -0
- wyzeapy/exceptions.py +1 -2
- wyzeapy/payload_factory.py +496 -0
- wyzeapy/services/base_service.py +119 -4
- wyzeapy/services/camera_service.py +63 -27
- wyzeapy/services/wall_switch_service.py +0 -1
- wyzeapy/types.py +9 -5
- wyzeapy/utils.py +18 -8
- wyzeapy/wyze_auth_lib.py +17 -0
- {wyzeapy-0.5.23.dist-info → wyzeapy-0.5.24.dist-info}/METADATA +4 -4
- wyzeapy-0.5.24.dist-info/RECORD +23 -0
- wyzeapy-0.5.23.dist-info/RECORD +0 -23
- {wyzeapy-0.5.23.dist-info → wyzeapy-0.5.24.dist-info}/LICENSES/GPL-3.0-only.txt +0 -0
- {wyzeapy-0.5.23.dist-info → wyzeapy-0.5.24.dist-info}/WHEEL +0 -0
wyzeapy/const.py
CHANGED
|
@@ -15,6 +15,9 @@ PHONE_ID = str(uuid.uuid4())
|
|
|
15
15
|
APP_INFO = 'wyze_android_2.19.14' # Required for the thermostat
|
|
16
16
|
SC = "9f275790cab94a72bd206c8876429f3c"
|
|
17
17
|
SV = "9d74946e652647e9b6c9d59326aef104"
|
|
18
|
+
CLIENT_VER = "2"
|
|
19
|
+
SOURCE = "ios/WZCameraSDK"
|
|
20
|
+
APP_PLATFORM = "ios"
|
|
18
21
|
|
|
19
22
|
# Crypto secrets
|
|
20
23
|
OLIVE_SIGNING_SECRET = 'wyze_app_secret_key_132' # Required for the thermostat
|
wyzeapy/exceptions.py
CHANGED
wyzeapy/payload_factory.py
CHANGED
|
@@ -72,3 +72,499 @@ def olive_create_hms_patch_payload(hms_id: str) -> Dict[str, Any]:
|
|
|
72
72
|
return {
|
|
73
73
|
"hms_id": hms_id
|
|
74
74
|
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def devicemgmt_create_capabilities_payload(type: str, value: str):
|
|
78
|
+
match type:
|
|
79
|
+
case "floodlight":
|
|
80
|
+
return {
|
|
81
|
+
"iid": 4,
|
|
82
|
+
"name": "floodlight",
|
|
83
|
+
"properties": [
|
|
84
|
+
{
|
|
85
|
+
"prop": "on",
|
|
86
|
+
"value": value
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
case "spotlight":
|
|
91
|
+
return {
|
|
92
|
+
"iid": 5,
|
|
93
|
+
"name": "spotlight",
|
|
94
|
+
"properties": [
|
|
95
|
+
{
|
|
96
|
+
"prop": "on",
|
|
97
|
+
"value": value
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
case "power":
|
|
102
|
+
return {
|
|
103
|
+
"functions": [
|
|
104
|
+
{
|
|
105
|
+
"in": {
|
|
106
|
+
"wakeup-live-view": "1"
|
|
107
|
+
},
|
|
108
|
+
"name": value
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
"iid": 1,
|
|
112
|
+
"name": "iot-device"
|
|
113
|
+
}
|
|
114
|
+
case "siren":
|
|
115
|
+
return {
|
|
116
|
+
"functions": [
|
|
117
|
+
{
|
|
118
|
+
"in": {},
|
|
119
|
+
"name": value
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"name": "siren"
|
|
123
|
+
}
|
|
124
|
+
case _:
|
|
125
|
+
raise NotImplementedError(f"No action of type ({type}) has been implemented.")
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def devicemgmt_get_iot_props_list(model: str):
|
|
129
|
+
match model:
|
|
130
|
+
case "LD_CFP": # Floodlight Pro
|
|
131
|
+
return [
|
|
132
|
+
{
|
|
133
|
+
"iid": 2,
|
|
134
|
+
"name": "camera",
|
|
135
|
+
"properties": [
|
|
136
|
+
"motion-detect",
|
|
137
|
+
"resolution",
|
|
138
|
+
"bit-rate",
|
|
139
|
+
"live-stream-mode",
|
|
140
|
+
"recording-mode",
|
|
141
|
+
"frame-rate",
|
|
142
|
+
"night-shot",
|
|
143
|
+
"night-shot-state",
|
|
144
|
+
"rotate-angle",
|
|
145
|
+
"time-watermark",
|
|
146
|
+
"logo-watermark",
|
|
147
|
+
"recording-trigger-source",
|
|
148
|
+
"recording-content-type",
|
|
149
|
+
"motion-push",
|
|
150
|
+
"speaker",
|
|
151
|
+
"microphone",
|
|
152
|
+
"unusual-sound-push",
|
|
153
|
+
"flip",
|
|
154
|
+
"motion-detect-recording",
|
|
155
|
+
"cool-down-interval",
|
|
156
|
+
"infrared-mode",
|
|
157
|
+
"sound-collection-on",
|
|
158
|
+
"live-stream-protocol",
|
|
159
|
+
"ai-push",
|
|
160
|
+
"voice-template",
|
|
161
|
+
"motion-category"
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"iid": 3,
|
|
166
|
+
"name": "device-info",
|
|
167
|
+
"properties": [
|
|
168
|
+
"device-id",
|
|
169
|
+
"device-model",
|
|
170
|
+
"firmware-ver",
|
|
171
|
+
"mac",
|
|
172
|
+
"timezone",
|
|
173
|
+
"lat",
|
|
174
|
+
"ip",
|
|
175
|
+
"lon",
|
|
176
|
+
"hardware-ver",
|
|
177
|
+
"public-ip"
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"iid": 1,
|
|
182
|
+
"name": "iot-device",
|
|
183
|
+
"properties": [
|
|
184
|
+
"iot-state",
|
|
185
|
+
"iot-power",
|
|
186
|
+
"push-switch"
|
|
187
|
+
]
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"iid": 9,
|
|
191
|
+
"name": "camera-ai",
|
|
192
|
+
"properties": [
|
|
193
|
+
"smart-detection-type",
|
|
194
|
+
"on"
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"iid": 4,
|
|
199
|
+
"name": "floodlight",
|
|
200
|
+
"properties": [
|
|
201
|
+
"on",
|
|
202
|
+
"enabled",
|
|
203
|
+
"mode",
|
|
204
|
+
"trigger-source",
|
|
205
|
+
"brightness",
|
|
206
|
+
"light-on-duration",
|
|
207
|
+
"voice-template",
|
|
208
|
+
"motion-warning-switch",
|
|
209
|
+
"motion-activate-light-switch",
|
|
210
|
+
"motion-activate-light-schedule",
|
|
211
|
+
"motion-activate-brightness",
|
|
212
|
+
"ambient-light-switch",
|
|
213
|
+
"ambient-light-schedule",
|
|
214
|
+
"ambient-light-brightness",
|
|
215
|
+
"motion-tag",
|
|
216
|
+
"light-model",
|
|
217
|
+
"flash-with-siren"
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"iid": 11,
|
|
222
|
+
"name": "indicator-light",
|
|
223
|
+
"properties": [
|
|
224
|
+
"on",
|
|
225
|
+
"mode",
|
|
226
|
+
"brightness",
|
|
227
|
+
"color",
|
|
228
|
+
"color-temperature"
|
|
229
|
+
]
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"iid": 8,
|
|
233
|
+
"name": "memory-card-management",
|
|
234
|
+
"properties": [
|
|
235
|
+
"storage-used-space",
|
|
236
|
+
"storage-total-space",
|
|
237
|
+
"storage-status",
|
|
238
|
+
"sd-card-playback-enabled"
|
|
239
|
+
]
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"iid": 6,
|
|
243
|
+
"name": "motion-detection",
|
|
244
|
+
"properties": [
|
|
245
|
+
"sensitivity-motion",
|
|
246
|
+
"on",
|
|
247
|
+
"motion-zone",
|
|
248
|
+
"motion-zone-selected-block",
|
|
249
|
+
"motion-zone-block-size",
|
|
250
|
+
"motion-tag",
|
|
251
|
+
"edge-detection-type",
|
|
252
|
+
"motion-warning-switch",
|
|
253
|
+
"motion-warning-tone",
|
|
254
|
+
"motion-warning-interval",
|
|
255
|
+
"motion-warning-schedule",
|
|
256
|
+
"motion-warning-sound",
|
|
257
|
+
"motion-warning-trigger-setting"
|
|
258
|
+
]
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"iid": 7,
|
|
262
|
+
"name": "siren",
|
|
263
|
+
"properties": [
|
|
264
|
+
"state"
|
|
265
|
+
]
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"iid": 5,
|
|
269
|
+
"name": "wifi",
|
|
270
|
+
"properties": [
|
|
271
|
+
"on",
|
|
272
|
+
"signal-strength",
|
|
273
|
+
"wifi-ssid",
|
|
274
|
+
"wifi-encrypted-password"
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
case "AN_RSCW": # Battery Cam pro
|
|
279
|
+
return [
|
|
280
|
+
{
|
|
281
|
+
"iid": 2,
|
|
282
|
+
"name": "camera",
|
|
283
|
+
"properties": [
|
|
284
|
+
"motion-detect",
|
|
285
|
+
"resolution",
|
|
286
|
+
"bit-rate",
|
|
287
|
+
"live-stream-mode",
|
|
288
|
+
"recording-mode",
|
|
289
|
+
"frame-rate",
|
|
290
|
+
"night-shot",
|
|
291
|
+
"night-shot-state",
|
|
292
|
+
"time-watermark",
|
|
293
|
+
"logo-watermark",
|
|
294
|
+
"cool-down-interval",
|
|
295
|
+
"recording-content-type",
|
|
296
|
+
"video-length-limit",
|
|
297
|
+
"motion-push",
|
|
298
|
+
"speaker",
|
|
299
|
+
"unusual-sound-push",
|
|
300
|
+
"microphone",
|
|
301
|
+
"infrared-mode",
|
|
302
|
+
"motion-detect-recording",
|
|
303
|
+
"live-stream-protocol",
|
|
304
|
+
"recording-resolution",
|
|
305
|
+
"recording-start-time",
|
|
306
|
+
"recording-schedule-duration",
|
|
307
|
+
"voice-template",
|
|
308
|
+
"rotate-angle",
|
|
309
|
+
"sound-collection-on",
|
|
310
|
+
"ai-push"
|
|
311
|
+
]
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
"iid": 3,
|
|
315
|
+
"name": "device-info",
|
|
316
|
+
"properties": [
|
|
317
|
+
"device-id",
|
|
318
|
+
"device-model",
|
|
319
|
+
"firmware-ver",
|
|
320
|
+
"mac",
|
|
321
|
+
"timezone",
|
|
322
|
+
"lat",
|
|
323
|
+
"ip",
|
|
324
|
+
"lon",
|
|
325
|
+
"company-code",
|
|
326
|
+
"device-setting-channel",
|
|
327
|
+
"network-connection-mode",
|
|
328
|
+
"hardware-ver",
|
|
329
|
+
"public-ip"
|
|
330
|
+
]
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"iid": 1,
|
|
334
|
+
"name": "iot-device",
|
|
335
|
+
"properties": [
|
|
336
|
+
"iot-state",
|
|
337
|
+
"iot-power",
|
|
338
|
+
"push-switch",
|
|
339
|
+
"mqtt-check"
|
|
340
|
+
]
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
"iid": 7,
|
|
344
|
+
"name": "battery",
|
|
345
|
+
"properties": [
|
|
346
|
+
"battery-level",
|
|
347
|
+
"low-battery-push",
|
|
348
|
+
"power-source",
|
|
349
|
+
"charging-status",
|
|
350
|
+
"power-saving"
|
|
351
|
+
]
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
"iid": 12,
|
|
355
|
+
"name": "camera-ai",
|
|
356
|
+
"properties": [
|
|
357
|
+
"smart-detection-type",
|
|
358
|
+
"on"
|
|
359
|
+
]
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"iid": 8,
|
|
363
|
+
"name": "indicator-light",
|
|
364
|
+
"properties": [
|
|
365
|
+
"on",
|
|
366
|
+
"mode"
|
|
367
|
+
]
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
"iid": 6,
|
|
371
|
+
"name": "memory-card-management",
|
|
372
|
+
"properties": [
|
|
373
|
+
"storage-used-space",
|
|
374
|
+
"storage-total-space",
|
|
375
|
+
"storage-status",
|
|
376
|
+
"sd-card-playback-enabled"
|
|
377
|
+
]
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"iid": 11,
|
|
381
|
+
"name": "motion-detection",
|
|
382
|
+
"properties": [
|
|
383
|
+
"sensitivity-motion",
|
|
384
|
+
"on",
|
|
385
|
+
"area-length",
|
|
386
|
+
"motion-zone",
|
|
387
|
+
"motion-zone-block-size",
|
|
388
|
+
"motion-zone-selected-block",
|
|
389
|
+
"edge-detection-type",
|
|
390
|
+
"motion-tag"
|
|
391
|
+
]
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
"iid": 4,
|
|
395
|
+
"name": "siren",
|
|
396
|
+
"properties": [
|
|
397
|
+
"state",
|
|
398
|
+
"siren-on-ts"
|
|
399
|
+
]
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
"iid": 14,
|
|
403
|
+
"name": "solar-panel",
|
|
404
|
+
"properties": [
|
|
405
|
+
"enabled",
|
|
406
|
+
"on"
|
|
407
|
+
]
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
"iid": 5,
|
|
411
|
+
"name": "spotlight",
|
|
412
|
+
"properties": [
|
|
413
|
+
"on",
|
|
414
|
+
"enabled",
|
|
415
|
+
"brightness",
|
|
416
|
+
"motion-activate-light-switch",
|
|
417
|
+
"sunset-to-sunrise",
|
|
418
|
+
"motion-activate-light-schedule",
|
|
419
|
+
"trigger-source"
|
|
420
|
+
]
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"iid": 9,
|
|
424
|
+
"name": "wifi",
|
|
425
|
+
"properties": [
|
|
426
|
+
"on",
|
|
427
|
+
"signal-strength",
|
|
428
|
+
"wifi-ssid",
|
|
429
|
+
"wifi-encrypted-password"
|
|
430
|
+
]
|
|
431
|
+
}
|
|
432
|
+
]
|
|
433
|
+
case "GW_GC1": # OG
|
|
434
|
+
return [
|
|
435
|
+
{
|
|
436
|
+
"iid": 2,
|
|
437
|
+
"name": "camera",
|
|
438
|
+
"properties": [
|
|
439
|
+
"motion-detect",
|
|
440
|
+
"resolution",
|
|
441
|
+
"bit-rate",
|
|
442
|
+
"live-stream-mode",
|
|
443
|
+
"recording-mode",
|
|
444
|
+
"frame-rate",
|
|
445
|
+
"night-shot",
|
|
446
|
+
"night-shot-state",
|
|
447
|
+
"time-watermark",
|
|
448
|
+
"logo-watermark",
|
|
449
|
+
"cool-down-interval",
|
|
450
|
+
"recording-content-type",
|
|
451
|
+
"video-length-limit",
|
|
452
|
+
"motion-push",
|
|
453
|
+
"speaker",
|
|
454
|
+
"unusual-sound-push",
|
|
455
|
+
"microphone",
|
|
456
|
+
"infrared-mode",
|
|
457
|
+
"motion-detect-recording",
|
|
458
|
+
"live-stream-protocol",
|
|
459
|
+
"recording-resolution",
|
|
460
|
+
"recording-start-time",
|
|
461
|
+
"recording-schedule-duration",
|
|
462
|
+
"voice-template",
|
|
463
|
+
"rotate-angle",
|
|
464
|
+
"sound-collection-on",
|
|
465
|
+
"ai-push"
|
|
466
|
+
]
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
"iid": 3,
|
|
470
|
+
"name": "device-info",
|
|
471
|
+
"properties": [
|
|
472
|
+
"device-id",
|
|
473
|
+
"device-model",
|
|
474
|
+
"firmware-ver",
|
|
475
|
+
"mac",
|
|
476
|
+
"timezone",
|
|
477
|
+
"lat",
|
|
478
|
+
"ip",
|
|
479
|
+
"lon",
|
|
480
|
+
"company-code",
|
|
481
|
+
"device-setting-channel",
|
|
482
|
+
"network-connection-mode",
|
|
483
|
+
"hardware-ver",
|
|
484
|
+
"public-ip"
|
|
485
|
+
]
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
"iid": 1,
|
|
489
|
+
"name": "iot-device",
|
|
490
|
+
"properties": [
|
|
491
|
+
"iot-state",
|
|
492
|
+
"iot-power",
|
|
493
|
+
"push-switch",
|
|
494
|
+
"mqtt-check"
|
|
495
|
+
]
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
"iid": 12,
|
|
499
|
+
"name": "camera-ai",
|
|
500
|
+
"properties": [
|
|
501
|
+
"smart-detection-type",
|
|
502
|
+
"on"
|
|
503
|
+
]
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
"iid": 8,
|
|
507
|
+
"name": "indicator-light",
|
|
508
|
+
"properties": [
|
|
509
|
+
"on",
|
|
510
|
+
"mode"
|
|
511
|
+
]
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
"iid": 6,
|
|
515
|
+
"name": "memory-card-management",
|
|
516
|
+
"properties": [
|
|
517
|
+
"storage-used-space",
|
|
518
|
+
"storage-total-space",
|
|
519
|
+
"storage-status",
|
|
520
|
+
"sd-card-playback-enabled"
|
|
521
|
+
]
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
"iid": 11,
|
|
525
|
+
"name": "motion-detection",
|
|
526
|
+
"properties": [
|
|
527
|
+
"sensitivity-motion",
|
|
528
|
+
"on",
|
|
529
|
+
"area-length",
|
|
530
|
+
"motion-zone",
|
|
531
|
+
"motion-zone-block-size",
|
|
532
|
+
"motion-zone-selected-block",
|
|
533
|
+
"edge-detection-type",
|
|
534
|
+
"motion-tag"
|
|
535
|
+
]
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
"iid": 4,
|
|
539
|
+
"name": "siren",
|
|
540
|
+
"properties": [
|
|
541
|
+
"state",
|
|
542
|
+
"siren-on-ts"
|
|
543
|
+
]
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
"iid": 5,
|
|
547
|
+
"name": "spotlight",
|
|
548
|
+
"properties": [
|
|
549
|
+
"on",
|
|
550
|
+
"enabled",
|
|
551
|
+
"brightness",
|
|
552
|
+
"motion-activate-light-switch",
|
|
553
|
+
"sunset-to-sunrise",
|
|
554
|
+
"motion-activate-light-schedule",
|
|
555
|
+
"trigger-source"
|
|
556
|
+
]
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
"iid": 9,
|
|
560
|
+
"name": "wifi",
|
|
561
|
+
"properties": [
|
|
562
|
+
"on",
|
|
563
|
+
"signal-strength",
|
|
564
|
+
"wifi-ssid",
|
|
565
|
+
"wifi-encrypted-password"
|
|
566
|
+
]
|
|
567
|
+
}
|
|
568
|
+
]
|
|
569
|
+
case _:
|
|
570
|
+
raise NotImplementedError(f"No iot props for model ({model}) have been defined.")
|
wyzeapy/services/base_service.py
CHANGED
|
@@ -12,14 +12,14 @@ 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 PHONE_SYSTEM_TYPE, APP_VERSION, APP_VER, PHONE_ID, APP_NAME, OLIVE_APP_ID, APP_INFO, SC, SV
|
|
15
|
+
from ..const import PHONE_SYSTEM_TYPE, APP_VERSION, APP_VER, PHONE_ID, APP_NAME, OLIVE_APP_ID, APP_INFO, SC, SV, APP_PLATFORM, SOURCE
|
|
16
16
|
from ..crypto import olive_create_signature
|
|
17
17
|
from ..payload_factory import olive_create_hms_patch_payload, olive_create_hms_payload, \
|
|
18
18
|
olive_create_hms_get_payload, ford_create_payload, olive_create_get_payload, olive_create_post_payload, \
|
|
19
|
-
olive_create_user_info_payload
|
|
20
|
-
from ..types import PropertyIDs, Device
|
|
19
|
+
olive_create_user_info_payload, devicemgmt_create_capabilities_payload, devicemgmt_get_iot_props_list
|
|
20
|
+
from ..types import PropertyIDs, Device, DeviceMgmtToggleType
|
|
21
21
|
from ..utils import check_for_errors_standard, check_for_errors_hms, check_for_errors_lock, \
|
|
22
|
-
check_for_errors_iot, wyze_encrypt
|
|
22
|
+
check_for_errors_iot, wyze_encrypt, check_for_errors_devicemgmt
|
|
23
23
|
from ..wyze_auth_lib import WyzeAuthLib
|
|
24
24
|
|
|
25
25
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -326,6 +326,121 @@ class BaseService:
|
|
|
326
326
|
json=payload)
|
|
327
327
|
|
|
328
328
|
check_for_errors_standard(self, response_json)
|
|
329
|
+
|
|
330
|
+
async def _run_action_devicemgmt(self, device: Device, type: str, value: str) -> None:
|
|
331
|
+
"""
|
|
332
|
+
Wraps the devicemgmt-service-beta.wyze.com/device-management/api/action/run_action endpoint
|
|
333
|
+
|
|
334
|
+
:param device: The device for which to run the action
|
|
335
|
+
:param state: on or off
|
|
336
|
+
:return:
|
|
337
|
+
"""
|
|
338
|
+
|
|
339
|
+
await self._auth_lib.refresh_if_should()
|
|
340
|
+
|
|
341
|
+
capabilities = devicemgmt_create_capabilities_payload(type, value)
|
|
342
|
+
|
|
343
|
+
payload = {
|
|
344
|
+
"capabilities": [
|
|
345
|
+
capabilities
|
|
346
|
+
],
|
|
347
|
+
"nonce": int(time.time() * 1000),
|
|
348
|
+
"targetInfo": {
|
|
349
|
+
"id": device.mac,
|
|
350
|
+
"productModel": device.product_model,
|
|
351
|
+
"type": "DEVICE"
|
|
352
|
+
},
|
|
353
|
+
"transactionId": "0a5b20591fedd4du1b93f90743ba0csd" # OG cam needs this (doesn't matter what the value is)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
headers = {
|
|
357
|
+
"authorization": self._auth_lib.token.access_token,
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
response_json = await self._auth_lib.post("https://devicemgmt-service-beta.wyze.com/device-management/api/action/run_action",
|
|
361
|
+
json=payload, headers=headers)
|
|
362
|
+
|
|
363
|
+
check_for_errors_iot(self, response_json)
|
|
364
|
+
|
|
365
|
+
async def _set_toggle(self, device: Device, toggleType: DeviceMgmtToggleType, state: str) -> None:
|
|
366
|
+
"""
|
|
367
|
+
Wraps the ai-subscription-service-beta.wyzecam.com/v4/subscription-service/toggle-management endpoint
|
|
368
|
+
|
|
369
|
+
:param device: The device for which to get the state
|
|
370
|
+
:param toggleType: Enum for the toggle type
|
|
371
|
+
:param state: String state to set for the toggle
|
|
372
|
+
"""
|
|
373
|
+
|
|
374
|
+
await self._auth_lib.refresh_if_should()
|
|
375
|
+
|
|
376
|
+
payload = {
|
|
377
|
+
"data": [
|
|
378
|
+
{
|
|
379
|
+
"device_firmware": "1234567890",
|
|
380
|
+
"device_id": device.mac,
|
|
381
|
+
"device_model": device.product_model,
|
|
382
|
+
"page_id": [
|
|
383
|
+
toggleType.pageId
|
|
384
|
+
],
|
|
385
|
+
"toggle_update": [
|
|
386
|
+
{
|
|
387
|
+
"toggle_id": toggleType.toggleId,
|
|
388
|
+
"toggle_status": state
|
|
389
|
+
}
|
|
390
|
+
]
|
|
391
|
+
}
|
|
392
|
+
],
|
|
393
|
+
"nonce": str(int(time.time() * 1000))
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
signature = olive_create_signature(payload, self._auth_lib.token.access_token)
|
|
398
|
+
headers = {
|
|
399
|
+
"access_token": self._auth_lib.token.access_token,
|
|
400
|
+
"timestamp": str(int(time.time() * 1000)),
|
|
401
|
+
"appid": OLIVE_APP_ID,
|
|
402
|
+
"source": SOURCE,
|
|
403
|
+
"signature2": signature,
|
|
404
|
+
"appplatform": APP_PLATFORM,
|
|
405
|
+
"appversion": APP_VERSION,
|
|
406
|
+
"requestid": "35374158s4s313b9a2be7c057f2da5d1"
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
response_json = await self._auth_lib.put("https://ai-subscription-service-beta.wyzecam.com/v4/subscription-service/toggle-management",
|
|
410
|
+
json=payload, headers=headers)
|
|
411
|
+
|
|
412
|
+
check_for_errors_devicemgmt(self, response_json)
|
|
413
|
+
|
|
414
|
+
async def _get_iot_prop_devicemgmt(self, device: Device) -> Dict[str, Any]:
|
|
415
|
+
"""
|
|
416
|
+
Wraps the devicemgmt-service-beta.wyze.com/device-management/api/device-property/get_iot_prop endpoint
|
|
417
|
+
|
|
418
|
+
:param device: The device for which to get the state
|
|
419
|
+
:return:
|
|
420
|
+
"""
|
|
421
|
+
|
|
422
|
+
await self._auth_lib.refresh_if_should()
|
|
423
|
+
|
|
424
|
+
payload = {
|
|
425
|
+
"capabilities": devicemgmt_get_iot_props_list(device.product_model),
|
|
426
|
+
"nonce": int(time.time() * 1000),
|
|
427
|
+
"targetInfo": {
|
|
428
|
+
"id": device.mac,
|
|
429
|
+
"productModel": device.product_model,
|
|
430
|
+
"type": "DEVICE"
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
headers = {
|
|
435
|
+
"authorization": self._auth_lib.token.access_token,
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
response_json = await self._auth_lib.post("https://devicemgmt-service-beta.wyze.com/device-management/api/device-property/get_iot_prop",
|
|
439
|
+
json=payload, headers=headers)
|
|
440
|
+
|
|
441
|
+
check_for_errors_iot(self, response_json)
|
|
442
|
+
|
|
443
|
+
return response_json
|
|
329
444
|
|
|
330
445
|
async def _set_property(self, device: Device, pid: str, pvalue: str) -> None:
|
|
331
446
|
"""
|
|
@@ -14,11 +14,14 @@ from aiohttp import ClientOSError, ContentTypeError
|
|
|
14
14
|
from ..exceptions import UnknownApiError
|
|
15
15
|
from .base_service import BaseService
|
|
16
16
|
from .update_manager import DeviceUpdater
|
|
17
|
-
from ..types import Device, DeviceTypes, Event, PropertyIDs
|
|
17
|
+
from ..types import Device, DeviceTypes, Event, PropertyIDs, DeviceMgmtToggleProps
|
|
18
18
|
from ..utils import return_event_for_device, create_pid_pair
|
|
19
19
|
|
|
20
20
|
_LOGGER = logging.getLogger(__name__)
|
|
21
21
|
|
|
22
|
+
# NOTE: Make sure to also define props in devicemgmt_create_capabilities_payload()
|
|
23
|
+
DEVICEMGMT_API_MODELS = ["LD_CFP", "AN_RSCW", "GW_GC1"] # Floodlight pro, battery cam pro, and OG use a diffrent api (devicemgmt)
|
|
24
|
+
|
|
22
25
|
|
|
23
26
|
class Camera(Device):
|
|
24
27
|
def __init__(self, dictionary: Dict[Any, Any]):
|
|
@@ -50,20 +53,35 @@ class CameraService(BaseService):
|
|
|
50
53
|
camera.last_event_ts = event.event_ts
|
|
51
54
|
|
|
52
55
|
# Update camera state
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
56
|
+
if (camera.product_model in DEVICEMGMT_API_MODELS): # New api
|
|
57
|
+
state_response: Dict[str, Any] = await self._get_iot_prop_devicemgmt(camera)
|
|
58
|
+
for propCategory in state_response['data']['capabilities']:
|
|
59
|
+
if propCategory['name'] == "camera":
|
|
60
|
+
camera.motion = propCategory['properties']['motion-detect-recording']
|
|
61
|
+
if propCategory['name'] == "floodlight" or propCategory['name'] == "spotlight":
|
|
62
|
+
camera.floodlight = propCategory['properties']['on']
|
|
63
|
+
if propCategory['name'] == "siren":
|
|
64
|
+
camera.siren = propCategory['properties']['state']
|
|
65
|
+
if propCategory['name'] == "iot-device":
|
|
66
|
+
camera.notify = propCategory['properties']['push-switch']
|
|
67
|
+
camera.on = propCategory['properties']['iot-power']
|
|
68
|
+
camera.available = propCategory['properties']['iot-state']
|
|
69
|
+
|
|
70
|
+
else: # All other cam types (old api?)
|
|
71
|
+
state_response: List[Tuple[PropertyIDs, Any]] = await self._get_property_list(camera)
|
|
72
|
+
for property, value in state_response:
|
|
73
|
+
if property is PropertyIDs.AVAILABLE:
|
|
74
|
+
camera.available = value == "1"
|
|
75
|
+
if property is PropertyIDs.ON:
|
|
76
|
+
camera.on = value == "1"
|
|
77
|
+
if property is PropertyIDs.CAMERA_SIREN:
|
|
78
|
+
camera.siren = value == "1"
|
|
79
|
+
if property is PropertyIDs.FLOOD_LIGHT:
|
|
80
|
+
camera.floodlight = value == "1"
|
|
81
|
+
if property is PropertyIDs.NOTIFICATION:
|
|
82
|
+
camera.notify = value == "1"
|
|
83
|
+
if property is PropertyIDs.MOTION_DETECTION:
|
|
84
|
+
camera.motion = value == "1"
|
|
67
85
|
|
|
68
86
|
return camera
|
|
69
87
|
|
|
@@ -102,35 +120,53 @@ class CameraService(BaseService):
|
|
|
102
120
|
return [Camera(camera.raw_dict) for camera in cameras]
|
|
103
121
|
|
|
104
122
|
async def turn_on(self, camera: Camera):
|
|
105
|
-
await self.
|
|
123
|
+
if (camera.product_model in DEVICEMGMT_API_MODELS): await self._run_action_devicemgmt(camera, "power", "wakeup") # Some camera models use a diffrent api
|
|
124
|
+
else: await self._run_action(camera, "power_on")
|
|
106
125
|
|
|
107
126
|
async def turn_off(self, camera: Camera):
|
|
108
|
-
await self.
|
|
127
|
+
if (camera.product_model in DEVICEMGMT_API_MODELS): await self._run_action_devicemgmt(camera, "power", "sleep") # Some camera models use a diffrent api
|
|
128
|
+
else: await self._run_action(camera, "power_off")
|
|
109
129
|
|
|
110
130
|
async def siren_on(self, camera: Camera):
|
|
111
|
-
await self.
|
|
131
|
+
if (camera.product_model in DEVICEMGMT_API_MODELS): await self._run_action_devicemgmt(camera, "siren", "siren-on") # Some camera models use a diffrent api
|
|
132
|
+
else: await self._run_action(camera, "siren_on")
|
|
112
133
|
|
|
113
134
|
async def siren_off(self, camera: Camera):
|
|
114
|
-
await self.
|
|
135
|
+
if (camera.product_model in DEVICEMGMT_API_MODELS): await self._run_action_devicemgmt(camera, "siren", "siren-off") # Some camera models use a diffrent api
|
|
136
|
+
else: await self._run_action(camera, "siren_off")
|
|
115
137
|
|
|
138
|
+
# Also controls lamp socket and BCP spotlight
|
|
116
139
|
async def floodlight_on(self, camera: Camera):
|
|
117
|
-
await self.
|
|
140
|
+
if (camera.product_model == "AN_RSCW"): await self._run_action_devicemgmt(camera, "spotlight", "1") # Battery cam pro integrated spotlight is controllable
|
|
141
|
+
elif (camera.product_model in DEVICEMGMT_API_MODELS): await self._run_action_devicemgmt(camera, "floodlight", "1") # Some camera models use a diffrent api
|
|
142
|
+
else: await self._set_property(camera, PropertyIDs.FLOOD_LIGHT.value, "1")
|
|
118
143
|
|
|
144
|
+
# Also controls lamp socket and BCP spotlight
|
|
119
145
|
async def floodlight_off(self, camera: Camera):
|
|
120
|
-
await self.
|
|
146
|
+
if (camera.product_model == "AN_RSCW"): await self._run_action_devicemgmt(camera, "spotlight", "0") # Battery cam pro integrated spotlight is controllable
|
|
147
|
+
elif (camera.product_model in DEVICEMGMT_API_MODELS): await self._run_action_devicemgmt(camera, "floodlight", "0") # Some camera models use a diffrent api
|
|
148
|
+
else: await self._set_property(camera, PropertyIDs.FLOOD_LIGHT.value, "2")
|
|
121
149
|
|
|
122
150
|
async def turn_on_notifications(self, camera: Camera):
|
|
123
|
-
await self.
|
|
151
|
+
if (camera.product_model in DEVICEMGMT_API_MODELS): await self._set_toggle(camera, DeviceMgmtToggleProps.NOTIFICATION_TOGGLE.value, "1")
|
|
152
|
+
else: await self._set_property(camera, PropertyIDs.NOTIFICATION.value, "1")
|
|
124
153
|
|
|
125
154
|
async def turn_off_notifications(self, camera: Camera):
|
|
126
|
-
await self.
|
|
155
|
+
if (camera.product_model in DEVICEMGMT_API_MODELS): await self._set_toggle(camera, DeviceMgmtToggleProps.NOTIFICATION_TOGGLE.value, "0")
|
|
156
|
+
else: await self._set_property(camera, PropertyIDs.NOTIFICATION.value, "0")
|
|
127
157
|
|
|
128
158
|
# Both properties need to be set on newer cams, older cameras seem to only react
|
|
129
159
|
# to the first property but it doesnt hurt to set both
|
|
130
160
|
async def turn_on_motion_detection(self, camera: Camera):
|
|
131
|
-
await self.
|
|
132
|
-
await self.
|
|
161
|
+
if (camera.product_model in DEVICEMGMT_API_MODELS): await self._set_toggle(camera, DeviceMgmtToggleProps.EVENT_RECORDING_TOGGLE.value, "1")
|
|
162
|
+
elif (camera.product_model in ["WVOD1", "HL_WCO2"]): await self._set_property_list(camera, [create_pid_pair(PropertyIDs.WCO_MOTION_DETECTION, "1")])
|
|
163
|
+
else:
|
|
164
|
+
await self._set_property(camera, PropertyIDs.MOTION_DETECTION.value, "1")
|
|
165
|
+
await self._set_property(camera, PropertyIDs.MOTION_DETECTION_TOGGLE.value, "1")
|
|
133
166
|
|
|
134
167
|
async def turn_off_motion_detection(self, camera: Camera):
|
|
135
|
-
await self.
|
|
136
|
-
await self.
|
|
168
|
+
if (camera.product_model in DEVICEMGMT_API_MODELS): await self._set_toggle(camera, DeviceMgmtToggleProps.EVENT_RECORDING_TOGGLE.value, "0")
|
|
169
|
+
elif (camera.product_model in ["WVOD1", "HL_WCO2"]): await self._set_property_list(camera, [create_pid_pair(PropertyIDs.WCO_MOTION_DETECTION, "0")])
|
|
170
|
+
else:
|
|
171
|
+
await self._set_property(camera, PropertyIDs.MOTION_DETECTION.value, "0")
|
|
172
|
+
await self._set_property(camera, PropertyIDs.MOTION_DETECTION_TOGGLE.value, "0")
|
|
@@ -74,7 +74,6 @@ class WallSwitchService(BaseService):
|
|
|
74
74
|
return [WallSwitch(switch.raw_dict) for switch in switches]
|
|
75
75
|
|
|
76
76
|
async def turn_on(self, switch: WallSwitch):
|
|
77
|
-
logging.warn("%s", switch.single_press_type)
|
|
78
77
|
if switch.single_press_type == SinglePressType.IOT:
|
|
79
78
|
await self.iot_on(switch)
|
|
80
79
|
else:
|
wyzeapy/types.py
CHANGED
|
@@ -102,10 +102,11 @@ class PropertyIDs(Enum):
|
|
|
102
102
|
CONTACT_STATE = "P1301"
|
|
103
103
|
MOTION_STATE = "P1302"
|
|
104
104
|
CAMERA_SIREN = "P1049"
|
|
105
|
-
FLOOD_LIGHT = "P1056"
|
|
105
|
+
FLOOD_LIGHT = "P1056" # Also lamp socket on v3/v4 with lamp socket accessory
|
|
106
106
|
SUN_MATCH = "P1528"
|
|
107
107
|
MOTION_DETECTION = "P1047" # Current Motion Detection State of the Camera
|
|
108
108
|
MOTION_DETECTION_TOGGLE = "P1001" # This toggles Camera Motion Detection On/Off
|
|
109
|
+
WCO_MOTION_DETECTION = "P1029" # Wyze cam outdoor requires both P1047 and P1029 to be set. P1029 is set via set_property_list
|
|
109
110
|
|
|
110
111
|
|
|
111
112
|
class WallSwitchProps(Enum):
|
|
@@ -207,10 +208,13 @@ class HMSStatus(Enum):
|
|
|
207
208
|
AWAY = 'away'
|
|
208
209
|
|
|
209
210
|
|
|
211
|
+
class DeviceMgmtToggleType:
|
|
212
|
+
def __init__(self, pageId, toggleId):
|
|
213
|
+
self.pageId = pageId
|
|
214
|
+
self.toggleId = toggleId
|
|
210
215
|
|
|
211
216
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
217
|
+
class DeviceMgmtToggleProps(Enum):
|
|
218
|
+
EVENT_RECORDING_TOGGLE = DeviceMgmtToggleType("cam_event_recording", "ge.motion_detect_recording")
|
|
219
|
+
NOTIFICATION_TOGGLE = DeviceMgmtToggleType("cam_device_notify", "ge.push_switch")
|
|
216
220
|
|
wyzeapy/utils.py
CHANGED
|
@@ -73,22 +73,23 @@ def create_password(password: str) -> str:
|
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
def check_for_errors_standard(service, response_json: Dict[str, Any]) -> None:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
response_code = response_json['code']
|
|
77
|
+
if response_code != ResponseCodes.SUCCESS.value:
|
|
78
|
+
if response_code == ResponseCodes.PARAMETER_ERROR.value:
|
|
79
|
+
raise ParameterError(response_code, response_json['msg'])
|
|
80
|
+
elif response_code == ResponseCodes.ACCESS_TOKEN_ERROR.value:
|
|
80
81
|
service._auth_lib.token.expired = True
|
|
81
|
-
raise AccessTokenError("Access Token expired, attempting to refresh")
|
|
82
|
-
elif
|
|
82
|
+
raise AccessTokenError(response_code, "Access Token expired, attempting to refresh")
|
|
83
|
+
elif response_code == ResponseCodes.DEVICE_OFFLINE.value:
|
|
83
84
|
return
|
|
84
85
|
else:
|
|
85
|
-
raise UnknownApiError(response_json)
|
|
86
|
+
raise UnknownApiError(response_code, response_json['msg'])
|
|
86
87
|
|
|
87
88
|
|
|
88
89
|
def check_for_errors_lock(service, response_json: Dict[str, Any]) -> None:
|
|
89
90
|
if response_json['ErrNo'] != 0:
|
|
90
91
|
if response_json.get('code') == ResponseCodes.PARAMETER_ERROR.value:
|
|
91
|
-
raise ParameterError
|
|
92
|
+
raise ParameterError(response_json)
|
|
92
93
|
elif response_json.get('code') == ResponseCodes.ACCESS_TOKEN_ERROR.value:
|
|
93
94
|
service._auth_lib.token.expired = True
|
|
94
95
|
raise AccessTokenError("Access Token expired, attempting to refresh")
|
|
@@ -96,6 +97,15 @@ def check_for_errors_lock(service, response_json: Dict[str, Any]) -> None:
|
|
|
96
97
|
raise UnknownApiError(response_json)
|
|
97
98
|
|
|
98
99
|
|
|
100
|
+
def check_for_errors_devicemgmt(service, response_json: Dict[Any, Any]) -> None:
|
|
101
|
+
if response_json['status'] != 200:
|
|
102
|
+
if "InvalidTokenError>" in response_json['response']['errors'][0]['message']:
|
|
103
|
+
service._auth_lib.token.expired = True
|
|
104
|
+
raise AccessTokenError("Access Token expired, attempting to refresh")
|
|
105
|
+
else:
|
|
106
|
+
raise UnknownApiError(response_json)
|
|
107
|
+
|
|
108
|
+
|
|
99
109
|
def check_for_errors_iot(service, response_json: Dict[Any, Any]) -> None:
|
|
100
110
|
if response_json['code'] != 1:
|
|
101
111
|
if str(response_json['code']) == ResponseCodes.ACCESS_TOKEN_ERROR.value:
|
wyzeapy/wyze_auth_lib.py
CHANGED
|
@@ -267,6 +267,23 @@ class WyzeAuthLib:
|
|
|
267
267
|
except ContentTypeError:
|
|
268
268
|
_LOGGER.debug(f"Response: {response}")
|
|
269
269
|
return await response.json()
|
|
270
|
+
|
|
271
|
+
async def put(self, url, json=None, headers=None, data=None) -> Dict[Any, Any]:
|
|
272
|
+
async with ClientSession(connector=TCPConnector(ttl_dns_cache=(30 * 60))) as _session:
|
|
273
|
+
response = await _session.put(url, json=json, headers=headers, data=data)
|
|
274
|
+
# Relocated these below as the sanitization seems to modify the data before it goes to the post.
|
|
275
|
+
_LOGGER.debug("Request:")
|
|
276
|
+
_LOGGER.debug(f"url: {url}")
|
|
277
|
+
_LOGGER.debug(f"json: {self.sanitize(json)}")
|
|
278
|
+
_LOGGER.debug(f"headers: {self.sanitize(headers)}")
|
|
279
|
+
_LOGGER.debug(f"data: {self.sanitize(data)}")
|
|
280
|
+
# Log the response.json() if it exists, if not log the response.
|
|
281
|
+
try:
|
|
282
|
+
response_json = await response.json()
|
|
283
|
+
_LOGGER.debug(f"Response Json: {self.sanitize(response_json)}")
|
|
284
|
+
except ContentTypeError:
|
|
285
|
+
_LOGGER.debug(f"Response: {response}")
|
|
286
|
+
return await response.json()
|
|
270
287
|
|
|
271
288
|
async def get(self, url, headers=None, params=None) -> Dict[Any, Any]:
|
|
272
289
|
async with ClientSession(connector=TCPConnector(ttl_dns_cache=(30 * 60))) as _session:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wyzeapy
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.24
|
|
4
4
|
Summary: A library for interacting with Wyze devices
|
|
5
5
|
License: GPL-3.0-only
|
|
6
6
|
Author: Katie Mulliken
|
|
@@ -10,6 +10,6 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
-
Requires-Dist: aiodns (>=3.
|
|
14
|
-
Requires-Dist: aiohttp (>=3.
|
|
15
|
-
Requires-Dist: pycryptodome (>=3.
|
|
13
|
+
Requires-Dist: aiodns (>=3.2.0,<4.0.0)
|
|
14
|
+
Requires-Dist: aiohttp (>=3.10.9,<4.0.0)
|
|
15
|
+
Requires-Dist: pycryptodome (>=3.21.0,<4.0.0)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
wyzeapy/__init__.py,sha256=GqTfzIPOJLdexQMtjvUsDR60oPB-rJGVSK_93FcCSuw,8918
|
|
2
|
+
wyzeapy/const.py,sha256=dm8-tXt_Tl75QXwr_DFfS6nQxQD8lkepWU7RveFVFkI,1054
|
|
3
|
+
wyzeapy/crypto.py,sha256=EI9WkKq4jS0nZS5CIEOSYD_9WtM7kEzrhqEg6YdPUIo,1342
|
|
4
|
+
wyzeapy/exceptions.py,sha256=BVRF7GMMC2T_ZSfGoIVHQsEjVQ3URd5xT6OYqfNxkY0,759
|
|
5
|
+
wyzeapy/payload_factory.py,sha256=PtnxN9awH4Wh7FPXrGhfHvyGPPYLLZc4XQ2ldZIZZjk,18897
|
|
6
|
+
wyzeapy/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
wyzeapy/services/base_service.py,sha256=6wRppqI5WD0KRHQiCek39PRNh6Ze7dd2bLN1nz5-uMI,28140
|
|
8
|
+
wyzeapy/services/bulb_service.py,sha256=n2Pvuunz5d7Iv275vDQjKxByowBDkVoVrztBLyDAOZE,6840
|
|
9
|
+
wyzeapy/services/camera_service.py,sha256=mco8YvhybiNUifBaMIf8oTGKc12D73EEAPydtB8ZhQA,9379
|
|
10
|
+
wyzeapy/services/hms_service.py,sha256=3Fhqlmk96dm8LFajjW6P40DCIYMudfN3YIDoVIonqGw,2459
|
|
11
|
+
wyzeapy/services/lock_service.py,sha256=cQ3A8nuovqPoofVBoo4dnnP-3GAkrf5Kgn0dPJWyhc0,1780
|
|
12
|
+
wyzeapy/services/sensor_service.py,sha256=xI--Zr4Dm6DuZrV5pNxBVA1C6rrfhG4T0AFkvXCxVP8,3252
|
|
13
|
+
wyzeapy/services/switch_service.py,sha256=8LGZ1MloLGEXLVy8PaUwfoEzCXdwefLIyGUc2aJ4yPc,2205
|
|
14
|
+
wyzeapy/services/thermostat_service.py,sha256=3yJ8Jx7WPROTkiD2868QrfALFR1QB6_JI4LqcMzOOVc,5228
|
|
15
|
+
wyzeapy/services/update_manager.py,sha256=036ClmJMFzXjD03mfg5DIyjB3xwqHoWkmpU2tcquc5Q,6132
|
|
16
|
+
wyzeapy/services/wall_switch_service.py,sha256=gc6RDDJ5mceiKQUUs0n1wUKM2Y9Hj4_V2SLX9PxRa0g,4262
|
|
17
|
+
wyzeapy/types.py,sha256=22v06L9tugwo2BS-lzM7fRbQHkk4a_FQhzTNlpA7tPA,6366
|
|
18
|
+
wyzeapy/utils.py,sha256=vxwshLArRvP7g3qpFBdFcXBCM2741ItNSSsfdeHD5GU,4755
|
|
19
|
+
wyzeapy/wyze_auth_lib.py,sha256=ERDuTQiTpbcNH5-Z38dGFTbLynvkejghp_eCYtb7OQQ,13712
|
|
20
|
+
wyzeapy-0.5.24.dist-info/LICENSES/GPL-3.0-only.txt,sha256=tqi_Y64slbCqJW7ndGgNe9GPIfRX2nVGb3YQs7FqzE4,34670
|
|
21
|
+
wyzeapy-0.5.24.dist-info/METADATA,sha256=MoEwtozkI-NR6jzDV4lU1KLcoyjwFXl8TYUnWmZ3up8,562
|
|
22
|
+
wyzeapy-0.5.24.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
23
|
+
wyzeapy-0.5.24.dist-info/RECORD,,
|
wyzeapy-0.5.23.dist-info/RECORD
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
wyzeapy/__init__.py,sha256=GqTfzIPOJLdexQMtjvUsDR60oPB-rJGVSK_93FcCSuw,8918
|
|
2
|
-
wyzeapy/const.py,sha256=HqihFV6Hb9yZmUzxrhcrX93cJ2urvtCyUz9s8jP-IVU,989
|
|
3
|
-
wyzeapy/crypto.py,sha256=EI9WkKq4jS0nZS5CIEOSYD_9WtM7kEzrhqEg6YdPUIo,1342
|
|
4
|
-
wyzeapy/exceptions.py,sha256=4eBi7YRWafJlG5M7Cqr_swGKqBggm0Iomf5-Gv6ecgo,871
|
|
5
|
-
wyzeapy/payload_factory.py,sha256=bWRo-xMFfhtxzUcsYd2Eo56MqXmWYuDi8J865Uj_L0E,1920
|
|
6
|
-
wyzeapy/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
wyzeapy/services/base_service.py,sha256=37747wJ9_Sy-rQzNetGYlJiGlnv4uWq7DqFCMveaIj8,23794
|
|
8
|
-
wyzeapy/services/bulb_service.py,sha256=n2Pvuunz5d7Iv275vDQjKxByowBDkVoVrztBLyDAOZE,6840
|
|
9
|
-
wyzeapy/services/camera_service.py,sha256=bkvd5Na-mh55xoR0CsTLTHI8685j5EoBKn1H_4mwBO8,5694
|
|
10
|
-
wyzeapy/services/hms_service.py,sha256=3Fhqlmk96dm8LFajjW6P40DCIYMudfN3YIDoVIonqGw,2459
|
|
11
|
-
wyzeapy/services/lock_service.py,sha256=cQ3A8nuovqPoofVBoo4dnnP-3GAkrf5Kgn0dPJWyhc0,1780
|
|
12
|
-
wyzeapy/services/sensor_service.py,sha256=xI--Zr4Dm6DuZrV5pNxBVA1C6rrfhG4T0AFkvXCxVP8,3252
|
|
13
|
-
wyzeapy/services/switch_service.py,sha256=8LGZ1MloLGEXLVy8PaUwfoEzCXdwefLIyGUc2aJ4yPc,2205
|
|
14
|
-
wyzeapy/services/thermostat_service.py,sha256=3yJ8Jx7WPROTkiD2868QrfALFR1QB6_JI4LqcMzOOVc,5228
|
|
15
|
-
wyzeapy/services/update_manager.py,sha256=036ClmJMFzXjD03mfg5DIyjB3xwqHoWkmpU2tcquc5Q,6132
|
|
16
|
-
wyzeapy/services/wall_switch_service.py,sha256=1PmDyKh6WR8ZVVHsj9CAiIDOyG18D0wmH64U2XluT5I,4315
|
|
17
|
-
wyzeapy/types.py,sha256=rUjW2n21ArbxxRpFQGZ5pUIt4bb6JJAkTXElSFHXLiU,5828
|
|
18
|
-
wyzeapy/utils.py,sha256=t2rktlOBXJ5O8YDwVkDwbEpBCwNA7TpiwVVeiDdpzu8,4267
|
|
19
|
-
wyzeapy/wyze_auth_lib.py,sha256=NWlWEMMNeEuCYLo7rxWd1EpJWPsP3huhJatfKTCkKm0,12713
|
|
20
|
-
wyzeapy-0.5.23.dist-info/LICENSES/GPL-3.0-only.txt,sha256=tqi_Y64slbCqJW7ndGgNe9GPIfRX2nVGb3YQs7FqzE4,34670
|
|
21
|
-
wyzeapy-0.5.23.dist-info/METADATA,sha256=0kXEypIc1o-__Yrfu0yj-MI_5-dUvGAUq5GxOWFy-5o,557
|
|
22
|
-
wyzeapy-0.5.23.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
23
|
-
wyzeapy-0.5.23.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|