1
mirror of https://github.com/home-assistant/core synced 2024-07-12 07:21:24 +02:00

Fix types for WLED (#50001)

This commit is contained in:
Dermot Duffy 2021-05-09 10:34:21 -07:00 committed by GitHub
parent 2ca0eb61dc
commit 4e4042a869
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 37 additions and 45 deletions

View File

@ -10,7 +10,14 @@ from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_NAME, CONF_HOST
from homeassistant.const import (
ATTR_IDENTIFIERS,
ATTR_MANUFACTURER,
ATTR_MODEL,
ATTR_NAME,
ATTR_SW_VERSION,
CONF_HOST,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.entity import DeviceInfo
@ -20,13 +27,7 @@ from homeassistant.helpers.update_coordinator import (
UpdateFailed,
)
from .const import (
ATTR_IDENTIFIERS,
ATTR_MANUFACTURER,
ATTR_MODEL,
ATTR_SOFTWARE_VERSION,
DOMAIN,
)
from .const import DOMAIN
SCAN_INTERVAL = timedelta(seconds=5)
PLATFORMS = (LIGHT_DOMAIN, SENSOR_DOMAIN, SWITCH_DOMAIN)
@ -128,6 +129,8 @@ class WLEDDataUpdateCoordinator(DataUpdateCoordinator[WLEDDevice]):
class WLEDEntity(CoordinatorEntity):
"""Defines a base WLED entity."""
coordinator: WLEDDataUpdateCoordinator
def __init__(
self,
*,
@ -172,5 +175,5 @@ class WLEDDeviceEntity(WLEDEntity):
ATTR_NAME: self.coordinator.data.info.name,
ATTR_MANUFACTURER: self.coordinator.data.info.brand,
ATTR_MODEL: self.coordinator.data.info.product,
ATTR_SOFTWARE_VERSION: self.coordinator.data.info.version,
ATTR_SW_VERSION: self.coordinator.data.info.version,
}

View File

@ -1,6 +1,8 @@
"""Config flow to configure the WLED integration."""
from __future__ import annotations
from typing import Any
import voluptuous as vol
from wled import WLED, WLEDConnectionError
@ -8,7 +10,7 @@ from homeassistant.config_entries import SOURCE_ZEROCONF, ConfigFlow
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.typing import ConfigType
from homeassistant.helpers.typing import DiscoveryInfoType
from .const import DOMAIN
@ -18,16 +20,16 @@ class WLEDFlowHandler(ConfigFlow, domain=DOMAIN):
VERSION = 1
async def async_step_user(self, user_input: ConfigType | None = None) -> FlowResult:
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle a flow initiated by the user."""
return await self._handle_config_flow(user_input)
async def async_step_zeroconf(
self, discovery_info: ConfigType | None = None
self, discovery_info: DiscoveryInfoType
) -> FlowResult:
"""Handle zeroconf discovery."""
if discovery_info is None:
return self.async_abort(reason="cannot_connect")
# Hostname is format: wled-livingroom.local.
host = discovery_info["hostname"].rstrip(".")
@ -46,13 +48,13 @@ class WLEDFlowHandler(ConfigFlow, domain=DOMAIN):
return await self._handle_config_flow(discovery_info, True)
async def async_step_zeroconf_confirm(
self, user_input: ConfigType = None
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle a flow initiated by zeroconf."""
return await self._handle_config_flow(user_input)
async def _handle_config_flow(
self, user_input: ConfigType | None = None, prepare: bool = False
self, user_input: dict[str, Any] | None = None, prepare: bool = False
) -> FlowResult:
"""Config flow handler for WLED."""
source = self.context.get("source")
@ -63,6 +65,9 @@ class WLEDFlowHandler(ConfigFlow, domain=DOMAIN):
return self._show_confirm_dialog()
return self._show_setup_form()
# if prepare is True, user_input can not be None.
assert user_input is not None
if source == SOURCE_ZEROCONF:
user_input[CONF_HOST] = self.context.get(CONF_HOST)
user_input[CONF_MAC] = self.context.get(CONF_MAC)

View File

@ -7,12 +7,9 @@ DOMAIN = "wled"
ATTR_COLOR_PRIMARY = "color_primary"
ATTR_DURATION = "duration"
ATTR_FADE = "fade"
ATTR_IDENTIFIERS = "identifiers"
ATTR_INTENSITY = "intensity"
ATTR_LED_COUNT = "led_count"
ATTR_MANUFACTURER = "manufacturer"
ATTR_MAX_POWER = "max_power"
ATTR_MODEL = "model"
ATTR_ON = "on"
ATTR_PALETTE = "palette"
ATTR_PLAYLIST = "playlist"

View File

@ -58,6 +58,7 @@ async def async_setup_entry(
coordinator: WLEDDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
platform = entity_platform.async_get_current_platform()
platform.async_register_entity_service(
SERVICE_EFFECT,
{
@ -127,7 +128,7 @@ class WLEDMasterLight(LightEntity, WLEDDeviceEntity):
@wled_exception_handler
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the light."""
data = {ATTR_ON: False}
data: dict[str, bool | int] = {ATTR_ON: False}
if ATTR_TRANSITION in kwargs:
# WLED uses 100ms per unit, so 10 = 1 second.
@ -138,7 +139,7 @@ class WLEDMasterLight(LightEntity, WLEDDeviceEntity):
@wled_exception_handler
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the light."""
data = {ATTR_ON: True}
data: dict[str, bool | int] = {ATTR_ON: True}
if ATTR_TRANSITION in kwargs:
# WLED uses 100ms per unit, so 10 = 1 second.
@ -230,7 +231,7 @@ class WLEDSegmentLight(LightEntity, WLEDDeviceEntity):
}
@property
def hs_color(self) -> tuple[float, float] | None:
def hs_color(self) -> tuple[float, float]:
"""Return the hue and saturation color value [float, float]."""
color = self.coordinator.data.state.segments[self._segment].color_primary
return color_util.color_RGB_to_hs(*color[:3])
@ -295,7 +296,7 @@ class WLEDSegmentLight(LightEntity, WLEDDeviceEntity):
@wled_exception_handler
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the light."""
data = {ATTR_ON: False}
data: dict[str, bool | int] = {ATTR_ON: False}
if ATTR_TRANSITION in kwargs:
# WLED uses 100ms per unit, so 10 = 1 second.
@ -312,7 +313,10 @@ class WLEDSegmentLight(LightEntity, WLEDDeviceEntity):
@wled_exception_handler
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the light."""
data = {ATTR_ON: True, ATTR_SEGMENT_ID: self._segment}
data: dict[str, Any] = {
ATTR_ON: True,
ATTR_SEGMENT_ID: self._segment,
}
if ATTR_COLOR_TEMP in kwargs:
mireds = color_util.color_temperature_kelvin_to_mired(
@ -385,7 +389,7 @@ class WLEDSegmentLight(LightEntity, WLEDDeviceEntity):
speed: int | None = None,
) -> None:
"""Set the effect of a WLED light."""
data = {ATTR_SEGMENT_ID: self._segment}
data: dict[str, bool | int | str | None] = {ATTR_SEGMENT_ID: self._segment}
if effect is not None:
data[ATTR_EFFECT] = effect
@ -419,7 +423,7 @@ class WLEDSegmentLight(LightEntity, WLEDDeviceEntity):
def async_update_segments(
entry: ConfigEntry,
coordinator: WLEDDataUpdateCoordinator,
current: dict[int, WLEDSegmentLight],
current: dict[int, WLEDSegmentLight | WLEDMasterLight],
async_add_entities,
) -> None:
"""Update segments."""
@ -459,7 +463,7 @@ def async_update_segments(
async def async_remove_entity(
index: int,
coordinator: WLEDDataUpdateCoordinator,
current: dict[int, WLEDSegmentLight],
current: dict[int, WLEDSegmentLight | WLEDMasterLight],
) -> None:
"""Remove WLED segment light from Home Assistant."""
entity = current[index]

View File

@ -74,7 +74,7 @@ class WLEDSensor(WLEDDeviceEntity, SensorEntity):
return f"{self.coordinator.data.info.mac_address}_{self._key}"
@property
def unit_of_measurement(self) -> str:
def unit_of_measurement(self) -> str | None:
"""Return the unit this state is expressed in."""
return self._unit_of_measurement

View File

@ -1325,9 +1325,6 @@ ignore_errors = true
[mypy-homeassistant.components.withings.*]
ignore_errors = true
[mypy-homeassistant.components.wled.*]
ignore_errors = true
[mypy-homeassistant.components.wunderground.*]
ignore_errors = true

View File

@ -236,7 +236,6 @@ IGNORED_MODULES: Final[list[str]] = [
"homeassistant.components.wemo.*",
"homeassistant.components.wink.*",
"homeassistant.components.withings.*",
"homeassistant.components.wled.*",
"homeassistant.components.wunderground.*",
"homeassistant.components.xbox.*",
"homeassistant.components.xiaomi_aqara.*",

View File

@ -119,19 +119,6 @@ async def test_zeroconf_confirm_connection_error(
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
@patch("homeassistant.components.wled.WLED.update", side_effect=WLEDConnectionError)
async def test_zeroconf_no_data(
update_mock: MagicMock, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test we abort if zeroconf provides no data."""
flow = config_flow.WLEDFlowHandler()
flow.hass = hass
result = await flow.async_step_zeroconf()
assert result["reason"] == "cannot_connect"
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
async def test_user_device_exists_abort(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None: