Skip to content

Commit bb9060b

Browse files
authored
Merge pull request #185 from sdrapha/fix_bulbs
Fix logic for setting bulb attributes when bulb is OFF
2 parents 1df3790 + 818e851 commit bb9060b

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

src/pyvesync/helpers.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
API_BASE_URL = 'https://smartapi.vesync.com'
1717
API_RATE_LIMIT = 30
18-
API_TIMEOUT = 5
18+
# If device is out of reach, the cloud api sends a timeout response after 7 seconds,
19+
# using 8 here so there is time enough to catch that message
20+
API_TIMEOUT = 8
1921
USER_AGENT = ("VeSync/3.2.39 (com.etekcity.vesyncPlatform;"
2022
" build:5; iOS 15.5.0) Alamofire/5.2.1")
2123

src/pyvesync/vesyncbulb.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -471,14 +471,18 @@ def set_status(self, brightness: Optional[NUMERIC_T] = None,
471471
if red is not None and green is not None and blue is not None:
472472
new_color = self._validate_rgb(red, green, blue)
473473
color_mode = 'color'
474-
if new_color == self._color:
474+
if self.device_status == 'on' and new_color == self._color:
475475
logger.debug("New color is same as current color")
476476
return True
477477
else:
478478
logger.debug("RGB Values not provided")
479479
new_color = None
480480
if brightness is not None:
481481
brightness_update = int(self._validate_brightness(brightness))
482+
# Do nothing if brightness is passed and same as current
483+
if self.device_status == 'on' and brightness_update == self._brightness:
484+
logger.debug('Brightness already set to %s', brightness)
485+
return True
482486
color_mode = 'white'
483487
else:
484488
logger.debug("Brightness and RGB values are not set")
@@ -627,7 +631,11 @@ def set_brightness(self, brightness: int) -> bool:
627631
logger.debug('%s is not dimmable', self.device_name)
628632
return False
629633
brightness_update = int(self._validate_brightness(brightness))
630-
634+
if self.device_status == 'on' and brightness_update == self._brightness:
635+
logger.debug("Device already in requested state")
636+
return True
637+
if self.device_status == 'off':
638+
self.toggle('on')
631639
body = helpers.req_body(self.manager, 'devicestatus')
632640
body['uuid'] = self.uuid
633641
body['status'] = 'on'
@@ -734,7 +742,8 @@ def toggle(self, status) -> bool:
734742
def set_brightness(self, brightness: int) -> bool:
735743
"""Set brightness of tunable bulb."""
736744
brightness_update = int(self._validate_brightness(brightness))
737-
if brightness_update == self._brightness:
745+
if self.device_status == 'on' and brightness_update == self._brightness:
746+
logger.debug("Device already in requested state")
738747
return True
739748
body = helpers.req_body(self.manager, 'bypass')
740749
body['cid'] = self.cid
@@ -765,7 +774,8 @@ def set_brightness(self, brightness: int) -> bool:
765774
def set_color_temp(self, color_temp: int) -> bool:
766775
"""Set Color Temperature of Bulb in pct (1 - 100)."""
767776
color_temp_update = self._validate_color_temp(color_temp)
768-
if color_temp_update == self._color_temp:
777+
if self.device_status == 'on' and color_temp_update == self._color_temp:
778+
logger.debug("Device already in requested state")
769779
return True
770780
body = helpers.req_body(self.manager, 'bypass')
771781
body['cid'] = self.cid
@@ -844,7 +854,8 @@ def _interpret_apicall_result(self, response) -> None:
844854
sat = float(innerresult.get('saturation')/100)
845855
val = float(innerresult.get('value'))
846856
self._color = Color(hue=hue, saturation=sat, value=val)
847-
elif response.get('code') == -11300030:
857+
elif (response.get('code') == -11300030 or
858+
response.get('code') == -11302030):
848859
logger.debug('%s device request timeout', self.device_name)
849860
self.connection_status = 'offline'
850861
self.device_status = 'off'
@@ -1001,7 +1012,7 @@ def set_hsv(self, hue: NUMERIC_T = None,
10011012
if val != "":
10021013
if val != current_dict[key]:
10031014
same_colors = False
1004-
if same_colors:
1015+
if self.device_status == 'on' and same_colors:
10051016
logger.debug("Device already in requested state")
10061017
return True
10071018
for key, val in arg_dict.items():
@@ -1084,7 +1095,7 @@ def set_status(self,
10841095
if all(locals().get(k) is None for k in force_list):
10851096

10861097
# Do nothing if brightness is passed and same as current
1087-
if brightness_update == self._brightness:
1098+
if self.device_status == 'on' and brightness_update == self._brightness:
10881099
logger.debug('Brightness already set to %s', brightness)
10891100
return True
10901101
request_dict['force'] = 0

src/tests/test_x_vesync_bulbs.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ def test_brightness(self):
7777
self.mock_api.return_value = ({'code': 0}, 200)
7878
bulb = VeSyncBulbESL100(DEV_LIST_DETAIL, self.manager)
7979
assert bulb.set_brightness(50)
80+
assert bulb.turn_off()
81+
assert bulb.set_brightness(50)
82+
assert bulb.device_status == 'on'
8083

8184
def test_invalid_brightness(self):
8285
self.mock_api.return_value = ({'code': 0}, 200)
@@ -137,6 +140,9 @@ def test_brightness(self):
137140
bulb = VeSyncBulbESL100CW(DEV_LIST_DETAIL_CW, self.manager)
138141
assert bulb.set_brightness(50)
139142
assert bulb.brightness == 50
143+
assert bulb.turn_off()
144+
assert bulb.set_brightness(50)
145+
assert bulb.device_status == 'on'
140146

141147
def test_invalid_brightness(self):
142148
self.mock_api.return_value = ({'code': 0}, 200)
@@ -197,6 +203,9 @@ def test_brightness(self):
197203
bulb = VeSyncBulbESL100MC(DEV_LIST_DETAIL_MC, self.manager)
198204
assert bulb.set_brightness(50)
199205
assert bulb.brightness == 50
206+
assert bulb.turn_off()
207+
assert bulb.set_brightness(50)
208+
assert bulb.device_status == 'on'
200209

201210
def test_invalid_brightness(self):
202211
self.mock_api.return_value = ({'code': 0}, 200)
@@ -258,6 +267,9 @@ def test_brightness(self):
258267
bulb = VeSyncBulbValcenoA19MC(DEV_LIST_DETAIL_VALCENO, self.manager)
259268
assert bulb.set_brightness(50)
260269
assert bulb.brightness == 50
270+
assert bulb.turn_off()
271+
assert bulb.set_brightness(50)
272+
assert bulb.device_status == 'on'
261273

262274
def test_invalid_brightness(self):
263275
"""Test invalid brightness on Valceno."""

tox.ini

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
[tox]
2-
envlist = py39, pylint, lint, mypy
2+
envlist = py311, py310, py39, py38, pylint, lint, mypy
33
skip_missing_interpreters = True
44
ignore_basepython_conflict = True
55

66
[testenv]
7-
basepython = {env:PYTHON3_PATH:python39}
87
deps =
98
pytest
109
pyyaml

0 commit comments

Comments
 (0)