pyezvizapi 1.0.0.2__tar.gz → 1.0.0.4__tar.gz

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.

Files changed (25) hide show
  1. {pyezvizapi-1.0.0.2/pyezvizapi.egg-info → pyezvizapi-1.0.0.4}/PKG-INFO +1 -1
  2. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/api_endpoints.py +13 -11
  3. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/client.py +151 -86
  4. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/light_bulb.py +1 -1
  5. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/utils.py +6 -1
  6. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4/pyezvizapi.egg-info}/PKG-INFO +1 -1
  7. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/setup.py +1 -1
  8. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/LICENSE +0 -0
  9. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/LICENSE.md +0 -0
  10. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/MANIFEST.in +0 -0
  11. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/README.md +0 -0
  12. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/__init__.py +0 -0
  13. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/__main__.py +0 -0
  14. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/camera.py +0 -0
  15. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/cas.py +0 -0
  16. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/constants.py +0 -0
  17. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/exceptions.py +0 -0
  18. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/mqtt.py +0 -0
  19. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi/test_cam_rtsp.py +0 -0
  20. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi.egg-info/SOURCES.txt +0 -0
  21. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi.egg-info/dependency_links.txt +0 -0
  22. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi.egg-info/entry_points.txt +0 -0
  23. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi.egg-info/requires.txt +0 -0
  24. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/pyezvizapi.egg-info/top_level.txt +0 -0
  25. {pyezvizapi-1.0.0.2 → pyezvizapi-1.0.0.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pyezvizapi
3
- Version: 1.0.0.2
3
+ Version: 1.0.0.4
4
4
  Summary: Pilot your Ezviz cameras
5
5
  Home-page: https://github.com/RenierM26/pyEzvizApi/
6
6
  Author: Renier Moorcroft
@@ -7,31 +7,36 @@ API_ENDPOINT_LOGIN = "/v3/users/login/v5"
7
7
  API_ENDPOINT_LOGOUT = "/v3/users/logout/v2"
8
8
  API_ENDPOINT_REFRESH_SESSION_ID = "/v3/apigateway/login"
9
9
  API_ENDPOINT_SERVER_INFO = "/v3/configurations/system/info"
10
+
10
11
  API_ENDPOINT_USER_ID = "/v3/userdevices/v1/token"
11
12
  API_ENDPOINT_GROUP_DEFENCE_MODE = "/v3/userdevices/v1/group/defenceMode"
13
+ API_ENDPOINT_PAGELIST = "/v3/userdevices/v1/resources/pagelist"
14
+ API_ENDPOINT_SWITCH_DEFENCE_MODE = "/v3/userdevices/v1/group/switchDefenceMode"
12
15
 
13
16
  API_ENDPOINT_PANORAMIC_DEVICES_OPERATION = "/v3/panoramicDevices/operation"
14
17
  API_ENDPOINT_UPGRADE_DEVICE = "/v3/upgrades/v1/devices/"
15
18
  API_ENDPOINT_SEND_CODE = "/v3/sms/nologin/checkcode"
19
+ API_ENDPOINT_UNIFIEDMSG_LIST_GET = "/v3/unifiedmsg/list"
20
+ API_ENDPOINT_IOT_FEATURE = "/v3/iot-feature/feature/"
21
+ API_ENDPOINT_CALLING_NOTIFY = "/v3/calling/"
16
22
 
17
23
  API_ENDPOINT_ALARMINFO_GET = "/v3/alarms/v2/advanced"
18
- API_ENDPOINT_UNIFIEDMSG_LIST_GET = "/v3/unifiedmsg/list"
19
24
  API_ENDPOINT_V3_ALARMS = "/v3/alarms/"
20
- API_ENDPOINT_SET_LUMINANCE = "/v3/alarms/device/alarmLight"
25
+ API_ENDPOINT_SET_LUMINANCE = "/v3/alarms/device/alarmLight/"
21
26
 
22
- API_ENDPOINT_PAGELIST = "/v3/userdevices/v1/resources/pagelist"
23
- API_ENDPOINT_SWITCH_DEFENCE_MODE = "/v3/userdevices/v1/group/switchDefenceMode"
27
+ API_ENDPOINT_DEVCONFIG_BY_KEY = "/v3/devconfig/v1/keyValue/"
28
+ API_ENDPOINT_CAM_AUTH_CODE = "/v3/devconfig/authcode/query/"
24
29
 
25
30
  API_ENDPOINT_DETECTION_SENSIBILITY = "/api/device/configAlgorithm"
26
31
  API_ENDPOINT_DETECTION_SENSIBILITY_GET = "/api/device/queryAlgorithmConfig"
27
32
  API_ENDPOINT_SET_DEFENCE_SCHEDULE = "/api/device/defence/plan2"
28
33
  API_ENDPOINT_CAM_ENCRYPTKEY = "/api/device/query/encryptkey"
29
- API_ENDPOINT_CAM_AUTH_CODE = "/v3/devconfig/authcode/query/"
34
+ API_ENDPOINT_OFFLINE_NOTIFY = "/api/device/notify/switch"
30
35
  API_ENDPOINT_CANCEL_ALARM = "/api/device/cancelAlarm"
31
36
  API_ENDPOINT_DEVICE_SYS_OPERATION = "/api/device/v2/sysOper/"
32
37
  API_ENDPOINT_DEVICE_STORAGE_STATUS = "/api/device/queryStorageStatus"
33
- API_ENDPOINT_DEVCONFIG_BY_KEY = "/v3/devconfig/v1/keyValue/"
34
- API_ENDPOINT_IOT_FEATURE = "/v3/iot-feature/feature/"
38
+ API_ENDPOINT_CREATE_PANORAMIC = "/api/panoramic/devices/pics/collect"
39
+ API_ENDPOINT_RETURN_PANORAMIC = "/api/panoramic/devices/pics"
35
40
 
36
41
  # Videogo DeviceApi
37
42
  API_ENDPOINT_DEVICES = "/v3/devices/"
@@ -42,10 +47,7 @@ API_ENDPOINT_ALARM_SOUND = "/alarm/sound"
42
47
  API_ENDPOINT_SWITCH_SOUND_ALARM = "/sendAlarm"
43
48
  API_ENDPOINT_DO_NOT_DISTURB = "/nodisturb"
44
49
  API_ENDPOINT_VIDEO_ENCRYPT = "encryptedInfo/risk"
45
- API_ENDPOINT_CHANGE_DEFENCE_STATUS = "changeDefenceStatusReq"
46
-
47
- API_ENDPOINT_CREATE_PANORAMIC = "/api/panoramic/devices/pics/collect"
48
- API_ENDPOINT_RETURN_PANORAMIC = "/api/panoramic/devices/pics"
50
+ API_ENDPOINT_CHANGE_DEFENCE_STATUS = "/changeDefenceStatusReq"
49
51
 
50
52
  # MQTT
51
53
  API_ENDPOINT_REGISTER_MQTT = "/v1/getClientId"
@@ -15,6 +15,7 @@ import requests
15
15
  from .api_endpoints import (
16
16
  API_ENDPOINT_ALARM_SOUND,
17
17
  API_ENDPOINT_ALARMINFO_GET,
18
+ API_ENDPOINT_CALLING_NOTIFY,
18
19
  API_ENDPOINT_CAM_AUTH_CODE,
19
20
  API_ENDPOINT_CAM_ENCRYPTKEY,
20
21
  API_ENDPOINT_CANCEL_ALARM,
@@ -31,6 +32,7 @@ from .api_endpoints import (
31
32
  API_ENDPOINT_IOT_FEATURE,
32
33
  API_ENDPOINT_LOGIN,
33
34
  API_ENDPOINT_LOGOUT,
35
+ API_ENDPOINT_OFFLINE_NOTIFY,
34
36
  API_ENDPOINT_PAGELIST,
35
37
  API_ENDPOINT_PANORAMIC_DEVICES_OPERATION,
36
38
  API_ENDPOINT_PTZCONTROL,
@@ -123,7 +125,7 @@ class EzvizClient:
123
125
 
124
126
  try:
125
127
  req = self._session.post(
126
- "https://" + self._token["api_url"] + API_ENDPOINT_LOGIN,
128
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_LOGIN}",
127
129
  allow_redirects=False,
128
130
  data=payload,
129
131
  timeout=self._timeout,
@@ -193,7 +195,7 @@ class EzvizClient:
193
195
  """Send verification code."""
194
196
  try:
195
197
  req = self._session.post(
196
- "https://" + self._token["api_url"] + API_ENDPOINT_SEND_CODE,
198
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_SEND_CODE}",
197
199
  data={
198
200
  "from": self.account,
199
201
  "bizType": "TERMINAL_BIND",
@@ -230,7 +232,7 @@ class EzvizClient:
230
232
 
231
233
  try:
232
234
  req = self._session.get(
233
- f"https://{self._token['api_url']}{API_ENDPOINT_SERVER_INFO}",
235
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_SERVER_INFO}",
234
236
  timeout=self._timeout,
235
237
  )
236
238
  req.raise_for_status()
@@ -286,7 +288,7 @@ class EzvizClient:
286
288
 
287
289
  try:
288
290
  req = self._session.get(
289
- "https://" + self._token["api_url"] + API_ENDPOINT_PAGELIST,
291
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_PAGELIST}",
290
292
  params=params,
291
293
  timeout=self._timeout,
292
294
  )
@@ -355,7 +357,7 @@ class EzvizClient:
355
357
 
356
358
  try:
357
359
  req = self._session.get(
358
- "https://" + self._token["api_url"] + API_ENDPOINT_ALARMINFO_GET,
360
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_ALARMINFO_GET}",
359
361
  params=params,
360
362
  timeout=self._timeout,
361
363
  )
@@ -418,7 +420,7 @@ class EzvizClient:
418
420
 
419
421
  try:
420
422
  req = self._session.get(
421
- "https://" + self._token["api_url"] + API_ENDPOINT_UNIFIEDMSG_LIST_GET,
423
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_UNIFIEDMSG_LIST_GET}",
422
424
  params=params,
423
425
  timeout=self._timeout,
424
426
  )
