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:
@@ -11,7 +11,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
class AmbientLight(IotModule):
|
||||
"""Implements ambient light controls for the motion sensor."""
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -40,7 +40,7 @@ class AmbientLight(IotModule):
|
||||
)
|
||||
)
|
||||
|
||||
def query(self):
|
||||
def query(self) -> dict:
|
||||
"""Request configuration."""
|
||||
req = merge(
|
||||
self.query_for_command("get_config"),
|
||||
@@ -74,18 +74,18 @@ class AmbientLight(IotModule):
|
||||
"""Return True if the module is enabled."""
|
||||
return int(self.data["get_current_brt"]["value"])
|
||||
|
||||
async def set_enabled(self, state: bool):
|
||||
async def set_enabled(self, state: bool) -> dict:
|
||||
"""Enable/disable LAS."""
|
||||
return await self.call("set_enable", {"enable": int(state)})
|
||||
|
||||
async def current_brightness(self) -> int:
|
||||
async def current_brightness(self) -> dict:
|
||||
"""Return current brightness.
|
||||
|
||||
Return value units.
|
||||
"""
|
||||
return await self.call("get_current_brt")
|
||||
|
||||
async def set_brightness_limit(self, value: int):
|
||||
async def set_brightness_limit(self, value: int) -> dict:
|
||||
"""Set the limit when the motion sensor is inactive.
|
||||
|
||||
See `presets` for preset values. Custom values are also likely allowed.
|
||||
|
@@ -24,7 +24,7 @@ class CloudInfo(BaseModel):
|
||||
class Cloud(IotModule):
|
||||
"""Module implementing support for cloud services."""
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
@@ -44,7 +44,7 @@ class Cloud(IotModule):
|
||||
"""Return true if device is connected to the cloud."""
|
||||
return self.info.binded
|
||||
|
||||
def query(self):
|
||||
def query(self) -> dict:
|
||||
"""Request cloud connectivity info."""
|
||||
return self.query_for_command("get_info")
|
||||
|
||||
@@ -53,20 +53,20 @@ class Cloud(IotModule):
|
||||
"""Return information about the cloud connectivity."""
|
||||
return CloudInfo.parse_obj(self.data["get_info"])
|
||||
|
||||
def get_available_firmwares(self):
|
||||
def get_available_firmwares(self) -> dict:
|
||||
"""Return list of available firmwares."""
|
||||
return self.query_for_command("get_intl_fw_list")
|
||||
|
||||
def set_server(self, url: str):
|
||||
def set_server(self, url: str) -> dict:
|
||||
"""Set the update server URL."""
|
||||
return self.query_for_command("set_server_url", {"server": url})
|
||||
|
||||
def connect(self, username: str, password: str):
|
||||
def connect(self, username: str, password: str) -> dict:
|
||||
"""Login to the cloud using given information."""
|
||||
return self.query_for_command(
|
||||
"bind", {"username": username, "password": password}
|
||||
)
|
||||
|
||||
def disconnect(self):
|
||||
def disconnect(self) -> dict:
|
||||
"""Disconnect from the cloud."""
|
||||
return self.query_for_command("unbind")
|
||||
|
@@ -70,7 +70,7 @@ class Emeter(Usage, EnergyInterface):
|
||||
"""Get the current voltage in V."""
|
||||
return self.status.voltage
|
||||
|
||||
async def erase_stats(self):
|
||||
async def erase_stats(self) -> dict:
|
||||
"""Erase all stats.
|
||||
|
||||
Uses different query than usage meter.
|
||||
@@ -81,7 +81,9 @@ class Emeter(Usage, EnergyInterface):
|
||||
"""Return real-time statistics."""
|
||||
return EmeterStatus(await self.call("get_realtime"))
|
||||
|
||||
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, ...}.
|
||||
@@ -90,7 +92,9 @@ class Emeter(Usage, EnergyInterface):
|
||||
data = self._convert_stat_data(data["day_list"], entry_key="day", kwh=kwh)
|
||||
return data
|
||||
|
||||
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.
|
||||
|
||||
The return value is a dictionary of {month: energy, ...}.
|
||||
|
@@ -14,7 +14,7 @@ class Led(IotModule, LedInterface):
|
||||
return {}
|
||||
|
||||
@property
|
||||
def mode(self):
|
||||
def mode(self) -> str:
|
||||
"""LED mode setting.
|
||||
|
||||
"always", "never"
|
||||
@@ -27,7 +27,7 @@ class Led(IotModule, LedInterface):
|
||||
sys_info = self.data
|
||||
return bool(1 - sys_info["led_off"])
|
||||
|
||||
async def set_led(self, state: bool):
|
||||
async def set_led(self, state: bool) -> dict:
|
||||
"""Set the state of the led (night mode)."""
|
||||
return await self.call("set_led_off", {"off": int(not state)})
|
||||
|
||||
|
@@ -27,7 +27,7 @@ class Light(IotModule, LightInterface):
|
||||
_device: IotBulb | IotDimmer
|
||||
_light_state: LightState
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features."""
|
||||
super()._initialize_features()
|
||||
device = self._device
|
||||
@@ -185,7 +185,7 @@ class Light(IotModule, LightInterface):
|
||||
return bulb._color_temp
|
||||
|
||||
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.
|
||||
|
||||
|
@@ -50,7 +50,7 @@ class LightEffect(IotModule, LightEffectInterface):
|
||||
*,
|
||||
brightness: int | None = None,
|
||||
transition: int | None = None,
|
||||
) -> None:
|
||||
) -> dict:
|
||||
"""Set an effect on the device.
|
||||
|
||||
If brightness or transition is defined,
|
||||
@@ -73,7 +73,7 @@ class LightEffect(IotModule, LightEffectInterface):
|
||||
effect_dict = EFFECT_MAPPING_V1["Aurora"]
|
||||
effect_dict = {**effect_dict}
|
||||
effect_dict["enable"] = 0
|
||||
await self.set_custom_effect(effect_dict)
|
||||
return await self.set_custom_effect(effect_dict)
|
||||
elif effect not in EFFECT_MAPPING_V1:
|
||||
raise ValueError(f"The effect {effect} is not a built in effect.")
|
||||
else:
|
||||
@@ -84,12 +84,12 @@ class LightEffect(IotModule, LightEffectInterface):
|
||||
if transition is not None:
|
||||
effect_dict["transition"] = transition
|
||||
|
||||
await self.set_custom_effect(effect_dict)
|
||||
return await self.set_custom_effect(effect_dict)
|
||||
|
||||
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
|
||||
@@ -104,7 +104,7 @@ class LightEffect(IotModule, LightEffectInterface):
|
||||
"""Return True if the device supports setting custom effects."""
|
||||
return True
|
||||
|
||||
def query(self):
|
||||
def query(self) -> dict:
|
||||
"""Return the base query."""
|
||||
return {}
|
||||
|
||||
|
@@ -41,7 +41,7 @@ class LightPreset(IotModule, LightPresetInterface):
|
||||
_presets: dict[str, IotLightPreset]
|
||||
_preset_list: list[str]
|
||||
|
||||
async def _post_update_hook(self):
|
||||
async def _post_update_hook(self) -> None:
|
||||
"""Update the internal presets."""
|
||||
self._presets = {
|
||||
f"Light preset {index+1}": IotLightPreset(**vals)
|
||||
@@ -93,7 +93,7 @@ class LightPreset(IotModule, LightPresetInterface):
|
||||
async def set_preset(
|
||||
self,
|
||||
preset_name: str,
|
||||
) -> None:
|
||||
) -> dict:
|
||||
"""Set a light preset for the device."""
|
||||
light = self._device.modules[Module.Light]
|
||||
if preset_name == self.PRESET_NOT_SET:
|
||||
@@ -104,7 +104,7 @@ class LightPreset(IotModule, LightPresetInterface):
|
||||
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 light.set_state(preset)
|
||||
return await light.set_state(preset)
|
||||
|
||||
@property
|
||||
def has_save_preset(self) -> bool:
|
||||
@@ -115,7 +115,7 @@ class LightPreset(IotModule, LightPresetInterface):
|
||||
self,
|
||||
preset_name: str,
|
||||
preset_state: LightState,
|
||||
) -> None:
|
||||
) -> dict:
|
||||
"""Update the preset with preset_name with the new preset_info."""
|
||||
if len(self._presets) == 0:
|
||||
raise KasaException("Device does not supported saving presets")
|
||||
@@ -129,7 +129,7 @@ class LightPreset(IotModule, LightPresetInterface):
|
||||
|
||||
return await self.call("set_preferred_state", state)
|
||||
|
||||
def query(self):
|
||||
def query(self) -> dict:
|
||||
"""Return the base query."""
|
||||
return {}
|
||||
|
||||
@@ -142,7 +142,7 @@ class LightPreset(IotModule, LightPresetInterface):
|
||||
if "id" not in vals
|
||||
]
|
||||
|
||||
async def _deprecated_save_preset(self, preset: IotLightPreset):
|
||||
async def _deprecated_save_preset(self, preset: IotLightPreset) -> dict:
|
||||
"""Save a setting preset.
|
||||
|
||||
You can either construct a preset object manually, or pass an existing one
|
||||
|
@@ -24,7 +24,7 @@ class Range(Enum):
|
||||
class Motion(IotModule):
|
||||
"""Implements the motion detection (PIR) module."""
|
||||
|
||||
def _initialize_features(self):
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
# Only add features if the device supports the module
|
||||
if "get_config" not in self.data:
|
||||
@@ -48,7 +48,7 @@ class Motion(IotModule):
|
||||
)
|
||||
)
|
||||
|
||||
def query(self):
|
||||
def query(self) -> dict:
|
||||
"""Request PIR configuration."""
|
||||
return self.query_for_command("get_config")
|
||||
|
||||
@@ -67,13 +67,13 @@ class Motion(IotModule):
|
||||
"""Return True if module is enabled."""
|
||||
return bool(self.config["enable"])
|
||||
|
||||
async def set_enabled(self, state: bool):
|
||||
async def set_enabled(self, state: bool) -> dict:
|
||||
"""Enable/disable PIR."""
|
||||
return await self.call("set_enable", {"enable": int(state)})
|
||||
|
||||
async def set_range(
|
||||
self, *, range: Range | None = None, custom_range: int | None = None
|
||||
):
|
||||
) -> dict:
|
||||
"""Set the range for the sensor.
|
||||
|
||||
:param range: for using standard ranges
|
||||
@@ -93,7 +93,7 @@ class Motion(IotModule):
|
||||
"""Return inactivity timeout in milliseconds."""
|
||||
return self.config["cold_time"]
|
||||
|
||||
async def set_inactivity_timeout(self, timeout: int):
|
||||
async def set_inactivity_timeout(self, timeout: int) -> dict:
|
||||
"""Set inactivity timeout in milliseconds.
|
||||
|
||||
Note, that you need to delete the default "Smart Control" rule in the app
|
||||
|
@@ -57,7 +57,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
class RuleModule(IotModule):
|
||||
"""Base class for rule-based modules, such as countdown and antitheft."""
|
||||
|
||||
def query(self):
|
||||
def query(self) -> dict:
|
||||
"""Prepare the query for rules."""
|
||||
q = self.query_for_command("get_rules")
|
||||
return merge(q, self.query_for_command("get_next_action"))
|
||||
@@ -73,14 +73,14 @@ class RuleModule(IotModule):
|
||||
_LOGGER.error("Unable to read rule list: %s (data: %s)", ex, self.data)
|
||||
return []
|
||||
|
||||
async def set_enabled(self, state: bool):
|
||||
async def set_enabled(self, state: bool) -> dict:
|
||||
"""Enable or disable the service."""
|
||||
return await self.call("set_overall_enable", state)
|
||||
return await self.call("set_overall_enable", {"enable": state})
|
||||
|
||||
async def delete_rule(self, rule: Rule):
|
||||
async def delete_rule(self, rule: Rule) -> dict:
|
||||
"""Delete the given rule."""
|
||||
return await self.call("delete_rule", {"id": rule.id})
|
||||
|
||||
async def delete_all_rules(self):
|
||||
async def delete_all_rules(self) -> dict:
|
||||
"""Delete all rules."""
|
||||
return await self.call("delete_all_rules")
|
||||
|
@@ -15,14 +15,14 @@ class Time(IotModule, TimeInterface):
|
||||
|
||||
_timezone: tzinfo = timezone.utc
|
||||
|
||||
def query(self):
|
||||
def query(self) -> dict:
|
||||
"""Request time and timezone."""
|
||||
q = self.query_for_command("get_time")
|
||||
|
||||
merge(q, self.query_for_command("get_timezone"))
|
||||
return q
|
||||
|
||||
async def _post_update_hook(self):
|
||||
async def _post_update_hook(self) -> None:
|
||||
"""Perform actions after a device update."""
|
||||
if res := self.data.get("get_timezone"):
|
||||
self._timezone = await get_timezone(res.get("index"))
|
||||
@@ -47,7 +47,7 @@ class Time(IotModule, TimeInterface):
|
||||
"""Return current timezone."""
|
||||
return self._timezone
|
||||
|
||||
async def get_time(self):
|
||||
async def get_time(self) -> datetime | None:
|
||||
"""Return current device time."""
|
||||
try:
|
||||
res = await self.call("get_time")
|
||||
@@ -88,6 +88,6 @@ class Time(IotModule, TimeInterface):
|
||||
except Exception as ex:
|
||||
raise KasaException(ex) from ex
|
||||
|
||||
async def get_timezone(self):
|
||||
async def get_timezone(self) -> dict:
|
||||
"""Request timezone information from the device."""
|
||||
return await self.call("get_timezone")
|
||||
|
@@ -10,7 +10,7 @@ from ..iotmodule import IotModule, merge
|
||||
class Usage(IotModule):
|
||||
"""Baseclass for emeter/usage interfaces."""
|
||||
|
||||
def query(self):
|
||||
def query(self) -> dict:
|
||||
"""Return the base query."""
|
||||
now = datetime.now()
|
||||
year = now.year
|
||||
@@ -25,22 +25,22 @@ class Usage(IotModule):
|
||||
return req
|
||||
|
||||
@property
|
||||
def estimated_query_response_size(self):
|
||||
def estimated_query_response_size(self) -> int:
|
||||
"""Estimated maximum query response size."""
|
||||
return 2048
|
||||
|
||||
@property
|
||||
def daily_data(self):
|
||||
def daily_data(self) -> list[dict]:
|
||||
"""Return statistics on daily basis."""
|
||||
return self.data["get_daystat"]["day_list"]
|
||||
|
||||
@property
|
||||
def monthly_data(self):
|
||||
def monthly_data(self) -> list[dict]:
|
||||
"""Return statistics on monthly basis."""
|
||||
return self.data["get_monthstat"]["month_list"]
|
||||
|
||||
@property
|
||||
def usage_today(self):
|
||||
def usage_today(self) -> int | None:
|
||||
"""Return today's usage in minutes."""
|
||||
today = datetime.now().day
|
||||
# Traverse the list in reverse order to find the latest entry.
|
||||
@@ -50,7 +50,7 @@ class Usage(IotModule):
|
||||
return None
|
||||
|
||||
@property
|
||||
def usage_this_month(self):
|
||||
def usage_this_month(self) -> int | None:
|
||||
"""Return usage in this month in minutes."""
|
||||
this_month = datetime.now().month
|
||||
# Traverse the list in reverse order to find the latest entry.
|
||||
@@ -59,7 +59,9 @@ class Usage(IotModule):
|
||||
return entry["time"]
|
||||
return None
|
||||
|
||||
async def get_raw_daystat(self, *, year=None, month=None) -> dict:
|
||||
async def get_raw_daystat(
|
||||
self, *, year: int | None = None, month: int | None = None
|
||||
) -> dict:
|
||||
"""Return raw daily stats for the given year & month."""
|
||||
if year is None:
|
||||
year = datetime.now().year
|
||||
@@ -68,14 +70,16 @@ class Usage(IotModule):
|
||||
|
||||
return await self.call("get_daystat", {"year": year, "month": month})
|
||||
|
||||
async def get_raw_monthstat(self, *, year=None) -> dict:
|
||||
async def get_raw_monthstat(self, *, year: int | None = None) -> dict:
|
||||
"""Return raw monthly stats for the given year."""
|
||||
if year is None:
|
||||
year = datetime.now().year
|
||||
|
||||
return await self.call("get_monthstat", {"year": year})
|
||||
|
||||
async def get_daystat(self, *, year=None, month=None) -> dict:
|
||||
async def get_daystat(
|
||||
self, *, year: int | None = None, month: int | None = None
|
||||
) -> dict:
|
||||
"""Return daily stats for the given year & month.
|
||||
|
||||
The return value is a dictionary of {day: time, ...}.
|
||||
@@ -84,7 +88,7 @@ class Usage(IotModule):
|
||||
data = self._convert_stat_data(data["day_list"], entry_key="day")
|
||||
return data
|
||||
|
||||
async def get_monthstat(self, *, year=None) -> dict:
|
||||
async def get_monthstat(self, *, year: int | None = None) -> dict:
|
||||
"""Return monthly stats for the given year.
|
||||
|
||||
The return value is a dictionary of {month: time, ...}.
|
||||
@@ -93,11 +97,11 @@ class Usage(IotModule):
|
||||
data = self._convert_stat_data(data["month_list"], entry_key="month")
|
||||
return data
|
||||
|
||||
async def erase_stats(self):
|
||||
async def erase_stats(self) -> dict:
|
||||
"""Erase all stats."""
|
||||
return await self.call("erase_runtime_stat")
|
||||
|
||||
def _convert_stat_data(self, data, entry_key) -> dict:
|
||||
def _convert_stat_data(self, data: list[dict], entry_key: str) -> dict:
|
||||
"""Return usage information keyed with the day/month.
|
||||
|
||||
The incoming data is a list of dictionaries::
|
||||
@@ -113,6 +117,6 @@ class Usage(IotModule):
|
||||
if not data:
|
||||
return {}
|
||||
|
||||
data = {entry[entry_key]: entry["time"] for entry in data}
|
||||
res = {entry[entry_key]: entry["time"] for entry in data}
|
||||
|
||||
return data
|
||||
return res
|
||||
|
Reference in New Issue
Block a user