pyvesync 2.1.15__tar.gz → 2.1.17__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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: pyvesync
3
- Version: 2.1.15
3
+ Version: 2.1.17
4
4
  Summary: pyvesync is a library to manage Etekcity Devices, Cosori Air Fryers and Levoit Air Purifiers run on the VeSync app.
5
5
  Home-page: https://github.com/webdjoe/pyvesync
6
6
  Author: Mark Perdue, Joe Trabulsy
@@ -24,6 +24,18 @@ Requires-Dist: pytest; extra == "dev"
24
24
  Requires-Dist: pytest-cov; extra == "dev"
25
25
  Requires-Dist: pyyaml; extra == "dev"
26
26
  Requires-Dist: tox; extra == "dev"
27
+ Dynamic: author
28
+ Dynamic: author-email
29
+ Dynamic: classifier
30
+ Dynamic: description
31
+ Dynamic: description-content-type
32
+ Dynamic: home-page
33
+ Dynamic: keywords
34
+ Dynamic: license
35
+ Dynamic: provides-extra
36
+ Dynamic: requires-dist
37
+ Dynamic: requires-python
38
+ Dynamic: summary
27
39
 
28
40
  # pyvesync [![build status](https://img.shields.io/pypi/v/pyvesync.svg)](https://pypi.python.org/pypi/pyvesync) [![Build Status](https://dev.azure.com/webdjoe/pyvesync/_apis/build/status/webdjoe.pyvesync?branchName=master)](https://dev.azure.com/webdjoe/pyvesync/_build/latest?definitionId=4&branchName=master) [![Open Source? Yes!](https://badgen.net/badge/Open%20Source%20%3F/Yes%21/blue?icon=github)](https://github.com/Naereen/badges/) [![PyPI license](https://img.shields.io/pypi/l/ansicolortags.svg)](https://pypi.python.org/pypi/ansicolortags/) <!-- omit in toc -->
29
41
 
@@ -10,7 +10,7 @@ with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
10
10
 
