mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-08-09 20:24:02 +00:00
Make module names consistent and remove redundant module casting (#909)
Address the inconsistent naming of smart modules by removing all "Module" suffixes and aligning filenames with class names. Removes the casting of modules to the correct module type now that is is redundant. Update the adding of iot modules to use the ModuleName class rather than a free string.
This commit is contained in:
@@ -1,51 +1,51 @@
|
||||
"""Modules for SMART devices."""
|
||||
|
||||
from .alarmmodule import AlarmModule
|
||||
from .autooffmodule import AutoOffModule
|
||||
from .battery import BatterySensor
|
||||
from .alarm import Alarm
|
||||
from .autooff import AutoOff
|
||||
from .batterysensor import BatterySensor
|
||||
from .brightness import Brightness
|
||||
from .childdevicemodule import ChildDeviceModule
|
||||
from .cloudmodule import CloudModule
|
||||
from .colormodule import ColorModule
|
||||
from .colortemp import ColorTemperatureModule
|
||||
from .contact import ContactSensor
|
||||
from .childdevice import ChildDevice
|
||||
from .cloud import Cloud
|
||||
from .color import Color
|
||||
from .colortemperature import ColorTemperature
|
||||
from .contactsensor import ContactSensor
|
||||
from .devicemodule import DeviceModule
|
||||
from .energymodule import EnergyModule
|
||||
from .fanmodule import FanModule
|
||||
from .energy import Energy
|
||||
from .fan import Fan
|
||||
from .firmware import Firmware
|
||||
from .frostprotection import FrostProtectionModule
|
||||
from .humidity import HumiditySensor
|
||||
from .ledmodule import LedModule
|
||||
from .lighteffectmodule import LightEffectModule
|
||||
from .lighttransitionmodule import LightTransitionModule
|
||||
from .reportmodule import ReportModule
|
||||
from .temperature import TemperatureSensor
|
||||
from .frostprotection import FrostProtection
|
||||
from .humiditysensor import HumiditySensor
|
||||
from .led import Led
|
||||
from .lighteffect import LightEffect
|
||||
from .lighttransition import LightTransition
|
||||
from .reportmode import ReportMode
|
||||
from .temperaturecontrol import TemperatureControl
|
||||
from .timemodule import TimeModule
|
||||
from .waterleak import WaterleakSensor
|
||||
from .temperaturesensor import TemperatureSensor
|
||||
from .time import Time
|
||||
from .waterleaksensor import WaterleakSensor
|
||||
|
||||
__all__ = [
|
||||
"AlarmModule",
|
||||
"TimeModule",
|
||||
"EnergyModule",
|
||||
"Alarm",
|
||||
"Time",
|
||||
"Energy",
|
||||
"DeviceModule",
|
||||
"ChildDeviceModule",
|
||||
"ChildDevice",
|
||||
"BatterySensor",
|
||||
"HumiditySensor",
|
||||
"TemperatureSensor",
|
||||
"TemperatureControl",
|
||||
"ReportModule",
|
||||
"AutoOffModule",
|
||||
"LedModule",
|
||||
"ReportMode",
|
||||
"AutoOff",
|
||||
"Led",
|
||||
"Brightness",
|
||||
"FanModule",
|
||||
"Fan",
|
||||
"Firmware",
|
||||
"CloudModule",
|
||||
"LightEffectModule",
|
||||
"LightTransitionModule",
|
||||
"ColorTemperatureModule",
|
||||
"ColorModule",
|
||||
"Cloud",
|
||||
"LightEffect",
|
||||
"LightTransition",
|
||||
"ColorTemperature",
|
||||
"Color",
|
||||
"WaterleakSensor",
|
||||
"ContactSensor",
|
||||
"FrostProtectionModule",
|
||||
"FrostProtection",
|
||||
]
|
||||
|
@@ -6,7 +6,7 @@ from ...feature import Feature
|
||||
from ..smartmodule import SmartModule
|
||||
|
||||
|
||||
class AlarmModule(SmartModule):
|
||||
class Alarm(SmartModule):
|
||||
"""Implementation of alarm module."""
|
||||
|
||||
REQUIRED_COMPONENT = "alarm"
|
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
||||
from ..smartdevice import SmartDevice
|
||||
|
||||
|
||||
class AutoOffModule(SmartModule):
|
||||
class AutoOff(SmartModule):
|
||||
"""Implementation of auto off module."""
|
||||
|
||||
REQUIRED_COMPONENT = "auto_off"
|
@@ -3,7 +3,7 @@
|
||||
from ..smartmodule import SmartModule
|
||||
|
||||
|
||||
class ChildDeviceModule(SmartModule):
|
||||
class ChildDevice(SmartModule):
|
||||
"""Implementation for child devices."""
|
||||
|
||||
REQUIRED_COMPONENT = "child_device"
|
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
||||
from ..smartdevice import SmartDevice
|
||||
|
||||
|
||||
class CloudModule(SmartModule):
|
||||
class Cloud(SmartModule):
|
||||
"""Implementation of cloud module."""
|
||||
|
||||
QUERY_GETTER_NAME = "get_connect_cloud_state"
|
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
||||
from ..smartdevice import SmartDevice
|
||||
|
||||
|
||||
class ColorModule(SmartModule):
|
||||
class Color(SmartModule):
|
||||
"""Implementation of color module."""
|
||||
|
||||
REQUIRED_COMPONENT = "color"
|
@@ -18,7 +18,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
DEFAULT_TEMP_RANGE = [2500, 6500]
|
||||
|
||||
|
||||
class ColorTemperatureModule(SmartModule):
|
||||
class ColorTemperature(SmartModule):
|
||||
"""Implementation of color temp module."""
|
||||
|
||||
REQUIRED_COMPONENT = "color_temperature"
|
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
||||
from ..smartdevice import SmartDevice
|
||||
|
||||
|
||||
class EnergyModule(SmartModule):
|
||||
class Energy(SmartModule):
|
||||
"""Implementation of energy monitoring module."""
|
||||
|
||||
REQUIRED_COMPONENT = "energy_monitoring"
|
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
||||
from ..smartdevice import SmartDevice
|
||||
|
||||
|
||||
class FanModule(SmartModule):
|
||||
class Fan(SmartModule):
|
||||
"""Implementation of fan_control module."""
|
||||
|
||||
REQUIRED_COMPONENT = "fan_control"
|
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
||||
from ..smartdevice import SmartDevice
|
||||
|
||||
|
||||
class FrostProtectionModule(SmartModule):
|
||||
class FrostProtection(SmartModule):
|
||||
"""Implementation for frost protection module.
|
||||
|
||||
This basically turns the thermostat on and off.
|
||||
|
@@ -2,11 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from ...interfaces.led import Led
|
||||
from ...interfaces.led import Led as LedInterface
|
||||
from ..smartmodule import SmartModule
|
||||
|
||||
|
||||
class LedModule(SmartModule, Led):
|
||||
class Led(SmartModule, LedInterface):
|
||||
"""Implementation of led controls."""
|
||||
|
||||
REQUIRED_COMPONENT = "led"
|
@@ -6,14 +6,14 @@ import base64
|
||||
import copy
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ...interfaces.lighteffect import LightEffect
|
||||
from ...interfaces.lighteffect import LightEffect as LightEffectInterface
|
||||
from ..smartmodule import SmartModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..smartdevice import SmartDevice
|
||||
|
||||
|
||||
class LightEffectModule(SmartModule, LightEffect):
|
||||
class LightEffect(SmartModule, LightEffectInterface):
|
||||
"""Implementation of dynamic light effects."""
|
||||
|
||||
REQUIRED_COMPONENT = "light_effect"
|
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
||||
from ..smartdevice import SmartDevice
|
||||
|
||||
|
||||
class LightTransitionModule(SmartModule):
|
||||
class LightTransition(SmartModule):
|
||||
"""Implementation of gradual on/off."""
|
||||
|
||||
REQUIRED_COMPONENT = "on_off_gradually"
|
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
||||
from ..smartdevice import SmartDevice
|
||||
|
||||
|
||||
class ReportModule(SmartModule):
|
||||
class ReportMode(SmartModule):
|
||||
"""Implementation of report module."""
|
||||
|
||||
REQUIRED_COMPONENT = "report_mode"
|
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
||||
from ..smartdevice import SmartDevice
|
||||
|
||||
|
||||
class TimeModule(SmartModule):
|
||||
class Time(SmartModule):
|
||||
"""Implementation of device_local_time."""
|
||||
|
||||
REQUIRED_COMPONENT = "time"
|
@@ -20,15 +20,10 @@ from ..module import Module
|
||||
from ..modulemapping import ModuleMapping, ModuleName
|
||||
from ..smartprotocol import SmartProtocol
|
||||
from .modules import (
|
||||
Brightness,
|
||||
CloudModule,
|
||||
ColorModule,
|
||||
ColorTemperatureModule,
|
||||
Cloud,
|
||||
DeviceModule,
|
||||
EnergyModule,
|
||||
FanModule,
|
||||
Firmware,
|
||||
TimeModule,
|
||||
Time,
|
||||
)
|
||||
from .smartmodule import SmartModule
|
||||
|
||||
@@ -39,7 +34,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
# the child but only work on the parent. See longer note below in _initialize_modules.
|
||||
# This list should be updated when creating new modules that could have the
|
||||
# same issue, homekit perhaps?
|
||||
WALL_SWITCH_PARENT_ONLY_MODULES = [DeviceModule, TimeModule, Firmware, CloudModule]
|
||||
WALL_SWITCH_PARENT_ONLY_MODULES = [DeviceModule, Time, Firmware, Cloud]
|
||||
|
||||
|
||||
# Device must go last as the other interfaces also inherit Device
|
||||
@@ -329,11 +324,11 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
self._add_feature(feat)
|
||||
|
||||
@property
|
||||
def is_cloud_connected(self):
|
||||
def is_cloud_connected(self) -> bool:
|
||||
"""Returns if the device is connected to the cloud."""
|
||||
if "CloudModule" not in self.modules:
|
||||
if Module.Cloud not in self.modules:
|
||||
return False
|
||||
return self.modules["CloudModule"].is_connected
|
||||
return self.modules[Module.Cloud].is_connected
|
||||
|
||||
@property
|
||||
def sys_info(self) -> dict[str, Any]:
|
||||
@@ -357,10 +352,10 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
def time(self) -> datetime:
|
||||
"""Return the time."""
|
||||
# TODO: Default to parent's time module for child devices
|
||||
if self._parent and "TimeModule" in self.modules:
|
||||
_timemod = cast(TimeModule, self._parent.modules["TimeModule"]) # noqa: F405
|
||||
if self._parent and Module.Time in self.modules:
|
||||
_timemod = self._parent.modules[Module.Time]
|
||||
else:
|
||||
_timemod = cast(TimeModule, self.modules["TimeModule"]) # noqa: F405
|
||||
_timemod = self.modules[Module.Time]
|
||||
|
||||
return _timemod.time
|
||||
|
||||
@@ -437,7 +432,7 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
@property
|
||||
def has_emeter(self) -> bool:
|
||||
"""Return if the device has emeter."""
|
||||
return "EnergyModule" in self.modules
|
||||
return Module.Energy in self.modules
|
||||
|
||||
@property
|
||||
def is_dimmer(self) -> bool:
|
||||
@@ -479,19 +474,19 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
@property
|
||||
def emeter_realtime(self) -> EmeterStatus:
|
||||
"""Get the emeter status."""
|
||||
energy = cast(EnergyModule, self.modules["EnergyModule"])
|
||||
energy = self.modules[Module.Energy]
|
||||
return energy.emeter_realtime
|
||||
|
||||
@property
|
||||
def emeter_this_month(self) -> float | None:
|
||||
"""Get the emeter value for this month."""
|
||||
energy = cast(EnergyModule, self.modules["EnergyModule"])
|
||||
energy = self.modules[Module.Energy]
|
||||
return energy.emeter_this_month
|
||||
|
||||
@property
|
||||
def emeter_today(self) -> float | None:
|
||||
"""Get the emeter value for today."""
|
||||
energy = cast(EnergyModule, self.modules["EnergyModule"])
|
||||
energy = self.modules[Module.Energy]
|
||||
return energy.emeter_today
|
||||
|
||||
@property
|
||||
@@ -503,8 +498,7 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
):
|
||||
return None
|
||||
on_time = cast(float, on_time)
|
||||
if (timemod := self.modules.get("TimeModule")) is not None:
|
||||
timemod = cast(TimeModule, timemod) # noqa: F405
|
||||
if (timemod := self.modules.get(Module.Time)) is not None:
|
||||
return timemod.time - timedelta(seconds=on_time)
|
||||
else: # We have no device time, use current local time.
|
||||
return datetime.now().replace(microsecond=0) - timedelta(seconds=on_time)
|
||||
@@ -650,37 +644,37 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
@property
|
||||
def is_fan(self) -> bool:
|
||||
"""Return True if the device is a fan."""
|
||||
return "FanModule" in self.modules
|
||||
return Module.Fan in self.modules
|
||||
|
||||
@property
|
||||
def fan_speed_level(self) -> int:
|
||||
"""Return fan speed level."""
|
||||
if not self.is_fan:
|
||||
raise KasaException("Device is not a Fan")
|
||||
return cast(FanModule, self.modules["FanModule"]).fan_speed_level
|
||||
return self.modules[Module.Fan].fan_speed_level
|
||||
|
||||
async def set_fan_speed_level(self, level: int):
|
||||
"""Set fan speed level."""
|
||||
if not self.is_fan:
|
||||
raise KasaException("Device is not a Fan")
|
||||
await cast(FanModule, self.modules["FanModule"]).set_fan_speed_level(level)
|
||||
await self.modules[Module.Fan].set_fan_speed_level(level)
|
||||
|
||||
# Bulb interface methods
|
||||
|
||||
@property
|
||||
def is_color(self) -> bool:
|
||||
"""Whether the bulb supports color changes."""
|
||||
return "ColorModule" in self.modules
|
||||
return Module.Color in self.modules
|
||||
|
||||
@property
|
||||
def is_dimmable(self) -> bool:
|
||||
"""Whether the bulb supports brightness changes."""
|
||||
return "Brightness" in self.modules
|
||||
return Module.Brightness in self.modules
|
||||
|
||||
@property
|
||||
def is_variable_color_temp(self) -> bool:
|
||||
"""Whether the bulb supports color temperature changes."""
|
||||
return "ColorTemperatureModule" in self.modules
|
||||
return Module.ColorTemperature in self.modules
|
||||
|
||||
@property
|
||||
def valid_temperature_range(self) -> ColorTempRange:
|
||||
@@ -691,9 +685,7 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
if not self.is_variable_color_temp:
|
||||
raise KasaException("Color temperature not supported")
|
||||
|
||||
return cast(
|
||||
ColorTemperatureModule, self.modules["ColorTemperatureModule"]
|
||||
).valid_temperature_range
|
||||
return self.modules[Module.ColorTemperature].valid_temperature_range
|
||||
|
||||
@property
|
||||
def hsv(self) -> HSV:
|
||||
@@ -704,7 +696,7 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
if not self.is_color:
|
||||
raise KasaException("Bulb does not support color.")
|
||||
|
||||
return cast(ColorModule, self.modules["ColorModule"]).hsv
|
||||
return self.modules[Module.Color].hsv
|
||||
|
||||
@property
|
||||
def color_temp(self) -> int:
|
||||
@@ -712,9 +704,7 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
if not self.is_variable_color_temp:
|
||||
raise KasaException("Bulb does not support colortemp.")
|
||||
|
||||
return cast(
|
||||
ColorTemperatureModule, self.modules["ColorTemperatureModule"]
|
||||
).color_temp
|
||||
return self.modules[Module.ColorTemperature].color_temp
|
||||
|
||||
@property
|
||||
def brightness(self) -> int:
|
||||
@@ -722,7 +712,7 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
if not self.is_dimmable: # pragma: no cover
|
||||
raise KasaException("Bulb is not dimmable.")
|
||||
|
||||
return cast(Brightness, self.modules["Brightness"]).brightness
|
||||
return self.modules[Module.Brightness].brightness
|
||||
|
||||
async def set_hsv(
|
||||
self,
|
||||
@@ -744,9 +734,7 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
if not self.is_color:
|
||||
raise KasaException("Bulb does not support color.")
|
||||
|
||||
return await cast(ColorModule, self.modules["ColorModule"]).set_hsv(
|
||||
hue, saturation, value
|
||||
)
|
||||
return await self.modules[Module.Color].set_hsv(hue, saturation, value)
|
||||
|
||||
async def set_color_temp(
|
||||
self, temp: int, *, brightness=None, transition: int | None = None
|
||||
@@ -760,9 +748,7 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
"""
|
||||
if not self.is_variable_color_temp:
|
||||
raise KasaException("Bulb does not support colortemp.")
|
||||
return await cast(
|
||||
ColorTemperatureModule, self.modules["ColorTemperatureModule"]
|
||||
).set_color_temp(temp)
|
||||
return await self.modules[Module.ColorTemperature].set_color_temp(temp)
|
||||
|
||||
async def set_brightness(
|
||||
self, brightness: int, *, transition: int | None = None
|
||||
@@ -777,9 +763,7 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
if not self.is_dimmable: # pragma: no cover
|
||||
raise KasaException("Bulb is not dimmable.")
|
||||
|
||||
return await cast(Brightness, self.modules["Brightness"]).set_brightness(
|
||||
brightness
|
||||
)
|
||||
return await self.modules[Module.Brightness].set_brightness(brightness)
|
||||
|
||||
@property
|
||||
def presets(self) -> list[BulbPreset]:
|
||||
@@ -789,4 +773,4 @@ class SmartDevice(Bulb, Fan, Device):
|
||||
@property
|
||||
def has_effects(self) -> bool:
|
||||
"""Return True if the device supports effects."""
|
||||
return "LightEffectModule" in self.modules
|
||||
return Module.LightEffect in self.modules
|
||||
|
Reference in New Issue
Block a user