Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions kasa/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ class Feature:
minimum_value: int = 0
#: Maximum value
maximum_value: int = 2**16 # Arbitrary max
#: Attribute containing the name of the range getter property.
#: If set, this property will be used to set *minimum_value* and *maximum_value*.
range_getter: Optional[str] = None

def __post_init__(self):
"""Handle late-binding of members."""
container = self.container if self.container is not None else self.device
if self.range_getter is not None:
self.minimum_value, self.maximum_value = getattr(
container, self.range_getter
)

@property
def value(self):
Expand Down
2 changes: 2 additions & 0 deletions kasa/smart/modules/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .brightness import Brightness
from .childdevicemodule import ChildDeviceModule
from .cloudmodule import CloudModule
from .colortemp import ColorTemperatureModule
from .devicemodule import DeviceModule
from .energymodule import EnergyModule
from .firmware import Firmware
Expand All @@ -31,4 +32,5 @@
"Firmware",
"CloudModule",
"LightTransitionModule",
"ColorTemperatureModule",
]
55 changes: 55 additions & 0 deletions kasa/smart/modules/colortemp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""Implementation of color temp module."""
from typing import TYPE_CHECKING, Dict

from ...bulb import ColorTempRange
from ...feature import Feature
from ..smartmodule import SmartModule

if TYPE_CHECKING:
from ..smartdevice import SmartDevice


class ColorTemperatureModule(SmartModule):
"""Implementation of color temp module."""

REQUIRED_COMPONENT = "color_temperature"

def __init__(self, device: "SmartDevice", module: str):
super().__init__(device, module)
self._add_feature(
Feature(
device,
"Color temperature",
container=self,
attribute_getter="color_temp",
attribute_setter="set_color_temp",
range_getter="valid_temperature_range",
)
)

def query(self) -> Dict:
"""Query to execute during the update cycle."""
# Color temp is contained in the main device info response.
return {}

@property
def valid_temperature_range(self) -> ColorTempRange:
"""Return valid color-temp range."""
return ColorTempRange(*self.data.get("color_temp_range"))

@property
def color_temp(self):
"""Return current color temperature."""
return self.data["color_temp"]

async def set_color_temp(self, temp: int):
"""Set the color temperature."""
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(
*valid_temperature_range, temp
)
)

return await self.call("set_device_info", {"color_temp": temp})
Empty file.
31 changes: 31 additions & 0 deletions kasa/tests/smart/features/test_colortemp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import pytest

from kasa.smart import SmartDevice
from kasa.tests.conftest import parametrize

brightness = parametrize("colortemp smart", component_filter="color_temperature")


@brightness
async def test_colortemp_component(dev: SmartDevice):
"""Test brightness feature."""
assert isinstance(dev, SmartDevice)
assert "color_temperature" in dev._components

# Test getting the value
feature = dev.features["color_temperature"]
assert isinstance(feature.value, int)
assert isinstance(feature.minimum_value, int)
assert isinstance(feature.maximum_value, int)

# Test setting the value
# We need to take the min here, as L9xx reports a range [9000, 9000].
new_value = min(feature.minimum_value + 1, feature.maximum_value)
await feature.set_value(new_value)
assert feature.value == new_value

with pytest.raises(ValueError):
await feature.set_value(feature.minimum_value - 10)

with pytest.raises(ValueError):
await feature.set_value(feature.maximum_value + 10)