mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-11-25 10:48:17 +00:00
Enable and convert to future annotations (#838)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
"""Implementation of alarm module."""
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...feature import Feature, FeatureType
|
||||
from ..smartmodule import SmartModule
|
||||
@@ -14,14 +16,14 @@ class AlarmModule(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "alarm"
|
||||
|
||||
def query(self) -> Dict:
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
return {
|
||||
"get_alarm_configure": None,
|
||||
"get_support_alarm_type_list": None, # This should be needed only once
|
||||
}
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -59,7 +61,7 @@ class AlarmModule(SmartModule):
|
||||
return self.data["get_alarm_configure"]["type"]
|
||||
|
||||
@property
|
||||
def alarm_sounds(self) -> List[str]:
|
||||
def alarm_sounds(self) -> list[str]:
|
||||
"""Return list of available alarm sounds."""
|
||||
return self.data["get_support_alarm_type_list"]["alarm_type_list"]
|
||||
|
||||
@@ -74,7 +76,7 @@ class AlarmModule(SmartModule):
|
||||
return self._device.sys_info["in_alarm"]
|
||||
|
||||
@property
|
||||
def source(self) -> Optional[str]:
|
||||
def source(self) -> str | None:
|
||||
"""Return the alarm cause."""
|
||||
src = self._device.sys_info["in_alarm_source"]
|
||||
return src if src else None
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
"""Implementation of auto off module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from typing import TYPE_CHECKING, Dict, Optional
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...feature import Feature
|
||||
from ..smartmodule import SmartModule
|
||||
@@ -16,7 +18,7 @@ class AutoOffModule(SmartModule):
|
||||
REQUIRED_COMPONENT = "auto_off"
|
||||
QUERY_GETTER_NAME = "get_auto_off_config"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -42,7 +44,7 @@ class AutoOffModule(SmartModule):
|
||||
)
|
||||
)
|
||||
|
||||
def query(self) -> Dict:
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
return {self.QUERY_GETTER_NAME: {"start_index": 0}}
|
||||
|
||||
@@ -75,7 +77,7 @@ class AutoOffModule(SmartModule):
|
||||
return self._device.sys_info["auto_off_status"] == "on"
|
||||
|
||||
@property
|
||||
def auto_off_at(self) -> Optional[datetime]:
|
||||
def auto_off_at(self) -> datetime | None:
|
||||
"""Return when the device will be turned off automatically."""
|
||||
if not self.is_timer_active:
|
||||
return None
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Implementation of battery module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...feature import Feature, FeatureType
|
||||
@@ -15,7 +17,7 @@ class BatterySensor(SmartModule):
|
||||
REQUIRED_COMPONENT = "battery_detect"
|
||||
QUERY_GETTER_NAME = "get_battery_detect_info"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"""Implementation of brightness module."""
|
||||
|
||||
from typing import TYPE_CHECKING, Dict
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...feature import Feature, FeatureType
|
||||
from ..smartmodule import SmartModule
|
||||
@@ -14,7 +16,7 @@ class Brightness(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "brightness"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -29,7 +31,7 @@ class Brightness(SmartModule):
|
||||
)
|
||||
)
|
||||
|
||||
def query(self) -> Dict:
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
# Brightness is contained in the main device info response.
|
||||
return {}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Implementation of cloud module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...feature import Feature, FeatureType
|
||||
@@ -15,7 +17,7 @@ class CloudModule(SmartModule):
|
||||
QUERY_GETTER_NAME = "get_connect_cloud_state"
|
||||
REQUIRED_COMPONENT = "cloud_connect"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
|
||||
self._add_feature(
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"""Implementation of color temp module."""
|
||||
|
||||
from typing import TYPE_CHECKING, Dict
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...bulb import ColorTempRange
|
||||
from ...feature import Feature
|
||||
@@ -15,7 +17,7 @@ class ColorTemperatureModule(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "color_temperature"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -28,7 +30,7 @@ class ColorTemperatureModule(SmartModule):
|
||||
)
|
||||
)
|
||||
|
||||
def query(self) -> Dict:
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
# Color temp is contained in the main device info response.
|
||||
return {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Implementation of device module."""
|
||||
|
||||
from typing import Dict
|
||||
from __future__ import annotations
|
||||
|
||||
from ..smartmodule import SmartModule
|
||||
|
||||
@@ -10,7 +10,7 @@ class DeviceModule(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "device"
|
||||
|
||||
def query(self) -> Dict:
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
query = {
|
||||
"get_device_info": None,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"""Implementation of energy monitoring module."""
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, Optional
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...emeterstatus import EmeterStatus
|
||||
from ...feature import Feature
|
||||
@@ -15,7 +17,7 @@ class EnergyModule(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "energy_monitoring"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -42,7 +44,7 @@ class EnergyModule(SmartModule):
|
||||
)
|
||||
) # Wh or kWH?
|
||||
|
||||
def query(self) -> Dict:
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
req = {
|
||||
"get_energy_usage": None,
|
||||
@@ -77,15 +79,15 @@ class EnergyModule(SmartModule):
|
||||
)
|
||||
|
||||
@property
|
||||
def emeter_this_month(self) -> Optional[float]:
|
||||
def emeter_this_month(self) -> float | None:
|
||||
"""Get the emeter value for this month."""
|
||||
return self._convert_energy_data(self.energy.get("month_energy"), 1 / 1000)
|
||||
|
||||
@property
|
||||
def emeter_today(self) -> Optional[float]:
|
||||
def emeter_today(self) -> float | None:
|
||||
"""Get the emeter value for today."""
|
||||
return self._convert_energy_data(self.energy.get("today_energy"), 1 / 1000)
|
||||
|
||||
def _convert_energy_data(self, data, scale) -> Optional[float]:
|
||||
def _convert_energy_data(self, data, scale) -> float | None:
|
||||
"""Return adjusted emeter information."""
|
||||
return data if not data else data * scale
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
"""Implementation of fan_control module."""
|
||||
from typing import TYPE_CHECKING, Dict
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...feature import Feature, FeatureType
|
||||
from ..smartmodule import SmartModule
|
||||
@@ -13,7 +16,7 @@ class FanModule(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "fan_control"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
|
||||
self._add_feature(
|
||||
@@ -37,11 +40,11 @@ class FanModule(SmartModule):
|
||||
attribute_getter="sleep_mode",
|
||||
attribute_setter="set_sleep_mode",
|
||||
icon="mdi:sleep",
|
||||
type=FeatureType.Switch
|
||||
type=FeatureType.Switch,
|
||||
)
|
||||
)
|
||||
|
||||
def query(self) -> Dict:
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
return {}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"""Implementation of firmware module."""
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, Optional
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from ...exceptions import SmartErrorCode
|
||||
from ...feature import Feature, FeatureType
|
||||
@@ -20,11 +22,11 @@ class UpdateInfo(BaseModel):
|
||||
"""Update info status object."""
|
||||
|
||||
status: int = Field(alias="type")
|
||||
fw_ver: Optional[str] = None
|
||||
release_date: Optional[date] = None
|
||||
release_notes: Optional[str] = Field(alias="release_note", default=None)
|
||||
fw_size: Optional[int] = None
|
||||
oem_id: Optional[str] = None
|
||||
fw_ver: Optional[str] = None # noqa: UP007
|
||||
release_date: Optional[date] = None # noqa: UP007
|
||||
release_notes: Optional[str] = Field(alias="release_note", default=None) # noqa: UP007
|
||||
fw_size: Optional[int] = None # noqa: UP007
|
||||
oem_id: Optional[str] = None # noqa: UP007
|
||||
needs_upgrade: bool = Field(alias="need_to_upgrade")
|
||||
|
||||
@validator("release_date", pre=True)
|
||||
@@ -47,7 +49,7 @@ class Firmware(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "firmware"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
if self.supported_version > 1:
|
||||
self._add_feature(
|
||||
@@ -70,7 +72,7 @@ class Firmware(SmartModule):
|
||||
)
|
||||
)
|
||||
|
||||
def query(self) -> Dict:
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
req = {
|
||||
"get_latest_fw": None,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Implementation of humidity module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...feature import Feature, FeatureType
|
||||
@@ -15,7 +17,7 @@ class HumiditySensor(SmartModule):
|
||||
REQUIRED_COMPONENT = "humidity"
|
||||
QUERY_GETTER_NAME = "get_comfort_humidity_config"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"""Module for led controls."""
|
||||
|
||||
from typing import TYPE_CHECKING, Dict
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...feature import Feature, FeatureType
|
||||
from ..smartmodule import SmartModule
|
||||
@@ -15,7 +17,7 @@ class LedModule(SmartModule):
|
||||
REQUIRED_COMPONENT = "led"
|
||||
QUERY_GETTER_NAME = "get_led_info"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -29,7 +31,7 @@ class LedModule(SmartModule):
|
||||
)
|
||||
)
|
||||
|
||||
def query(self) -> Dict:
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
return {self.QUERY_GETTER_NAME: {"led_rule": None}}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Module for smooth light transitions."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...exceptions import KasaException
|
||||
@@ -17,7 +19,7 @@ class LightTransitionModule(SmartModule):
|
||||
QUERY_GETTER_NAME = "get_on_off_gradually_info"
|
||||
MAXIMUM_DURATION = 60
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._create_features()
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Implementation of report module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ...feature import Feature
|
||||
@@ -15,7 +17,7 @@ class ReportModule(SmartModule):
|
||||
REQUIRED_COMPONENT = "report_mode"
|
||||
QUERY_GETTER_NAME = "get_report_mode"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Implementation of temperature module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
from ...feature import Feature, FeatureType
|
||||
@@ -15,7 +17,7 @@ class TemperatureSensor(SmartModule):
|
||||
REQUIRED_COMPONENT = "temperature"
|
||||
QUERY_GETTER_NAME = "get_comfort_temp_config"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Implementation of time module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from time import mktime
|
||||
from typing import TYPE_CHECKING, cast
|
||||
@@ -17,7 +19,7 @@ class TimeModule(SmartModule):
|
||||
REQUIRED_COMPONENT = "time"
|
||||
QUERY_GETTER_NAME = "get_device_time"
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
super().__init__(device, module)
|
||||
|
||||
self._add_feature(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Module for tapo-branded smart bulbs (L5**)."""
|
||||
|
||||
from typing import Dict, List, Optional
|
||||
from __future__ import annotations
|
||||
|
||||
from ..bulb import Bulb
|
||||
from ..exceptions import KasaException
|
||||
@@ -55,7 +55,7 @@ class SmartBulb(SmartDevice, Bulb):
|
||||
return "dynamic_light_effect_enable" in self._info
|
||||
|
||||
@property
|
||||
def effect(self) -> Dict:
|
||||
def effect(self) -> dict:
|
||||
"""Return effect state.
|
||||
|
||||
This follows the format used by SmartLightStrip.
|
||||
@@ -79,7 +79,7 @@ class SmartBulb(SmartDevice, Bulb):
|
||||
return data
|
||||
|
||||
@property
|
||||
def effect_list(self) -> Optional[List[str]]:
|
||||
def effect_list(self) -> list[str] | None:
|
||||
"""Return built-in effects list.
|
||||
|
||||
Example:
|
||||
@@ -124,10 +124,10 @@ class SmartBulb(SmartDevice, Bulb):
|
||||
self,
|
||||
hue: int,
|
||||
saturation: int,
|
||||
value: Optional[int] = None,
|
||||
value: int | None = None,
|
||||
*,
|
||||
transition: Optional[int] = None,
|
||||
) -> Dict:
|
||||
transition: int | None = None,
|
||||
) -> dict:
|
||||
"""Set new HSV.
|
||||
|
||||
Note, transition is not supported and will be ignored.
|
||||
@@ -163,8 +163,8 @@ class SmartBulb(SmartDevice, Bulb):
|
||||
return await self.protocol.query({"set_device_info": {**request_payload}})
|
||||
|
||||
async def set_color_temp(
|
||||
self, temp: int, *, brightness=None, transition: Optional[int] = None
|
||||
) -> Dict:
|
||||
self, temp: int, *, brightness=None, transition: int | None = None
|
||||
) -> dict:
|
||||
"""Set the color temperature of the device in kelvin.
|
||||
|
||||
Note, transition is not supported and will be ignored.
|
||||
@@ -193,8 +193,8 @@ class SmartBulb(SmartDevice, Bulb):
|
||||
raise ValueError(f"Invalid brightness value: {value} (valid range: 1-100%)")
|
||||
|
||||
async def set_brightness(
|
||||
self, brightness: int, *, transition: Optional[int] = None
|
||||
) -> Dict:
|
||||
self, brightness: int, *, transition: int | None = None
|
||||
) -> dict:
|
||||
"""Set the brightness in percentage.
|
||||
|
||||
Note, transition is not supported and will be ignored.
|
||||
@@ -215,13 +215,13 @@ class SmartBulb(SmartDevice, Bulb):
|
||||
self,
|
||||
effect: str,
|
||||
*,
|
||||
brightness: Optional[int] = None,
|
||||
transition: Optional[int] = None,
|
||||
brightness: int | None = None,
|
||||
transition: int | None = None,
|
||||
) -> None:
|
||||
"""Set an effect on the device."""
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def presets(self) -> List[BulbPreset]:
|
||||
def presets(self) -> list[BulbPreset]:
|
||||
"""Return a list of available bulb setting presets."""
|
||||
return []
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"""Child device implementation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from ..device_type import DeviceType
|
||||
from ..deviceconfig import DeviceConfig
|
||||
@@ -22,8 +23,8 @@ class SmartChildDevice(SmartDevice):
|
||||
parent: SmartDevice,
|
||||
info,
|
||||
component_info,
|
||||
config: Optional[DeviceConfig] = None,
|
||||
protocol: Optional[SmartProtocol] = None,
|
||||
config: DeviceConfig | None = None,
|
||||
protocol: SmartProtocol | None = None,
|
||||
) -> None:
|
||||
super().__init__(parent.host, config=parent.config, protocol=parent.protocol)
|
||||
self._parent = parent
|
||||
@@ -38,7 +39,7 @@ class SmartChildDevice(SmartDevice):
|
||||
@classmethod
|
||||
async def create(cls, parent: SmartDevice, child_info, child_components):
|
||||
"""Create a child device based on device info and component listing."""
|
||||
child: "SmartChildDevice" = cls(parent, child_info, child_components)
|
||||
child: SmartChildDevice = cls(parent, child_info, child_components)
|
||||
await child._initialize_modules()
|
||||
await child._initialize_features()
|
||||
return child
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
"""Module for a SMART device."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Sequence, cast
|
||||
from typing import TYPE_CHECKING, Any, Mapping, Sequence, cast
|
||||
|
||||
from ..aestransport import AesTransport
|
||||
from ..device import Device, WifiNetwork
|
||||
@@ -28,20 +30,20 @@ class SmartDevice(Device):
|
||||
self,
|
||||
host: str,
|
||||
*,
|
||||
config: Optional[DeviceConfig] = None,
|
||||
protocol: Optional[SmartProtocol] = None,
|
||||
config: DeviceConfig | None = None,
|
||||
protocol: SmartProtocol | None = None,
|
||||
) -> None:
|
||||
_protocol = protocol or SmartProtocol(
|
||||
transport=AesTransport(config=config or DeviceConfig(host=host)),
|
||||
)
|
||||
super().__init__(host=host, config=config, protocol=_protocol)
|
||||
self.protocol: SmartProtocol
|
||||
self._components_raw: Optional[Dict[str, Any]] = None
|
||||
self._components: Dict[str, int] = {}
|
||||
self._state_information: Dict[str, Any] = {}
|
||||
self.modules: Dict[str, "SmartModule"] = {}
|
||||
self._parent: Optional["SmartDevice"] = None
|
||||
self._children: Mapping[str, "SmartDevice"] = {}
|
||||
self._components_raw: dict[str, Any] | None = None
|
||||
self._components: dict[str, int] = {}
|
||||
self._state_information: dict[str, Any] = {}
|
||||
self.modules: dict[str, SmartModule] = {}
|
||||
self._parent: SmartDevice | None = None
|
||||
self._children: Mapping[str, SmartDevice] = {}
|
||||
self._last_update = {}
|
||||
|
||||
async def _initialize_children(self):
|
||||
@@ -74,7 +76,7 @@ class SmartDevice(Device):
|
||||
}
|
||||
|
||||
@property
|
||||
def children(self) -> Sequence["SmartDevice"]:
|
||||
def children(self) -> Sequence[SmartDevice]:
|
||||
"""Return list of children."""
|
||||
return list(self._children.values())
|
||||
|
||||
@@ -130,7 +132,7 @@ class SmartDevice(Device):
|
||||
await self._negotiate()
|
||||
await self._initialize_modules()
|
||||
|
||||
req: Dict[str, Any] = {}
|
||||
req: dict[str, Any] = {}
|
||||
|
||||
# TODO: this could be optimized by constructing the query only once
|
||||
for module in self.modules.values():
|
||||
@@ -236,7 +238,7 @@ class SmartDevice(Device):
|
||||
self._add_feature(feat)
|
||||
|
||||
@property
|
||||
def sys_info(self) -> Dict[str, Any]:
|
||||
def sys_info(self) -> dict[str, Any]:
|
||||
"""Returns the device info."""
|
||||
return self._info # type: ignore
|
||||
|
||||
@@ -246,7 +248,7 @@ class SmartDevice(Device):
|
||||
return str(self._info.get("model"))
|
||||
|
||||
@property
|
||||
def alias(self) -> Optional[str]:
|
||||
def alias(self) -> str | None:
|
||||
"""Returns the device alias or nickname."""
|
||||
if self._info and (nickname := self._info.get("nickname")):
|
||||
return base64.b64decode(nickname).decode()
|
||||
@@ -265,13 +267,13 @@ class SmartDevice(Device):
|
||||
return _timemod.time
|
||||
|
||||
@property
|
||||
def timezone(self) -> Dict:
|
||||
def timezone(self) -> dict:
|
||||
"""Return the timezone and time_difference."""
|
||||
ti = self.time
|
||||
return {"timezone": ti.tzname()}
|
||||
|
||||
@property
|
||||
def hw_info(self) -> Dict:
|
||||
def hw_info(self) -> dict:
|
||||
"""Return hardware info for the device."""
|
||||
return {
|
||||
"sw_ver": self._info.get("fw_ver"),
|
||||
@@ -284,7 +286,7 @@ class SmartDevice(Device):
|
||||
}
|
||||
|
||||
@property
|
||||
def location(self) -> Dict:
|
||||
def location(self) -> dict:
|
||||
"""Return the device location."""
|
||||
loc = {
|
||||
"latitude": cast(float, self._info.get("latitude", 0)) / 10_000,
|
||||
@@ -293,7 +295,7 @@ class SmartDevice(Device):
|
||||
return loc
|
||||
|
||||
@property
|
||||
def rssi(self) -> Optional[int]:
|
||||
def rssi(self) -> int | None:
|
||||
"""Return the rssi."""
|
||||
rssi = self._info.get("rssi")
|
||||
return int(rssi) if rssi else None
|
||||
@@ -321,7 +323,7 @@ class SmartDevice(Device):
|
||||
self._info = info
|
||||
|
||||
async def _query_helper(
|
||||
self, method: str, params: Optional[Dict] = None, child_ids=None
|
||||
self, method: str, params: dict | None = None, child_ids=None
|
||||
) -> Any:
|
||||
res = await self.protocol.query({method: params})
|
||||
|
||||
@@ -378,19 +380,19 @@ class SmartDevice(Device):
|
||||
return energy.emeter_realtime
|
||||
|
||||
@property
|
||||
def emeter_this_month(self) -> Optional[float]:
|
||||
def emeter_this_month(self) -> float | None:
|
||||
"""Get the emeter value for this month."""
|
||||
energy = cast(EnergyModule, self.modules["EnergyModule"]) # noqa: F405
|
||||
return energy.emeter_this_month
|
||||
|
||||
@property
|
||||
def emeter_today(self) -> Optional[float]:
|
||||
def emeter_today(self) -> float | None:
|
||||
"""Get the emeter value for today."""
|
||||
energy = cast(EnergyModule, self.modules["EnergyModule"]) # noqa: F405
|
||||
return energy.emeter_today
|
||||
|
||||
@property
|
||||
def on_since(self) -> Optional[datetime]:
|
||||
def on_since(self) -> datetime | None:
|
||||
"""Return the time that the device was turned on or None if turned off."""
|
||||
if (
|
||||
not self._info.get("device_on")
|
||||
@@ -404,7 +406,7 @@ class SmartDevice(Device):
|
||||
else: # We have no device time, use current local time.
|
||||
return datetime.now().replace(microsecond=0) - timedelta(seconds=on_time)
|
||||
|
||||
async def wifi_scan(self) -> List[WifiNetwork]:
|
||||
async def wifi_scan(self) -> list[WifiNetwork]:
|
||||
"""Scan for available wifi networks."""
|
||||
|
||||
def _net_for_scan_info(res):
|
||||
@@ -527,7 +529,7 @@ class SmartDevice(Device):
|
||||
|
||||
@staticmethod
|
||||
def _get_device_type_from_components(
|
||||
components: List[str], device_type: str
|
||||
components: list[str], device_type: str
|
||||
) -> DeviceType:
|
||||
"""Find type to be displayed as a supported device category."""
|
||||
if "HUB" in device_type:
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
"""Base implementation for SMART modules."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Dict, Type
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ..exceptions import KasaException
|
||||
from ..module import Module
|
||||
@@ -18,9 +20,9 @@ class SmartModule(Module):
|
||||
NAME: str
|
||||
REQUIRED_COMPONENT: str
|
||||
QUERY_GETTER_NAME: str
|
||||
REGISTERED_MODULES: Dict[str, Type["SmartModule"]] = {}
|
||||
REGISTERED_MODULES: dict[str, type[SmartModule]] = {}
|
||||
|
||||
def __init__(self, device: "SmartDevice", module: str):
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
self._device: SmartDevice
|
||||
super().__init__(device, module)
|
||||
|
||||
@@ -36,7 +38,7 @@ class SmartModule(Module):
|
||||
"""Name of the module."""
|
||||
return getattr(self, "NAME", self.__class__.__name__)
|
||||
|
||||
def query(self) -> Dict:
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle.
|
||||
|
||||
Default implementation uses the raw query getter w/o parameters.
|
||||
|
||||
Reference in New Issue
Block a user