pyezvizapi 1.0.0.0__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 pyezvizapi might be problematic. Click here for more details.
- pyezvizapi/__init__.py +54 -0
- pyezvizapi/__main__.py +459 -0
- pyezvizapi/api_endpoints.py +52 -0
- pyezvizapi/camera.py +258 -0
- pyezvizapi/cas.py +169 -0
- pyezvizapi/client.py +2089 -0
- pyezvizapi/constants.py +381 -0
- pyezvizapi/exceptions.py +29 -0
- pyezvizapi/light_bulb.py +126 -0
- pyezvizapi/mqtt.py +259 -0
- pyezvizapi/test_cam_rtsp.py +149 -0
- pyezvizapi/utils.py +160 -0
- pyezvizapi-1.0.0.0.dist-info/LICENSE +201 -0
- pyezvizapi-1.0.0.0.dist-info/LICENSE.md +201 -0
- pyezvizapi-1.0.0.0.dist-info/METADATA +18 -0
- pyezvizapi-1.0.0.0.dist-info/RECORD +19 -0
- pyezvizapi-1.0.0.0.dist-info/WHEEL +5 -0
- pyezvizapi-1.0.0.0.dist-info/entry_points.txt +2 -0
- pyezvizapi-1.0.0.0.dist-info/top_level.txt +1 -0
pyezvizapi/constants.py
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
"""Device switch types relationship."""
|
|
2
|
+
from enum import Enum, unique
|
|
3
|
+
|
|
4
|
+
FEATURE_CODE = "1fc28fa018178a1cd1c091b13b2f9f02"
|
|
5
|
+
XOR_KEY = b"\x0c\x0eJ^X\x15@Rr"
|
|
6
|
+
DEFAULT_TIMEOUT = 25
|
|
7
|
+
MAX_RETRIES = 3
|
|
8
|
+
REQUEST_HEADER = {
|
|
9
|
+
"featureCode": FEATURE_CODE,
|
|
10
|
+
"clientType": "3",
|
|
11
|
+
"osVersion": "",
|
|
12
|
+
"clientVersion": "",
|
|
13
|
+
"netType": "WIFI",
|
|
14
|
+
"customno": "1000001",
|
|
15
|
+
"ssid": "",
|
|
16
|
+
"clientNo": "web_site",
|
|
17
|
+
"appId": "ys7",
|
|
18
|
+
"language": "en_GB",
|
|
19
|
+
"lang": "en",
|
|
20
|
+
"sessionId": "",
|
|
21
|
+
"User-Agent": "okhttp/3.12.1",
|
|
22
|
+
} # Standard android header.
|
|
23
|
+
MQTT_APP_KEY = "4c6b3cc2-b5eb-4813-a592-612c1374c1fe"
|
|
24
|
+
APP_SECRET = "17454517-cc1c-42b3-a845-99b4a15dd3e6"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@unique
|
|
28
|
+
class MessageFilterType(Enum):
|
|
29
|
+
"""Message filter types for unified list."""
|
|
30
|
+
|
|
31
|
+
FILTER_TYPE_MOTION = 2402
|
|
32
|
+
FILTER_TYPE_PERSON = 2403
|
|
33
|
+
FILTER_TYPE_VEHICLE = 2404
|
|
34
|
+
FILTER_TYPE_SOUND = 2405
|
|
35
|
+
FILTER_TYPE_ALL_ALARM = 2401
|
|
36
|
+
FILTER_TYPE_SYSTEM_MESSAGE = 2101
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@unique
|
|
40
|
+
class DeviceSwitchType(Enum):
|
|
41
|
+
"""Device switch name and number."""
|
|
42
|
+
|
|
43
|
+
ALARM_TONE = 1
|
|
44
|
+
STREAM_ADAPTIVE = 2
|
|
45
|
+
LIGHT = 3
|
|
46
|
+
INTELLIGENT_ANALYSIS = 4
|
|
47
|
+
LOG_UPLOAD = 5
|
|
48
|
+
DEFENCE_PLAN = 6
|
|
49
|
+
PRIVACY = 7
|
|
50
|
+
SOUND_LOCALIZATION = 8
|
|
51
|
+
CRUISE = 9
|
|
52
|
+
INFRARED_LIGHT = 10
|
|
53
|
+
WIFI = 11
|
|
54
|
+
WIFI_MARKETING = 12
|
|
55
|
+
WIFI_LIGHT = 13
|
|
56
|
+
PLUG = 14
|
|
57
|
+
SLEEP = 21
|
|
58
|
+
SOUND = 22
|
|
59
|
+
BABY_CARE = 23
|
|
60
|
+
LOGO = 24
|
|
61
|
+
MOBILE_TRACKING = 25
|
|
62
|
+
CHANNELOFFLINE = 26
|
|
63
|
+
ALL_DAY_VIDEO = 29
|
|
64
|
+
AUTO_SLEEP = 32
|
|
65
|
+
ROAMING_STATUS = 34
|
|
66
|
+
DEVICE_4G = 35
|
|
67
|
+
ALARM_REMIND_MODE = 37
|
|
68
|
+
OUTDOOR_RINGING_SOUND = 39
|
|
69
|
+
INTELLIGENT_PQ_SWITCH = 40
|
|
70
|
+
DOORBELL_TALK = 101
|
|
71
|
+
HUMAN_INTELLIGENT_DETECTION = 200
|
|
72
|
+
LIGHT_FLICKER = 301
|
|
73
|
+
ALARM_LIGHT = 303
|
|
74
|
+
ALARM_LIGHT_RELEVANCE = 305
|
|
75
|
+
DEVICE_HUMAN_RELATE_LIGHT = 41
|
|
76
|
+
TAMPER_ALARM = 306
|
|
77
|
+
DETECTION_TYPE = 451
|
|
78
|
+
OUTLET_RECOVER = 600
|
|
79
|
+
CHIME_INDICATOR_LIGHT = 611
|
|
80
|
+
TRACKING = 650
|
|
81
|
+
CRUISE_TRACKING = 651
|
|
82
|
+
PARTIAL_IMAGE_OPTIMIZE = 700
|
|
83
|
+
FEATURE_TRACKING = 701
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@unique
|
|
87
|
+
class SupportExt(Enum):
|
|
88
|
+
"""Supported device extensions."""
|
|
89
|
+
|
|
90
|
+
SupportAITag = 522
|
|
91
|
+
SupportAbsenceReminder = 181
|
|
92
|
+
SupportActiveDefense = 96
|
|
93
|
+
SupportAddDelDetector = 19
|
|
94
|
+
SupportAddSmartChildDev = 156
|
|
95
|
+
SupportAlarmInterval = 406
|
|
96
|
+
SupportAlarmLight = 113
|
|
97
|
+
SupportAlarmVoice = 7
|
|
98
|
+
SupportAlertDelaySetup = 383
|
|
99
|
+
SupportAlertTone = 215
|
|
100
|
+
SupportAntiOpen = 213
|
|
101
|
+
SupportApMode = 106
|
|
102
|
+
SupportAssociateDoorlockOnline = 415
|
|
103
|
+
SupportAudioCollect = 165, 1
|
|
104
|
+
SupportAudioConfigApn = 695
|
|
105
|
+
SupportAudioOnoff = 63
|
|
106
|
+
SupportAutoAdjust = 45
|
|
107
|
+
SupportAutoOffline = 8
|
|
108
|
+
SupportAutoSleep = 144
|
|
109
|
+
SupportBackLight = 303
|
|
110
|
+
SupportBackendLinkIpcStream = 596
|
|
111
|
+
SupportBatteryDeviceP2p = 336
|
|
112
|
+
SupportBatteryManage = 119
|
|
113
|
+
SupportBatteryNonPerOperateP2p = 417
|
|
114
|
+
SupportBatteryNumber = 322
|
|
115
|
+
SupportBellSet = 164
|
|
116
|
+
SupportBluetooth = 58
|
|
117
|
+
SupportBodyFaceFilter = 318
|
|
118
|
+
SupportBodyFaceMarker = 319
|
|
119
|
+
SupportCall = 191
|
|
120
|
+
SupportCapture = 14
|
|
121
|
+
SupportChanType = 52
|
|
122
|
+
SupportChangeSafePasswd = 15
|
|
123
|
+
SupportChangeVoice = 481
|
|
124
|
+
SupportChangeVolume = 203
|
|
125
|
+
SupportChannelOffline = 70
|
|
126
|
+
SupportChannelTalk = 192
|
|
127
|
+
SupportChime = 115
|
|
128
|
+
SupportChimeDoorbellAutolink = 334
|
|
129
|
+
SupportChimeIndicatorLight = 186
|
|
130
|
+
SupportCloseInfraredLight = 48
|
|
131
|
+
SupportCloud = 11
|
|
132
|
+
SupportCloudVersion = 12
|
|
133
|
+
SupportConcealResource = 286, -1
|
|
134
|
+
SupportCorrelationAlarm = 387
|
|
135
|
+
SupportCustomVoice = 92
|
|
136
|
+
SupportCustomVoicePlan = 222
|
|
137
|
+
SupportDayNightSwitch = 238
|
|
138
|
+
SupportDdns = 175
|
|
139
|
+
SupportDecivePowerMessage = 218
|
|
140
|
+
SupportDecouplingAlarmVoice = 473
|
|
141
|
+
SupportDefaultVoice = 202
|
|
142
|
+
SupportDefence = 1
|
|
143
|
+
SupportDefencePlan = 3
|
|
144
|
+
SupportDetectHumanCar = 224
|
|
145
|
+
SupportDetectMoveHumanCar = 302
|
|
146
|
+
SupportDevOfflineAlarm = 450
|
|
147
|
+
SupportDeviceIntrusionDetection = 385
|
|
148
|
+
SupportDeviceLinkDevice = 593
|
|
149
|
+
SupportDeviceRevisionSetting = 499
|
|
150
|
+
SupportDeviceRfSignalReport = 325
|
|
151
|
+
SupportDeviceRing = 185
|
|
152
|
+
SupportDeviceTransboundaryDetection = 386
|
|
153
|
+
SupportDevicelog = 216
|
|
154
|
+
SupportDisk = 4
|
|
155
|
+
SupportDiskBlackList = 367
|
|
156
|
+
SupportDisturbMode = 217
|
|
157
|
+
SupportDisturbNewMode = 292
|
|
158
|
+
SupportDoorCallPlayBack = 545
|
|
159
|
+
SupportDoorCallQuickReply = 544
|
|
160
|
+
SupportDoorbellIndicatorLight = 242
|
|
161
|
+
SupportDoorbellTalk = 101
|
|
162
|
+
SupportEcdhV2getString = 519
|
|
163
|
+
SupportEmojiInteraction = 573
|
|
164
|
+
SupportEnStandard = 235
|
|
165
|
+
SupportEncrypt = 9
|
|
166
|
+
SupportEzvizChime = 380
|
|
167
|
+
SupportFaceFrameMark = 196
|
|
168
|
+
SupportFeatureTrack = 321
|
|
169
|
+
SupportFecCeilingCorrectType = 312
|
|
170
|
+
SupportFecWallCorrectType = 313
|
|
171
|
+
SupportFilter = 360
|
|
172
|
+
SupportFishEye = 91
|
|
173
|
+
SupportFlashLamp = 496
|
|
174
|
+
SupportFlowStatistics = 53
|
|
175
|
+
SupportFullScreenPtz = 81
|
|
176
|
+
SupportFulldayRecord = 88
|
|
177
|
+
SupportGetDeviceAuthCode = 492
|
|
178
|
+
SupportHorizontalPanoramic = 95
|
|
179
|
+
SupportHostScreen = 240
|
|
180
|
+
SupportIndicatorBrightness = 188
|
|
181
|
+
SupportIndicatorLightDay = 331
|
|
182
|
+
SupportIntellectualHumanFace = 351
|
|
183
|
+
SupportIntelligentNightVisionDuration = 353
|
|
184
|
+
SupportIntelligentPQSwitch = 366
|
|
185
|
+
SupportIntelligentTrack = 73
|
|
186
|
+
SupportInterconnectionDbChime = 550
|
|
187
|
+
SupportIpcLink = 20
|
|
188
|
+
SupportIsapi = 145
|
|
189
|
+
SupportKeyFocus = 74
|
|
190
|
+
SupportKindsP2pMode = 566
|
|
191
|
+
SupportLanguagegetString = 47
|
|
192
|
+
SupportLightAbilityRemind = 301
|
|
193
|
+
SupportLightRelate = 297
|
|
194
|
+
SupportLocalConnect = 507
|
|
195
|
+
SupportLocalLockGate = 662
|
|
196
|
+
SupportLockConfigWay = 679
|
|
197
|
+
SupportMessage = 6
|
|
198
|
+
SupportMicroVolumnSet = 77
|
|
199
|
+
SupportMicroscope = 60
|
|
200
|
+
SupportModifyChanName = 49
|
|
201
|
+
SupportModifyDetectorguardgetString = 23
|
|
202
|
+
SupportModifyDetectorname = 21
|
|
203
|
+
SupportMore = 54
|
|
204
|
+
SupportMotionDetection = 97
|
|
205
|
+
SupportMultiScreen = 17
|
|
206
|
+
SupportMultiSubsys = 255
|
|
207
|
+
SupportMusic = 67
|
|
208
|
+
SupportMusicPlay = 602
|
|
209
|
+
SupportNatPass = 84
|
|
210
|
+
SupportNetProtect = 290
|
|
211
|
+
SupportNewSearchRecords = 256
|
|
212
|
+
SupportNightVisionMode = 206
|
|
213
|
+
SupportNoencriptViaAntProxy = 79
|
|
214
|
+
SupportNvrEncrypt = 465
|
|
215
|
+
SupportOneKeyPatrol = 571
|
|
216
|
+
SupportPaging = 249
|
|
217
|
+
SupportPartialImageOptimize = 221
|
|
218
|
+
SupportPicInPic = 460
|
|
219
|
+
SupportPirDetect = 100
|
|
220
|
+
SupportPirSetting = 118
|
|
221
|
+
SupportPlaybackAsyn = 375
|
|
222
|
+
SupportPlaybackMaxSpeed = 610
|
|
223
|
+
SupportPlaybackQualityChange = 200
|
|
224
|
+
SupportPlaybackSmallSpeed = 585
|
|
225
|
+
SupportPoweroffRecovery = 189
|
|
226
|
+
SupportPreP2P = 59
|
|
227
|
+
SupportPreset = 34
|
|
228
|
+
SupportPresetAlarm = 72
|
|
229
|
+
SupportPreviewCorrectionInOldWay = 581
|
|
230
|
+
SupportProtectionMode = 64
|
|
231
|
+
SupportPtz = 154
|
|
232
|
+
SupportPtz45Degree = 32
|
|
233
|
+
SupportPtzCenterMirror = 37
|
|
234
|
+
SupportPtzCommonCruise = 35
|
|
235
|
+
SupportPtzFigureCruise = 36
|
|
236
|
+
SupportPtzFocus = 99
|
|
237
|
+
SupportPtzHorizontal360 = 199
|
|
238
|
+
SupportPtzLeftRight = 31
|
|
239
|
+
SupportPtzLeftRightMirror = 38
|
|
240
|
+
SupportPtzManualCtrl = 586
|
|
241
|
+
SupportPtzModel = 50
|
|
242
|
+
SupportPtzNew = 605
|
|
243
|
+
SupportPtzPrivacy = 40
|
|
244
|
+
SupportPtzTopBottom = 30
|
|
245
|
+
SupportPtzTopBottomMirror = 39
|
|
246
|
+
SupportPtzZoom = 33
|
|
247
|
+
SupportPtzcmdViaP2pv3 = 169
|
|
248
|
+
SupportQosTalkVersion = 287
|
|
249
|
+
SupportQuickplayWay = 149
|
|
250
|
+
SupportRateLimit = 65
|
|
251
|
+
SupportRebootDevice = 452
|
|
252
|
+
SupportRegularBrightnessPlan = 384
|
|
253
|
+
SupportRelatedDevice = 26
|
|
254
|
+
SupportRelatedStorage = 27
|
|
255
|
+
SupportRelationCamera = 117
|
|
256
|
+
SupportRemindAudition = 434
|
|
257
|
+
SupportRemoteAuthRandcode = 28
|
|
258
|
+
SupportRemoteOpenDoor = 592
|
|
259
|
+
SupportRemoteQuiet = 55
|
|
260
|
+
SupportReplayChanNums = 94
|
|
261
|
+
SupportReplayDownload = 260
|
|
262
|
+
SupportReplaySpeed = 68
|
|
263
|
+
SupportResolutiongetString = 16
|
|
264
|
+
SupportRestartTime = 103
|
|
265
|
+
SupportReverseDirect = 69
|
|
266
|
+
SupportRingingSoundSelect = 241
|
|
267
|
+
SupportSafeModePlan = 22
|
|
268
|
+
SupportSdCover = 483
|
|
269
|
+
SupportSdHideRecord = 600
|
|
270
|
+
SupportSdkTransport = 29
|
|
271
|
+
SupportSeekPlayback = 257
|
|
272
|
+
SupportSensibilityAdjust = 61
|
|
273
|
+
SupportServerSideEncryption = 261
|
|
274
|
+
SupportSetWireioType = 205
|
|
275
|
+
SupportSignalCheck = 535
|
|
276
|
+
SupportSimCard = 194
|
|
277
|
+
SupportSleep = 62
|
|
278
|
+
SupportSmartBodyDetect = 244
|
|
279
|
+
SupportSmartNightVision = 274
|
|
280
|
+
SupportSoundLightAlarm = 214
|
|
281
|
+
SupportSsl = 25
|
|
282
|
+
SupportSwitchLog = 187
|
|
283
|
+
SupportSwitchTalkmode = 170
|
|
284
|
+
SupportTalk = 2
|
|
285
|
+
SupportTalkType = 51
|
|
286
|
+
SupportTalkVolumeAdj = 455
|
|
287
|
+
SupportTamperAlarm = 327
|
|
288
|
+
SupportTearFilm = 454
|
|
289
|
+
SupportTemperatureAlarm = 76
|
|
290
|
+
SupportTextToVoice = 574
|
|
291
|
+
SupportTimeSchedulePlan = 209
|
|
292
|
+
SupportTimezone = 46
|
|
293
|
+
SupportTracking = 198
|
|
294
|
+
SupportTvEntranceOff = 578
|
|
295
|
+
SupportUnLock = 78
|
|
296
|
+
SupportUnbind = 44
|
|
297
|
+
SupportUpgrade = 10
|
|
298
|
+
SupportUploadCloudFile = 18
|
|
299
|
+
SupportVerticalPanoramic = 112
|
|
300
|
+
SupportVolumnSet = 75
|
|
301
|
+
SupportWeixin = 24
|
|
302
|
+
SupportWifi = 13
|
|
303
|
+
SupportWifi24G = 41
|
|
304
|
+
SupportWifi5G = 42
|
|
305
|
+
SupportWifiLock = 541
|
|
306
|
+
SupportWifiManager = 239
|
|
307
|
+
SupportWifiPortal = 43
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
@unique
|
|
311
|
+
class SoundMode(Enum):
|
|
312
|
+
"""Alarm sound level description."""
|
|
313
|
+
|
|
314
|
+
SILENT = 2
|
|
315
|
+
SOFT = 0
|
|
316
|
+
INTENSE = 1
|
|
317
|
+
CUSTOM = 3
|
|
318
|
+
PLAN = 4
|
|
319
|
+
UNKNOWN = -1
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
@unique
|
|
323
|
+
class DefenseModeType(Enum):
|
|
324
|
+
"""Defense mode name and number."""
|
|
325
|
+
|
|
326
|
+
HOME_MODE = 1
|
|
327
|
+
AWAY_MODE = 2
|
|
328
|
+
SLEEP_MODE = 3
|
|
329
|
+
UNSET_MODE = 0
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
@unique
|
|
333
|
+
class IntelligentDetectionMode(Enum):
|
|
334
|
+
"""Intelligent detection modes."""
|
|
335
|
+
|
|
336
|
+
INTELLI_MODE_HUMAN_SHAPE = 1
|
|
337
|
+
INTELLI_MODE_PIR = 5
|
|
338
|
+
INTELLI_MODE_IMAGE_CHANGE = 3
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
@unique
|
|
342
|
+
class NightVisionMode(Enum):
|
|
343
|
+
"""Intelligent detection modes."""
|
|
344
|
+
|
|
345
|
+
NIGHT_VISION_COLOUR = 1
|
|
346
|
+
NIGHT_VISION_B_W = 0
|
|
347
|
+
NIGHT_VISION_SMART = 2
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
@unique
|
|
351
|
+
class DisplayMode(Enum):
|
|
352
|
+
"""Display modes or image styles."""
|
|
353
|
+
|
|
354
|
+
DISPLAY_MODE_ORIGINAL = 1
|
|
355
|
+
DISPLAY_MODE_SOFT = 2
|
|
356
|
+
DISPLAY_MODE_VIVID = 3
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
@unique
|
|
360
|
+
class BatteryCameraWorkMode(Enum):
|
|
361
|
+
"""Battery camera work modes."""
|
|
362
|
+
|
|
363
|
+
PLUGGED_IN = 2
|
|
364
|
+
HIGH_PERFORMANCE = 1
|
|
365
|
+
POWER_SAVE = 0
|
|
366
|
+
SUPER_POWER_SAVE = 3
|
|
367
|
+
CUSTOM = 4
|
|
368
|
+
HYBERNATE = 5 #not sure
|
|
369
|
+
UNKNOWN = -1
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
class DeviceCatagories(Enum):
|
|
373
|
+
"""Supported device categories."""
|
|
374
|
+
|
|
375
|
+
COMMON_DEVICE_CATEGORY = "COMMON"
|
|
376
|
+
CAMERA_DEVICE_CATEGORY = "IPC"
|
|
377
|
+
BATTERY_CAMERA_DEVICE_CATEGORY = "BatteryCamera"
|
|
378
|
+
DOORBELL_DEVICE_CATEGORY = "BDoorBell"
|
|
379
|
+
BASE_STATION_DEVICE_CATEGORY = "XVR"
|
|
380
|
+
CAT_EYE_CATEGORY = "CatEye"
|
|
381
|
+
LIGHTING = "lighting"
|
pyezvizapi/exceptions.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""PyEzviz Exceptions."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class PyEzvizError(Exception):
|
|
5
|
+
"""Ezviz api exception."""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class InvalidURL(PyEzvizError):
|
|
9
|
+
"""Invalid url exception."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class HTTPError(PyEzvizError):
|
|
13
|
+
"""Invalid host exception."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class InvalidHost(PyEzvizError):
|
|
17
|
+
"""Invalid host exception."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AuthTestResultFailed(PyEzvizError):
|
|
21
|
+
"""Authentication failed."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class EzvizAuthTokenExpired(PyEzvizError):
|
|
25
|
+
"""Authentication failed because token is invalid or expired."""
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class EzvizAuthVerificationCode(PyEzvizError):
|
|
29
|
+
"""Authentication failed because MFA verification code is required."""
|
pyezvizapi/light_bulb.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""pyezviz camera api."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
|
|
7
|
+
from .constants import DeviceSwitchType
|
|
8
|
+
from .exceptions import PyEzvizError
|
|
9
|
+
from .utils import fetch_nested_value
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from .client import EzvizClient
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class EzvizLightBulb:
|
|
16
|
+
"""Initialize Ezviz Light Bulb object."""
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self, client: EzvizClient, serial: str, device_obj: dict | None = None
|
|
20
|
+
) -> None:
|
|
21
|
+
"""Initialize the light bulb object."""
|
|
22
|
+
self._client = client
|
|
23
|
+
self._serial = serial
|
|
24
|
+
self._device = (
|
|
25
|
+
device_obj if device_obj else self._client.get_device_infos(self._serial)
|
|
26
|
+
)
|
|
27
|
+
self._feature_json = self.get_feature_json()
|
|
28
|
+
self._switch: dict[int, bool] = {
|
|
29
|
+
switch["type"]: switch["enable"] for switch in self._device["SWITCH"]
|
|
30
|
+
}
|
|
31
|
+
if DeviceSwitchType.ALARM_LIGHT.value not in self._switch:
|
|
32
|
+
# trying to have same interface as the camera's light
|
|
33
|
+
self._switch[DeviceSwitchType.ALARM_LIGHT.value] = self.get_feature_item("light_switch")["dataValue"]
|
|
34
|
+
|
|
35
|
+
def fetch_key(self, keys: list, default_value: Any = None) -> Any:
|
|
36
|
+
"""Fetch dictionary key."""
|
|
37
|
+
return fetch_nested_value(self._device, keys, default_value)
|
|
38
|
+
|
|
39
|
+
def _local_ip(self) -> Any:
|
|
40
|
+
"""Fix empty ip value for certain cameras."""
|
|
41
|
+
if (
|
|
42
|
+
self.fetch_key(["WIFI", "address"])
|
|
43
|
+
and self._device["WIFI"]["address"] != "0.0.0.0"
|
|
44
|
+
):
|
|
45
|
+
return self._device["WIFI"]["address"]
|
|
46
|
+
|
|
47
|
+
# Seems to return none or 0.0.0.0 on some.
|
|
48
|
+
if (
|
|
49
|
+
self.fetch_key(["CONNECTION", "localIp"])
|
|
50
|
+
and self._device["CONNECTION"]["localIp"] != "0.0.0.0"
|
|
51
|
+
):
|
|
52
|
+
return self._device["CONNECTION"]["localIp"]
|
|
53
|
+
|
|
54
|
+
return "0.0.0.0"
|
|
55
|
+
|
|
56
|
+
def get_feature_json(self) -> Any:
|
|
57
|
+
"""Parse the FEATURE json."""
|
|
58
|
+
try:
|
|
59
|
+
json_output = json.loads(self._device["FEATURE"]["featureJson"])
|
|
60
|
+
|
|
61
|
+
except ValueError as err:
|
|
62
|
+
raise PyEzvizError(
|
|
63
|
+
"Impossible to decode FEATURE: "
|
|
64
|
+
+ str(err)
|
|
65
|
+
) from err
|
|
66
|
+
|
|
67
|
+
return json_output
|
|
68
|
+
|
|
69
|
+
def get_feature_item(self, key: str, default_value: Any = None) -> Any:
|
|
70
|
+
"""Get items fron FEATURE."""
|
|
71
|
+
items = self._feature_json["featureItemDtos"]
|
|
72
|
+
for item in items:
|
|
73
|
+
if item["itemKey"] == key:
|
|
74
|
+
return item
|
|
75
|
+
return default_value
|
|
76
|
+
|
|
77
|
+
def get_product_id(self) -> Any:
|
|
78
|
+
"""Get product id."""
|
|
79
|
+
return self._feature_json["productId"]
|
|
80
|
+
|
|
81
|
+
def status(self) -> dict[Any, Any]:
|
|
82
|
+
"""Return the status of the light bulb."""
|
|
83
|
+
return {
|
|
84
|
+
"serial": self._serial,
|
|
85
|
+
"name": self.fetch_key(["deviceInfos", "name"]),
|
|
86
|
+
"version": self.fetch_key(["deviceInfos", "version"]),
|
|
87
|
+
"upgrade_available": bool(
|
|
88
|
+
self.fetch_key(["UPGRADE", "isNeedUpgrade"]) == 3
|
|
89
|
+
),
|
|
90
|
+
"status": self.fetch_key(["deviceInfos", "status"]),
|
|
91
|
+
"device_category": self.fetch_key(["deviceInfos", "deviceCategory"]),
|
|
92
|
+
"device_sub_category": self.fetch_key(["deviceInfos", "deviceSubCategory"]),
|
|
93
|
+
"upgrade_percent": self.fetch_key(["STATUS", "upgradeProcess"]),
|
|
94
|
+
"upgrade_in_progress": bool(
|
|
95
|
+
self.fetch_key(["STATUS", "upgradeStatus"]) == 0
|
|
96
|
+
),
|
|
97
|
+
"latest_firmware_info": self.fetch_key(["UPGRADE", "upgradePackageInfo"]),
|
|
98
|
+
"local_ip": self._local_ip(),
|
|
99
|
+
"wan_ip": self.fetch_key(["CONNECTION", "netIp"]),
|
|
100
|
+
"mac_address": self.fetch_key(["deviceInfos", "mac"]),
|
|
101
|
+
"supported_channels": self.fetch_key(["deviceInfos", "channelNumber"]),
|
|
102
|
+
"wifiInfos": self._device["WIFI"],
|
|
103
|
+
"switches": self._switch,
|
|
104
|
+
"optionals": self.fetch_key(["STATUS", "optionals"]),
|
|
105
|
+
"supportExt": self._device["deviceInfos"]["supportExt"],
|
|
106
|
+
"ezDeviceCapability": self.fetch_key(["deviceInfos", "ezDeviceCapability"]),
|
|
107
|
+
|
|
108
|
+
"featureItems": self._feature_json["featureItemDtos"],
|
|
109
|
+
"productId": self._feature_json["productId"],
|
|
110
|
+
"color_temperature": self.get_feature_item("color_temperature")["dataValue"],
|
|
111
|
+
|
|
112
|
+
"is_on": self.get_feature_item("light_switch")["dataValue"],
|
|
113
|
+
"brightness": self.get_feature_item("brightness")["dataValue"],
|
|
114
|
+
# same as brightness... added in order to keep "same interface" between camera and light bulb objects
|
|
115
|
+
"alarm_light_luminance": self.get_feature_item("brightness")["dataValue"],
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
def toggle_switch(self) -> bool:
|
|
119
|
+
"""Toggle on/off light bulb."""
|
|
120
|
+
item = self.get_feature_item("light_switch")
|
|
121
|
+
return self._client.set_device_feature_by_key(
|
|
122
|
+
self._serial,
|
|
123
|
+
self.get_product_id(),
|
|
124
|
+
not bool(item["dataValue"]),
|
|
125
|
+
item["itemKey"]
|
|
126
|
+
)
|