mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 19:23:34 +00:00
Bulbs: allow specifying transition for state changes (#70)
All state changing functions now allow defining transition time in milliseconds
This commit is contained in:
parent
dd073fa8c8
commit
99e0c4a418
@ -142,8 +142,11 @@ class SmartBulb(SmartDevice):
|
|||||||
# TODO: add warning and refer to use light.state?
|
# TODO: add warning and refer to use light.state?
|
||||||
return await self._query_helper(self.LIGHT_SERVICE, "get_light_state")
|
return await self._query_helper(self.LIGHT_SERVICE, "get_light_state")
|
||||||
|
|
||||||
async def set_light_state(self, state: Dict) -> Dict:
|
async def set_light_state(self, state: Dict, *, transition: int = None) -> Dict:
|
||||||
"""Set the light state."""
|
"""Set the light state."""
|
||||||
|
if transition is not None:
|
||||||
|
state["transition_period"] = transition
|
||||||
|
|
||||||
light_state = await self._query_helper(
|
light_state = await self._query_helper(
|
||||||
self.LIGHT_SERVICE, "transition_light_state", state
|
self.LIGHT_SERVICE, "transition_light_state", state
|
||||||
)
|
)
|
||||||
@ -174,12 +177,15 @@ class SmartBulb(SmartDevice):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@requires_update
|
@requires_update
|
||||||
async def set_hsv(self, hue: int, saturation: int, value: int):
|
async def set_hsv(
|
||||||
|
self, hue: int, saturation: int, value: int, *, transition: int = None
|
||||||
|
) -> Dict:
|
||||||
"""Set new HSV.
|
"""Set new HSV.
|
||||||
|
|
||||||
:param int hue: hue in degrees
|
:param int hue: hue in degrees
|
||||||
:param int saturation: saturation in percentage [0,100]
|
:param int saturation: saturation in percentage [0,100]
|
||||||
:param int value: value in percentage [0, 100]
|
:param int value: value in percentage [0, 100]
|
||||||
|
:param int transition: transition in milliseconds.
|
||||||
"""
|
"""
|
||||||
if not self.is_color:
|
if not self.is_color:
|
||||||
raise SmartDeviceException("Bulb does not support color.")
|
raise SmartDeviceException("Bulb does not support color.")
|
||||||
@ -203,7 +209,8 @@ class SmartBulb(SmartDevice):
|
|||||||
"brightness": value,
|
"brightness": value,
|
||||||
"color_temp": 0,
|
"color_temp": 0,
|
||||||
}
|
}
|
||||||
await self.set_light_state(light_state)
|
|
||||||
|
return await self.set_light_state(light_state, transition=transition)
|
||||||
|
|
||||||
@property # type: ignore
|
@property # type: ignore
|
||||||
@requires_update
|
@requires_update
|
||||||
@ -216,8 +223,12 @@ class SmartBulb(SmartDevice):
|
|||||||
return int(light_state["color_temp"])
|
return int(light_state["color_temp"])
|
||||||
|
|
||||||
@requires_update
|
@requires_update
|
||||||
async def set_color_temp(self, temp: int) -> None:
|
async def set_color_temp(self, temp: int, *, transition: int = None) -> Dict:
|
||||||
"""Set the color temperature of the device in kelvin."""
|
"""Set the color temperature of the device in kelvin.
|
||||||
|
|
||||||
|
:param int temp: The new color temperature, in Kelvin
|
||||||
|
:param int transition: transition in milliseconds.
|
||||||
|
"""
|
||||||
if not self.is_variable_color_temp:
|
if not self.is_variable_color_temp:
|
||||||
raise SmartDeviceException("Bulb does not support colortemp.")
|
raise SmartDeviceException("Bulb does not support colortemp.")
|
||||||
|
|
||||||
@ -229,7 +240,7 @@ class SmartBulb(SmartDevice):
|
|||||||
)
|
)
|
||||||
|
|
||||||
light_state = {"color_temp": temp}
|
light_state = {"color_temp": temp}
|
||||||
await self.set_light_state(light_state)
|
return await self.set_light_state(light_state, transition=transition)
|
||||||
|
|
||||||
@property # type: ignore
|
@property # type: ignore
|
||||||
@requires_update
|
@requires_update
|
||||||
@ -242,15 +253,19 @@ class SmartBulb(SmartDevice):
|
|||||||
return int(light_state["brightness"])
|
return int(light_state["brightness"])
|
||||||
|
|
||||||
@requires_update
|
@requires_update
|
||||||
async def set_brightness(self, brightness: int) -> None:
|
async def set_brightness(self, brightness: int, *, transition: int = None) -> Dict:
|
||||||
"""Set the brightness in percentage."""
|
"""Set the brightness in percentage.
|
||||||
|
|
||||||
|
:param int brightness: brightness in percent
|
||||||
|
:param int transition: transition in milliseconds.
|
||||||
|
"""
|
||||||
if not self.is_dimmable: # pragma: no cover
|
if not self.is_dimmable: # pragma: no cover
|
||||||
raise SmartDeviceException("Bulb is not dimmable.")
|
raise SmartDeviceException("Bulb is not dimmable.")
|
||||||
|
|
||||||
self._raise_for_invalid_brightness(brightness)
|
self._raise_for_invalid_brightness(brightness)
|
||||||
|
|
||||||
light_state = {"brightness": brightness}
|
light_state = {"brightness": brightness}
|
||||||
await self.set_light_state(light_state)
|
return await self.set_light_state(light_state, transition=transition)
|
||||||
|
|
||||||
@property # type: ignore
|
@property # type: ignore
|
||||||
@requires_update
|
@requires_update
|
||||||
@ -275,13 +290,19 @@ class SmartBulb(SmartDevice):
|
|||||||
light_state = self.light_state
|
light_state = self.light_state
|
||||||
return bool(light_state["on_off"])
|
return bool(light_state["on_off"])
|
||||||
|
|
||||||
async def turn_off(self) -> None:
|
async def turn_off(self, *, transition: int = None) -> Dict:
|
||||||
"""Turn the bulb off."""
|
"""Turn the bulb off.
|
||||||
await self.set_light_state({"on_off": 0})
|
|
||||||
|
|
||||||
async def turn_on(self) -> None:
|
:param int transition: transition in milliseconds.
|
||||||
"""Turn the bulb on."""
|
"""
|
||||||
await self.set_light_state({"on_off": 1})
|
return await self.set_light_state({"on_off": 0}, transition=transition)
|
||||||
|
|
||||||
|
async def turn_on(self, *, transition: int = None) -> Dict:
|
||||||
|
"""Turn the bulb on.
|
||||||
|
|
||||||
|
:param int transition: transition in milliseconds.
|
||||||
|
"""
|
||||||
|
return await self.set_light_state({"on_off": 1}, transition=transition)
|
||||||
|
|
||||||
@property # type: ignore
|
@property # type: ignore
|
||||||
@requires_update
|
@requires_update
|
||||||
|
@ -493,7 +493,7 @@ class SmartDevice:
|
|||||||
"""
|
"""
|
||||||
await self._query_helper("system", "reboot", {"delay": delay})
|
await self._query_helper("system", "reboot", {"delay": delay})
|
||||||
|
|
||||||
async def turn_off(self) -> None:
|
async def turn_off(self) -> Dict:
|
||||||
"""Turn off the device."""
|
"""Turn off the device."""
|
||||||
raise NotImplementedError("Device subclass needs to implement this.")
|
raise NotImplementedError("Device subclass needs to implement this.")
|
||||||
|
|
||||||
@ -503,7 +503,7 @@ class SmartDevice:
|
|||||||
"""Return True if device is off."""
|
"""Return True if device is off."""
|
||||||
return not self.is_on
|
return not self.is_on
|
||||||
|
|
||||||
async def turn_on(self) -> None:
|
async def turn_on(self) -> Dict:
|
||||||
"""Turn device on."""
|
"""Turn device on."""
|
||||||
raise NotImplementedError("Device subclass needs to implement this.")
|
raise NotImplementedError("Device subclass needs to implement this.")
|
||||||
|
|
||||||
|
@ -69,6 +69,17 @@ async def test_hsv(dev, turn_on):
|
|||||||
assert brightness == 1
|
assert brightness == 1
|
||||||
|
|
||||||
|
|
||||||
|
@color_bulb
|
||||||
|
async def test_set_hsv_transition(dev, mocker):
|
||||||
|
set_light_state = mocker.patch("kasa.SmartBulb.set_light_state")
|
||||||
|
await dev.set_hsv(10, 10, 100, transition=1000)
|
||||||
|
|
||||||
|
set_light_state.assert_called_with(
|
||||||
|
{"hue": 10, "saturation": 10, "brightness": 100, "color_temp": 0},
|
||||||
|
transition=1000,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@color_bulb
|
@color_bulb
|
||||||
@turn_on
|
@turn_on
|
||||||
async def test_invalid_hsv(dev, turn_on):
|
async def test_invalid_hsv(dev, turn_on):
|
||||||
@ -123,6 +134,14 @@ async def test_try_set_colortemp(dev, turn_on):
|
|||||||
assert dev.color_temp == 2700
|
assert dev.color_temp == 2700
|
||||||
|
|
||||||
|
|
||||||
|
@variable_temp
|
||||||
|
async def test_set_color_temp_transition(dev, mocker):
|
||||||
|
set_light_state = mocker.patch("kasa.SmartBulb.set_light_state")
|
||||||
|
await dev.set_color_temp(2700, transition=100)
|
||||||
|
|
||||||
|
set_light_state.assert_called_with({"color_temp": 2700}, transition=100)
|
||||||
|
|
||||||
|
|
||||||
@variable_temp
|
@variable_temp
|
||||||
async def test_unknown_temp_range(dev, monkeypatch):
|
async def test_unknown_temp_range(dev, monkeypatch):
|
||||||
with pytest.raises(SmartDeviceException):
|
with pytest.raises(SmartDeviceException):
|
||||||
@ -166,6 +185,26 @@ async def test_dimmable_brightness(dev, turn_on):
|
|||||||
await dev.set_brightness("foo")
|
await dev.set_brightness("foo")
|
||||||
|
|
||||||
|
|
||||||
|
@bulb
|
||||||
|
async def test_turn_on_transition(dev, mocker):
|
||||||
|
set_light_state = mocker.patch("kasa.SmartBulb.set_light_state")
|
||||||
|
await dev.turn_on(transition=1000)
|
||||||
|
|
||||||
|
set_light_state.assert_called_with({"on_off": 1}, transition=1000)
|
||||||
|
|
||||||
|
await dev.turn_off(transition=100)
|
||||||
|
|
||||||
|
set_light_state.assert_called_with({"on_off": 0}, transition=100)
|
||||||
|
|
||||||
|
|
||||||
|
@bulb
|
||||||
|
async def test_dimmable_brightness_transition(dev, mocker):
|
||||||
|
set_light_state = mocker.patch("kasa.SmartBulb.set_light_state")
|
||||||
|
await dev.set_brightness(10, transition=1000)
|
||||||
|
|
||||||
|
set_light_state.assert_called_with({"brightness": 10}, transition=1000)
|
||||||
|
|
||||||
|
|
||||||
@dimmable
|
@dimmable
|
||||||
async def test_invalid_brightness(dev):
|
async def test_invalid_brightness(dev):
|
||||||
assert dev.is_dimmable
|
assert dev.is_dimmable
|
||||||
|
Loading…
Reference in New Issue
Block a user