From 5625d89696ec03bb44c5751d7a661cc5faa37eb6 Mon Sep 17 00:00:00 2001 From: Steven B <51370195+sdb9696@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:48:00 +0000 Subject: [PATCH 1/3] Migrate IotLightPreset to mashumaru --- kasa/iot/modules/lightpreset.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/kasa/iot/modules/lightpreset.py b/kasa/iot/modules/lightpreset.py index 6b46f7535..b6a40535b 100644 --- a/kasa/iot/modules/lightpreset.py +++ b/kasa/iot/modules/lightpreset.py @@ -3,14 +3,15 @@ from __future__ import annotations from collections.abc import Sequence -from dataclasses import asdict +from dataclasses import asdict, dataclass from typing import TYPE_CHECKING -from pydantic.v1 import BaseModel, Field +from mashumaro.config import BaseConfig from ...exceptions import KasaException from ...interfaces import LightPreset as LightPresetInterface from ...interfaces import LightState +from ...json import DataClassJSONMixin from ...module import Module from ..iotmodule import IotModule @@ -21,21 +22,27 @@ # error: Signature of "__replace__" incompatible with supertype "LightState" -class IotLightPreset(BaseModel, LightState): # type: ignore[override] +@dataclass(kw_only=True) +class IotLightPreset(DataClassJSONMixin, LightState): # type: ignore[override] """Light configuration preset.""" - index: int = Field(kw_only=True) - brightness: int = Field(kw_only=True) + class Config(BaseConfig): + """Config class.""" + + omit_none = True + + index: int + brightness: int # These are not available for effect mode presets on light strips - hue: int | None = Field(kw_only=True, default=None) - saturation: int | None = Field(kw_only=True, default=None) - color_temp: int | None = Field(kw_only=True, default=None) + hue: int | None = None + saturation: int | None = None + color_temp: int | None = None # Variables for effect mode presets - custom: int | None = Field(kw_only=True, default=None) - id: str | None = Field(kw_only=True, default=None) - mode: int | None = Field(kw_only=True, default=None) + custom: int | None = None + id: str | None = None + mode: int | None = None class LightPreset(IotModule, LightPresetInterface): @@ -47,7 +54,7 @@ class LightPreset(IotModule, LightPresetInterface): async def _post_update_hook(self) -> None: """Update the internal presets.""" self._presets = { - f"Light preset {index+1}": IotLightPreset(**vals) + f"Light preset {index+1}": IotLightPreset.from_dict(vals) for index, vals in enumerate(self.data["preferred_state"]) # Devices may list some light effects along with normal presets but these # are handled by the LightEffect module so exclude preferred states with id @@ -157,4 +164,4 @@ async def _deprecated_save_preset(self, preset: IotLightPreset) -> dict: if preset.index >= len(self._presets): raise KasaException("Invalid preset index") - return await self.call("set_preferred_state", preset.dict(exclude_none=True)) + return await self.call("set_preferred_state", preset.to_dict()) From abd3af5e7c5d719339883645986a10f817ad227b Mon Sep 17 00:00:00 2001 From: Steven B <51370195+sdb9696@users.noreply.github.com> Date: Tue, 19 Nov 2024 18:28:41 +0000 Subject: [PATCH 2/3] Fix tests and make repr return dict repr --- kasa/iot/iotbulb.py | 2 +- kasa/iot/modules/lightpreset.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/kasa/iot/iotbulb.py b/kasa/iot/iotbulb.py index e0e95020c..656e10fdb 100644 --- a/kasa/iot/iotbulb.py +++ b/kasa/iot/iotbulb.py @@ -179,7 +179,7 @@ class IotBulb(IotDevice): Bulb configuration presets can be accessed using the :func:`presets` property: >>> bulb.presets - [IotLightPreset(index=0, brightness=50, hue=0, saturation=0, color_temp=2700, custom=None, id=None, mode=None), IotLightPreset(index=1, brightness=100, hue=0, saturation=75, color_temp=0, custom=None, id=None, mode=None), IotLightPreset(index=2, brightness=100, hue=120, saturation=75, color_temp=0, custom=None, id=None, mode=None), IotLightPreset(index=3, brightness=100, hue=240, saturation=75, color_temp=0, custom=None, id=None, mode=None)] + [{'brightness': 50, 'hue': 0, 'saturation': 0, 'color_temp': 2700, 'index': 0}, {'brightness': 100, 'hue': 0, 'saturation': 75, 'color_temp': 0, 'index': 1}, {'brightness': 100, 'hue': 120, 'saturation': 75, 'color_temp': 0, 'index': 2}, {'brightness': 100, 'hue': 240, 'saturation': 75, 'color_temp': 0, 'index': 3}] To modify an existing preset, pass :class:`~kasa.interfaces.light.LightPreset` instance to :func:`save_preset` method: diff --git a/kasa/iot/modules/lightpreset.py b/kasa/iot/modules/lightpreset.py index b6a40535b..94c2e1237 100644 --- a/kasa/iot/modules/lightpreset.py +++ b/kasa/iot/modules/lightpreset.py @@ -22,7 +22,7 @@ # error: Signature of "__replace__" incompatible with supertype "LightState" -@dataclass(kw_only=True) +@dataclass(kw_only=True, repr=False) class IotLightPreset(DataClassJSONMixin, LightState): # type: ignore[override] """Light configuration preset.""" @@ -31,6 +31,9 @@ class Config(BaseConfig): omit_none = True + def __repr__(self) -> str: + return repr(self.to_dict()) + index: int brightness: int From 12732bfe42bed2257bdeedcf625f1fa4aeee1a6c Mon Sep 17 00:00:00 2001 From: Steven B <51370195+sdb9696@users.noreply.github.com> Date: Tue, 19 Nov 2024 20:03:12 +0000 Subject: [PATCH 3/3] Remove repr overload --- kasa/iot/iotbulb.py | 2 +- kasa/iot/modules/lightpreset.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/kasa/iot/iotbulb.py b/kasa/iot/iotbulb.py index 656e10fdb..14c711031 100644 --- a/kasa/iot/iotbulb.py +++ b/kasa/iot/iotbulb.py @@ -178,7 +178,7 @@ class IotBulb(IotDevice): Bulb configuration presets can be accessed using the :func:`presets` property: - >>> bulb.presets + >>> [ preset.to_dict() for preset in bulb.presets } [{'brightness': 50, 'hue': 0, 'saturation': 0, 'color_temp': 2700, 'index': 0}, {'brightness': 100, 'hue': 0, 'saturation': 75, 'color_temp': 0, 'index': 1}, {'brightness': 100, 'hue': 120, 'saturation': 75, 'color_temp': 0, 'index': 2}, {'brightness': 100, 'hue': 240, 'saturation': 75, 'color_temp': 0, 'index': 3}] To modify an existing preset, pass :class:`~kasa.interfaces.light.LightPreset` diff --git a/kasa/iot/modules/lightpreset.py b/kasa/iot/modules/lightpreset.py index 94c2e1237..d97bfc4a8 100644 --- a/kasa/iot/modules/lightpreset.py +++ b/kasa/iot/modules/lightpreset.py @@ -31,9 +31,6 @@ class Config(BaseConfig): omit_none = True - def __repr__(self) -> str: - return repr(self.to_dict()) - index: int brightness: int