@@ -570,7 +572,7 @@ class EzvizClient:
570
572
 
571
573
  try:
572
574
  req = self._session.put(
573
- url=f"https://{self._token['api_url']}{API_ENDPOINT_DEVICES}{serial}/{channel_no}/{API_ENDPOINT_CHANGE_DEFENCE_STATUS}",
575
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_DEVICES}{serial}/{channel_no}{API_ENDPOINT_CHANGE_DEFENCE_STATUS}",
574
576
  timeout=self._timeout,
575
577
  data={
576
578
  "type": arm_type,
@@ -771,11 +773,7 @@ class EzvizClient:
771
773
 
772
774
  try:
773
775
  req = self._session.put(
774
- "https://"
775
- + self._token["api_url"]
776
- + API_ENDPOINT_UPGRADE_DEVICE
777
- + serial
778
- + "/0/upgrade",
776
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_UPGRADE_DEVICE}{serial}/0/upgrade",
779
777
  timeout=self._timeout,
780
778
  )
781
779
 
@@ -862,12 +860,7 @@ class EzvizClient:
862
860
 
863
861
  try:
864
862
  req = self._session.put(
865
- "https://"
866
- + self._token["api_url"]
867
- + API_ENDPOINT_DEVICES
868
- + serial
869
- + "/0"
870
- + API_ENDPOINT_SWITCH_SOUND_ALARM,
863
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_DEVICES}{serial}/0{API_ENDPOINT_SWITCH_SOUND_ALARM}",
871
864
  data={
872
865
  "enable": enable,
873
866
  },
