Improve type hints in light (#78349)

This commit is contained in:
epenet 2022-09-14 13:36:20 +02:00 committed by GitHub
parent 374b72f052
commit 1fcab33653
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 28 deletions

View File

@ -197,7 +197,7 @@ class LIFXManager:
) )
await self.effects_conductor.start(effect, bulbs) await self.effects_conductor.start(effect, bulbs)
elif service == SERVICE_EFFECT_COLORLOOP: elif service == SERVICE_EFFECT_COLORLOOP:
preprocess_turn_on_alternatives(self.hass, kwargs) # type: ignore[no-untyped-call] preprocess_turn_on_alternatives(self.hass, kwargs)
brightness = None brightness = None
if ATTR_BRIGHTNESS in kwargs: if ATTR_BRIGHTNESS in kwargs:

View File

@ -70,7 +70,7 @@ def find_hsbk(hass: HomeAssistant, **kwargs: Any) -> list[float | int | None] |
""" """
hue, saturation, brightness, kelvin = [None] * 4 hue, saturation, brightness, kelvin = [None] * 4
preprocess_turn_on_alternatives(hass, kwargs) # type: ignore[no-untyped-call] preprocess_turn_on_alternatives(hass, kwargs)
if ATTR_HS_COLOR in kwargs: if ATTR_HS_COLOR in kwargs:
hue, saturation = kwargs[ATTR_HS_COLOR] hue, saturation = kwargs[ATTR_HS_COLOR]

View File

