pyezvizapi 1.0.2.8__tar.gz → 1.0.3.0__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 (27) hide show
  1. {pyezvizapi-1.0.2.8/pyezvizapi.egg-info → pyezvizapi-1.0.3.0}/PKG-INFO +1 -1
  2. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/api_endpoints.py +1 -0
  3. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/client.py +132 -30
  4. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/constants.py +6 -0
  5. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0/pyezvizapi.egg-info}/PKG-INFO +1 -1
  6. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/setup.py +1 -1
  7. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/LICENSE +0 -0
  8. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/LICENSE.md +0 -0
  9. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/MANIFEST.in +0 -0
  10. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/README.md +0 -0
  11. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/__init__.py +0 -0
  12. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/__main__.py +0 -0
  13. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/camera.py +0 -0
  14. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/cas.py +0 -0
  15. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/exceptions.py +0 -0
  16. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/light_bulb.py +0 -0
  17. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/models.py +0 -0
  18. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/mqtt.py +0 -0
  19. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/test_cam_rtsp.py +0 -0
  20. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/test_mqtt.py +0 -0
  21. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi/utils.py +0 -0
  22. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi.egg-info/SOURCES.txt +0 -0
  23. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi.egg-info/dependency_links.txt +0 -0
  24. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi.egg-info/entry_points.txt +0 -0
  25. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi.egg-info/requires.txt +0 -0
  26. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/pyezvizapi.egg-info/top_level.txt +0 -0
  27. {pyezvizapi-1.0.2.8 → pyezvizapi-1.0.3.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyezvizapi
3
- Version: 1.0.2.8
3
+ Version: 1.0.3.0
4
4
  Summary: Pilot your Ezviz cameras
5
5
  Home-page: https://github.com/RenierM26/pyEzvizApi/
6
6
  Author: Renier Moorcroft
@@ -39,6 +39,7 @@ API_ENDPOINT_DETECTION_SENSIBILITY = "/api/device/configAlgorithm"
39
39
  API_ENDPOINT_DETECTION_SENSIBILITY_GET = "/api/device/queryAlgorithmConfig"
40
40
  API_ENDPOINT_SENSITIVITY = "/v3/devconfig/v1/sensitivity/"
41
41
  API_ENDPOINT_SET_DEFENCE_SCHEDULE = "/api/device/defence/plan2"
42
+ API_ENDPOINT_DEVICE_SWITCH_STATUS_LEGACY = "/api/device/switchStatus"
42
43
  API_ENDPOINT_CAM_ENCRYPTKEY = "/api/device/query/encryptkey"
43
44
  API_ENDPOINT_OFFLINE_NOTIFY = "/api/device/notify/switch"
44
45
  API_ENDPOINT_CANCEL_ALARM = "/api/device/cancelAlarm"
@@ -2,13 +2,12 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from collections.abc import Callable
5
+ from collections.abc import Callable, Mapping
6
6
  from datetime import datetime
7
7
  import hashlib
8
8
  import json
9
9
  import logging
10
10
  from typing import Any, ClassVar, TypedDict, cast
11
- import urllib.parse
12
11
  from uuid import uuid4
13
12
 
14
13
  import requests
@@ -28,6 +27,7 @@ from .api_endpoints import (
28
27
  API_ENDPOINT_DEVCONFIG_BY_KEY,
29
28
  API_ENDPOINT_DEVICE_BASICS,
30
29
  API_ENDPOINT_DEVICE_STORAGE_STATUS,
30
+ API_ENDPOINT_DEVICE_SWITCH_STATUS_LEGACY,
31
31
  API_ENDPOINT_DEVICE_SYS_OPERATION,
32
32
  API_ENDPOINT_DEVICES,
33
33
  API_ENDPOINT_DO_NOT_DISTURB,
@@ -648,26 +648,103 @@ class EzvizClient:
648
648
  self._ensure_ok(json_output, "Could not get unified message list")
649
649
  return json_output
650
650
 
651
+ def set_switch_v3(
652
+ self,
653
+ serial: str,
654
+ switch_type: int,
655
+ enable: bool | int,
656
+ channel: int = 0,
657
+ max_retries: int = 0,
658
+ ) -> dict:
659
+ """Update a device switch via the v3 endpoint."""
660
+
661
+ if max_retries > MAX_RETRIES:
662
+ raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
663
+
664
+ enable_flag = 1 if bool(enable) else 0
665
+ path = (
666
+ f"{API_ENDPOINT_DEVICES}{serial}/{channel}/{enable_flag}/"
667
+ f"{switch_type}{API_ENDPOINT_SWITCH_STATUS}"
668
+ )
669
+ payload = self._request_json(
670
+ "PUT",
671
+ path,
672
+ retry_401=True,
673
+ max_retries=max_retries,
674
+ )
675
+ self._ensure_ok(payload, "Could not set the switch")
676
+ return payload
677
+
678
+ def set_switch_legacy(
679
+ self,
680
+ serial: str,
681
+ switch_type: int,
682
+ enable: bool | int,
683
+ channel: int = 0,
684
+ max_retries: int = 0,
685
+ ) -> dict:
686
+ """Fallback legacy switch endpoint used by older firmware."""
687
+
688
+ if max_retries > MAX_RETRIES:
689
+ raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
690
+
691
+ payload = self._request_json(
692
+ "POST",
693
+ API_ENDPOINT_DEVICE_SWITCH_STATUS_LEGACY,
694
+ data={
695
+ "serial": serial,
696
+ "enable": "1" if bool(enable) else "0",
697
+ "type": str(switch_type),
698
+ "channel": str(channel),
699
+ },
700
+ retry_401=True,
701
+ max_retries=max_retries,
702
+ )
703
+ self._ensure_ok(payload, "Could not set the switch (legacy)")
704
+ return payload
705
+
706
+ def set_switch(
707
+ self,
708
+ serial: str,
709
+ switch_type: int,
710
+ enable: bool | int,
711
+ channel: int = 0,
712
+ max_retries: int = 0,
713
+ ) -> dict:
714
+ """Try the v3 switch endpoint, falling back to the legacy API if needed."""
715
+
716
+ try:
717
+ return self.set_switch_v3(
718
+ serial, switch_type, enable, channel, max_retries=max_retries
719
+ )
720
+ except PyEzvizError as first_error:
721
+ try:
722
+ return self.set_switch_legacy(
723
+ serial, switch_type, enable, channel, max_retries=max_retries
724
+ )
725
+ except PyEzvizError:
726
+ raise first_error from None
727
+
651
728
  def switch_status(
652
729
  self,
653
730
  serial: str,
654
731
  status_type: int,
655
- enable: int,
732
+ enable: bool | int,
656
733
  channel_no: int = 0,
657
734
  max_retries: int = 0,
658
735
  ) -> bool:
659
736
  """Camera features are represented as switches. Switch them on or off."""
660
- if max_retries > MAX_RETRIES:
661
- raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
662
- json_output = self._request_json(
663
- "PUT",
664
- f"{API_ENDPOINT_DEVICES}{serial}/{channel_no}/{enable}/{status_type}{API_ENDPOINT_SWITCH_STATUS}",
665
- retry_401=True,
737
+
738
+ target_state = bool(enable)
739
+ self.set_switch(
740
+ serial,
741
+ status_type,
742
+ target_state,
743
+ channel=channel_no,
666
744
  max_retries=max_retries,
667
745
  )
668
- self._ensure_ok(json_output, "Could not set the switch")
669
746
  if self._cameras.get(serial):
670
- self._cameras[serial]["switches"][status_type] = bool(enable)
747
+ self._cameras[serial]["switches"][status_type] = target_state
671
748
  return True
672
749
 
673
750
  def switch_status_other(
@@ -793,36 +870,61 @@ class EzvizClient:
793
870
  serial, value=f'{{"mode":{mode}}}', key="display_mode"
794
871
  )
795
872
 
796
- def set_device_config_by_key(
873
+ def set_dev_config_kv(
797
874
  self,
798
875
  serial: str,
799
- value: Any,
876
+ channel: int,
800
877
  key: str,
878
+ value: Mapping[str, Any] | str | bytes | float | bool,
801
879
  max_retries: int = 0,
802
- ) -> bool:
803
- """Change value on device by setting key."""
880
+ ) -> dict:
881
+ """Update a device configuration key/value pair via devconfig."""
882
+
804
883
  if max_retries > MAX_RETRIES:
805
884
  raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
806
885
 
807
- params = {"key": key, "value": value}
808
- params_str = urllib.parse.urlencode(
809
- params, safe="}{:"
810
- ) # not encode curly braces and colon
886
+ if isinstance(value, Mapping):
887
+ value_payload = json.dumps(value, separators=(",", ":"))
888
+ elif isinstance(value, bytes):
889
+ value_payload = value.decode()
890
+ elif isinstance(value, bool):
891
+ value_payload = "1" if value else "0"
892
+ elif isinstance(value, (int, float)):
893
+ value_payload = str(value)
894
+ else:
895
+ value_payload = str(value)
811
896
 
812
- full_url = f"https://{self._token['api_url']}{API_ENDPOINT_DEVCONFIG_BY_KEY}{serial}/1/op"
897
+ data = {
898
+ "key": key,
899
+ "value": value_payload,
900
+ }
813
901
 
814
- # EZVIZ api request needs {}: in the url, but requests lib doesn't allow it
815
- # so we need to manually prepare it
816
- req_prep = requests.Request(
817
- method="PUT", url=full_url, headers=self._session.headers
818
- ).prepare()
819
- req_prep.url = full_url + "?" + params_str
902
+ payload = self._request_json(
903
+ "PUT",
904
+ f"{API_ENDPOINT_DEVCONFIG_BY_KEY}{serial}/{channel}/op",
905
+ data=data,
906
+ retry_401=True,
907
+ max_retries=max_retries,
908
+ )
909
+ self._ensure_ok(payload, "Could not set devconfig key")
910
+ return payload
820
911
 
821
- req = self._send_prepared(req_prep, retry_401=True, max_retries=max_retries)
822
- json_output = self._parse_json(req)
823
- if not self._meta_ok(json_output):
824
- raise PyEzvizError(f"Could not set config key '${key}': Got {json_output})")
912
+ def set_device_config_by_key(
913
+ self,
914
+ serial: str,
915
+ value: Any,
916
+ key: str,
917
+ max_retries: int = 0,
918
+ ) -> bool:
919
+ """Change value on device by setting key."""
825
920
 
921
+ self.set_dev_config_kv(
922
+ serial,
923
+ 1,
924
+ key,
925
+ value,
926
+ max_retries=max_retries,
927
+ )
826
928
  return True
827
929
 
828
930
  def set_device_feature_by_key(
@@ -84,11 +84,14 @@ class DeviceSwitchType(Enum):
84
84
  TAMPER_ALARM = 306
85
85
  DETECTION_TYPE = 451
86
86
  OUTLET_RECOVER = 600
87
+ WIDE_DYNAMIC_RANGE = 604
87
88
  CHIME_INDICATOR_LIGHT = 611
89
+ DISTORTION_CORRECTION = 617
88
90
  TRACKING = 650
89
91
  CRUISE_TRACKING = 651
90
92
  PARTIAL_IMAGE_OPTIMIZE = 700
91
93
  FEATURE_TRACKING = 701
94
+ LOGO_WATERMARK = 702
92
95
 
93
96
 
94
97
  @unique
@@ -173,6 +176,7 @@ class SupportExt(Enum):
173
176
  SupportDisk = 4
174
177
  SupportDiskBlackList = 367
175
178
  SupportDistributionNetworkBetweenDevice = 420
179
+ SupportDistortionCorrection = 490
176
180
  SupportDisturbMode = 217
177
181
  SupportDisturbNewMode = 292
178
182
  SupportDoorCallPlayBack = 545
@@ -221,6 +225,7 @@ class SupportExt(Enum):
221
225
  SupportLightRelate = 297
222
226
  SupportLocalConnect = 507
223
227
  SupportLocalLockGate = 662
228
+ SupportLogoWatermark = 632
224
229
  SupportLockConfigWay = 679
225
230
  SupportMessage = 6
226
231
  SupportMicroVolumnSet = 77
@@ -329,6 +334,7 @@ class SupportExt(Enum):
329
334
  SupportSleep = 62
330
335
  SupportSmartBodyDetect = 244
331
336
  SupportSmartNightVision = 274
337
+ SupportWideDynamicRange = 273
332
338
  SupportSoundLightAlarm = 214
333
339
  SupportSsl = 25
334
340
  SupportStopRecordVideo = 219
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyezvizapi
3
- Version: 1.0.2.8
3
+ Version: 1.0.3.0
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.2.8",
8
+ version="1.0.3.0",
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