mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-05-11 00:51:14 +00:00
Improve bulb API, force turn on for all light changes as offline changes are not supported (#76)
* Add ignore_default to lights to allow setting to specific light state, force bulb on when changing the settings, allow defining brightness for set_color_temp, add a couple of new API methods * Fix and simplify transition_light_state to make tests pass
This commit is contained in:
parent
f9a987ca18
commit
44e2998705
@ -153,6 +153,25 @@ class SmartBulb(SmartDevice):
|
|||||||
|
|
||||||
return light_state
|
return light_state
|
||||||
|
|
||||||
|
async def get_light_details(self) -> Dict[str, int]:
|
||||||
|
"""Return light details.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'lamp_beam_angle': 290, 'min_voltage': 220, 'max_voltage': 240,
|
||||||
|
'wattage': 5, 'incandescent_equivalent': 40, 'max_lumens': 450,
|
||||||
|
'color_rendering_index': 80}
|
||||||
|
"""
|
||||||
|
return await self._query_helper(self.LIGHT_SERVICE, "get_light_details")
|
||||||
|
|
||||||
|
async def get_turn_on_behavior(self) -> Dict:
|
||||||
|
"""Return the behavior for turning the bulb on.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'soft_on': {'mode': 'last_status'},
|
||||||
|
'hard_on': {'mode': 'last_status'}}
|
||||||
|
"""
|
||||||
|
return await self._query_helper(self.LIGHT_SERVICE, "get_default_behavior")
|
||||||
|
|
||||||
async def get_light_state(self) -> Dict[str, Dict]:
|
async def get_light_state(self) -> Dict[str, Dict]:
|
||||||
"""Query the light state."""
|
"""Query the light state."""
|
||||||
# TODO: add warning and refer to use light.state?
|
# TODO: add warning and refer to use light.state?
|
||||||
@ -163,6 +182,13 @@ class SmartBulb(SmartDevice):
|
|||||||
if transition is not None:
|
if transition is not None:
|
||||||
state["transition_period"] = transition
|
state["transition_period"] = transition
|
||||||
|
|
||||||
|
# if no on/off is defined, turn on the light
|
||||||
|
if "on_off" not in state:
|
||||||
|
state["on_off"] = 1
|
||||||
|
|
||||||
|
# This is necessary to allow turning on into a specific state
|
||||||
|
state["ignore_default"] = 1
|
||||||
|
|
||||||
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
|
||||||
)
|
)
|
||||||
@ -239,7 +265,9 @@ 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, *, transition: int = None) -> Dict:
|
async def set_color_temp(
|
||||||
|
self, temp: int, *, brightness=None, 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 temp: The new color temperature, in Kelvin
|
||||||
@ -256,6 +284,9 @@ class SmartBulb(SmartDevice):
|
|||||||
)
|
)
|
||||||
|
|
||||||
light_state = {"color_temp": temp}
|
light_state = {"color_temp": temp}
|
||||||
|
if brightness is not None:
|
||||||
|
light_state["brightness"] = brightness
|
||||||
|
|
||||||
return await self.set_light_state(light_state, transition=transition)
|
return await self.set_light_state(light_state, transition=transition)
|
||||||
|
|
||||||
@property # type: ignore
|
@property # type: ignore
|
||||||
|
@ -323,31 +323,33 @@ class FakeTransportProtocol(TPLinkSmartHomeProtocol):
|
|||||||
self.proto["system"]["get_sysinfo"]["relay_state"] = 1
|
self.proto["system"]["get_sysinfo"]["relay_state"] = 1
|
||||||
self.proto["system"]["get_sysinfo"]["brightness"] = x["brightness"]
|
self.proto["system"]["get_sysinfo"]["brightness"] = x["brightness"]
|
||||||
|
|
||||||
def transition_light_state(self, x, *args):
|
def transition_light_state(self, state_changes, *args):
|
||||||
_LOGGER.debug("Setting light state to %s", x)
|
_LOGGER.debug("Setting light state to %s", state_changes)
|
||||||
light_state = self.proto["system"]["get_sysinfo"]["light_state"]
|
light_state = self.proto["system"]["get_sysinfo"]["light_state"]
|
||||||
# The required change depends on the light state,
|
|
||||||
# exception being turning the bulb on and off
|
|
||||||
|
|
||||||
if "on_off" in x:
|
_LOGGER.debug("Current light state: %s", light_state)
|
||||||
if x["on_off"] and not light_state["on_off"]: # turning on
|
new_state = light_state
|
||||||
|
|
||||||
|
if state_changes["on_off"] == 1: # turn on requested
|
||||||
|
if not light_state[
|
||||||
|
"on_off"
|
||||||
|
]: # if we were off, use the dft_on_state as a base
|
||||||
|
_LOGGER.debug("Bulb was off, using dft_on_state")
|
||||||
new_state = light_state["dft_on_state"]
|
new_state = light_state["dft_on_state"]
|
||||||
new_state["on_off"] = 1
|
|
||||||
self.proto["system"]["get_sysinfo"]["light_state"] = new_state
|
|
||||||
elif not x["on_off"] and light_state["on_off"]:
|
|
||||||
new_state = {"dft_on_state": light_state, "on_off": 0}
|
|
||||||
|
|
||||||
self.proto["system"]["get_sysinfo"]["light_state"] = new_state
|
# override the existing settings
|
||||||
|
new_state.update(state_changes)
|
||||||
|
|
||||||
return
|
if (
|
||||||
|
not state_changes["on_off"] and "dft_on_state" not in light_state
|
||||||
|
): # if not already off, pack the data inside dft_on_state
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Bulb was on and turn_off was requested, saving to dft_on_state"
|
||||||
|
)
|
||||||
|
new_state = {"dft_on_state": light_state, "on_off": 0}
|
||||||
|
|
||||||
if not light_state["on_off"] and "on_off" not in x:
|
_LOGGER.debug("New light state: %s", new_state)
|
||||||
light_state = light_state["dft_on_state"]
|
self.proto["system"]["get_sysinfo"]["light_state"] = new_state
|
||||||
|
|
||||||
_LOGGER.debug("Old state: %s", light_state)
|
|
||||||
for key in x:
|
|
||||||
light_state[key] = x[key]
|
|
||||||
_LOGGER.debug("New state: %s", light_state)
|
|
||||||
|
|
||||||
def light_state(self, x, *args):
|
def light_state(self, x, *args):
|
||||||
light_state = self.proto["system"]["get_sysinfo"]["light_state"]
|
light_state = self.proto["system"]["get_sysinfo"]["light_state"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user