Remove xiaomi_miio from mypy ignore list (#74669)

This commit is contained in:
epenet 2022-07-09 19:59:11 +02:00 committed by GitHub
parent e74f7d13ab
commit 5360e56d09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 63 additions and 69 deletions

View File

@ -18,6 +18,7 @@ from miio import (
CleaningDetails, CleaningDetails,
CleaningSummary, CleaningSummary,
ConsumableStatus, ConsumableStatus,
Device as MiioDevice,
DeviceException, DeviceException,
DNDStatus, DNDStatus,
Fan, Fan,
@ -283,10 +284,10 @@ async def async_create_miio_device_and_coordinator(
host = entry.data[CONF_HOST] host = entry.data[CONF_HOST]
token = entry.data[CONF_TOKEN] token = entry.data[CONF_TOKEN]
name = entry.title name = entry.title
device = None device: MiioDevice | None = None
migrate = False migrate = False
update_method = _async_update_data_default update_method = _async_update_data_default
coordinator_class = DataUpdateCoordinator coordinator_class: type[DataUpdateCoordinator] = DataUpdateCoordinator
if ( if (
model not in MODELS_HUMIDIFIER model not in MODELS_HUMIDIFIER
@ -345,10 +346,13 @@ async def async_create_miio_device_and_coordinator(
if migrate: if migrate:
# Removing fan platform entity for humidifiers and migrate the name to the config entry for migration # Removing fan platform entity for humidifiers and migrate the name to the config entry for migration
entity_registry = er.async_get(hass) entity_registry = er.async_get(hass)
assert entry.unique_id
entity_id = entity_registry.async_get_entity_id("fan", DOMAIN, entry.unique_id) entity_id = entity_registry.async_get_entity_id("fan", DOMAIN, entry.unique_id)
if entity_id: if entity_id:
# This check is entities that have a platform migration only and should be removed in the future # This check is entities that have a platform migration only and should be removed in the future
if migrate_entity_name := entity_registry.async_get(entity_id).name: if (entity := entity_registry.async_get(entity_id)) and (
migrate_entity_name := entity.name
):
hass.config_entries.async_update_entry(entry, title=migrate_entity_name) hass.config_entries.async_update_entry(entry, title=migrate_entity_name)
entity_registry.async_remove(entity_id) entity_registry.async_remove(entity_id)
@ -377,8 +381,10 @@ async def async_setup_gateway_entry(hass: HomeAssistant, entry: ConfigEntry) ->
name = entry.title name = entry.title
gateway_id = entry.unique_id gateway_id = entry.unique_id
assert gateway_id
# For backwards compat # For backwards compat
if entry.unique_id.endswith("-gateway"): if gateway_id.endswith("-gateway"):
hass.config_entries.async_update_entry(entry, unique_id=entry.data["mac"]) hass.config_entries.async_update_entry(entry, unique_id=entry.data["mac"])
entry.async_on_unload(entry.add_update_listener(update_listener)) entry.async_on_unload(entry.add_update_listener(update_listener))
@ -419,7 +425,7 @@ async def async_setup_gateway_entry(hass: HomeAssistant, entry: ConfigEntry) ->
return async_update_data return async_update_data
coordinator_dict = {} coordinator_dict: dict[str, DataUpdateCoordinator] = {}
for sub_device in gateway.gateway_device.devices.values(): for sub_device in gateway.gateway_device.devices.values():
# Create update coordinator # Create update coordinator
coordinator_dict[sub_device.sid] = DataUpdateCoordinator( coordinator_dict[sub_device.sid] = DataUpdateCoordinator(

View File

@ -1,4 +1,5 @@
"""Support for Xiaomi Mi Air Quality Monitor (PM2.5).""" """Support for Xiaomi Mi Air Quality Monitor (PM2.5)."""
from collections.abc import Callable
import logging import logging
from miio import AirQualityMonitor, AirQualityMonitorCGDN1, DeviceException from miio import AirQualityMonitor, AirQualityMonitorCGDN1, DeviceException
@ -218,7 +219,7 @@ class AirMonitorCGDN1(XiaomiMiioEntity, AirQualityEntity):
return self._particulate_matter_10 return self._particulate_matter_10
DEVICE_MAP = { DEVICE_MAP: dict[str, dict[str, Callable]] = {
MODEL_AIRQUALITYMONITOR_S1: { MODEL_AIRQUALITYMONITOR_S1: {
"device_class": AirQualityMonitor, "device_class": AirQualityMonitor,
"entity_class": AirMonitorS1, "entity_class": AirMonitorS1,

View File

@ -1,7 +1,7 @@
"""Support for Xiaomi Miio binary sensors.""" """Support for Xiaomi Miio binary sensors."""
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable, Iterable
from dataclasses import dataclass from dataclasses import dataclass
import logging import logging
@ -180,7 +180,7 @@ async def async_setup_entry(
if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE: if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE:
model = config_entry.data[CONF_MODEL] model = config_entry.data[CONF_MODEL]
sensors = [] sensors: Iterable[str] = []
if model in MODEL_AIRFRESH_A1 or model in MODEL_AIRFRESH_T2017: if model in MODEL_AIRFRESH_A1 or model in MODEL_AIRFRESH_T2017:
sensors = AIRFRESH_A1_BINARY_SENSORS sensors = AIRFRESH_A1_BINARY_SENSORS
elif model in MODEL_FAN_ZA5: elif model in MODEL_FAN_ZA5:

View File

@ -184,9 +184,9 @@ class XiaomiCoordinatedMiioEntity(CoordinatorEntity[_T]):
return int(timedelta.total_seconds()) return int(timedelta.total_seconds())
@staticmethod @staticmethod
def _parse_datetime_time(time: datetime.time) -> str: def _parse_datetime_time(initial_time: datetime.time) -> str:
time = datetime.datetime.now().replace( time = datetime.datetime.now().replace(
hour=time.hour, minute=time.minute, second=0, microsecond=0 hour=initial_time.hour, minute=initial_time.minute, second=0, microsecond=0
) )
if time < datetime.datetime.now(): if time < datetime.datetime.now():

View File

@ -8,7 +8,7 @@ import voluptuous as vol
from homeassistant.components.device_tracker import ( from homeassistant.components.device_tracker import (
DOMAIN, DOMAIN,
PLATFORM_SCHEMA, PLATFORM_SCHEMA as BASE_PLATFORM_SCHEMA,
DeviceScanner, DeviceScanner,
) )
from homeassistant.const import CONF_HOST, CONF_TOKEN from homeassistant.const import CONF_HOST, CONF_TOKEN
@ -18,7 +18,7 @@ from homeassistant.helpers.typing import ConfigType
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( PLATFORM_SCHEMA = BASE_PLATFORM_SCHEMA.extend(
{ {
vol.Required(CONF_HOST): cv.string, vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_TOKEN): vol.All(cv.string, vol.Length(min=32, max=32)), vol.Required(CONF_TOKEN): vol.All(cv.string, vol.Length(min=32, max=32)),

View File

@ -183,7 +183,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up the Fan from a config entry.""" """Set up the Fan from a config entry."""
entities = [] entities: list[FanEntity] = []
entity: FanEntity
if not config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE: if not config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE:
return return
@ -299,7 +300,7 @@ class XiaomiGenericDevice(XiaomiCoordinatedMiioEntity, FanEntity):
return self._preset_modes return self._preset_modes
@property @property
def percentage(self) -> None: def percentage(self) -> int | None:
"""Return the percentage based speed of the fan.""" """Return the percentage based speed of the fan."""
return None return None

View File

@ -68,7 +68,8 @@ async def async_setup_entry(
if not config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE: if not config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE:
return return
entities = [] entities: list[HumidifierEntity] = []
entity: HumidifierEntity
model = config_entry.data[CONF_MODEL] model = config_entry.data[CONF_MODEL]
unique_id = config_entry.unique_id unique_id = config_entry.unique_id
coordinator = hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR] coordinator = hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR]
@ -112,6 +113,7 @@ class XiaomiGenericHumidifier(XiaomiCoordinatedMiioEntity, HumidifierEntity):
_attr_device_class = HumidifierDeviceClass.HUMIDIFIER _attr_device_class = HumidifierDeviceClass.HUMIDIFIER
_attr_supported_features = HumidifierEntityFeature.MODES _attr_supported_features = HumidifierEntityFeature.MODES
supported_features: int
def __init__(self, name, device, entry, unique_id, coordinator): def __init__(self, name, device, entry, unique_id, coordinator):
"""Initialize the generic Xiaomi device.""" """Initialize the generic Xiaomi device."""
@ -169,6 +171,8 @@ class XiaomiGenericHumidifier(XiaomiCoordinatedMiioEntity, HumidifierEntity):
class XiaomiAirHumidifier(XiaomiGenericHumidifier, HumidifierEntity): class XiaomiAirHumidifier(XiaomiGenericHumidifier, HumidifierEntity):
"""Representation of a Xiaomi Air Humidifier.""" """Representation of a Xiaomi Air Humidifier."""
available_modes: list[str]
def __init__(self, name, device, entry, unique_id, coordinator): def __init__(self, name, device, entry, unique_id, coordinator):
"""Initialize the plug switch.""" """Initialize the plug switch."""
super().__init__(name, device, entry, unique_id, coordinator) super().__init__(name, device, entry, unique_id, coordinator)

View File

@ -1,4 +1,6 @@
"""Support for Xiaomi Philips Lights.""" """Support for Xiaomi Philips Lights."""
from __future__ import annotations
import asyncio import asyncio
import datetime import datetime
from datetime import timedelta from datetime import timedelta
@ -6,7 +8,14 @@ from functools import partial
import logging import logging
from math import ceil from math import ceil
from miio import Ceil, DeviceException, PhilipsBulb, PhilipsEyecare, PhilipsMoonlight from miio import (
Ceil,
Device as MiioDevice,
DeviceException,
PhilipsBulb,
PhilipsEyecare,
PhilipsMoonlight,
)
from miio.gateway.gateway import ( from miio.gateway.gateway import (
GATEWAY_MODEL_AC_V1, GATEWAY_MODEL_AC_V1,
GATEWAY_MODEL_AC_V2, GATEWAY_MODEL_AC_V2,
@ -115,7 +124,9 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up the Xiaomi light from a config entry.""" """Set up the Xiaomi light from a config entry."""
entities = [] entities: list[LightEntity] = []
entity: LightEntity
light: MiioDevice
if config_entry.data[CONF_FLOW_TYPE] == CONF_GATEWAY: if config_entry.data[CONF_FLOW_TYPE] == CONF_GATEWAY:
gateway = hass.data[DOMAIN][config_entry.entry_id][CONF_GATEWAY] gateway = hass.data[DOMAIN][config_entry.entry_id][CONF_GATEWAY]
@ -195,7 +206,7 @@ async def async_setup_entry(
async def async_service_handler(service: ServiceCall) -> None: async def async_service_handler(service: ServiceCall) -> None:
"""Map services to methods on Xiaomi Philips Lights.""" """Map services to methods on Xiaomi Philips Lights."""
method = SERVICE_TO_METHOD.get(service.service) method = SERVICE_TO_METHOD[service.service]
params = { params = {
key: value key: value
for key, value in service.data.items() for key, value in service.data.items()
@ -372,7 +383,7 @@ class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight):
@staticmethod @staticmethod
def delayed_turn_off_timestamp( def delayed_turn_off_timestamp(
countdown: int, current: datetime, previous: datetime countdown: int, current: datetime.datetime, previous: datetime.datetime
): ):
"""Update the turn off timestamp only if necessary.""" """Update the turn off timestamp only if necessary."""
if countdown is not None and countdown > 0: if countdown is not None and countdown > 0:
@ -671,7 +682,7 @@ class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight):
@staticmethod @staticmethod
def delayed_turn_off_timestamp( def delayed_turn_off_timestamp(
countdown: int, current: datetime, previous: datetime countdown: int, current: datetime.datetime, previous: datetime.datetime
): ):
"""Update the turn off timestamp only if necessary.""" """Update the turn off timestamp only if necessary."""
if countdown is not None and countdown > 0: if countdown is not None and countdown > 0:
@ -783,7 +794,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
return 588 return 588
@property @property
def hs_color(self) -> tuple: def hs_color(self) -> tuple[float, float] | None:
"""Return the hs color value.""" """Return the hs color value."""
return self._hs_color return self._hs_color

View File

@ -1,6 +1,7 @@
"""Support for Xiaomi Mi Air Quality Monitor (PM2.5) and Humidifier.""" """Support for Xiaomi Mi Air Quality Monitor (PM2.5) and Humidifier."""
from __future__ import annotations from __future__ import annotations
from collections.abc import Iterable
from dataclasses import dataclass from dataclasses import dataclass
import logging import logging
@ -470,7 +471,7 @@ FAN_V2_V3_SENSORS = (
FAN_ZA5_SENSORS = (ATTR_HUMIDITY, ATTR_TEMPERATURE) FAN_ZA5_SENSORS = (ATTR_HUMIDITY, ATTR_TEMPERATURE)
MODEL_TO_SENSORS_MAP = { MODEL_TO_SENSORS_MAP: dict[str, tuple[str, ...]] = {
MODEL_AIRFRESH_A1: AIRFRESH_SENSORS_A1, MODEL_AIRFRESH_A1: AIRFRESH_SENSORS_A1,
MODEL_AIRFRESH_VA2: AIRFRESH_SENSORS, MODEL_AIRFRESH_VA2: AIRFRESH_SENSORS,
MODEL_AIRFRESH_T2017: AIRFRESH_SENSORS_T2017, MODEL_AIRFRESH_T2017: AIRFRESH_SENSORS_T2017,
@ -661,7 +662,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up the Xiaomi sensor from a config entry.""" """Set up the Xiaomi sensor from a config entry."""
entities = [] entities: list[SensorEntity] = []
if config_entry.data[CONF_FLOW_TYPE] == CONF_GATEWAY: if config_entry.data[CONF_FLOW_TYPE] == CONF_GATEWAY:
gateway = hass.data[DOMAIN][config_entry.entry_id][CONF_GATEWAY] gateway = hass.data[DOMAIN][config_entry.entry_id][CONF_GATEWAY]
@ -715,7 +716,7 @@ async def async_setup_entry(
) )
else: else:
device = hass.data[DOMAIN][config_entry.entry_id][KEY_DEVICE] device = hass.data[DOMAIN][config_entry.entry_id][KEY_DEVICE]
sensors = [] sensors: Iterable[str] = []
if model in MODEL_TO_SENSORS_MAP: if model in MODEL_TO_SENSORS_MAP:
sensors = MODEL_TO_SENSORS_MAP[model] sensors = MODEL_TO_SENSORS_MAP[model]
elif model in MODELS_HUMIDIFIER_MIOT: elif model in MODELS_HUMIDIFIER_MIOT:

View File

@ -201,12 +201,20 @@ MODEL_TO_FEATURES_MAP = {
@dataclass @dataclass
class XiaomiMiioSwitchDescription(SwitchEntityDescription): class XiaomiMiioSwitchRequiredKeyMixin:
"""A class that describes switch entities."""
feature: int
method_on: str
method_off: str
@dataclass
class XiaomiMiioSwitchDescription(
SwitchEntityDescription, XiaomiMiioSwitchRequiredKeyMixin
):
"""A class that describes switch entities.""" """A class that describes switch entities."""
feature: int | None = None
method_on: str | None = None
method_off: str | None = None
available_with_device_off: bool = True available_with_device_off: bool = True
@ -443,7 +451,7 @@ async def async_setup_other_entry(hass, config_entry, async_add_entities):
async def async_service_handler(service: ServiceCall) -> None: async def async_service_handler(service: ServiceCall) -> None:
"""Map services to methods on XiaomiPlugGenericSwitch.""" """Map services to methods on XiaomiPlugGenericSwitch."""
method = SERVICE_TO_METHOD.get(service.service) method = SERVICE_TO_METHOD[service.service]
params = { params = {
key: value key: value
for key, value in service.data.items() for key, value in service.data.items()
@ -480,6 +488,8 @@ async def async_setup_other_entry(hass, config_entry, async_add_entities):
class XiaomiGenericCoordinatedSwitch(XiaomiCoordinatedMiioEntity, SwitchEntity): class XiaomiGenericCoordinatedSwitch(XiaomiCoordinatedMiioEntity, SwitchEntity):
"""Representation of a Xiaomi Plug Generic.""" """Representation of a Xiaomi Plug Generic."""
entity_description: XiaomiMiioSwitchDescription
def __init__(self, name, device, entry, unique_id, coordinator, description): def __init__(self, name, device, entry, unique_id, coordinator, description):
"""Initialize the plug switch.""" """Initialize the plug switch."""
super().__init__(name, device, entry, unique_id, coordinator) super().__init__(name, device, entry, unique_id, coordinator)

View File

@ -2863,33 +2863,3 @@ ignore_errors = true
[mypy-homeassistant.components.xbox.sensor] [mypy-homeassistant.components.xbox.sensor]
ignore_errors = true ignore_errors = true
[mypy-homeassistant.components.xiaomi_miio]
ignore_errors = true
[mypy-homeassistant.components.xiaomi_miio.air_quality]
ignore_errors = true
[mypy-homeassistant.components.xiaomi_miio.binary_sensor]
ignore_errors = true
[mypy-homeassistant.components.xiaomi_miio.device]
ignore_errors = true
[mypy-homeassistant.components.xiaomi_miio.device_tracker]
ignore_errors = true
[mypy-homeassistant.components.xiaomi_miio.fan]
ignore_errors = true
[mypy-homeassistant.components.xiaomi_miio.humidifier]
ignore_errors = true
[mypy-homeassistant.components.xiaomi_miio.light]
ignore_errors = true
[mypy-homeassistant.components.xiaomi_miio.sensor]
ignore_errors = true
[mypy-homeassistant.components.xiaomi_miio.switch]
ignore_errors = true

View File

@ -89,16 +89,6 @@ IGNORED_MODULES: Final[list[str]] = [
"homeassistant.components.xbox.browse_media", "homeassistant.components.xbox.browse_media",
"homeassistant.components.xbox.media_source", "homeassistant.components.xbox.media_source",
"homeassistant.components.xbox.sensor", "homeassistant.components.xbox.sensor",
"homeassistant.components.xiaomi_miio",
"homeassistant.components.xiaomi_miio.air_quality",
"homeassistant.components.xiaomi_miio.binary_sensor",
"homeassistant.components.xiaomi_miio.device",
"homeassistant.components.xiaomi_miio.device_tracker",
"homeassistant.components.xiaomi_miio.fan",
"homeassistant.components.xiaomi_miio.humidifier",
"homeassistant.components.xiaomi_miio.light",
"homeassistant.components.xiaomi_miio.sensor",
"homeassistant.components.xiaomi_miio.switch",
] ]
# Component modules which should set no_implicit_reexport = true. # Component modules which should set no_implicit_reexport = true.