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.

@@ -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"
@@ -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."""
@@ -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
+ )