smartbulb: Limit brightness range to 1-100 (#829)

The allowed brightness for tested light devices (L530, L900) is [1-100]
instead of [0-100] like it was for some kasa devices.
This commit is contained in:
Teemu R 2024-04-17 13:33:10 +02:00 committed by GitHub
parent 700643d3cf
commit 82d92aeea5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 28 deletions

View File

@ -28,8 +28,7 @@ class SmartBulb(SmartDevice, Bulb):
@property @property
def is_dimmable(self) -> bool: def is_dimmable(self) -> bool:
"""Whether the bulb supports brightness changes.""" """Whether the bulb supports brightness changes."""
# TODO: this makes an assumption that only dimmables report this return "Brightness" in self.modules
return "brightness" in self._info
@property @property
def is_variable_color_temp(self) -> bool: def is_variable_color_temp(self) -> bool:
@ -188,6 +187,11 @@ class SmartBulb(SmartDevice, Bulb):
return await self.protocol.query({"set_device_info": {"color_temp": temp}}) return await self.protocol.query({"set_device_info": {"color_temp": temp}})
def _raise_for_invalid_brightness(self, value: int):
"""Raise error on invalid brightness value."""
if not isinstance(value, int) or not (1 <= value <= 100):
raise ValueError(f"Invalid brightness value: {value} (valid range: 1-100%)")
async def set_brightness( async def set_brightness(
self, brightness: int, *, transition: Optional[int] = None self, brightness: int, *, transition: Optional[int] = None
) -> Dict: ) -> Dict:
@ -201,25 +205,12 @@ class SmartBulb(SmartDevice, Bulb):
if not self.is_dimmable: # pragma: no cover if not self.is_dimmable: # pragma: no cover
raise KasaException("Bulb is not dimmable.") raise KasaException("Bulb is not dimmable.")
self._raise_for_invalid_brightness(brightness)
return await self.protocol.query( return await self.protocol.query(
{"set_device_info": {"brightness": brightness}} {"set_device_info": {"brightness": brightness}}
) )
# Default state information, should be made to settings
"""
"info": {
"default_states": {
"re_power_type": "always_on",
"type": "last_states",
"state": {
"brightness": 36,
"hue": 0,
"saturation": 0,
"color_temp": 2700,
},
},
"""
async def set_effect( async def set_effect(
self, self,
effect: str, effect: str,
@ -229,15 +220,6 @@ class SmartBulb(SmartDevice, Bulb):
) -> None: ) -> None:
"""Set an effect on the device.""" """Set an effect on the device."""
raise NotImplementedError() raise NotImplementedError()
# TODO: the code below does to activate the effect but gives no error
return await self.protocol.query(
{
"set_device_info": {
"dynamic_light_effect_enable": 1,
"dynamic_light_effect_id": effect,
}
}
)
@property @property
def presets(self) -> List[BulbPreset]: def presets(self) -> List[BulbPreset]:

View File

@ -16,7 +16,7 @@ async def test_brightness_component(dev: SmartDevice):
# Test getting the value # Test getting the value
feature = dev.features["brightness"] feature = dev.features["brightness"]
assert isinstance(feature.value, int) assert isinstance(feature.value, int)
assert feature.value > 0 and feature.value <= 100 assert feature.value > 1 and feature.value <= 100
# Test setting the value # Test setting the value
await feature.set_value(10) await feature.set_value(10)

View File

@ -8,9 +8,10 @@ from pytest_mock import MockerFixture
from kasa import KasaException from kasa import KasaException
from kasa.exceptions import SmartErrorCode from kasa.exceptions import SmartErrorCode
from kasa.smart import SmartDevice from kasa.smart import SmartBulb, SmartDevice
from .conftest import ( from .conftest import (
bulb_smart,
device_smart, device_smart,
) )
@ -103,3 +104,25 @@ async def test_update_module_queries(dev: SmartDevice, mocker: MockerFixture):
full_query = {**full_query, **mod.query()} full_query = {**full_query, **mod.query()}
query.assert_called_with(full_query) query.assert_called_with(full_query)
@bulb_smart
async def test_smartdevice_brightness(dev: SmartBulb):
"""Test brightness setter and getter."""
assert isinstance(dev, SmartDevice)
assert "brightness" in dev._components
# Test getting the value
feature = dev.features["brightness"]
assert feature.minimum_value == 1
assert feature.maximum_value == 100
await dev.set_brightness(10)
await dev.update()
assert dev.brightness == 10
with pytest.raises(ValueError):
await dev.set_brightness(feature.minimum_value - 10)
with pytest.raises(ValueError):
await dev.set_brightness(feature.maximum_value + 10)