@@ -908,7 +901,7 @@ class EzvizClient:
908
901
 
909
902
  try:
910
903
  req = self._session.get(
911
- f"https://{self._token['api_url']}{API_ENDPOINT_USER_ID}",
904
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_USER_ID}",
912
905
  timeout=self._timeout,
913
906
  )
914
907
  req.raise_for_status()
@@ -958,10 +951,7 @@ class EzvizClient:
958
951
 
959
952
  try:
960
953
  req = self._session.put(
961
- "https://"
962
- + self._token["api_url"]
963
- + API_ENDPOINT_DEVICES
964
- + API_ENDPOINT_VIDEO_ENCRYPT,
954
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_DEVICES}{API_ENDPOINT_VIDEO_ENCRYPT}",
965
955
  data={
966
956
  "deviceSerial": serial,
967
957
  "isEncrypt": enable, # 1 = enable, 0 = disable, 2 = change password
@@ -1068,6 +1058,69 @@ class EzvizClient:
1068
1058
 
1069
1059
  return True
1070
1060
 
1061
+ def set_offline_notification(
1062
+ self,
1063
+ serial: str,
1064
+ enable: int = 1,
1065
+ req_type: int = 1,
1066
+ max_retries: int = 0,
1067
+ ) -> bool:
1068
+ """Set offline notification."""
1069
+ if max_retries > MAX_RETRIES:
1070
+ raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
1071
+
1072
+ try:
1073
+ req = self._session.post(
1074
+ url=f'https://{self._token["api_url"]}{API_ENDPOINT_OFFLINE_NOTIFY}',
1075
+ data={
1076
+ "reqType": req_type,
1077
+ "serial": serial,
1078
+ "status": enable,
1079
+ },
1080
+ timeout=self._timeout,
1081
+ )
1082
+
1083
+ req.raise_for_status()
1084
+
1085
+ except requests.HTTPError as err:
1086
+ if err.response.status_code == 401:
1087
+ # session is wrong, need to relogin
1088
+ self.login()
1089
+ return self.set_offline_notification(
1090
+ serial,
1091
+ enable,
1092
+ req_type,
1093
+ max_retries + 1,
1094
+ )
1095
+
1096
+ raise HTTPError from err
1097
+
1098
+ try:
1099
+ json_output = req.json()
1100
+
1101
+ except ValueError as err:
1102
+ raise PyEzvizError(
1103
+ "Impossible to decode response: "
1104
+ + str(err)
1105
+ + "\nResponse was: "
1106
+ + str(req.text)
1107
+ ) from err
1108
+
1109
+ if json_output["resultCode"] != "0":
1110
+ if json_output["resultCode"] == "-1":
1111
+ _LOGGER.warning(
1112
+ "Unable to set offline notification, camera %s is unreachable, retrying %s of %s",
1113
+ serial,
1114
+ max_retries,
1115
+ MAX_RETRIES,
1116
+ )
1117
+ return self.set_offline_notification(
1118
+ serial, enable, req_type, max_retries + 1
1119
+ )
1120
+ raise PyEzvizError(f"Could not set offline notification {json_output})")
1121
+
1122
+ return True
1123
+
1071
1124
  def get_group_defence_mode(self, max_retries: int = 0) -> Any:
1072
1125
  """Get group arm status. The alarm arm/disarm concept on 1st page of app."""
1073
1126
 
@@ -1076,7 +1129,7 @@ class EzvizClient:
1076
1129
 
1077
1130
  try:
1078
1131
  req = self._session.get(
1079
- "https://" + self._token["api_url"] + API_ENDPOINT_GROUP_DEFENCE_MODE,
1132
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_GROUP_DEFENCE_MODE}",
1080
1133
  params={
1081
1134
  "groupId": -1,
1082
1135
  },
@@ -1119,7 +1172,7 @@ class EzvizClient:
1119
1172
 
1120
1173
  try:
1121
1174
  req = self._session.post(
1122
- "https://" + self._token["api_url"] + API_ENDPOINT_CANCEL_ALARM,
1175
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_CANCEL_ALARM}",
1123
1176
  data={"subSerial": serial},
1124
1177
  timeout=self._timeout,
1125
1178
  )