11
11
  setup(
12
12
  name='pyvesync',
13
- version='2.1.15',
13
+ version='2.1.17',
14
14
  description='pyvesync is a library to manage Etekcity\
15
15
  Devices, Cosori Air Fryers and Levoit Air \
16
16
  Purifiers run on the VeSync app.',
@@ -119,7 +119,9 @@ air_features: dict = {
119
119
  'LV-PUR131S': {
120
120
  'module': 'VeSyncAir131',
121
121
  'models': ['LV-PUR131S', 'LV-RH131S'],
122
- 'features': ['air_quality']
122
+ 'modes': ['manual', 'auto', 'sleep', 'off'],
123
+ 'features': ['air_quality'],
124
+ 'levels': list(range(1, 3))
123
125
  },
124
126
  'Vital100S': {
125
127
  'module': 'VeSyncAirBaseV2',
@@ -1571,7 +1573,19 @@ class VeSyncAir131(VeSyncBaseDevice):
1571
1573
  def __init__(self, details, manager):
1572
1574
  """Initilize air purifier class."""
1573
1575
  super().__init__(details, manager)
1574
-
1576
+ self.enabled = True
1577
+ self._config_dict = model_features(self.device_type)
1578
+ self._features = self._config_dict.get('features', [])
1579
+ if not isinstance(self._config_dict.get('modes'), list):
1580
+ logger.error(
1581
+ 'Please set modes for %s in the configuration',
1582
+ self.device_type)
1583
+ raise KeyError(f'Modes not set in configuration for {self.device_name}')
1584
+ self.modes = self._config_dict['modes']
1585
+ if 'air_quality' in self._features:
1586
+ self.air_quality_feature = True
1587
+ else:
1588
+ self.air_quality_feature = False
1575
1589
  self.details = {}
1576
1590
 
1577
1591
  def get_details(self) -> None:
@@ -1986,6 +2000,8 @@ class VeSyncHumid200300S(VeSyncBaseDevice):
1986
2000
  def build_humid_dict(self, dev_dict: Dict[str, str]) -> None:
1987
2001
  """Build humidifier status dictionary."""
1988
2002
  self.enabled = dev_dict.get('enabled')
2003
+ self.device_status = 'on' if self.enabled else 'off'
2004
+ self.mode = dev_dict.get('mode', None)
1989
2005
  self.details['humidity'] = dev_dict.get('humidity', 0)
1990
2006
  self.details['mist_virtual_level'] = dev_dict.get(
1991
2007
  'mist_virtual_level', 0)
@@ -2795,6 +2811,12 @@ class VeSyncSuperior6000S(VeSyncBaseDevice):
2795
2811
  """Get Humidity level."""
2796
2812
  return self.details['humidity']
2797
2813
 
2814
+ # Duplicate for compatibility
2815
+ @property
2816
+ def humidity(self):
2817
+ """Get Humidity level."""
2818
+ return self.details['humidity']
2819
+
2798
2820
  @property
2799
2821
  def mist_level(self):
2800
2822
  """Get current mist level."""
@@ -2853,6 +2875,11 @@ class VeSyncSuperior6000S(VeSyncBaseDevice):
2853
2875
  """Current temperature."""
2854
2876
  return self.details['temperature']
2855
2877
 
2878
+ @property
2879
+ def auto_humidity(self):
2880
+ """Auto target humidity."""
2881
+ return self.config['target_humidity']
2882
+
2856
2883
  @property
2857
2884
  def target_humidity(self):
2858
2885
  """The target humidity when in humidity mode."""
@@ -21,6 +21,8 @@ outlet_config = {
21
21
  'module': 'VeSyncOutlet15A'},
22
22
  'ESO15-TB': {
23
23
  'module': 'VeSyncOutdoorPlug'},
24
+ 'BSDOG01': {
25
+ 'module': 'VeSyncOutletBSDGO1'},
24
26
  }
25
27
 
26
28
  outlet_modules = {k: v['module'] for k, v in outlet_config.items()}
@@ -573,7 +575,6 @@ class VeSyncOutlet15A(VeSyncOutlet):
573
575
  if Helpers.code_check(response):
574
576
  self.device_status = 'off'
575
577
  return True
576
-
577
578
  logger.warning('Error turning %s off', self.device_name)
578
579
  return False
579
580
 
@@ -733,9 +734,73 @@ class VeSyncOutdoorPlug(VeSyncOutlet):
733
734
  return False
734
735
 
735
736
  def turn_on(self) -> bool:
736
- """Turn outdoor outlet on and return True if successful."""
737
+ """Turn on outlet."""
737
738
  return bool(self.toggle('on'))
738
739
 
739
740
  def turn_off(self) -> bool:
740
- """Turn outdoor outlet off and return True if successful."""
741
+ """Turn off outlet."""
741
742
  return bool(self.toggle('off'))
743
+
744
+
745
+ class VeSyncOutletBSDGO1(VeSyncOutlet):
746
+ """VeSync BSDGO1 smart plug."""
747
+
748
+ def __init__(self, details, manager):
749
+ """Initialize BSDGO1 smart plug class."""
750
+ super().__init__(details, manager)
751
+
752
+ def get_details(self) -> None:
753
+ """Get BSDGO1 device details."""
754
+ body = Helpers.req_body(self.manager, 'bypassV2')
755
+ body['cid'] = self.cid
756
+ body['configModule'] = self.config_module
757
+ body['payload'] = {
758
+ 'method': 'getProperty',
759
+ 'source': 'APP',
760
+ 'data': {}
761
+ }
762
+
763
+ r, _ = Helpers.call_api(
764
+ '/cloud/v2/deviceManaged/bypassV2',
765
+ 'post',
766
+ headers=Helpers.req_header_bypass(),
767
+ json_object=body,
768
+ )
769
+
770
+ if Helpers.code_check(r):
771
+ self.device_status = 'on' if r.get('result', {}).get(
772
+ 'powerSwitch_1') == 1 else 'off'
773
+ else:
774
+ logger.debug('Error getting %s details', self.device_name)
775
+
776
+ def turn_on(self) -> bool:
777
+ """Turn BSDGO1 outlet on."""
778
+ return self._set_power(True)
779
+
780
+ def turn_off(self) -> bool:
781
+ """Turn BSDGO1 outlet off."""
782
+ return self._set_power(False)
783
+
784
+ def _set_power(self, power: bool) -> bool:
785
+ """Set power state of BSDGO1 outlet."""
786
+ body = Helpers.req_body(self.manager, 'bypassV2')
787
+ body['cid'] = self.cid
788
+ body['configModule'] = self.config_module
789
+ body['payload'] = {
790
+ 'data': {'powerSwitch_1': 1 if power else 0},
791
+ 'method': 'setProperty',
792
+ 'source': 'APP'
793
+ }
794
+
795
+ r, _ = Helpers.call_api(
796
+ '/cloud/v2/deviceManaged/bypassV2',
797
+ 'post',
798
+ headers=Helpers.req_header_bypass(),
799
+ json_object=body,
800
+ )
801
+
802
+ if Helpers.code_check(r):
803
+ self.device_status = 'on' if power else 'off'
804
+ return True
805
+ logger.warning('Error turning %s %s', self.device_name, 'on' if power else 'off')
806
+ return False
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: pyvesync
3
- Version: 2.1.15
3
+ Version: 2.1.17
4
4
  Summary: pyvesync is a library to manage Etekcity Devices, Cosori Air Fryers and Levoit Air Purifiers run on the VeSync app.
5
5
  Home-page: https://github.com/webdjoe/pyvesync
6
6
  Author: Mark Perdue, Joe Trabulsy
@@ -24,6 +24,18 @@ Requires-Dist: pytest; extra == "dev"
24
24
  Requires-Dist: pytest-cov; extra == "dev"
25
25
  Requires-Dist: pyyaml; extra == "dev"
26
26
  Requires-Dist: tox; extra == "dev"
27
+ Dynamic: author
28
+ Dynamic: author-email
29
+ Dynamic: classifier
30
+ Dynamic: description
31
+ Dynamic: description-content-type
32
+ Dynamic: home-page
33
+ Dynamic: keywords
34
+ Dynamic: license
35
+ Dynamic: provides-extra
36
+ Dynamic: requires-dist
37
+ Dynamic: requires-python
38
+ Dynamic: summary
27
39
 
28
40
  # pyvesync [![build status](https://img.shields.io/pypi/v/pyvesync.svg)](https://pypi.python.org/pypi/pyvesync) [![Build Status](https://dev.azure.com/webdjoe/pyvesync/_apis/build/status/webdjoe.pyvesync?branchName=master)](https://dev.azure.com/webdjoe/pyvesync/_build/latest?definitionId=4&branchName=master) [![Open Source? Yes!](https://badgen.net/badge/Open%20Source%20%3F/Yes%21/blue?icon=github)](https://github.com/Naereen/badges/) [![PyPI license](https://img.shields.io/pypi/l/ansicolortags.svg)](https://pypi.python.org/pypi/ansicolortags/) <!-- omit in toc -->
29
41
 
File without changes
File without changes
File without changes
File without changes
File without changes