diff --git a/custom_components/adaptive_lighting/__init__.py b/custom_components/adaptive_lighting/__init__.py index 13c2d7d1..0c8bad80 100644 --- a/custom_components/adaptive_lighting/__init__.py +++ b/custom_components/adaptive_lighting/__init__.py @@ -70,12 +70,12 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry): return True -async def async_update_options(hass, config_entry: ConfigEntry): +async def async_update_options(hass: HomeAssistant, config_entry: ConfigEntry): """Update options.""" await hass.config_entries.async_reload(config_entry.entry_id) -async def async_unload_entry(hass, config_entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Unload a config entry.""" unload_ok = await hass.config_entries.async_forward_entry_unload( config_entry, diff --git a/custom_components/adaptive_lighting/_docs_helpers.py b/custom_components/adaptive_lighting/_docs_helpers.py index 31225a6c..49899395 100644 --- a/custom_components/adaptive_lighting/_docs_helpers.py +++ b/custom_components/adaptive_lighting/_docs_helpers.py @@ -57,8 +57,6 @@ def _type_to_str(type_: Any) -> str: # noqa: PLR0911 def generate_config_markdown_table(): - import pandas as pd - rows = [] for k, default, type_ in VALIDATION_TUPLES: description = DOCS[k] @@ -84,12 +82,11 @@ def _schema_to_dict(schema: vol.Schema) -> dict[str, tuple[Any, Any]]: def _generate_service_markdown_table( - schema: dict[str, tuple[Any, Any]], + schema: vol.Schema, alternative_docs: dict[str, str] | None = None, ): - schema = _schema_to_dict(schema) rows = [] - for k, (default, type_) in schema.items(): + for k, (default, type_) in _schema_to_dict(schema).items(): if alternative_docs is not None and k in alternative_docs: description = alternative_docs[k] else: diff --git a/custom_components/adaptive_lighting/adaptation_utils.py b/custom_components/adaptive_lighting/adaptation_utils.py index aea061d1..2c339223 100644 --- a/custom_components/adaptive_lighting/adaptation_utils.py +++ b/custom_components/adaptive_lighting/adaptation_utils.py @@ -54,7 +54,7 @@ def _split_service_call_data(service_data: ServiceData) -> list[ServiceData]: common_data = {k: service_data[k] for k in common_attrs if k in service_data} attributes_split_sequence = [BRIGHTNESS_ATTRS, COLOR_ATTRS] - service_datas = [] + service_datas: list[dict[str, Any]] = [] for attributes in attributes_split_sequence: split_data = { @@ -106,7 +106,7 @@ async def _create_service_call_data_iterator( hass: HomeAssistant, service_datas: list[ServiceData], filter_by_state: bool, -) -> AsyncGenerator[ServiceData, None]: +) -> AsyncGenerator[ServiceData]: """Enumerates and filters a list of service datas on the fly. If filtering is enabled, every service data is filtered by the current state of @@ -141,7 +141,7 @@ class AdaptationData: entity_id: str context: Context sleep_time: float - service_call_datas: AsyncGenerator[ServiceData, None] + service_call_datas: AsyncGenerator[ServiceData] force: bool max_length: int which: Literal["brightness", "color", "both"] diff --git a/custom_components/adaptive_lighting/color_and_brightness.py b/custom_components/adaptive_lighting/color_and_brightness.py index 6fdb7083..2fd93e67 100644 --- a/custom_components/adaptive_lighting/color_and_brightness.py +++ b/custom_components/adaptive_lighting/color_and_brightness.py @@ -8,8 +8,8 @@ import datetime import logging import math from dataclasses import dataclass -from datetime import timedelta -from functools import cached_property, partial +from datetime import UTC, timedelta +from functools import partial from typing import TYPE_CHECKING, Any, Literal, cast from homeassistant.util.color import ( @@ -17,9 +17,10 @@ from homeassistant.util.color import ( color_temperature_to_rgb, color_xy_to_hs, ) +from propcache.api import cached_property if TYPE_CHECKING: - import astral + import astral.location # Same as homeassistant.const.SUN_EVENT_SUNRISE and homeassistant.const.SUN_EVENT_SUNSET # We re-define them here to not depend on homeassistant in this file. @@ -32,7 +33,6 @@ SUN_EVENT_MIDNIGHT = "solar_midnight" _ORDER = (SUN_EVENT_SUNRISE, SUN_EVENT_NOON, SUN_EVENT_SUNSET, SUN_EVENT_MIDNIGHT) _ALLOWED_ORDERS = {_ORDER[i:] + _ORDER[:i] for i in range(len(_ORDER))} -UTC = datetime.timezone.utc utcnow: partial[datetime.datetime] = partial(datetime.datetime.now, UTC) utcnow.__doc__ = "Get now in UTC time." @@ -44,7 +44,7 @@ class SunEvents: """Track the state of the sun and associated light settings.""" name: str - astral_location: astral.Location + astral_location: astral.location.Location sunrise_time: datetime.time | None min_sunrise_time: datetime.time | None max_sunrise_time: datetime.time | None @@ -198,7 +198,7 @@ class SunLightSettings: """Track the state of the sun and associated light settings.""" name: str - astral_location: astral.Location + astral_location: astral.location.Location adapt_until_sleep: bool max_brightness: int max_color_temp: int @@ -296,7 +296,7 @@ class SunLightSettings: ) return clamp(brightness, self.min_brightness, self.max_brightness) - def brightness_pct(self, dt: datetime.datetime, is_sleep: bool) -> float: + def brightness_pct(self, dt: datetime.datetime, is_sleep: bool) -> float | None: """Calculate the brightness in %.""" if is_sleep: return self.sleep_brightness @@ -331,7 +331,7 @@ class SunLightSettings: ) -> dict[str, Any]: """Calculate the brightness and color.""" sun_position = self.sun.sun_position(dt) - rgb_color: tuple[float, float, float] + rgb_color: tuple[int, int, int] # Variable `force_rgb_color` is needed for RGB color after sunset (if enabled) force_rgb_color = False brightness_pct = self.brightness_pct(dt, is_sleep) diff --git a/custom_components/adaptive_lighting/config_flow.py b/custom_components/adaptive_lighting/config_flow.py index 3922d000..00214fdb 100644 --- a/custom_components/adaptive_lighting/config_flow.py +++ b/custom_components/adaptive_lighting/config_flow.py @@ -1,6 +1,7 @@ """Config flow for Adaptive Lighting integration.""" import logging +from typing import Any import homeassistant.helpers.config_validation as cv import voluptuous as vol @@ -40,7 +41,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): errors=errors, ) - async def async_step_import(self, user_input=None): + async def async_step_import(self, user_input: dict[str, Any]): """Handle configuration by YAML file.""" await self.async_set_unique_id(user_input[CONF_NAME]) # Keep a list of switches that are configured via YAML