mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 19:23:34 +00:00
Migrate TurnOnBehaviours to mashumaro (#1285)
This commit is contained in:
parent
0e5013d4b4
commit
955e7ab4d0
@ -4,10 +4,13 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
from dataclasses import dataclass
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import cast
|
from typing import Annotated, cast
|
||||||
|
|
||||||
from pydantic.v1 import BaseModel, Field, root_validator
|
from mashumaro import DataClassDictMixin
|
||||||
|
from mashumaro.config import BaseConfig
|
||||||
|
from mashumaro.types import Alias
|
||||||
|
|
||||||
from ..device_type import DeviceType
|
from ..device_type import DeviceType
|
||||||
from ..deviceconfig import DeviceConfig
|
from ..deviceconfig import DeviceConfig
|
||||||
@ -35,9 +38,12 @@ class BehaviorMode(str, Enum):
|
|||||||
Last = "last_status"
|
Last = "last_status"
|
||||||
#: Use chosen preset.
|
#: Use chosen preset.
|
||||||
Preset = "customize_preset"
|
Preset = "customize_preset"
|
||||||
|
#: Circadian
|
||||||
|
Circadian = "circadian"
|
||||||
|
|
||||||
|
|
||||||
class TurnOnBehavior(BaseModel):
|
@dataclass
|
||||||
|
class TurnOnBehavior(DataClassDictMixin):
|
||||||
"""Model to present a single turn on behavior.
|
"""Model to present a single turn on behavior.
|
||||||
|
|
||||||
:param int preset: the index number of wanted preset.
|
:param int preset: the index number of wanted preset.
|
||||||
@ -48,34 +54,30 @@ class TurnOnBehavior(BaseModel):
|
|||||||
to contain either the preset index, or ``None`` for the last known state.
|
to contain either the preset index, or ``None`` for the last known state.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#: Index of preset to use, or ``None`` for the last known state.
|
class Config(BaseConfig):
|
||||||
preset: int | None = Field(alias="index", default=None)
|
"""Serialization config."""
|
||||||
|
|
||||||
|
omit_none = True
|
||||||
|
serialize_by_alias = True
|
||||||
|
|
||||||
#: Wanted behavior
|
#: Wanted behavior
|
||||||
mode: BehaviorMode
|
mode: BehaviorMode
|
||||||
|
#: Index of preset to use, or ``None`` for the last known state.
|
||||||
@root_validator
|
preset: Annotated[int | None, Alias("index")] = None
|
||||||
def _mode_based_on_preset(cls, values: dict) -> dict:
|
brightness: int | None = None
|
||||||
"""Set the mode based on the preset value."""
|
color_temp: int | None = None
|
||||||
if values["preset"] is not None:
|
hue: int | None = None
|
||||||
values["mode"] = BehaviorMode.Preset
|
saturation: int | None = None
|
||||||
else:
|
|
||||||
values["mode"] = BehaviorMode.Last
|
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
"""Configuration to make the validator run when changing the values."""
|
|
||||||
|
|
||||||
validate_assignment = True
|
|
||||||
|
|
||||||
|
|
||||||
class TurnOnBehaviors(BaseModel):
|
@dataclass
|
||||||
|
class TurnOnBehaviors(DataClassDictMixin):
|
||||||
"""Model to contain turn on behaviors."""
|
"""Model to contain turn on behaviors."""
|
||||||
|
|
||||||
#: The behavior when the bulb is turned on programmatically.
|
#: The behavior when the bulb is turned on programmatically.
|
||||||
soft: TurnOnBehavior = Field(alias="soft_on")
|
soft: Annotated[TurnOnBehavior, Alias("soft_on")]
|
||||||
#: The behavior when the bulb has been off from mains power.
|
#: The behavior when the bulb has been off from mains power.
|
||||||
hard: TurnOnBehavior = Field(alias="hard_on")
|
hard: Annotated[TurnOnBehavior, Alias("hard_on")]
|
||||||
|
|
||||||
|
|
||||||
TPLINK_KELVIN = {
|
TPLINK_KELVIN = {
|
||||||
@ -303,7 +305,7 @@ class IotBulb(IotDevice):
|
|||||||
|
|
||||||
async def get_turn_on_behavior(self) -> TurnOnBehaviors:
|
async def get_turn_on_behavior(self) -> TurnOnBehaviors:
|
||||||
"""Return the behavior for turning the bulb on."""
|
"""Return the behavior for turning the bulb on."""
|
||||||
return TurnOnBehaviors.parse_obj(
|
return TurnOnBehaviors.from_dict(
|
||||||
await self._query_helper(self.LIGHT_SERVICE, "get_default_behavior")
|
await self._query_helper(self.LIGHT_SERVICE, "get_default_behavior")
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -314,7 +316,7 @@ class IotBulb(IotDevice):
|
|||||||
you should use :func:`get_turn_on_behavior` to get the current settings.
|
you should use :func:`get_turn_on_behavior` to get the current settings.
|
||||||
"""
|
"""
|
||||||
return await self._query_helper(
|
return await self._query_helper(
|
||||||
self.LIGHT_SERVICE, "set_default_behavior", behavior.dict(by_alias=True)
|
self.LIGHT_SERVICE, "set_default_behavior", behavior.to_dict()
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_light_state(self) -> dict[str, dict]:
|
async def get_light_state(self) -> dict[str, dict]:
|
||||||
|
@ -176,6 +176,23 @@ MOTION_MODULE = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIGHT_DETAILS = {
|
||||||
|
"color_rendering_index": 80,
|
||||||
|
"err_code": 0,
|
||||||
|
"incandescent_equivalent": 60,
|
||||||
|
"lamp_beam_angle": 150,
|
||||||
|
"max_lumens": 800,
|
||||||
|
"max_voltage": 120,
|
||||||
|
"min_voltage": 110,
|
||||||
|
"wattage": 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFAULT_BEHAVIOR = {
|
||||||
|
"err_code": 0,
|
||||||
|
"hard_on": {"mode": "circadian"},
|
||||||
|
"soft_on": {"mode": "last_status"},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class FakeIotProtocol(IotProtocol):
|
class FakeIotProtocol(IotProtocol):
|
||||||
def __init__(self, info, fixture_name=None, *, verbatim=False):
|
def __init__(self, info, fixture_name=None, *, verbatim=False):
|
||||||
@ -399,6 +416,8 @@ class FakeIotTransport(BaseTransport):
|
|||||||
},
|
},
|
||||||
"smartlife.iot.smartbulb.lightingservice": {
|
"smartlife.iot.smartbulb.lightingservice": {
|
||||||
"get_light_state": light_state,
|
"get_light_state": light_state,
|
||||||
|
"get_light_details": LIGHT_DETAILS,
|
||||||
|
"get_default_behavior": DEFAULT_BEHAVIOR,
|
||||||
"transition_light_state": transition_light_state,
|
"transition_light_state": transition_light_state,
|
||||||
"set_preferred_state": set_preferred_state,
|
"set_preferred_state": set_preferred_state,
|
||||||
},
|
},
|
||||||
@ -409,6 +428,8 @@ class FakeIotTransport(BaseTransport):
|
|||||||
"smartlife.iot.lightStrip": {
|
"smartlife.iot.lightStrip": {
|
||||||
"set_light_state": transition_light_state,
|
"set_light_state": transition_light_state,
|
||||||
"get_light_state": light_state,
|
"get_light_state": light_state,
|
||||||
|
"get_light_details": LIGHT_DETAILS,
|
||||||
|
"get_default_behavior": DEFAULT_BEHAVIOR,
|
||||||
"set_preferred_state": set_preferred_state,
|
"set_preferred_state": set_preferred_state,
|
||||||
},
|
},
|
||||||
"smartlife.iot.common.system": {
|
"smartlife.iot.common.system": {
|
||||||
|
@ -497,3 +497,9 @@ SYSINFO_SCHEMA_BULB = SYSINFO_SCHEMA.extend(
|
|||||||
@bulb
|
@bulb
|
||||||
def test_device_type_bulb(dev: Device):
|
def test_device_type_bulb(dev: Device):
|
||||||
assert dev.device_type in {DeviceType.Bulb, DeviceType.LightStrip}
|
assert dev.device_type in {DeviceType.Bulb, DeviceType.LightStrip}
|
||||||
|
|
||||||
|
|
||||||
|
@bulb_iot
|
||||||
|
async def test_turn_on_behaviours(dev: IotBulb):
|
||||||
|
behavior = await dev.get_turn_on_behavior()
|
||||||
|
assert behavior
|
||||||
|
Loading…
Reference in New Issue
Block a user