mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-08-06 10:44:04 +00:00
Enable ruff check for ANN (#1139)
This commit is contained in:
@@ -20,7 +20,7 @@ class Alarm(SmartModule):
|
||||
"get_support_alarm_type_list": None, # This should be needed only once
|
||||
}
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features.
|
||||
|
||||
This is implemented as some features depend on device responses.
|
||||
@@ -100,7 +100,7 @@ class Alarm(SmartModule):
|
||||
"""Return current alarm sound."""
|
||||
return self.data["get_alarm_configure"]["type"]
|
||||
|
||||
async def set_alarm_sound(self, sound: str):
|
||||
async def set_alarm_sound(self, sound: str) -> dict:
|
||||
"""Set alarm sound.
|
||||
|
||||
See *alarm_sounds* for list of available sounds.
|
||||
@@ -119,7 +119,7 @@ class Alarm(SmartModule):
|
||||
"""Return alarm volume."""
|
||||
return self.data["get_alarm_configure"]["volume"]
|
||||
|
||||
async def set_alarm_volume(self, volume: Literal["low", "normal", "high"]):
|
||||
async def set_alarm_volume(self, volume: Literal["low", "normal", "high"]) -> dict:
|
||||
"""Set alarm volume."""
|
||||
payload = self.data["get_alarm_configure"].copy()
|
||||
payload["volume"] = volume
|
||||
|
@@ -17,7 +17,7 @@ class AutoOff(SmartModule):
|
||||
REQUIRED_COMPONENT = "auto_off"
|
||||
QUERY_GETTER_NAME = "get_auto_off_config"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -63,7 +63,7 @@ class AutoOff(SmartModule):
|
||||
"""Return True if enabled."""
|
||||
return self.data["enable"]
|
||||
|
||||
async def set_enabled(self, enable: bool):
|
||||
async def set_enabled(self, enable: bool) -> dict:
|
||||
"""Enable/disable auto off."""
|
||||
return await self.call(
|
||||
"set_auto_off_config",
|
||||
@@ -75,7 +75,7 @@ class AutoOff(SmartModule):
|
||||
"""Return time until auto off."""
|
||||
return self.data["delay_min"]
|
||||
|
||||
async def set_delay(self, delay: int):
|
||||
async def set_delay(self, delay: int) -> dict:
|
||||
"""Set time until auto off."""
|
||||
return await self.call(
|
||||
"set_auto_off_config", {"delay_min": delay, "enable": self.data["enable"]}
|
||||
@@ -96,7 +96,7 @@ class AutoOff(SmartModule):
|
||||
|
||||
return self._device.time + timedelta(seconds=sysinfo["auto_off_remain_time"])
|
||||
|
||||
async def _check_supported(self):
|
||||
async def _check_supported(self) -> bool:
|
||||
"""Additional check to see if the module is supported by the device.
|
||||
|
||||
Parent devices that report components of children such as P300 will not have
|
||||
|
@@ -12,7 +12,7 @@ class BatterySensor(SmartModule):
|
||||
REQUIRED_COMPONENT = "battery_detect"
|
||||
QUERY_GETTER_NAME = "get_battery_detect_info"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -48,11 +48,11 @@ class BatterySensor(SmartModule):
|
||||
return {}
|
||||
|
||||
@property
|
||||
def battery(self):
|
||||
def battery(self) -> int:
|
||||
"""Return battery level."""
|
||||
return self._device.sys_info["battery_percentage"]
|
||||
|
||||
@property
|
||||
def battery_low(self):
|
||||
def battery_low(self) -> bool:
|
||||
"""Return True if battery is low."""
|
||||
return self._device.sys_info["at_low_battery"]
|
||||
|
@@ -14,7 +14,7 @@ class Brightness(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "brightness"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features."""
|
||||
super()._initialize_features()
|
||||
|
||||
@@ -39,7 +39,7 @@ class Brightness(SmartModule):
|
||||
return {}
|
||||
|
||||
@property
|
||||
def brightness(self):
|
||||
def brightness(self) -> int:
|
||||
"""Return current brightness."""
|
||||
# If the device supports effects and one is active, use its brightness
|
||||
if (
|
||||
@@ -49,7 +49,9 @@ class Brightness(SmartModule):
|
||||
|
||||
return self.data["brightness"]
|
||||
|
||||
async def set_brightness(self, brightness: int, *, transition: int | None = None):
|
||||
async def set_brightness(
|
||||
self, brightness: int, *, transition: int | None = None
|
||||
) -> dict:
|
||||
"""Set the brightness. A brightness value of 0 will turn off the light.
|
||||
|
||||
Note, transition is not supported and will be ignored.
|
||||
@@ -73,6 +75,6 @@ class Brightness(SmartModule):
|
||||
|
||||
return await self.call("set_device_info", {"brightness": brightness})
|
||||
|
||||
async def _check_supported(self):
|
||||
async def _check_supported(self) -> bool:
|
||||
"""Additional check to see if the module is supported by the device."""
|
||||
return "brightness" in self.data
|
||||
|
@@ -12,7 +12,7 @@ class ChildProtection(SmartModule):
|
||||
REQUIRED_COMPONENT = "child_protection"
|
||||
QUERY_GETTER_NAME = "get_child_protection"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
|
@@ -13,7 +13,7 @@ class Cloud(SmartModule):
|
||||
REQUIRED_COMPONENT = "cloud_connect"
|
||||
MINIMUM_UPDATE_INTERVAL_SECS = 60
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -29,7 +29,7 @@ class Cloud(SmartModule):
|
||||
)
|
||||
|
||||
@property
|
||||
def is_connected(self):
|
||||
def is_connected(self) -> bool:
|
||||
"""Return True if device is connected to the cloud."""
|
||||
if self._has_data_error():
|
||||
return False
|
||||
|
@@ -12,7 +12,7 @@ class Color(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "color"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -48,7 +48,7 @@ class Color(SmartModule):
|
||||
# due to the cpython implementation.
|
||||
return tuple.__new__(HSV, (h, s, v))
|
||||
|
||||
def _raise_for_invalid_brightness(self, value):
|
||||
def _raise_for_invalid_brightness(self, value: int) -> None:
|
||||
"""Raise error on invalid brightness value."""
|
||||
if not isinstance(value, int):
|
||||
raise TypeError("Brightness must be an integer")
|
||||
|
@@ -18,7 +18,7 @@ class ColorTemperature(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "color_temperature"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -52,11 +52,11 @@ class ColorTemperature(SmartModule):
|
||||
return ColorTempRange(*ct_range)
|
||||
|
||||
@property
|
||||
def color_temp(self):
|
||||
def color_temp(self) -> int:
|
||||
"""Return current color temperature."""
|
||||
return self.data["color_temp"]
|
||||
|
||||
async def set_color_temp(self, temp: int, *, brightness=None):
|
||||
async def set_color_temp(self, temp: int, *, brightness: int | None = None) -> dict:
|
||||
"""Set the color temperature."""
|
||||
valid_temperature_range = self.valid_temperature_range
|
||||
if temp < valid_temperature_range[0] or temp > valid_temperature_range[1]:
|
||||
|
@@ -12,7 +12,7 @@ class ContactSensor(SmartModule):
|
||||
REQUIRED_COMPONENT = None # we depend on availability of key
|
||||
REQUIRED_KEY_ON_PARENT = "open"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -32,6 +32,6 @@ class ContactSensor(SmartModule):
|
||||
return {}
|
||||
|
||||
@property
|
||||
def is_open(self):
|
||||
def is_open(self) -> bool:
|
||||
"""Return True if the contact sensor is open."""
|
||||
return self._device.sys_info["open"]
|
||||
|
@@ -10,7 +10,7 @@ class DeviceModule(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "device"
|
||||
|
||||
async def _post_update_hook(self):
|
||||
async def _post_update_hook(self) -> None:
|
||||
"""Perform actions after a device update.
|
||||
|
||||
Overrides the default behaviour to disable a module if the query returns
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import NoReturn
|
||||
|
||||
from ...emeterstatus import EmeterStatus
|
||||
from ...exceptions import KasaException
|
||||
from ...interfaces.energy import Energy as EnergyInterface
|
||||
@@ -31,34 +33,34 @@ class Energy(SmartModule, EnergyInterface):
|
||||
# Fallback if get_energy_usage does not provide current_power,
|
||||
# which can happen on some newer devices (e.g. P304M).
|
||||
elif (
|
||||
power := self.data.get("get_current_power").get("current_power")
|
||||
power := self.data.get("get_current_power", {}).get("current_power")
|
||||
) is not None:
|
||||
return power
|
||||
return None
|
||||
|
||||
@property
|
||||
@raise_if_update_error
|
||||
def energy(self):
|
||||
def energy(self) -> dict:
|
||||
"""Return get_energy_usage results."""
|
||||
if en := self.data.get("get_energy_usage"):
|
||||
return en
|
||||
return self.data
|
||||
|
||||
def _get_status_from_energy(self, energy) -> EmeterStatus:
|
||||
def _get_status_from_energy(self, energy: dict) -> EmeterStatus:
|
||||
return EmeterStatus(
|
||||
{
|
||||
"power_mw": energy.get("current_power"),
|
||||
"total": energy.get("today_energy") / 1_000,
|
||||
"power_mw": energy.get("current_power", 0),
|
||||
"total": energy.get("today_energy", 0) / 1_000,
|
||||
}
|
||||
)
|
||||
|
||||
@property
|
||||
@raise_if_update_error
|
||||
def status(self):
|
||||
def status(self) -> EmeterStatus:
|
||||
"""Get the emeter status."""
|
||||
return self._get_status_from_energy(self.energy)
|
||||
|
||||
async def get_status(self):
|
||||
async def get_status(self) -> EmeterStatus:
|
||||
"""Return real-time statistics."""
|
||||
res = await self.call("get_energy_usage")
|
||||
return self._get_status_from_energy(res["get_energy_usage"])
|
||||
@@ -67,13 +69,13 @@ class Energy(SmartModule, EnergyInterface):
|
||||
@raise_if_update_error
|
||||
def consumption_this_month(self) -> float | None:
|
||||
"""Get the emeter value for this month in kWh."""
|
||||
return self.energy.get("month_energy") / 1_000
|
||||
return self.energy.get("month_energy", 0) / 1_000
|
||||
|
||||
@property
|
||||
@raise_if_update_error
|
||||
def consumption_today(self) -> float | None:
|
||||
"""Get the emeter value for today in kWh."""
|
||||
return self.energy.get("today_energy") / 1_000
|
||||
return self.energy.get("today_energy", 0) / 1_000
|
||||
|
||||
@property
|
||||
@raise_if_update_error
|
||||
@@ -97,22 +99,26 @@ class Energy(SmartModule, EnergyInterface):
|
||||
"""Retrieve current energy readings."""
|
||||
return self.status
|
||||
|
||||
async def erase_stats(self):
|
||||
async def erase_stats(self) -> NoReturn:
|
||||
"""Erase all stats."""
|
||||
raise KasaException("Device does not support periodic statistics")
|
||||
|
||||
async def get_daily_stats(self, *, year=None, month=None, kwh=True) -> dict:
|
||||
async def get_daily_stats(
|
||||
self, *, year: int | None = None, month: int | None = None, kwh: bool = True
|
||||
) -> dict:
|
||||
"""Return daily stats for the given year & month.
|
||||
|
||||
The return value is a dictionary of {day: energy, ...}.
|
||||
"""
|
||||
raise KasaException("Device does not support periodic statistics")
|
||||
|
||||
async def get_monthly_stats(self, *, year=None, kwh=True) -> dict:
|
||||
async def get_monthly_stats(
|
||||
self, *, year: int | None = None, kwh: bool = True
|
||||
) -> dict:
|
||||
"""Return monthly stats for the given year."""
|
||||
raise KasaException("Device does not support periodic statistics")
|
||||
|
||||
async def _check_supported(self):
|
||||
async def _check_supported(self) -> bool:
|
||||
"""Additional check to see if the module is supported by the device."""
|
||||
# Energy module is not supported on P304M parent device
|
||||
return "device_on" in self._device.sys_info
|
||||
|
@@ -12,7 +12,7 @@ class Fan(SmartModule, FanInterface):
|
||||
|
||||
REQUIRED_COMPONENT = "fan_control"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -50,7 +50,7 @@ class Fan(SmartModule, FanInterface):
|
||||
"""Return fan speed level."""
|
||||
return 0 if self.data["device_on"] is False else self.data["fan_speed_level"]
|
||||
|
||||
async def set_fan_speed_level(self, level: int):
|
||||
async def set_fan_speed_level(self, level: int) -> dict:
|
||||
"""Set fan speed level, 0 for off, 1-4 for on."""
|
||||
if level < 0 or level > 4:
|
||||
raise ValueError("Invalid level, should be in range 0-4.")
|
||||
@@ -65,10 +65,10 @@ class Fan(SmartModule, FanInterface):
|
||||
"""Return sleep mode status."""
|
||||
return self.data["fan_sleep_mode_on"]
|
||||
|
||||
async def set_sleep_mode(self, on: bool):
|
||||
async def set_sleep_mode(self, on: bool) -> dict:
|
||||
"""Set sleep mode."""
|
||||
return await self.call("set_device_info", {"fan_sleep_mode_on": on})
|
||||
|
||||
async def _check_supported(self):
|
||||
async def _check_supported(self) -> bool:
|
||||
"""Is the module available on this device."""
|
||||
return "fan_speed_level" in self.data
|
||||
|
@@ -49,14 +49,14 @@ class UpdateInfo(BaseModel):
|
||||
needs_upgrade: bool = Field(alias="need_to_upgrade")
|
||||
|
||||
@validator("release_date", pre=True)
|
||||
def _release_date_optional(cls, v):
|
||||
def _release_date_optional(cls, v: str) -> str | None:
|
||||
if not v:
|
||||
return None
|
||||
|
||||
return v
|
||||
|
||||
@property
|
||||
def update_available(self):
|
||||
def update_available(self) -> bool:
|
||||
"""Return True if update available."""
|
||||
if self.status != 0:
|
||||
return True
|
||||
@@ -69,11 +69,11 @@ class Firmware(SmartModule):
|
||||
REQUIRED_COMPONENT = "firmware"
|
||||
MINIMUM_UPDATE_INTERVAL_SECS = 60 * 60 * 24
|
||||
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
def __init__(self, device: SmartDevice, module: str) -> None:
|
||||
super().__init__(device, module)
|
||||
self._firmware_update_info: UpdateInfo | None = None
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features."""
|
||||
device = self._device
|
||||
if self.supported_version > 1:
|
||||
@@ -183,7 +183,7 @@ class Firmware(SmartModule):
|
||||
@allow_update_after
|
||||
async def update(
|
||||
self, progress_cb: Callable[[DownloadState], Coroutine] | None = None
|
||||
):
|
||||
) -> dict:
|
||||
"""Update the device firmware."""
|
||||
if not self._firmware_update_info:
|
||||
raise KasaException(
|
||||
@@ -236,13 +236,15 @@ class Firmware(SmartModule):
|
||||
else:
|
||||
_LOGGER.warning("Unhandled state code: %s", state)
|
||||
|
||||
return state.dict()
|
||||
|
||||
@property
|
||||
def auto_update_enabled(self) -> bool:
|
||||
"""Return True if autoupdate is enabled."""
|
||||
return "enable" in self.data and self.data["enable"]
|
||||
|
||||
@allow_update_after
|
||||
async def set_auto_update_enabled(self, enabled: bool):
|
||||
async def set_auto_update_enabled(self, enabled: bool) -> dict:
|
||||
"""Change autoupdate setting."""
|
||||
data = {**self.data, "enable": enabled}
|
||||
await self.call("set_auto_update_info", data)
|
||||
return await self.call("set_auto_update_info", data)
|
||||
|
@@ -23,7 +23,7 @@ class FrostProtection(SmartModule):
|
||||
"""Return True if frost protection is on."""
|
||||
return self._device.sys_info["frost_protection_on"]
|
||||
|
||||
async def set_enabled(self, enable: bool):
|
||||
async def set_enabled(self, enable: bool) -> dict:
|
||||
"""Enable/disable frost protection."""
|
||||
return await self.call(
|
||||
"set_device_info",
|
||||
|
@@ -12,7 +12,7 @@ class HumiditySensor(SmartModule):
|
||||
REQUIRED_COMPONENT = "humidity"
|
||||
QUERY_GETTER_NAME = "get_comfort_humidity_config"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -45,7 +45,7 @@ class HumiditySensor(SmartModule):
|
||||
return {}
|
||||
|
||||
@property
|
||||
def humidity(self):
|
||||
def humidity(self) -> int:
|
||||
"""Return current humidity in percentage."""
|
||||
return self._device.sys_info["current_humidity"]
|
||||
|
||||
|
@@ -19,7 +19,7 @@ class Led(SmartModule, LedInterface):
|
||||
return {self.QUERY_GETTER_NAME: None}
|
||||
|
||||
@property
|
||||
def mode(self):
|
||||
def mode(self) -> str:
|
||||
"""LED mode setting.
|
||||
|
||||
"always", "never", "night_mode"
|
||||
@@ -27,12 +27,12 @@ class Led(SmartModule, LedInterface):
|
||||
return self.data["led_rule"]
|
||||
|
||||
@property
|
||||
def led(self):
|
||||
def led(self) -> bool:
|
||||
"""Return current led status."""
|
||||
return self.data["led_rule"] != "never"
|
||||
|
||||
@allow_update_after
|
||||
async def set_led(self, enable: bool):
|
||||
async def set_led(self, enable: bool) -> dict:
|
||||
"""Set led.
|
||||
|
||||
This should probably be a select with always/never/nightmode.
|
||||
@@ -41,7 +41,7 @@ class Led(SmartModule, LedInterface):
|
||||
return await self.call("set_led_info", dict(self.data, **{"led_rule": rule}))
|
||||
|
||||
@property
|
||||
def night_mode_settings(self):
|
||||
def night_mode_settings(self) -> dict:
|
||||
"""Night mode settings."""
|
||||
return {
|
||||
"start": self.data["start_time"],
|
||||
|
@@ -96,7 +96,7 @@ class Light(SmartModule, LightInterface):
|
||||
return await self._device.modules[Module.Color].set_hsv(hue, saturation, value)
|
||||
|
||||
async def set_color_temp(
|
||||
self, temp: int, *, brightness=None, transition: int | None = None
|
||||
self, temp: int, *, brightness: int | None = None, transition: int | None = None
|
||||
) -> dict:
|
||||
"""Set the color temperature of the device in kelvin.
|
||||
|
||||
|
@@ -81,7 +81,7 @@ class LightEffect(SmartModule, SmartLightEffect):
|
||||
*,
|
||||
brightness: int | None = None,
|
||||
transition: int | None = None,
|
||||
) -> None:
|
||||
) -> dict:
|
||||
"""Set an effect for the device.
|
||||
|
||||
Calling this will modify the brightness of the effect on the device.
|
||||
@@ -107,7 +107,7 @@ class LightEffect(SmartModule, SmartLightEffect):
|
||||
)
|
||||
await self.set_brightness(brightness, effect_id=effect_id)
|
||||
|
||||
await self.call("set_dynamic_light_effect_rule_enable", params)
|
||||
return await self.call("set_dynamic_light_effect_rule_enable", params)
|
||||
|
||||
@property
|
||||
def is_active(self) -> bool:
|
||||
@@ -139,11 +139,11 @@ class LightEffect(SmartModule, SmartLightEffect):
|
||||
*,
|
||||
transition: int | None = None,
|
||||
effect_id: str | None = None,
|
||||
):
|
||||
) -> dict:
|
||||
"""Set effect brightness."""
|
||||
new_effect = self._get_effect_data(effect_id=effect_id).copy()
|
||||
|
||||
def _replace_brightness(data, new_brightness):
|
||||
def _replace_brightness(data: list[int], new_brightness: int) -> list[int]:
|
||||
"""Replace brightness.
|
||||
|
||||
The first element is the brightness, the rest are unknown.
|
||||
@@ -163,7 +163,7 @@ class LightEffect(SmartModule, SmartLightEffect):
|
||||
async def set_custom_effect(
|
||||
self,
|
||||
effect_dict: dict,
|
||||
) -> None:
|
||||
) -> dict:
|
||||
"""Set a custom effect on the device.
|
||||
|
||||
:param str effect_dict: The custom effect dict to set
|
||||
|
@@ -29,12 +29,12 @@ class LightPreset(SmartModule, LightPresetInterface):
|
||||
_presets: dict[str, LightState]
|
||||
_preset_list: list[str]
|
||||
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
def __init__(self, device: SmartDevice, module: str) -> None:
|
||||
super().__init__(device, module)
|
||||
self._state_in_sysinfo = self.SYS_INFO_STATE_KEY in device.sys_info
|
||||
self._brightness_only: bool = False
|
||||
|
||||
async def _post_update_hook(self):
|
||||
async def _post_update_hook(self) -> None:
|
||||
"""Update the internal presets."""
|
||||
index = 0
|
||||
self._presets = {}
|
||||
@@ -113,7 +113,7 @@ class LightPreset(SmartModule, LightPresetInterface):
|
||||
async def set_preset(
|
||||
self,
|
||||
preset_name: str,
|
||||
) -> None:
|
||||
) -> dict:
|
||||
"""Set a light preset for the device."""
|
||||
light = self._device.modules[SmartModule.Light]
|
||||
if preset_name == self.PRESET_NOT_SET:
|
||||
@@ -123,14 +123,14 @@ class LightPreset(SmartModule, LightPresetInterface):
|
||||
preset = LightState(brightness=100)
|
||||
elif (preset := self._presets.get(preset_name)) is None: # type: ignore[assignment]
|
||||
raise ValueError(f"{preset_name} is not a valid preset: {self.preset_list}")
|
||||
await self._device.modules[SmartModule.Light].set_state(preset)
|
||||
return await self._device.modules[SmartModule.Light].set_state(preset)
|
||||
|
||||
@allow_update_after
|
||||
async def save_preset(
|
||||
self,
|
||||
preset_name: str,
|
||||
preset_state: LightState,
|
||||
) -> None:
|
||||
) -> dict:
|
||||
"""Update the preset with preset_name with the new preset_info."""
|
||||
if preset_name not in self._presets:
|
||||
raise ValueError(f"{preset_name} is not a valid preset: {self.preset_list}")
|
||||
@@ -138,11 +138,13 @@ class LightPreset(SmartModule, LightPresetInterface):
|
||||
if self._brightness_only:
|
||||
bright_list = [state.brightness for state in self._presets.values()]
|
||||
bright_list[index] = preset_state.brightness
|
||||
await self.call("set_preset_rules", {"brightness": bright_list})
|
||||
return await self.call("set_preset_rules", {"brightness": bright_list})
|
||||
else:
|
||||
state_params = asdict(preset_state)
|
||||
new_info = {k: v for k, v in state_params.items() if v is not None}
|
||||
await self.call("edit_preset_rules", {"index": index, "state": new_info})
|
||||
return await self.call(
|
||||
"edit_preset_rules", {"index": index, "state": new_info}
|
||||
)
|
||||
|
||||
@property
|
||||
def has_save_preset(self) -> bool:
|
||||
@@ -158,7 +160,7 @@ class LightPreset(SmartModule, LightPresetInterface):
|
||||
|
||||
return {self.QUERY_GETTER_NAME: {"start_index": 0}}
|
||||
|
||||
async def _check_supported(self):
|
||||
async def _check_supported(self) -> bool:
|
||||
"""Additional check to see if the module is supported by the device.
|
||||
|
||||
Parent devices that report components of children such as ks240 will not have
|
||||
|
@@ -16,7 +16,7 @@ class LightStripEffect(SmartModule, SmartLightEffect):
|
||||
|
||||
REQUIRED_COMPONENT = "light_strip_lighting_effect"
|
||||
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
def __init__(self, device: SmartDevice, module: str) -> None:
|
||||
super().__init__(device, module)
|
||||
effect_list = [self.LIGHT_EFFECTS_OFF]
|
||||
effect_list.extend(EFFECT_NAMES)
|
||||
@@ -66,7 +66,9 @@ class LightStripEffect(SmartModule, SmartLightEffect):
|
||||
eff = self.data["lighting_effect"]
|
||||
return eff["brightness"]
|
||||
|
||||
async def set_brightness(self, brightness: int, *, transition: int | None = None):
|
||||
async def set_brightness(
|
||||
self, brightness: int, *, transition: int | None = None
|
||||
) -> dict:
|
||||
"""Set effect brightness."""
|
||||
if brightness <= 0:
|
||||
return await self.set_effect(self.LIGHT_EFFECTS_OFF)
|
||||
@@ -91,7 +93,7 @@ class LightStripEffect(SmartModule, SmartLightEffect):
|
||||
*,
|
||||
brightness: int | None = None,
|
||||
transition: int | None = None,
|
||||
) -> None:
|
||||
) -> dict:
|
||||
"""Set an effect on the device.
|
||||
|
||||
If brightness or transition is defined,
|
||||
@@ -115,8 +117,7 @@ class LightStripEffect(SmartModule, SmartLightEffect):
|
||||
effect_dict = self._effect_mapping["Aurora"]
|
||||
effect_dict = {**effect_dict}
|
||||
effect_dict["enable"] = 0
|
||||
await self.set_custom_effect(effect_dict)
|
||||
return
|
||||
return await self.set_custom_effect(effect_dict)
|
||||
|
||||
if effect not in self._effect_mapping:
|
||||
raise ValueError(f"The effect {effect} is not a built in effect.")
|
||||
@@ -134,13 +135,13 @@ class LightStripEffect(SmartModule, SmartLightEffect):
|
||||
if transition is not None:
|
||||
effect_dict["transition"] = transition
|
||||
|
||||
await self.set_custom_effect(effect_dict)
|
||||
return await self.set_custom_effect(effect_dict)
|
||||
|
||||
@allow_update_after
|
||||
async def set_custom_effect(
|
||||
self,
|
||||
effect_dict: dict,
|
||||
) -> None:
|
||||
) -> dict:
|
||||
"""Set a custom effect on the device.
|
||||
|
||||
:param str effect_dict: The custom effect dict to set
|
||||
@@ -155,7 +156,7 @@ class LightStripEffect(SmartModule, SmartLightEffect):
|
||||
"""Return True if the device supports setting custom effects."""
|
||||
return True
|
||||
|
||||
def query(self):
|
||||
def query(self) -> dict:
|
||||
"""Return the base query."""
|
||||
return {}
|
||||
|
||||
|
@@ -39,14 +39,14 @@ class LightTransition(SmartModule):
|
||||
_off_state: _State
|
||||
_enabled: bool
|
||||
|
||||
def __init__(self, device: SmartDevice, module: str):
|
||||
def __init__(self, device: SmartDevice, module: str) -> None:
|
||||
super().__init__(device, module)
|
||||
self._state_in_sysinfo = all(
|
||||
key in device.sys_info for key in self.SYS_INFO_STATE_KEYS
|
||||
)
|
||||
self._supports_on_and_off: bool = self.supported_version > 1
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features."""
|
||||
icon = "mdi:transition"
|
||||
if not self._supports_on_and_off:
|
||||
@@ -138,7 +138,7 @@ class LightTransition(SmartModule):
|
||||
}
|
||||
|
||||
@allow_update_after
|
||||
async def set_enabled(self, enable: bool):
|
||||
async def set_enabled(self, enable: bool) -> dict:
|
||||
"""Enable gradual on/off."""
|
||||
if not self._supports_on_and_off:
|
||||
return await self.call("set_on_off_gradually_info", {"enable": enable})
|
||||
@@ -171,7 +171,7 @@ class LightTransition(SmartModule):
|
||||
return self._on_state["max_duration"]
|
||||
|
||||
@allow_update_after
|
||||
async def set_turn_on_transition(self, seconds: int):
|
||||
async def set_turn_on_transition(self, seconds: int) -> dict:
|
||||
"""Set turn on transition in seconds.
|
||||
|
||||
Setting to 0 turns the feature off.
|
||||
@@ -207,7 +207,7 @@ class LightTransition(SmartModule):
|
||||
return self._off_state["max_duration"]
|
||||
|
||||
@allow_update_after
|
||||
async def set_turn_off_transition(self, seconds: int):
|
||||
async def set_turn_off_transition(self, seconds: int) -> dict:
|
||||
"""Set turn on transition in seconds.
|
||||
|
||||
Setting to 0 turns the feature off.
|
||||
@@ -236,7 +236,7 @@ class LightTransition(SmartModule):
|
||||
else:
|
||||
return {self.QUERY_GETTER_NAME: None}
|
||||
|
||||
async def _check_supported(self):
|
||||
async def _check_supported(self) -> bool:
|
||||
"""Additional check to see if the module is supported by the device."""
|
||||
# For devices that report child components on the parent that are not
|
||||
# actually supported by the parent.
|
||||
|
@@ -11,7 +11,7 @@ class MotionSensor(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "sensitivity"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -31,6 +31,6 @@ class MotionSensor(SmartModule):
|
||||
return {}
|
||||
|
||||
@property
|
||||
def motion_detected(self):
|
||||
def motion_detected(self) -> bool:
|
||||
"""Return True if the motion has been detected."""
|
||||
return self._device.sys_info["detected"]
|
||||
|
@@ -12,7 +12,7 @@ class ReportMode(SmartModule):
|
||||
REQUIRED_COMPONENT = "report_mode"
|
||||
QUERY_GETTER_NAME = "get_report_mode"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -32,6 +32,6 @@ class ReportMode(SmartModule):
|
||||
return {}
|
||||
|
||||
@property
|
||||
def report_interval(self):
|
||||
def report_interval(self) -> int:
|
||||
"""Reporting interval of a sensor device."""
|
||||
return self._device.sys_info["report_interval"]
|
||||
|
@@ -26,7 +26,7 @@ class TemperatureControl(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "temp_control"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -92,7 +92,7 @@ class TemperatureControl(SmartModule):
|
||||
"""Return thermostat state."""
|
||||
return self._device.sys_info["frost_protection_on"] is False
|
||||
|
||||
async def set_state(self, enabled: bool):
|
||||
async def set_state(self, enabled: bool) -> dict:
|
||||
"""Set thermostat state."""
|
||||
return await self.call("set_device_info", {"frost_protection_on": not enabled})
|
||||
|
||||
@@ -147,7 +147,7 @@ class TemperatureControl(SmartModule):
|
||||
"""Return thermostat states."""
|
||||
return set(self._device.sys_info["trv_states"])
|
||||
|
||||
async def set_target_temperature(self, target: float):
|
||||
async def set_target_temperature(self, target: float) -> dict:
|
||||
"""Set target temperature."""
|
||||
if (
|
||||
target < self.minimum_target_temperature
|
||||
@@ -170,7 +170,7 @@ class TemperatureControl(SmartModule):
|
||||
"""Return temperature offset."""
|
||||
return self._device.sys_info["temp_offset"]
|
||||
|
||||
async def set_temperature_offset(self, offset: int):
|
||||
async def set_temperature_offset(self, offset: int) -> dict:
|
||||
"""Set temperature offset."""
|
||||
if offset < -10 or offset > 10:
|
||||
raise ValueError("Temperature offset must be [-10, 10]")
|
||||
|
@@ -14,7 +14,7 @@ class TemperatureSensor(SmartModule):
|
||||
REQUIRED_COMPONENT = "temperature"
|
||||
QUERY_GETTER_NAME = "get_comfort_temp_config"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -60,7 +60,7 @@ class TemperatureSensor(SmartModule):
|
||||
return {}
|
||||
|
||||
@property
|
||||
def temperature(self):
|
||||
def temperature(self) -> float:
|
||||
"""Return current humidity in percentage."""
|
||||
return self._device.sys_info["current_temp"]
|
||||
|
||||
@@ -74,6 +74,8 @@ class TemperatureSensor(SmartModule):
|
||||
"""Return current temperature unit."""
|
||||
return self._device.sys_info["temp_unit"]
|
||||
|
||||
async def set_temperature_unit(self, unit: Literal["celsius", "fahrenheit"]):
|
||||
async def set_temperature_unit(
|
||||
self, unit: Literal["celsius", "fahrenheit"]
|
||||
) -> dict:
|
||||
"""Set the device temperature unit."""
|
||||
return await self.call("set_temperature_unit", {"temp_unit": unit})
|
||||
|
@@ -21,7 +21,7 @@ class Time(SmartModule, TimeInterface):
|
||||
|
||||
_timezone: tzinfo = timezone.utc
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -35,7 +35,7 @@ class Time(SmartModule, TimeInterface):
|
||||
)
|
||||
)
|
||||
|
||||
async def _post_update_hook(self):
|
||||
async def _post_update_hook(self) -> None:
|
||||
"""Perform actions after a device update."""
|
||||
td = timedelta(minutes=cast(float, self.data.get("time_diff")))
|
||||
if region := self.data.get("region"):
|
||||
@@ -84,7 +84,7 @@ class Time(SmartModule, TimeInterface):
|
||||
params["region"] = region
|
||||
return await self.call("set_device_time", params)
|
||||
|
||||
async def _check_supported(self):
|
||||
async def _check_supported(self) -> bool:
|
||||
"""Additional check to see if the module is supported by the device.
|
||||
|
||||
Hub attached sensors report the time module but do return device time.
|
||||
|
@@ -22,7 +22,7 @@ class WaterleakSensor(SmartModule):
|
||||
|
||||
REQUIRED_COMPONENT = "sensor_alarm"
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
|
Reference in New Issue
Block a user