@ -8,7 +8,7 @@ from datetime import timedelta
from enum import IntEnum from enum import IntEnum
import logging import logging
import os import os
from typing import cast, final from typing import Any, cast, final
import voluptuous as vol import voluptuous as vol
@ -20,7 +20,7 @@ from homeassistant.const import (
SERVICE_TURN_ON, SERVICE_TURN_ON,
STATE_ON, STATE_ON,
) )
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers import config_validation as cv, entity_registry as er
from homeassistant.helpers.config_validation import ( # noqa: F401 from homeassistant.helpers.config_validation import ( # noqa: F401
@ -34,8 +34,6 @@ from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import bind_hass from homeassistant.loader import bind_hass
import homeassistant.util.color as color_util import homeassistant.util.color as color_util
# mypy: allow-untyped-defs, no-check-untyped-defs
DOMAIN = "light" DOMAIN = "light"
SCAN_INTERVAL = timedelta(seconds=30) SCAN_INTERVAL = timedelta(seconds=30)
DATA_PROFILES = "light_profiles" DATA_PROFILES = "light_profiles"
@ -288,7 +286,9 @@ def is_on(hass: HomeAssistant, entity_id: str) -> bool:
return hass.states.is_state(entity_id, STATE_ON) return hass.states.is_state(entity_id, STATE_ON)
def preprocess_turn_on_alternatives(hass, params): def preprocess_turn_on_alternatives(
hass: HomeAssistant, params: dict[str, Any]
) -> None:
"""Process extra data for turn light on request. """Process extra data for turn light on request.
Async friendly. Async friendly.
@ -316,7 +316,9 @@ def preprocess_turn_on_alternatives(hass, params):
params[ATTR_BRIGHTNESS] = round(255 * brightness_pct / 100) params[ATTR_BRIGHTNESS] = round(255 * brightness_pct / 100)
def filter_turn_off_params(light, params): def filter_turn_off_params(
light: LightEntity, params: dict[str, Any]
) -> dict[str, Any]:
"""Filter out params not used in turn off or not supported by the light.""" """Filter out params not used in turn off or not supported by the light."""
supported_features = light.supported_features supported_features = light.supported_features
@ -328,7 +330,7 @@ def filter_turn_off_params(light, params):
return {k: v for k, v in params.items() if k in (ATTR_TRANSITION, ATTR_FLASH)} return {k: v for k, v in params.items() if k in (ATTR_TRANSITION, ATTR_FLASH)}
def filter_turn_on_params(light, params): def filter_turn_on_params(light: LightEntity, params: dict[str, Any]) -> dict[str, Any]:
"""Filter out params not supported by the light.""" """Filter out params not supported by the light."""
supported_features = light.supported_features supported_features = light.supported_features
@ -372,9 +374,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
profiles = hass.data[DATA_PROFILES] = Profiles(hass) profiles = hass.data[DATA_PROFILES] = Profiles(hass)
await profiles.async_initialize() await profiles.async_initialize()
def preprocess_data(data): def preprocess_data(data: dict[str, Any]) -> dict[str | vol.Optional, Any]:
"""Preprocess the service data.""" """Preprocess the service data."""
base = { base: dict[str | vol.Optional, Any] = {
entity_field: data.pop(entity_field) entity_field: data.pop(entity_field)
for entity_field in cv.ENTITY_SERVICE_FIELDS for entity_field in cv.ENTITY_SERVICE_FIELDS
if entity_field in data if entity_field in data
@ -384,18 +386,20 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
base["params"] = data base["params"] = data
return base return base
async def async_handle_light_on_service(light, call): async def async_handle_light_on_service(
light: LightEntity, call: ServiceCall
) -> None:
"""Handle turning a light on. """Handle turning a light on.
If brightness is set to 0, this service will turn the light off. If brightness is set to 0, this service will turn the light off.
""" """
params = dict(call.data["params"]) params: dict[str, Any] = dict(call.data["params"])
# Only process params once we processed brightness step # Only process params once we processed brightness step
if params and ( if params and (
ATTR_BRIGHTNESS_STEP in params or ATTR_BRIGHTNESS_STEP_PCT in params ATTR_BRIGHTNESS_STEP in params or ATTR_BRIGHTNESS_STEP_PCT in params
): ):
brightness = light.brightness if light.is_on else 0 brightness = light.brightness if light.is_on and light.brightness else 0
if ATTR_BRIGHTNESS_STEP in params: if ATTR_BRIGHTNESS_STEP in params:
brightness += params.pop(ATTR_BRIGHTNESS_STEP) brightness += params.pop(ATTR_BRIGHTNESS_STEP)
@ -447,7 +451,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
rgb_color = color_util.color_rgbw_to_rgb(*rgbw_color) rgb_color = color_util.color_rgbw_to_rgb(*rgbw_color)
params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color) params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
elif (rgbww_color := params.pop(ATTR_RGBWW_COLOR, None)) is not None: elif (rgbww_color := params.pop(ATTR_RGBWW_COLOR, None)) is not None:
rgb_color = color_util.color_rgbww_to_rgb( rgb_color = color_util.color_rgbww_to_rgb( # type: ignore[call-arg]
*rgbww_color, light.min_mireds, light.max_mireds *rgbww_color, light.min_mireds, light.max_mireds
) )
params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color) params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
@ -460,7 +464,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
params[ATTR_RGBW_COLOR] = color_util.color_rgb_to_rgbw(*rgb_color) params[ATTR_RGBW_COLOR] = color_util.color_rgb_to_rgbw(*rgb_color)
elif ColorMode.RGBWW in supported_color_modes: elif ColorMode.RGBWW in supported_color_modes:
rgb_color = color_util.color_hs_to_RGB(*hs_color) rgb_color = color_util.color_hs_to_RGB(*hs_color)
params[ATTR_RGBWW_COLOR] = color_util.color_rgb_to_rgbww( params[ATTR_RGBWW_COLOR] = color_util.color_rgb_to_rgbww( # type: ignore[call-arg]
*rgb_color, light.min_mireds, light.max_mireds *rgb_color, light.min_mireds, light.max_mireds
) )
elif ColorMode.XY in supported_color_modes: elif ColorMode.XY in supported_color_modes:
@ -470,7 +474,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
if ColorMode.RGBW in supported_color_modes: if ColorMode.RGBW in supported_color_modes:
params[ATTR_RGBW_COLOR] = color_util.color_rgb_to_rgbw(*rgb_color) params[ATTR_RGBW_COLOR] = color_util.color_rgb_to_rgbw(*rgb_color)
elif ColorMode.RGBWW in supported_color_modes: elif ColorMode.RGBWW in supported_color_modes:
params[ATTR_RGBWW_COLOR] = color_util.color_rgb_to_rgbww( params[ATTR_RGBWW_COLOR] = color_util.color_rgb_to_rgbww( # type: ignore[call-arg]
*rgb_color, light.min_mireds, light.max_mireds *rgb_color, light.min_mireds, light.max_mireds
) )
elif ColorMode.HS in supported_color_modes: elif ColorMode.HS in supported_color_modes:
@ -488,7 +492,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
params[ATTR_RGBW_COLOR] = color_util.color_rgb_to_rgbw(*rgb_color) params[ATTR_RGBW_COLOR] = color_util.color_rgb_to_rgbw(*rgb_color)
elif ColorMode.RGBWW in supported_color_modes: elif ColorMode.RGBWW in supported_color_modes:
rgb_color = color_util.color_xy_to_RGB(*xy_color) rgb_color = color_util.color_xy_to_RGB(*xy_color)
params[ATTR_RGBWW_COLOR] = color_util.color_rgb_to_rgbww( params[ATTR_RGBWW_COLOR] = color_util.color_rgb_to_rgbww( # type: ignore[call-arg]
*rgb_color, light.min_mireds, light.max_mireds *rgb_color, light.min_mireds, light.max_mireds
) )
elif ATTR_RGBW_COLOR in params and ColorMode.RGBW not in supported_color_modes: elif ATTR_RGBW_COLOR in params and ColorMode.RGBW not in supported_color_modes:
@ -497,7 +501,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
if ColorMode.RGB in supported_color_modes: if ColorMode.RGB in supported_color_modes:
params[ATTR_RGB_COLOR] = rgb_color params[ATTR_RGB_COLOR] = rgb_color
elif ColorMode.RGBWW in supported_color_modes: elif ColorMode.RGBWW in supported_color_modes:
params[ATTR_RGBWW_COLOR] = color_util.color_rgb_to_rgbww( params[ATTR_RGBWW_COLOR] = color_util.color_rgb_to_rgbww( # type: ignore[call-arg]
*rgb_color, light.min_mireds, light.max_mireds *rgb_color, light.min_mireds, light.max_mireds
) )
elif ColorMode.HS in supported_color_modes: elif ColorMode.HS in supported_color_modes:
@ -508,7 +512,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
ATTR_RGBWW_COLOR in params and ColorMode.RGBWW not in supported_color_modes ATTR_RGBWW_COLOR in params and ColorMode.RGBWW not in supported_color_modes
): ):
rgbww_color = params.pop(ATTR_RGBWW_COLOR) rgbww_color = params.pop(ATTR_RGBWW_COLOR)
rgb_color = color_util.color_rgbww_to_rgb( rgb_color = color_util.color_rgbww_to_rgb( # type: ignore[call-arg]
*rgbww_color, light.min_mireds, light.max_mireds *rgbww_color, light.min_mireds, light.max_mireds
) )
if ColorMode.RGB in supported_color_modes: if ColorMode.RGB in supported_color_modes:
@ -534,7 +538,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
else: else:
await light.async_turn_on(**filter_turn_on_params(light, params)) await light.async_turn_on(**filter_turn_on_params(light, params))
async def async_handle_light_off_service(light, call): async def async_handle_light_off_service(
light: LightEntity, call: ServiceCall
) -> None:
"""Handle turning off a light.""" """Handle turning off a light."""
params = dict(call.data["params"]) params = dict(call.data["params"])
@ -543,7 +549,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
await light.async_turn_off(**filter_turn_off_params(light, params)) await light.async_turn_off(**filter_turn_off_params(light, params))
async def async_handle_toggle_service(light, call): async def async_handle_toggle_service(
light: LightEntity, call: ServiceCall
) -> None:
"""Handle toggling a light.""" """Handle toggling a light."""
if light.is_on: if light.is_on:
await async_handle_light_off_service(light, call) await async_handle_light_off_service(light, call)
@ -689,7 +697,9 @@ class Profiles:
self.data = await self.hass.async_add_executor_job(self._load_profile_data) self.data = await self.hass.async_add_executor_job(self._load_profile_data)
@callback @callback
def apply_default(self, entity_id: str, state_on: bool, params: dict) -> None: def apply_default(
self, entity_id: str, state_on: bool | None, params: dict[str, Any]
) -> None:
"""Return the default profile for the given light.""" """Return the default profile for the given light."""
for _entity_id in (entity_id, "group.all_lights"): for _entity_id in (entity_id, "group.all_lights"):
name = f"{_entity_id}.default" name = f"{_entity_id}.default"
@ -700,7 +710,7 @@ class Profiles:
params.setdefault(ATTR_TRANSITION, self.data[name].transition) params.setdefault(ATTR_TRANSITION, self.data[name].transition)
@callback @callback
def apply_profile(self, name: str, params: dict) -> None: def apply_profile(self, name: str, params: dict[str, Any]) -> None:
"""Apply a profile.""" """Apply a profile."""
if (profile := self.data.get(name)) is None: if (profile := self.data.get(name)) is None:
return return
@ -841,9 +851,9 @@ class LightEntity(ToggleEntity):
return self._attr_effect return self._attr_effect
@property @property
def capability_attributes(self): def capability_attributes(self) -> dict[str, Any]:
"""Return capability attributes.""" """Return capability attributes."""
data = {} data: dict[str, Any] = {}
supported_features = self.supported_features supported_features = self.supported_features
supported_color_modes = self._light_internal_supported_color_modes supported_color_modes = self._light_internal_supported_color_modes
@ -902,12 +912,12 @@ class LightEntity(ToggleEntity):
@final @final
@property @property
def state_attributes(self): def state_attributes(self) -> dict[str, Any] | None:
"""Return state attributes.""" """Return state attributes."""
if not self.is_on: if not self.is_on:
return None return None
data = {} data: dict[str, Any] = {}
supported_features = self.supported_features supported_features = self.supported_features
color_mode = self._light_internal_color_mode color_mode = self._light_internal_color_mode