Enable setting brightness with color temp for smart devices (#1091)

This commit is contained in:
Steven B. 2024-07-31 15:52:27 +01:00 committed by GitHub
parent 7bba9926ed
commit cb7e904d30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 15 deletions

View File

@ -211,14 +211,14 @@ class Feature:
"""Range of values if applicable."""
return self._get_property_value(self.range_getter)
@cached_property
@property
def maximum_value(self) -> int:
"""Maximum value."""
if range := self.range:
return range[1]
return self.DEFAULT_MAX
@cached_property
@property
def minimum_value(self) -> int:
"""Minimum value."""
if range := self.range:

View File

@ -429,7 +429,7 @@ class IotBulb(IotDevice):
if not self._is_variable_color_temp:
raise KasaException("Bulb does not support colortemp.")
valid_temperature_range = self.valid_temperature_range
valid_temperature_range = self._valid_temperature_range
if temp < valid_temperature_range[0] or temp > valid_temperature_range[1]:
raise ValueError(
"Temperature should be between {} and {}, was {}".format(

View File

@ -3,16 +3,11 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from ...feature import Feature
from ...interfaces.light import ColorTempRange
from ..smartmodule import SmartModule
if TYPE_CHECKING:
from ..smartdevice import SmartDevice
_LOGGER = logging.getLogger(__name__)
DEFAULT_TEMP_RANGE = [2500, 6500]
@ -23,11 +18,11 @@ class ColorTemperature(SmartModule):
REQUIRED_COMPONENT = "color_temperature"
def __init__(self, device: SmartDevice, module: str):
super().__init__(device, module)
def _initialize_features(self):
"""Initialize features."""
self._add_feature(
Feature(
device,
self._device,
"color_temperature",
"Color temperature",
container=self,
@ -61,7 +56,7 @@ class ColorTemperature(SmartModule):
"""Return current color temperature."""
return self.data["color_temp"]
async def set_color_temp(self, temp: int):
async def set_color_temp(self, temp: int, *, brightness=None):
"""Set the color temperature."""
valid_temperature_range = self.valid_temperature_range
if temp < valid_temperature_range[0] or temp > valid_temperature_range[1]:
@ -70,8 +65,10 @@ class ColorTemperature(SmartModule):
*valid_temperature_range, temp
)
)
return await self.call("set_device_info", {"color_temp": temp})
params = {"color_temp": temp}
if brightness:
params["brightness"] = brightness
return await self.call("set_device_info", params)
async def _check_supported(self) -> bool:
"""Check the color_temp_range has more than one value."""

View File

@ -107,7 +107,9 @@ class Light(SmartModule, LightInterface):
"""
if not self.is_variable_color_temp:
raise KasaException("Bulb does not support colortemp.")
return await self._device.modules[Module.ColorTemperature].set_color_temp(temp)
return await self._device.modules[Module.ColorTemperature].set_color_temp(
temp, brightness=brightness
)
async def set_brightness(
self, brightness: int, *, transition: int | None = None

View File

@ -12,6 +12,7 @@ from kasa.tests.device_fixtures import (
parametrize,
parametrize_combine,
plug_iot,
variable_temp_iot,
)
led_smart = parametrize(
@ -36,6 +37,14 @@ dimmable_smart = parametrize(
)
dimmable = parametrize_combine([dimmable_smart, dimmer_iot, dimmable_iot])
variable_temp_smart = parametrize(
"variable temp smart",
component_filter="color_temperature",
protocol_filter={"SMART"},
)
variable_temp = parametrize_combine([variable_temp_iot, variable_temp_smart])
light_preset_smart = parametrize(
"has light preset smart", component_filter="preset", protocol_filter={"SMART"}
)
@ -147,6 +156,45 @@ async def test_light_brightness(dev: Device):
await light.set_brightness(feature.maximum_value + 10)
@variable_temp
async def test_light_color_temp(dev: Device):
"""Test color temp setter and getter."""
assert isinstance(dev, Device)
light = next(get_parent_and_child_modules(dev, Module.Light))
assert light
if not light.is_variable_color_temp:
pytest.skip(
"Some smart light strips have color_temperature"
" component but min and max are the same"
)
# Test getting the value
feature = light._device.features["color_temperature"]
assert isinstance(feature.minimum_value, int)
assert isinstance(feature.maximum_value, int)
await light.set_color_temp(feature.minimum_value + 10)
await dev.update()
assert light.color_temp == feature.minimum_value + 10
# Test setting brightness with color temp
await light.set_brightness(50)
await dev.update()
assert light.brightness == 50
await light.set_color_temp(feature.minimum_value + 20, brightness=60)
await dev.update()
assert light.color_temp == feature.minimum_value + 20
assert light.brightness == 60
with pytest.raises(ValueError):
await light.set_color_temp(feature.minimum_value - 10)
with pytest.raises(ValueError):
await light.set_color_temp(feature.maximum_value + 10)
@light
async def test_light_set_state(dev: Device):
"""Test brightness setter and getter."""