@@ -1265,15 +1318,11 @@ class EzvizClient:
1265
1318
 
1266
1319
  try:
1267
1320
  req = self._session.put(
1268
- "https://"
1269
- + self._token["api_url"]
1270
- + API_ENDPOINT_DEVICES
1271
- + serial
1272
- + API_ENDPOINT_PTZCONTROL,
1321
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_DEVICES}{serial}{API_ENDPOINT_PTZCONTROL}",
1273
1322
  data={
1274
1323
  "command": command,
1275
1324
  "action": action,
1276
- "channelNo": "1",
1325
+ "channelNo": 1,
1277
1326
  "speed": speed,
1278
1327
  "uuid": str(uuid4()),
1279
1328
  "serial": serial,
@@ -1311,7 +1360,7 @@ class EzvizClient:
1311
1360
 
1312
1361
  try:
1313
1362
  req = self._session.post(
1314
- "https://" + self._token["api_url"] + API_ENDPOINT_CAM_ENCRYPTKEY,
1363
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_CAM_ENCRYPTKEY}",
1315
1364
  data={
1316
1365
  "checkcode": smscode,
1317
1366
  "serial": serial,
@@ -1363,23 +1412,28 @@ class EzvizClient:
1363
1412
 
1364
1413
  return json_output["encryptkey"]
1365
1414
 
1366
- def get_cam_auth_code(self, serial: str, max_retries: int = 0) -> Any:
1415
+ def get_cam_auth_code(
1416
+ self,
1417
+ serial: str,
1418
+ encrypt_pwd: str | None = None,
1419
+ msg_auth_code: int | None = None,
1420
+ max_retries: int = 0,
1421
+ ) -> Any:
1367
1422
  """Get Camera auth code. This is the verification code on the camera sticker."""
1368
1423
 
1369
1424
  if max_retries > MAX_RETRIES:
1370
1425
  raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
1371
1426
 
1427
+ params: dict[str, int | str | None] = {
1428
+ "encrptPwd": encrypt_pwd,
1429
+ "msgAuthCode": msg_auth_code,
1430
+ "senderType": 0,
1431
+ }
1432
+
1372
1433
  try:
1373
1434
  req = self._session.get(
1374
- "https://"
1375
- + self._token["api_url"]
1376
- + API_ENDPOINT_CAM_AUTH_CODE
1377
- + serial,
1378
- params={
1379
- "encrptPwd": "",
1380
- "msgAuthCode": "",
1381
- "senderType": 0,
1382
- },
1435
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_CAM_AUTH_CODE}{serial}",
1436
+ params=params,
1383
1437
  timeout=self._timeout,
1384
1438
  )
1385
1439
 
@@ -1389,7 +1443,9 @@ class EzvizClient:
1389
1443
  if err.response.status_code == 401:
1390
1444
  # session is wrong, need to relogin
1391
1445
  self.login()
1392
- return self.get_cam_auth_code(serial, max_retries + 1)
1446
+ return self.get_cam_auth_code(
1447
+ serial, encrypt_pwd, msg_auth_code, max_retries + 1
1448
+ )
1393
1449
 
1394
1450
  raise HTTPError from err
1395
1451
 
@@ -1419,7 +1475,7 @@ class EzvizClient:
1419
1475
 
1420
1476
  try:
1421
1477
  req = self._session.post(
1422
- "https://" + self._token["api_url"] + API_ENDPOINT_CREATE_PANORAMIC,
1478
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_CREATE_PANORAMIC}",
1423
1479
  data={"deviceSerial": serial},
1424
1480
  timeout=self._timeout,
1425
1481
  )
@@ -1467,7 +1523,7 @@ class EzvizClient:
1467
1523
 
1468
1524
  try:
1469
1525
  req = self._session.post(
1470
- "https://" + self._token["api_url"] + API_ENDPOINT_RETURN_PANORAMIC,
1526
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_RETURN_PANORAMIC}",
1471
1527
  data={"deviceSerial": serial},
1472
1528
  timeout=self._timeout,
1473
1529
  )
@@ -1522,9 +1578,7 @@ class EzvizClient:
1522
1578
 
1523
1579
  try:
1524
1580
  req = self._session.post(
1525
- "https://"
1526
- + self._token["api_url"]
1527
- + API_ENDPOINT_PANORAMIC_DEVICES_OPERATION,
1581
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_PANORAMIC_DEVICES_OPERATION}",
1528
1582
  data={
1529
1583
  "x": f"{x_axis:.6f}",
1530
1584
  "y": f"{y_axis:.6f}",
@@ -1558,9 +1612,7 @@ class EzvizClient:
1558
1612
  if self._token["session_id"] and self._token["rf_session_id"]:
1559
1613
  try:
1560
1614
  req = self._session.put(
1561
- "https://"
1562
- + self._token["api_url"]
1563
- + API_ENDPOINT_REFRESH_SESSION_ID,
1615
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_REFRESH_SESSION_ID}",
1564
1616
  data={
1565
1617
  "refreshSessionId": self._token["rf_session_id"],
1566
1618
  "featureCode": FEATURE_CODE,
@@ -1622,7 +1674,7 @@ class EzvizClient:
1622
1674
  """Close Ezviz session and remove login session from ezviz servers."""
1623
1675
  try:
1624
1676
  req = self._session.delete(
1625
- "https://" + self._token["api_url"] + API_ENDPOINT_LOGOUT,
1677
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_LOGOUT}",
1626
1678
  timeout=self._timeout,
1627
1679
  )
1628
1680
  req.raise_for_status()
@@ -1673,7 +1725,7 @@ class EzvizClient:
1673
1725
  )
