Skip to content

Commit

Permalink
Fix display & enabled/disabled bug
Browse files Browse the repository at this point in the history
  • Loading branch information
webdjoe committed Aug 9, 2023
1 parent 85fe110 commit fac605a
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 35 deletions.
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
include README.md LICENSE requirements.txt
exclude test
prune test
5 changes: 2 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

setup(
name='pyvesync',
version='2.1.8',
version='2.1.9',
description='pyvesync is a library to manage Etekcity\
Devices, Cosori Air Fryers and Levoit Air \
Purifiers run on the VeSync app.',
Expand All @@ -28,9 +28,8 @@
'Programming Language :: Python :: 3.8',
],
keywords=['iot', 'vesync', 'levoit', 'etekcity', 'cosori', 'valceno'],
packages=find_packages('src', exclude=['tests', 'tests.*']),
packages=find_packages('src', exclude=['tests', 'test*']),
package_dir={'': 'src'},
zip_safe=False,
install_requires=['requests>=2.20.0'],
extras_require={
'dev': ['pytest', 'pytest-cov', 'yaml', 'tox']
Expand Down
13 changes: 13 additions & 0 deletions src/pyvesync/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,19 @@ def redactor(cls, stringvalue: str) -> str:
'##_REDACTED_##', stringvalue)
return stringvalue

@staticmethod
def nested_code_check(response: dict) -> bool:
"""Return true if all code values are 0."""
if isinstance(response, dict):
for key, value in response.items():
if key == 'code':
if value != 0:
return False
elif isinstance(value, dict):
if not Helpers.nested_code_check(value):
return False
return True

@staticmethod
def call_api(api: str, method: str, json_object: Optional[dict] = None,
headers: Optional[dict] = None) -> tuple:
Expand Down
78 changes: 46 additions & 32 deletions src/pyvesync/vesyncfan.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
'module': 'VeSyncVital',
'models': ['LAP-V102S-AASR', 'LAP-V102S-WUS', 'LAP-V102S-WEU',
'LAP-V102S-AUSR', 'LAP-V102S-WJP'],
'modes': ['manual', 'auto', 'sleep', 'off'],
'modes': ['manual', 'auto', 'sleep', 'off', 'pet'],
'features': ['air_quality'],
'levels': list(range(1, 5))
},
Expand Down Expand Up @@ -768,29 +768,20 @@ def get_details(self) -> None:
headers=head,
json_object=body,
)
if not isinstance(r, dict):
logger.debug('Error in purifier response')
if Helpers.nested_code_check(r) is False or not isinstance(r, dict):
logger.debug('Error getting purifier details')
self.connection_status = 'offline'
return
if not isinstance(r.get('result'), dict):
logger.debug('Error in purifier response')
return
outer_result = r.get('result', {})
inner_result = None

if outer_result:
inner_result = r.get('result', {}).get('result')
if inner_result is not None and Helpers.code_check(r):
if outer_result.get('code') == 0:
self.build_purifier_dict(inner_result)
else:
self.online = False
logger.debug('error in inner result dict from purifier')
if inner_result.get('configuration', {}):
self.build_config_dict(inner_result.get('configuration', {}))
else:
logger.debug('No configuration found in purifier status')
inner_result = r.get('result', {}).get('result')

if inner_result is not None:
self.build_purifier_dict(inner_result)
else:
logger.debug('Error in purifier response')
self.connection_status = 'offline'
logger.debug('error in inner result dict from purifier')
if inner_result.get('configuration', {}):
self.build_config_dict(inner_result.get('configuration', {}))

def build_api_dict(self, method: str) -> Tuple[Dict, Dict]:
"""Return default body for Levoit Vital 100S/200S API."""
Expand All @@ -809,7 +800,7 @@ def build_api_dict(self, method: str) -> Tuple[Dict, Dict]:

def build_purifier_dict(self, dev_dict: dict) -> None:
"""Build Bypass purifier status dictionary."""
self.online = True
self.connection_status = 'online'
power_switch = bool(dev_dict.get('powerSwitch', 0))
self.enabled = power_switch
self.device_status = 'on' if power_switch is True else 'off'
Expand Down Expand Up @@ -846,10 +837,7 @@ def pet_mode(self) -> bool:

def set_light_detection(self, toggle: bool) -> bool:
"""Enable/Disable Light Detection Feature."""
if toggle is True:
toggle_id = 1
else:
toggle_id = 0
toggle_id = int(toggle)
if self.details['light_detection_switch'] == toggle_id:
logger.debug("Light Detection is already set to %s", toggle_id)
return True
Expand All @@ -863,7 +851,7 @@ def set_light_detection(self, toggle: bool) -> bool:
json_object=body,
)

if r is not None and Helpers.code_check(r):
if r is not None and Helpers.nested_code_check(r):
self.details['light_detection'] = toggle
return True
logger.debug("Error toggling purifier - %s",
Expand Down Expand Up @@ -901,7 +889,7 @@ def toggle_switch(self, toggle: bool) -> bool:
json_object=body,
)

if r is not None and Helpers.code_check(r):
if r is not None and Helpers.nested_code_check(r):
if toggle:
self.device_status = 'on'
else:
Expand Down Expand Up @@ -929,7 +917,7 @@ def set_child_lock(self, mode: bool) -> bool:
json_object=body,
)

if r is not None and Helpers.code_check(r):
if r is not None and Helpers.nested_code_check(r):
self.details['child_lock'] = mode
return True

Expand All @@ -954,7 +942,7 @@ def set_display(self, mode: bool) -> bool:
json_object=body,
)

if r is not None and Helpers.code_check(r):
if r is not None and Helpers.nested_code_check(r):
self.details['screen_switch'] = mode
return True

Expand Down Expand Up @@ -1004,7 +992,7 @@ def set_timer(self, timer_duration: int, action: str = 'off',
json_object=body,
)

if r is not None and Helpers.code_check(r):
if r is not None and Helpers.nested_code_check(r):
self.timer = Timer(timer_duration, action)
return True

Expand All @@ -1024,7 +1012,7 @@ def clear_timer(self) -> bool:
json_object=body,
)

if r is not None and Helpers.code_check(r):
if r is not None and Helpers.nested_code_check(r):
self.timer = None
return True

Expand Down Expand Up @@ -1164,6 +1152,32 @@ def mode_toggle(self, mode: str) -> bool:
logger.debug('Error setting purifier mode')
return False

def displayJSON(self) -> str:
"""Return air purifier status and properties in JSON output."""
sup = super().displayJSON()
sup_val = json.loads(sup)
sup_val.update(
{
'Mode': self.mode,
'Filter Life': str(self.details['filter_life']),
'Fan Level': str(self.speed),
'Display On': self.details['display'],
'Child Lock': self.details['child_lock'],
'Night Light': str(self.details['night_light']),
'Display Set On': self.details['screen_switch'],
'Light Detection Enabled': self.details['light_detection_switch'],
'Environment Light State': self.details['environment_light_state']
}
)
if self.air_quality_feature is True:
sup_val.update(
{'Air Quality Level': str(self.details.get('air_quality', ''))}
)
sup_val.update(
{'Air Quality Value': str(self.details.get('air_quality_value', ''))}
)
return json.dumps(sup_val, indent=4)


class VeSyncAir131(VeSyncBaseDevice):
"""Levoit Air Purifier Class."""
Expand Down

0 comments on commit fac605a

Please sign in to comment.