Enable ruff check for ANN (#1139)

This commit is contained in:
Teemu R.
2024-11-10 19:55:13 +01:00
committed by GitHub
parent 6b44fe6242
commit 66eb17057e
89 changed files with 596 additions and 452 deletions

View File

@@ -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.

View File

@@ -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")

View File

@@ -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, ...}.

View File

@@ -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)})

View File

@@ -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.

View File

@@ -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 {}

View File

@@ -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

View File

@@ -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

View File

@@ -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")

View File

@@ -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")

View File

@@ -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