mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-06-30 08:39:48 +00:00
Add Dimmer Configuration Support (#1484)
This commit is contained in:
parent
8259d28b12
commit
bff5409d22
@ -11,7 +11,7 @@ from ..module import Module
|
|||||||
from ..protocols import BaseProtocol
|
from ..protocols import BaseProtocol
|
||||||
from .iotdevice import KasaException, requires_update
|
from .iotdevice import KasaException, requires_update
|
||||||
from .iotplug import IotPlug
|
from .iotplug import IotPlug
|
||||||
from .modules import AmbientLight, Light, Motion
|
from .modules import AmbientLight, Dimmer, Light, Motion
|
||||||
|
|
||||||
|
|
||||||
class ButtonAction(Enum):
|
class ButtonAction(Enum):
|
||||||
@ -87,6 +87,7 @@ class IotDimmer(IotPlug):
|
|||||||
# TODO: need to be figured out what's the best approach to detect support
|
# TODO: need to be figured out what's the best approach to detect support
|
||||||
self.add_module(Module.IotMotion, Motion(self, "smartlife.iot.PIR"))
|
self.add_module(Module.IotMotion, Motion(self, "smartlife.iot.PIR"))
|
||||||
self.add_module(Module.IotAmbientLight, AmbientLight(self, "smartlife.iot.LAS"))
|
self.add_module(Module.IotAmbientLight, AmbientLight(self, "smartlife.iot.LAS"))
|
||||||
|
self.add_module(Module.IotDimmer, Dimmer(self, "smartlife.iot.dimmer"))
|
||||||
self.add_module(Module.Light, Light(self, "light"))
|
self.add_module(Module.Light, Light(self, "light"))
|
||||||
|
|
||||||
@property # type: ignore
|
@property # type: ignore
|
||||||
|
@ -4,6 +4,7 @@ from .ambientlight import AmbientLight
|
|||||||
from .antitheft import Antitheft
|
from .antitheft import Antitheft
|
||||||
from .cloud import Cloud
|
from .cloud import Cloud
|
||||||
from .countdown import Countdown
|
from .countdown import Countdown
|
||||||
|
from .dimmer import Dimmer
|
||||||
from .emeter import Emeter
|
from .emeter import Emeter
|
||||||
from .led import Led
|
from .led import Led
|
||||||
from .light import Light
|
from .light import Light
|
||||||
@ -20,6 +21,7 @@ __all__ = [
|
|||||||
"Antitheft",
|
"Antitheft",
|
||||||
"Cloud",
|
"Cloud",
|
||||||
"Countdown",
|
"Countdown",
|
||||||
|
"Dimmer",
|
||||||
"Emeter",
|
"Emeter",
|
||||||
"Led",
|
"Led",
|
||||||
"Light",
|
"Light",
|
||||||
|
270
kasa/iot/modules/dimmer.py
Normal file
270
kasa/iot/modules/dimmer.py
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
"""Implementation of the dimmer config module found in dimmers."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from datetime import timedelta
|
||||||
|
from typing import Any, Final, cast
|
||||||
|
|
||||||
|
from ...exceptions import KasaException
|
||||||
|
from ...feature import Feature
|
||||||
|
from ..iotmodule import IotModule, merge
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _td_to_ms(td: timedelta) -> int:
|
||||||
|
"""
|
||||||
|
Convert timedelta to integer milliseconds.
|
||||||
|
|
||||||
|
Uses default float to integer rounding.
|
||||||
|
"""
|
||||||
|
return int(td / timedelta(milliseconds=1))
|
||||||
|
|
||||||
|
|
||||||
|
class Dimmer(IotModule):
|
||||||
|
"""Implements the dimmer config module."""
|
||||||
|
|
||||||
|
THRESHOLD_ABS_MIN: Final[int] = 0
|
||||||
|
# Strange value, but verified against hardware (KS220).
|
||||||
|
THRESHOLD_ABS_MAX: Final[int] = 51
|
||||||
|
FADE_TIME_ABS_MIN: Final[timedelta] = timedelta(seconds=0)
|
||||||
|
# Arbitrary, but set low intending GENTLE FADE for longer fades.
|
||||||
|
FADE_TIME_ABS_MAX: Final[timedelta] = timedelta(seconds=10)
|
||||||
|
GENTLE_TIME_ABS_MIN: Final[timedelta] = timedelta(seconds=0)
|
||||||
|
# Arbitrary, but reasonable default.
|
||||||
|
GENTLE_TIME_ABS_MAX: Final[timedelta] = timedelta(seconds=120)
|
||||||
|
# Verified against KS220.
|
||||||
|
RAMP_RATE_ABS_MIN: Final[int] = 10
|
||||||
|
# Verified against KS220.
|
||||||
|
RAMP_RATE_ABS_MAX: Final[int] = 50
|
||||||
|
|
||||||
|
def _initialize_features(self) -> None:
|
||||||
|
"""Initialize features after the initial update."""
|
||||||
|
self._add_feature(
|
||||||
|
Feature(
|
||||||
|
device=self._device,
|
||||||
|
container=self,
|
||||||
|
id="dimmer_threshold_min",
|
||||||
|
name="Minimum dimming level",
|
||||||
|
icon="mdi:lightbulb-on-20",
|
||||||
|
attribute_getter="threshold_min",
|
||||||
|
attribute_setter="set_threshold_min",
|
||||||
|
range_getter=lambda: (self.THRESHOLD_ABS_MIN, self.THRESHOLD_ABS_MAX),
|
||||||
|
type=Feature.Type.Number,
|
||||||
|
category=Feature.Category.Config,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self._add_feature(
|
||||||
|
Feature(
|
||||||
|
device=self._device,
|
||||||
|
container=self,
|
||||||
|
id="dimmer_fade_off_time",
|
||||||
|
name="Dimmer fade off time",
|
||||||
|
icon="mdi:clock-in",
|
||||||
|
attribute_getter="fade_off_time",
|
||||||
|
attribute_setter="set_fade_off_time",
|
||||||
|
range_getter=lambda: (
|
||||||
|
_td_to_ms(self.FADE_TIME_ABS_MIN),
|
||||||
|
_td_to_ms(self.FADE_TIME_ABS_MAX),
|
||||||
|
),
|
||||||
|
type=Feature.Type.Number,
|
||||||
|
category=Feature.Category.Config,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self._add_feature(
|
||||||
|
Feature(
|
||||||
|
device=self._device,
|
||||||
|
container=self,
|
||||||
|
id="dimmer_fade_on_time",
|
||||||
|
name="Dimmer fade on time",
|
||||||
|
icon="mdi:clock-out",
|
||||||
|
attribute_getter="fade_on_time",
|
||||||
|
attribute_setter="set_fade_on_time",
|
||||||
|
range_getter=lambda: (
|
||||||
|
_td_to_ms(self.FADE_TIME_ABS_MIN),
|
||||||
|
_td_to_ms(self.FADE_TIME_ABS_MAX),
|
||||||
|
),
|
||||||
|
type=Feature.Type.Number,
|
||||||
|
category=Feature.Category.Config,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self._add_feature(
|
||||||
|
Feature(
|
||||||
|
device=self._device,
|
||||||
|
container=self,
|
||||||
|
id="dimmer_gentle_off_time",
|
||||||
|
name="Dimmer gentle off time",
|
||||||
|
icon="mdi:clock-in",
|
||||||
|
attribute_getter="gentle_off_time",
|
||||||
|
attribute_setter="set_gentle_off_time",
|
||||||
|
range_getter=lambda: (
|
||||||
|
_td_to_ms(self.GENTLE_TIME_ABS_MIN),
|
||||||
|
_td_to_ms(self.GENTLE_TIME_ABS_MAX),
|
||||||
|
),
|
||||||
|
type=Feature.Type.Number,
|
||||||
|
category=Feature.Category.Config,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self._add_feature(
|
||||||
|
Feature(
|
||||||
|
device=self._device,
|
||||||
|
container=self,
|
||||||
|
id="dimmer_gentle_on_time",
|
||||||
|
name="Dimmer gentle on time",
|
||||||
|
icon="mdi:clock-out",
|
||||||
|
attribute_getter="gentle_on_time",
|
||||||
|
attribute_setter="set_gentle_on_time",
|
||||||
|
range_getter=lambda: (
|
||||||
|
_td_to_ms(self.GENTLE_TIME_ABS_MIN),
|
||||||
|
_td_to_ms(self.GENTLE_TIME_ABS_MAX),
|
||||||
|
),
|
||||||
|
type=Feature.Type.Number,
|
||||||
|
category=Feature.Category.Config,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self._add_feature(
|
||||||
|
Feature(
|
||||||
|
device=self._device,
|
||||||
|
container=self,
|
||||||
|
id="dimmer_ramp_rate",
|
||||||
|
name="Dimmer ramp rate",
|
||||||
|
icon="mdi:clock-fast",
|
||||||
|
attribute_getter="ramp_rate",
|
||||||
|
attribute_setter="set_ramp_rate",
|
||||||
|
range_getter=lambda: (self.RAMP_RATE_ABS_MIN, self.RAMP_RATE_ABS_MAX),
|
||||||
|
type=Feature.Type.Number,
|
||||||
|
category=Feature.Category.Config,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def query(self) -> dict:
|
||||||
|
"""Request Dimming configuration."""
|
||||||
|
req = merge(
|
||||||
|
self.query_for_command("get_dimmer_parameters"),
|
||||||
|
self.query_for_command("get_default_behavior"),
|
||||||
|
)
|
||||||
|
|
||||||
|
return req
|
||||||
|
|
||||||
|
@property
|
||||||
|
def config(self) -> dict[str, Any]:
|
||||||
|
"""Return current configuration."""
|
||||||
|
return self.data["get_dimmer_parameters"]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def threshold_min(self) -> int:
|
||||||
|
"""Return the minimum dimming level for this dimmer."""
|
||||||
|
return self.config["minThreshold"]
|
||||||
|
|
||||||
|
async def set_threshold_min(self, min: int) -> dict:
|
||||||
|
"""Set the minimum dimming level for this dimmer.
|
||||||
|
|
||||||
|
The value will depend on the luminaries connected to the dimmer.
|
||||||
|
|
||||||
|
:param min: The minimum dimming level, in the range 0-51.
|
||||||
|
"""
|
||||||
|
if min < self.THRESHOLD_ABS_MIN or min > self.THRESHOLD_ABS_MAX:
|
||||||
|
raise KasaException(
|
||||||
|
"Minimum dimming threshold is outside the supported range: "
|
||||||
|
f"{self.THRESHOLD_ABS_MIN}-{self.THRESHOLD_ABS_MAX}"
|
||||||
|
)
|
||||||
|
return await self.call("calibrate_brightness", {"minThreshold": min})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fade_off_time(self) -> timedelta:
|
||||||
|
"""Return the fade off animation duration."""
|
||||||
|
return timedelta(milliseconds=cast(int, self.config["fadeOffTime"]))
|
||||||
|
|
||||||
|
async def set_fade_off_time(self, time: int | timedelta) -> dict:
|
||||||
|
"""Set the duration of the fade off animation.
|
||||||
|
|
||||||
|
:param time: The animation duration, in ms.
|
||||||
|
"""
|
||||||
|
if isinstance(time, int):
|
||||||
|
time = timedelta(milliseconds=time)
|
||||||
|
if time < self.FADE_TIME_ABS_MIN or time > self.FADE_TIME_ABS_MAX:
|
||||||
|
raise KasaException(
|
||||||
|
"Fade time is outside the bounds of the supported range:"
|
||||||
|
f"{self.FADE_TIME_ABS_MIN}-{self.FADE_TIME_ABS_MAX}"
|
||||||
|
)
|
||||||
|
return await self.call("set_fade_off_time", {"fadeTime": _td_to_ms(time)})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fade_on_time(self) -> timedelta:
|
||||||
|
"""Return the fade on animation duration."""
|
||||||
|
return timedelta(milliseconds=cast(int, self.config["fadeOnTime"]))
|
||||||
|
|
||||||
|
async def set_fade_on_time(self, time: int | timedelta) -> dict:
|
||||||
|
"""Set the duration of the fade on animation.
|
||||||
|
|
||||||
|
:param time: The animation duration, in ms.
|
||||||
|
"""
|
||||||
|
if isinstance(time, int):
|
||||||
|
time = timedelta(milliseconds=time)
|
||||||
|
if time < self.FADE_TIME_ABS_MIN or time > self.FADE_TIME_ABS_MAX:
|
||||||
|
raise KasaException(
|
||||||
|
"Fade time is outside the bounds of the supported range:"
|
||||||
|
f"{self.FADE_TIME_ABS_MIN}-{self.FADE_TIME_ABS_MAX}"
|
||||||
|
)
|
||||||
|
return await self.call("set_fade_on_time", {"fadeTime": _td_to_ms(time)})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gentle_off_time(self) -> timedelta:
|
||||||
|
"""Return the gentle fade off animation duration."""
|
||||||
|
return timedelta(milliseconds=cast(int, self.config["gentleOffTime"]))
|
||||||
|
|
||||||
|
async def set_gentle_off_time(self, time: int | timedelta) -> dict:
|
||||||
|
"""Set the duration of the gentle fade off animation.
|
||||||
|
|
||||||
|
:param time: The animation duration, in ms.
|
||||||
|
"""
|
||||||
|
if isinstance(time, int):
|
||||||
|
time = timedelta(milliseconds=time)
|
||||||
|
if time < self.GENTLE_TIME_ABS_MIN or time > self.GENTLE_TIME_ABS_MAX:
|
||||||
|
raise KasaException(
|
||||||
|
"Gentle off time is outside the bounds of the supported range: "
|
||||||
|
f"{self.GENTLE_TIME_ABS_MIN}-{self.GENTLE_TIME_ABS_MAX}."
|
||||||
|
)
|
||||||
|
return await self.call("set_gentle_off_time", {"duration": _td_to_ms(time)})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gentle_on_time(self) -> timedelta:
|
||||||
|
"""Return the gentle fade on animation duration."""
|
||||||
|
return timedelta(milliseconds=cast(int, self.config["gentleOnTime"]))
|
||||||
|
|
||||||
|
async def set_gentle_on_time(self, time: int | timedelta) -> dict:
|
||||||
|
"""Set the duration of the gentle fade on animation.
|
||||||
|
|
||||||
|
:param time: The animation duration, in ms.
|
||||||
|
"""
|
||||||
|
if isinstance(time, int):
|
||||||
|
time = timedelta(milliseconds=time)
|
||||||
|
if time < self.GENTLE_TIME_ABS_MIN or time > self.GENTLE_TIME_ABS_MAX:
|
||||||
|
raise KasaException(
|
||||||
|
"Gentle off time is outside the bounds of the supported range: "
|
||||||
|
f"{self.GENTLE_TIME_ABS_MIN}-{self.GENTLE_TIME_ABS_MAX}."
|
||||||
|
)
|
||||||
|
return await self.call("set_gentle_on_time", {"duration": _td_to_ms(time)})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ramp_rate(self) -> int:
|
||||||
|
"""Return the rate that the dimmer buttons increment the dimmer level."""
|
||||||
|
return self.config["rampRate"]
|
||||||
|
|
||||||
|
async def set_ramp_rate(self, rate: int) -> dict:
|
||||||
|
"""Set how quickly to ramp the dimming level when using the dimmer buttons.
|
||||||
|
|
||||||
|
:param rate: The rate to increment the dimming level with each press.
|
||||||
|
"""
|
||||||
|
if rate < self.RAMP_RATE_ABS_MIN or rate > self.RAMP_RATE_ABS_MAX:
|
||||||
|
raise KasaException(
|
||||||
|
"Gentle off time is outside the bounds of the supported range:"
|
||||||
|
f"{self.RAMP_RATE_ABS_MIN}-{self.RAMP_RATE_ABS_MAX}"
|
||||||
|
)
|
||||||
|
return await self.call("set_button_ramp_rate", {"rampRate": rate})
|
@ -111,6 +111,7 @@ class Module(ABC):
|
|||||||
IotAmbientLight: Final[ModuleName[iot.AmbientLight]] = ModuleName("ambient")
|
IotAmbientLight: Final[ModuleName[iot.AmbientLight]] = ModuleName("ambient")
|
||||||
IotAntitheft: Final[ModuleName[iot.Antitheft]] = ModuleName("anti_theft")
|
IotAntitheft: Final[ModuleName[iot.Antitheft]] = ModuleName("anti_theft")
|
||||||
IotCountdown: Final[ModuleName[iot.Countdown]] = ModuleName("countdown")
|
IotCountdown: Final[ModuleName[iot.Countdown]] = ModuleName("countdown")
|
||||||
|
IotDimmer: Final[ModuleName[iot.Dimmer]] = ModuleName("dimmer")
|
||||||
IotMotion: Final[ModuleName[iot.Motion]] = ModuleName("motion")
|
IotMotion: Final[ModuleName[iot.Motion]] = ModuleName("motion")
|
||||||
IotSchedule: Final[ModuleName[iot.Schedule]] = ModuleName("schedule")
|
IotSchedule: Final[ModuleName[iot.Schedule]] = ModuleName("schedule")
|
||||||
IotUsage: Final[ModuleName[iot.Usage]] = ModuleName("usage")
|
IotUsage: Final[ModuleName[iot.Usage]] = ModuleName("usage")
|
||||||
|
204
tests/iot/modules/test_dimmer.py
Normal file
204
tests/iot/modules/test_dimmer.py
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
from datetime import timedelta
|
||||||
|
from typing import Final
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
|
from kasa import KasaException, Module
|
||||||
|
from kasa.iot import IotDimmer
|
||||||
|
from kasa.iot.modules.dimmer import Dimmer
|
||||||
|
|
||||||
|
from ...device_fixtures import dimmer_iot
|
||||||
|
|
||||||
|
_TD_ONE_MS: Final[timedelta] = timedelta(milliseconds=1)
|
||||||
|
|
||||||
|
|
||||||
|
@dimmer_iot
|
||||||
|
def test_dimmer_getters(dev: IotDimmer):
|
||||||
|
assert Module.IotDimmer in dev.modules
|
||||||
|
dimmer: Dimmer = dev.modules[Module.IotDimmer]
|
||||||
|
|
||||||
|
assert dimmer.threshold_min == dimmer.config["minThreshold"]
|
||||||
|
assert int(dimmer.fade_off_time / _TD_ONE_MS) == dimmer.config["fadeOffTime"]
|
||||||
|
assert int(dimmer.fade_on_time / _TD_ONE_MS) == dimmer.config["fadeOnTime"]
|
||||||
|
assert int(dimmer.gentle_off_time / _TD_ONE_MS) == dimmer.config["gentleOffTime"]
|
||||||
|
assert int(dimmer.gentle_on_time / _TD_ONE_MS) == dimmer.config["gentleOnTime"]
|
||||||
|
assert dimmer.ramp_rate == dimmer.config["rampRate"]
|
||||||
|
|
||||||
|
|
||||||
|
@dimmer_iot
|
||||||
|
async def test_dimmer_setters(dev: IotDimmer, mocker: MockerFixture):
|
||||||
|
dimmer: Dimmer = dev.modules[Module.IotDimmer]
|
||||||
|
query_helper = mocker.patch("kasa.iot.IotDimmer._query_helper")
|
||||||
|
|
||||||
|
test_threshold = 10
|
||||||
|
await dimmer.set_threshold_min(test_threshold)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "calibrate_brightness", {"minThreshold": test_threshold}
|
||||||
|
)
|
||||||
|
|
||||||
|
test_time = 100
|
||||||
|
await dimmer.set_fade_off_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_fade_off_time", {"fadeTime": test_time}
|
||||||
|
)
|
||||||
|
await dimmer.set_fade_on_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_fade_on_time", {"fadeTime": test_time}
|
||||||
|
)
|
||||||
|
|
||||||
|
test_time = 1000
|
||||||
|
await dimmer.set_gentle_off_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_gentle_off_time", {"duration": test_time}
|
||||||
|
)
|
||||||
|
await dimmer.set_gentle_on_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_gentle_on_time", {"duration": test_time}
|
||||||
|
)
|
||||||
|
|
||||||
|
test_rate = 30
|
||||||
|
await dimmer.set_ramp_rate(test_rate)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_button_ramp_rate", {"rampRate": test_rate}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dimmer_iot
|
||||||
|
async def test_dimmer_setter_min(dev: IotDimmer, mocker: MockerFixture):
|
||||||
|
dimmer: Dimmer = dev.modules[Module.IotDimmer]
|
||||||
|
query_helper = mocker.patch("kasa.iot.IotDimmer._query_helper")
|
||||||
|
|
||||||
|
test_threshold = dimmer.THRESHOLD_ABS_MIN
|
||||||
|
await dimmer.set_threshold_min(test_threshold)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "calibrate_brightness", {"minThreshold": test_threshold}
|
||||||
|
)
|
||||||
|
|
||||||
|
test_time = int(dimmer.FADE_TIME_ABS_MIN / _TD_ONE_MS)
|
||||||
|
await dimmer.set_fade_off_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_fade_off_time", {"fadeTime": test_time}
|
||||||
|
)
|
||||||
|
await dimmer.set_fade_on_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_fade_on_time", {"fadeTime": test_time}
|
||||||
|
)
|
||||||
|
|
||||||
|
test_time = int(dimmer.GENTLE_TIME_ABS_MIN / _TD_ONE_MS)
|
||||||
|
await dimmer.set_gentle_off_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_gentle_off_time", {"duration": test_time}
|
||||||
|
)
|
||||||
|
await dimmer.set_gentle_on_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_gentle_on_time", {"duration": test_time}
|
||||||
|
)
|
||||||
|
|
||||||
|
test_rate = dimmer.RAMP_RATE_ABS_MIN
|
||||||
|
await dimmer.set_ramp_rate(test_rate)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_button_ramp_rate", {"rampRate": test_rate}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dimmer_iot
|
||||||
|
async def test_dimmer_setter_max(dev: IotDimmer, mocker: MockerFixture):
|
||||||
|
dimmer: Dimmer = dev.modules[Module.IotDimmer]
|
||||||
|
query_helper = mocker.patch("kasa.iot.IotDimmer._query_helper")
|
||||||
|
|
||||||
|
test_threshold = dimmer.THRESHOLD_ABS_MAX
|
||||||
|
await dimmer.set_threshold_min(test_threshold)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "calibrate_brightness", {"minThreshold": test_threshold}
|
||||||
|
)
|
||||||
|
|
||||||
|
test_time = int(dimmer.FADE_TIME_ABS_MAX / _TD_ONE_MS)
|
||||||
|
await dimmer.set_fade_off_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_fade_off_time", {"fadeTime": test_time}
|
||||||
|
)
|
||||||
|
await dimmer.set_fade_on_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_fade_on_time", {"fadeTime": test_time}
|
||||||
|
)
|
||||||
|
|
||||||
|
test_time = int(dimmer.GENTLE_TIME_ABS_MAX / _TD_ONE_MS)
|
||||||
|
await dimmer.set_gentle_off_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_gentle_off_time", {"duration": test_time}
|
||||||
|
)
|
||||||
|
await dimmer.set_gentle_on_time(test_time)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_gentle_on_time", {"duration": test_time}
|
||||||
|
)
|
||||||
|
|
||||||
|
test_rate = dimmer.RAMP_RATE_ABS_MAX
|
||||||
|
await dimmer.set_ramp_rate(test_rate)
|
||||||
|
query_helper.assert_called_with(
|
||||||
|
"smartlife.iot.dimmer", "set_button_ramp_rate", {"rampRate": test_rate}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dimmer_iot
|
||||||
|
async def test_dimmer_setters_min_oob(dev: IotDimmer, mocker: MockerFixture):
|
||||||
|
dimmer: Dimmer = dev.modules[Module.IotDimmer]
|
||||||
|
query_helper = mocker.patch("kasa.iot.IotDimmer._query_helper")
|
||||||
|
|
||||||
|
test_threshold = dimmer.THRESHOLD_ABS_MIN - 1
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_threshold_min(test_threshold)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
|
||||||
|
test_time = dimmer.FADE_TIME_ABS_MIN - _TD_ONE_MS
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_fade_off_time(test_time)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_fade_on_time(test_time)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
|
||||||
|
test_time = dimmer.GENTLE_TIME_ABS_MIN - _TD_ONE_MS
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_gentle_off_time(test_time)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_gentle_on_time(test_time)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
|
||||||
|
test_rate = dimmer.RAMP_RATE_ABS_MIN - 1
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_ramp_rate(test_rate)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
@dimmer_iot
|
||||||
|
async def test_dimmer_setters_max_oob(dev: IotDimmer, mocker: MockerFixture):
|
||||||
|
dimmer: Dimmer = dev.modules[Module.IotDimmer]
|
||||||
|
query_helper = mocker.patch("kasa.iot.IotDimmer._query_helper")
|
||||||
|
|
||||||
|
test_threshold = dimmer.THRESHOLD_ABS_MAX + 1
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_threshold_min(test_threshold)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
|
||||||
|
test_time = dimmer.FADE_TIME_ABS_MAX + _TD_ONE_MS
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_fade_off_time(test_time)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_fade_on_time(test_time)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
|
||||||
|
test_time = dimmer.GENTLE_TIME_ABS_MAX + _TD_ONE_MS
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_gentle_off_time(test_time)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_gentle_on_time(test_time)
|
||||||
|
query_helper.assert_not_called()
|
||||||
|
|
||||||
|
test_rate = dimmer.RAMP_RATE_ABS_MAX + 1
|
||||||
|
with pytest.raises(KasaException):
|
||||||
|
await dimmer.set_ramp_rate(test_rate)
|
||||||
|
query_helper.assert_not_called()
|
Loading…
x
Reference in New Issue
Block a user