1674
1726
  try:
1675
1727
  req = self._session.post(
1676
- "https://" + self._token["api_url"] + API_ENDPOINT_SET_DEFENCE_SCHEDULE,
1728
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_SET_DEFENCE_SCHEDULE}",
1677
1729
  data={
1678
1730
  "devTimingPlan": schedulestring,
1679
1731
  },
@@ -1722,10 +1774,9 @@ class EzvizClient:
1722
1774
  """Set defence mode for all devices. The alarm panel from main page is used."""
1723
1775
  if max_retries > MAX_RETRIES:
1724
1776
  raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
1725
-
1726
1777
  try:
1727
1778
  req = self._session.post(
1728
- "https://" + self._token["api_url"] + API_ENDPOINT_SWITCH_DEFENCE_MODE,
1779
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_SWITCH_DEFENCE_MODE}",
1729
1780
  data={
1730
1781
  "groupId": -1,
1731
1782
  "mode": mode,
@@ -1772,14 +1823,8 @@ class EzvizClient:
1772
1823
 
1773
1824
  try:
1774
1825
  req = self._session.put(
1775
- "https://"
1776
- + self._token["api_url"]
1777
- + API_ENDPOINT_V3_ALARMS
1778
- + serial
1779
- + "/"
1780
- + channelno
1781
- + API_ENDPOINT_DO_NOT_DISTURB,
1782
- data={"enable": enable, "channelNo": channelno, "deviceSerial": serial},
1826
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_V3_ALARMS}{serial}/{channelno}{API_ENDPOINT_DO_NOT_DISTURB}",
1827
+ data={"enable": enable},
1783
1828
  timeout=self._timeout,
1784
1829
  )
1785
1830
  req.raise_for_status()
@@ -1803,11 +1848,47 @@ class EzvizClient:
1803
1848
 
1804
1849
  return True
1805
1850
 
1851
+ def set_answer_call(
1852
+ self,
1853
+ serial: str,
1854
+ enable: int = 1,
1855
+ max_retries: int = 0,
1856
+ ) -> bool:
1857
+ """Set answer call on camera with specified serial."""
1858
+ if max_retries > MAX_RETRIES:
1859
+ raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
1860
+ try:
1861
+ req = self._session.put(
1862
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_CALLING_NOTIFY}{serial}{API_ENDPOINT_DO_NOT_DISTURB}",
1863
+ data={"deviceSerial": serial, "switchStatus": enable},
1864
+ timeout=self._timeout,
1865
+ )
1866
+ req.raise_for_status()
1867
+
1868
+ except requests.HTTPError as err:
1869
+ if err.response.status_code == 401:
1870
+ # session is wrong, need to re-log-in
1871
+ self.login()
1872
+ return self.set_answer_call(serial, enable, max_retries + 1)
1873
+
1874
+ raise HTTPError from err
1875
+
1876
+ try:
1877
+ json_output = req.json()
1878
+
1879
+ except ValueError as err:
1880
+ raise PyEzvizError("Could not decode response:" + str(err)) from err
1881
+
1882
+ if json_output["meta"]["code"] != 200:
1883
+ raise PyEzvizError(f"Could not set answer call: Got {json_output})")
1884
+
1885
+ return True
1886
+
1806
1887
  def set_floodlight_brightness(
1807
1888
  self,
1808
1889
  serial: str,
1809
1890
  luminance: int = 50,
1810
- channelno: str = "1",
1891
+ channelno: int = 1,
1811
1892
  max_retries: int = 0,
1812
1893
  ) -> bool | str:
1813
1894
  """Set brightness on camera with adjustable light."""
@@ -1821,13 +1902,7 @@ class EzvizClient:
1821
1902
 
1822
1903
  try:
1823
1904
  req = self._session.post(
1824
- "https://"
1825
- + self._token["api_url"]
1826
- + API_ENDPOINT_SET_LUMINANCE
1827
- + "/"
1828
- + serial
1829
- + "/"
1830
- + channelno,
1905
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_SET_LUMINANCE}{serial}/{channelno}",
1831
1906
  data={
1832
1907
  "luminance": luminance,
1833
1908
  },
@@ -1861,7 +1936,7 @@ class EzvizClient:
1861
1936
  self,
1862
1937
  serial: str,
1863
1938
  luminance: int = 50,
1864
- channelno: str = "1",
1939
+ channelno: int = 1,
1865
1940
  max_retries: int = 0,
1866
1941
  ) -> bool | str:
1867
1942
  """Facade that changes the brightness to light bulbs or cameras' light."""
@@ -1912,16 +1987,13 @@ class EzvizClient:
1912
1987
  raise PyEzvizError(
1913
1988
  "Unproper sensibility for type 0 (should be within 1 to 6)."
1914
1989
  )
1915
-
1916
1990
  try:
1917
1991
  req = self._session.post(
1918
- "https://"
1919
- + self._token["api_url"]
1920
- + API_ENDPOINT_DETECTION_SENSIBILITY,
1992
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_DETECTION_SENSIBILITY}",
1921
1993
  data={
1922
1994
  "subSerial": serial,
1923
1995
  "type": type_value,
1924
- "channelNo": "1",
1996
+ "channelNo": 1,
1925
1997
  "value": sensibility,
1926
1998
  },
1927
1999
  timeout=self._timeout,
@@ -1968,12 +2040,9 @@ class EzvizClient:
1968
2040
  """Get detection sensibility notifications."""
1969
2041
  if max_retries > MAX_RETRIES:
1970
2042
  raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
1971
-
1972
2043
  try:
1973
2044
  req = self._session.post(
1974
- "https://"
1975
- + self._token["api_url"]
1976
- + API_ENDPOINT_DETECTION_SENSIBILITY_GET,
2045
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_DETECTION_SENSIBILITY_GET}",
1977
2046
  data={
1978
2047
  "subSerial": serial,
1979
2048
  },
@@ -2035,11 +2104,7 @@ class EzvizClient:
2035
2104
 
2036
2105
  try:
2037
2106
  req = self._session.put(
2038
- "https://"
2039
- + self._token["api_url"]
2040
- + API_ENDPOINT_DEVICES
2041
- + serial
2042
- + API_ENDPOINT_ALARM_SOUND,
2107
+ url=f"https://{self._token['api_url']}{API_ENDPOINT_DEVICES}{serial}{API_ENDPOINT_ALARM_SOUND}",
2043
2108
  data={
2044
2109
  "enable": enable,
2045
2110
  "soundType": sound_type,
@@ -66,7 +66,7 @@ class EzvizLightBulb:
66
66
 
67
67
  return json_output
68
68
 
69
- def get_feature_item(self, key: str, default_value: Any = None) -> Any:
69
+ def get_feature_item(self, key: str, default_value: Any = { "dataValue" : "" }) -> Any:
70
70
  """Get items fron FEATURE."""
71
71
  items = self._feature_json["featureItemDtos"]
72
72
  for item in items:
@@ -114,7 +114,12 @@ def decrypt_image(input_data: bytes, password: str) -> bytes:
114
114
  return output_data
115
115
 
116
116
 
117
- def deep_merge(dict1, dict2):
117
+ def return_password_hash(password: str) -> str:
118
+ """Return the password hash."""
119
+ return md5(str.encode(md5(str.encode(password)).hexdigest())).hexdigest()
120
+
121
+
122
+ def deep_merge(dict1: Any, dict2: Any) -> Any:
118
123
  """Recursively merges two dictionaries, handling lists as well.
119
124
 
120
125
  Args:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pyezvizapi
3
- Version: 1.0.0.2
3
+ Version: 1.0.0.4
4
4
  Summary: Pilot your Ezviz cameras
5
5
  Home-page: https://github.com/RenierM26/pyEzvizApi/
6
6
  Author: Renier Moorcroft
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name='pyezvizapi',
8
- version="1.0.0.2",
8
+ version="1.0.0.4",
9
9
  license='Apache Software License 2.0',
10
10
  author='Renier Moorcroft',
11
11
  author_email='RenierM26@users.github.com',
File without changes
File without changes
File without changes
File without changes
File without changes