diff --git a/kasa/iot/iotbulb.py b/kasa/iot/iotbulb.py index e0e95020..14c71103 100644 --- a/kasa/iot/iotbulb.py +++ b/kasa/iot/iotbulb.py @@ -178,8 +178,8 @@ 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)] + >>> [ 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` instance to :func:`save_preset` method: diff --git a/kasa/iot/modules/lightpreset.py b/kasa/iot/modules/lightpreset.py index 6b46f753..d97bfc4a 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 @@ if TYPE_CHECKING: # error: Signature of "__replace__" incompatible with supertype "LightState" -class IotLightPreset(BaseModel, LightState): # type: ignore[override] +@dataclass(kw_only=True, repr=False) +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 @@ class LightPreset(IotModule, LightPresetInterface): 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())