From eebcbe97f6829c0e35680105675b340b69519a9a Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Fri, 16 Feb 2024 18:29:34 +0100 Subject: [PATCH 1/4] Add smartdevice module for led controls --- kasa/smart/modules/__init__.py | 9 ++++- kasa/smart/modules/ledmodule.py | 68 +++++++++++++++++++++++++++++++++ kasa/smart/smartdevice.py | 1 + 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 kasa/smart/modules/ledmodule.py diff --git a/kasa/smart/modules/__init__.py b/kasa/smart/modules/__init__.py index 564363222..6ee762843 100644 --- a/kasa/smart/modules/__init__.py +++ b/kasa/smart/modules/__init__.py @@ -2,6 +2,13 @@ from .childdevicemodule import ChildDeviceModule from .devicemodule import DeviceModule from .energymodule import EnergyModule +from .ledmodule import LedModule from .timemodule import TimeModule -__all__ = ["TimeModule", "EnergyModule", "DeviceModule", "ChildDeviceModule"] +__all__ = [ + "TimeModule", + "EnergyModule", + "DeviceModule", + "ChildDeviceModule", + "LedModule", +] diff --git a/kasa/smart/modules/ledmodule.py b/kasa/smart/modules/ledmodule.py new file mode 100644 index 000000000..6b7dc1268 --- /dev/null +++ b/kasa/smart/modules/ledmodule.py @@ -0,0 +1,68 @@ +"""Module for led controls.""" +from typing import TYPE_CHECKING, Dict + +from ...feature import Feature, FeatureType +from ..smartmodule import SmartModule + +if TYPE_CHECKING: + from ..smartdevice import SmartDevice + + +class LedModule(SmartModule): + """Implementation of led controls.""" + + REQUIRED_COMPONENT = "led" + QUERY_GETTER_NAME = "get_led_info" + + def __init__(self, device: "SmartDevice", module: str): + super().__init__(device, module) + self._add_feature( + Feature( + device=device, + container=self, + name="LED", + icon="mdi:led-{state}", + attribute_getter="led", + attribute_setter="set_led", + type=FeatureType.Switch, + ) + ) + + def query(self) -> Dict: + """Query to execute during the update cycle.""" + return {self.QUERY_GETTER_NAME: {"led_rule": None}} + + @property + def mode(self): + """LED mode setting. + + "always", "never", "night_mode" + """ + return self.data["led_rule"] + + @property + def led(self): + """Return current led status.""" + return self.data["led_status"] + + async def set_led(self, enable: bool): + """Set led. + + This should probably be a select with always/never/nightmode. + """ + rule = "always" if enable else "never" + return await self.call("set_led_info", self.data | {"led_rule": rule}) + + @property + def night_mode_settings(self): + """Night mode settings.""" + return { + "start": self.data["start_time"], + "end": self.data["end_time"], + "type": self.data["night_mode_type"], + "sunrise_offset": self.data["sunrise_offset"], + "sunset_offset": self.data["sunset_offset"], + } + + def __cli_output__(self): + return f"LED: {self.led} (mode: {self.mode})" diff --git a/kasa/smart/smartdevice.py b/kasa/smart/smartdevice.py index f5e41dc1b..50bf9715a 100644 --- a/kasa/smart/smartdevice.py +++ b/kasa/smart/smartdevice.py @@ -16,6 +16,7 @@ ChildDeviceModule, DeviceModule, EnergyModule, + LedModule, TimeModule, ) from .smartmodule import SmartModule From f9a9d07ceb525558da1414ace56f061afdc1e125 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Mon, 19 Feb 2024 18:51:58 +0100 Subject: [PATCH 2/4] Fix tests --- kasa/tests/fakeprotocol_smart.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/kasa/tests/fakeprotocol_smart.py b/kasa/tests/fakeprotocol_smart.py index bbadec0af..2f8782716 100644 --- a/kasa/tests/fakeprotocol_smart.py +++ b/kasa/tests/fakeprotocol_smart.py @@ -46,6 +46,20 @@ def credentials_hash(self): FIXTURE_MISSING_MAP = { "get_wireless_scan_info": ("wireless", {"ap_list": [], "wep_supported": False}), + "get_led_info": ( + "led", + { + "led_rule": "never", + "led_status": False, + "night_mode": { + "end_time": 420, + "night_mode_type": "sunrise_sunset", + "start_time": 1140, + "sunrise_offset": 0, + "sunset_offset": 0, + }, + }, + ), } async def send(self, request: str): From ff9f2b9d2286d8113e6d8c5f223426159533c02e Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Mon, 19 Feb 2024 20:45:25 +0100 Subject: [PATCH 3/4] Remove __cli_output__ --- kasa/smart/modules/ledmodule.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/kasa/smart/modules/ledmodule.py b/kasa/smart/modules/ledmodule.py index 6b7dc1268..72e3e33a2 100644 --- a/kasa/smart/modules/ledmodule.py +++ b/kasa/smart/modules/ledmodule.py @@ -63,6 +63,3 @@ def night_mode_settings(self): "sunrise_offset": self.data["sunrise_offset"], "sunset_offset": self.data["sunset_offset"], } - - def __cli_output__(self): - return f"LED: {self.led} (mode: {self.mode})" From 53117b6f55e59e8bee82976170f67e1b1a80219f Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Mon, 19 Feb 2024 20:53:39 +0100 Subject: [PATCH 4/4] Fix linting --- kasa/smart/smartdevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasa/smart/smartdevice.py b/kasa/smart/smartdevice.py index 1e505206e..d9e859d44 100644 --- a/kasa/smart/smartdevice.py +++ b/kasa/smart/smartdevice.py @@ -14,9 +14,9 @@ from ..smartprotocol import SmartProtocol from .modules import ( # noqa: F401 ChildDeviceModule, + CloudModule, DeviceModule, EnergyModule, - CloudModule, LedModule, LightTransitionModule, TimeModule,