Activate mypy for homematicip_cloud (#54950)

* Please mypy.

* Review comments.

* Review comments.
This commit is contained in:
jan iversen 2021-08-21 20:19:56 +02:00 committed by GitHub
parent 67d04b6082
commit f872594e26
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 57 additions and 47 deletions

View file

@ -52,7 +52,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
entry.data[HMIPC_HAPID] entry.data[HMIPC_HAPID]
for entry in hass.config_entries.async_entries(DOMAIN) for entry in hass.config_entries.async_entries(DOMAIN)
}: }:
hass.async_add_job( hass.async_create_task(
hass.config_entries.flow.async_init( hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
context={"source": config_entries.SOURCE_IMPORT}, context={"source": config_entries.SOURCE_IMPORT},

View file

@ -21,7 +21,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity import DeviceInfo
from . import DOMAIN as HMIPC_DOMAIN from . import DOMAIN as HMIPC_DOMAIN
from .hap import HomematicipHAP from .hap import AsyncHome, HomematicipHAP
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -41,7 +41,7 @@ class HomematicipAlarmControlPanelEntity(AlarmControlPanelEntity):
def __init__(self, hap: HomematicipHAP) -> None: def __init__(self, hap: HomematicipHAP) -> None:
"""Initialize the alarm control panel.""" """Initialize the alarm control panel."""
self._home = hap.home self._home: AsyncHome = hap.home
_LOGGER.info("Setting up %s", self.name) _LOGGER.info("Setting up %s", self.name)
@property @property

View file

@ -85,7 +85,7 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up the HomematicIP Cloud binary sensor from a config entry.""" """Set up the HomematicIP Cloud binary sensor from a config entry."""
hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id] hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id]
entities = [HomematicipCloudConnectionSensor(hap)] entities: list[HomematicipGenericEntity] = [HomematicipCloudConnectionSensor(hap)]
for device in hap.home.devices: for device in hap.home.devices:
if isinstance(device, AsyncAccelerationSensor): if isinstance(device, AsyncAccelerationSensor):
entities.append(HomematicipAccelerationSensor(hap, device)) entities.append(HomematicipAccelerationSensor(hap, device))
@ -254,7 +254,7 @@ class HomematicipMultiContactInterface(HomematicipGenericEntity, BinarySensorEnt
return DEVICE_CLASS_OPENING return DEVICE_CLASS_OPENING
@property @property
def is_on(self) -> bool: def is_on(self) -> bool | None:
"""Return true if the contact interface is on/open.""" """Return true if the contact interface is on/open."""
if self._device.functionalChannels[self._channel].windowState is None: if self._device.functionalChannels[self._channel].windowState is None:
return None return None

View file

@ -262,7 +262,7 @@ class HomematicipHeatingGroup(HomematicipGenericEntity, ClimateEntity):
return self._home.get_functionalHome(IndoorClimateHome) return self._home.get_functionalHome(IndoorClimateHome)
@property @property
def _device_profiles(self) -> list[str]: def _device_profiles(self) -> list[Any]:
"""Return the relevant profiles.""" """Return the relevant profiles."""
return [ return [
profile profile
@ -301,10 +301,10 @@ class HomematicipHeatingGroup(HomematicipGenericEntity, ClimateEntity):
) )
@property @property
def _relevant_profile_group(self) -> list[str]: def _relevant_profile_group(self) -> dict[str, int]:
"""Return the relevant profile groups.""" """Return the relevant profile groups."""
if self._disabled_by_cooling_mode: if self._disabled_by_cooling_mode:
return [] return {}
return HEATING_PROFILES if self._heat_mode_enabled else COOLING_PROFILES return HEATING_PROFILES if self._heat_mode_enabled else COOLING_PROFILES

View file

@ -23,9 +23,10 @@ class HomematicipCloudFlowHandler(config_entries.ConfigFlow):
VERSION = 1 VERSION = 1
auth: HomematicipAuth
def __init__(self) -> None: def __init__(self) -> None:
"""Initialize HomematicIP Cloud config flow.""" """Initialize HomematicIP Cloud config flow."""
self.auth = None
async def async_step_user(self, user_input=None) -> FlowResult: async def async_step_user(self, user_input=None) -> FlowResult:
"""Handle a flow initialized by the user.""" """Handle a flow initialized by the user."""

View file

@ -37,7 +37,7 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up the HomematicIP cover from a config entry.""" """Set up the HomematicIP cover from a config entry."""
hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id] hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id]
entities = [] entities: list[HomematicipGenericEntity] = []
for device in hap.home.devices: for device in hap.home.devices:
if isinstance(device, AsyncBlindModule): if isinstance(device, AsyncBlindModule):
entities.append(HomematicipBlindModule(hap, device)) entities.append(HomematicipBlindModule(hap, device))
@ -72,14 +72,14 @@ class HomematicipBlindModule(HomematicipGenericEntity, CoverEntity):
return DEVICE_CLASS_BLIND return DEVICE_CLASS_BLIND
@property @property
def current_cover_position(self) -> int: def current_cover_position(self) -> int | None:
"""Return current position of cover.""" """Return current position of cover."""
if self._device.primaryShadingLevel is not None: if self._device.primaryShadingLevel is not None:
return int((1 - self._device.primaryShadingLevel) * 100) return int((1 - self._device.primaryShadingLevel) * 100)
return None return None
@property @property
def current_cover_tilt_position(self) -> int: def current_cover_tilt_position(self) -> int | None:
"""Return current tilt position of cover.""" """Return current tilt position of cover."""
if self._device.secondaryShadingLevel is not None: if self._device.secondaryShadingLevel is not None:
return int((1 - self._device.secondaryShadingLevel) * 100) return int((1 - self._device.secondaryShadingLevel) * 100)
@ -165,7 +165,7 @@ class HomematicipMultiCoverShutter(HomematicipGenericEntity, CoverEntity):
return DEVICE_CLASS_SHUTTER return DEVICE_CLASS_SHUTTER
@property @property
def current_cover_position(self) -> int: def current_cover_position(self) -> int | None:
"""Return current position of cover.""" """Return current position of cover."""
if self._device.functionalChannels[self._channel].shutterLevel is not None: if self._device.functionalChannels[self._channel].shutterLevel is not None:
return int( return int(
@ -227,7 +227,7 @@ class HomematicipMultiCoverSlats(HomematicipMultiCoverShutter, CoverEntity):
) )
@property @property
def current_cover_tilt_position(self) -> int: def current_cover_tilt_position(self) -> int | None:
"""Return current tilt position of cover.""" """Return current tilt position of cover."""
if self._device.functionalChannels[self._channel].slatsLevel is not None: if self._device.functionalChannels[self._channel].slatsLevel is not None:
return int( return int(
@ -267,7 +267,7 @@ class HomematicipGarageDoorModule(HomematicipGenericEntity, CoverEntity):
"""Representation of the HomematicIP Garage Door Module.""" """Representation of the HomematicIP Garage Door Module."""
@property @property
def current_cover_position(self) -> int: def current_cover_position(self) -> int | None:
"""Return current position of cover.""" """Return current position of cover."""
door_state_to_position = { door_state_to_position = {
DoorState.CLOSED: 0, DoorState.CLOSED: 0,
@ -314,14 +314,14 @@ class HomematicipCoverShutterGroup(HomematicipGenericEntity, CoverEntity):
return DEVICE_CLASS_SHUTTER return DEVICE_CLASS_SHUTTER
@property @property
def current_cover_position(self) -> int: def current_cover_position(self) -> int | None:
"""Return current position of cover.""" """Return current position of cover."""
if self._device.shutterLevel is not None: if self._device.shutterLevel is not None:
return int((1 - self._device.shutterLevel) * 100) return int((1 - self._device.shutterLevel) * 100)
return None return None
@property @property
def current_cover_tilt_position(self) -> int: def current_cover_tilt_position(self) -> int | None:
"""Return current tilt position of cover.""" """Return current tilt position of cover."""
if self._device.slatsLevel is not None: if self._device.slatsLevel is not None:
return int((1 - self._device.slatsLevel) * 100) return int((1 - self._device.slatsLevel) * 100)

View file

@ -13,7 +13,7 @@ from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.entity import DeviceInfo, Entity from homeassistant.helpers.entity import DeviceInfo, Entity
from .const import DOMAIN as HMIPC_DOMAIN from .const import DOMAIN as HMIPC_DOMAIN
from .hap import HomematicipHAP from .hap import AsyncHome, HomematicipHAP
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -82,7 +82,7 @@ class HomematicipGenericEntity(Entity):
) -> None: ) -> None:
"""Initialize the generic entity.""" """Initialize the generic entity."""
self._hap = hap self._hap = hap
self._home = hap.home self._home: AsyncHome = hap.home
self._device = device self._device = device
self._post = post self._post = post
self._channel = channel self._channel = channel
@ -92,7 +92,7 @@ class HomematicipGenericEntity(Entity):
_LOGGER.info("Setting up %s (%s)", self.name, self._device.modelType) _LOGGER.info("Setting up %s (%s)", self.name, self._device.modelType)
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo | None:
"""Return device specific attributes.""" """Return device specific attributes."""
# Only physical devices should be HA devices. # Only physical devices should be HA devices.
if isinstance(self._device, AsyncDevice): if isinstance(self._device, AsyncDevice):

View file

@ -1,6 +1,9 @@
"""Access point for the HomematicIP Cloud component.""" """Access point for the HomematicIP Cloud component."""
from __future__ import annotations
import asyncio import asyncio
import logging import logging
from typing import Any, Callable
from homematicip.aio.auth import AsyncAuth from homematicip.aio.auth import AsyncAuth
from homematicip.aio.home import AsyncHome from homematicip.aio.home import AsyncHome
@ -21,11 +24,12 @@ _LOGGER = logging.getLogger(__name__)
class HomematicipAuth: class HomematicipAuth:
"""Manages HomematicIP client registration.""" """Manages HomematicIP client registration."""
auth: AsyncAuth
def __init__(self, hass, config) -> None: def __init__(self, hass, config) -> None:
"""Initialize HomematicIP Cloud client registration.""" """Initialize HomematicIP Cloud client registration."""
self.hass = hass self.hass = hass
self.config = config self.config = config
self.auth = None
async def async_setup(self) -> bool: async def async_setup(self) -> bool:
"""Connect to HomematicIP for registration.""" """Connect to HomematicIP for registration."""
@ -69,18 +73,19 @@ class HomematicipAuth:
class HomematicipHAP: class HomematicipHAP:
"""Manages HomematicIP HTTP and WebSocket connection.""" """Manages HomematicIP HTTP and WebSocket connection."""
home: AsyncHome
def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None:
"""Initialize HomematicIP Cloud connection.""" """Initialize HomematicIP Cloud connection."""
self.hass = hass self.hass = hass
self.config_entry = config_entry self.config_entry = config_entry
self.home = None
self._ws_close_requested = False self._ws_close_requested = False
self._retry_task = None self._retry_task: asyncio.Task | None = None
self._tries = 0 self._tries = 0
self._accesspoint_connected = True self._accesspoint_connected = True
self.hmip_device_by_entity_id = {} self.hmip_device_by_entity_id: dict[str, Any] = {}
self.reset_connection_listener = None self.reset_connection_listener: Callable | None = None
async def async_setup(self, tries: int = 0) -> bool: async def async_setup(self, tries: int = 0) -> bool:
"""Initialize connection.""" """Initialize connection."""
@ -228,7 +233,11 @@ class HomematicipHAP:
) )
async def get_hap( async def get_hap(
self, hass: HomeAssistant, hapid: str, authtoken: str, name: str self,
hass: HomeAssistant,
hapid: str | None,
authtoken: str | None,
name: str | None,
) -> AsyncHome: ) -> AsyncHome:
"""Create a HomematicIP access point object.""" """Create a HomematicIP access point object."""
home = AsyncHome(hass.loop, async_get_clientsession(hass)) home = AsyncHome(hass.loop, async_get_clientsession(hass))

View file

@ -40,7 +40,7 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up the HomematicIP Cloud lights from a config entry.""" """Set up the HomematicIP Cloud lights from a config entry."""
hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id] hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id]
entities = [] entities: list[HomematicipGenericEntity] = []
for device in hap.home.devices: for device in hap.home.devices:
if isinstance(device, AsyncBrandSwitchMeasuring): if isinstance(device, AsyncBrandSwitchMeasuring):
entities.append(HomematicipLightMeasuring(hap, device)) entities.append(HomematicipLightMeasuring(hap, device))
@ -174,14 +174,14 @@ class HomematicipNotificationLight(HomematicipGenericEntity, LightEntity):
hap, device, post="Bottom", channel=channel, is_multi_channel=True hap, device, post="Bottom", channel=channel, is_multi_channel=True
) )
self._color_switcher = { self._color_switcher: dict[str, tuple[float, float]] = {
RGBColorState.WHITE: [0.0, 0.0], RGBColorState.WHITE: (0.0, 0.0),
RGBColorState.RED: [0.0, 100.0], RGBColorState.RED: (0.0, 100.0),
RGBColorState.YELLOW: [60.0, 100.0], RGBColorState.YELLOW: (60.0, 100.0),
RGBColorState.GREEN: [120.0, 100.0], RGBColorState.GREEN: (120.0, 100.0),
RGBColorState.TURQUOISE: [180.0, 100.0], RGBColorState.TURQUOISE: (180.0, 100.0),
RGBColorState.BLUE: [240.0, 100.0], RGBColorState.BLUE: (240.0, 100.0),
RGBColorState.PURPLE: [300.0, 100.0], RGBColorState.PURPLE: (300.0, 100.0),
} }
@property @property
@ -202,10 +202,10 @@ class HomematicipNotificationLight(HomematicipGenericEntity, LightEntity):
return int((self._func_channel.dimLevel or 0.0) * 255) return int((self._func_channel.dimLevel or 0.0) * 255)
@property @property
def hs_color(self) -> tuple: def hs_color(self) -> tuple[float, float]:
"""Return the hue and saturation color value [float, float].""" """Return the hue and saturation color value [float, float]."""
simple_rgb_color = self._func_channel.simpleRGBColorState simple_rgb_color = self._func_channel.simpleRGBColorState
return self._color_switcher.get(simple_rgb_color, [0.0, 0.0]) return self._color_switcher.get(simple_rgb_color, (0.0, 0.0))
@property @property
def extra_state_attributes(self) -> dict[str, Any]: def extra_state_attributes(self) -> dict[str, Any]:

View file

@ -66,7 +66,7 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up the HomematicIP Cloud sensors from a config entry.""" """Set up the HomematicIP Cloud sensors from a config entry."""
hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id] hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id]
entities = [] entities: list[HomematicipGenericEntity] = []
for device in hap.home.devices: for device in hap.home.devices:
if isinstance(device, AsyncHomeControlAccessPoint): if isinstance(device, AsyncHomeControlAccessPoint):
entities.append(HomematicipAccesspointDutyCycle(hap, device)) entities.append(HomematicipAccesspointDutyCycle(hap, device))
@ -155,7 +155,7 @@ class HomematicipHeatingThermostat(HomematicipGenericEntity, SensorEntity):
super().__init__(hap, device, post="Heating") super().__init__(hap, device, post="Heating")
@property @property
def icon(self) -> str: def icon(self) -> str | None:
"""Return the icon.""" """Return the icon."""
if super().icon: if super().icon:
return super().icon return super().icon

View file

@ -297,7 +297,9 @@ async def _set_active_climate_profile(
async def _async_dump_hap_config(hass: HomeAssistant, service: ServiceCall) -> None: async def _async_dump_hap_config(hass: HomeAssistant, service: ServiceCall) -> None:
"""Service to dump the configuration of a Homematic IP Access Point.""" """Service to dump the configuration of a Homematic IP Access Point."""
config_path = service.data.get(ATTR_CONFIG_OUTPUT_PATH) or hass.config.config_dir config_path: str = (
service.data.get(ATTR_CONFIG_OUTPUT_PATH) or hass.config.config_dir or "."
)
config_file_prefix = service.data[ATTR_CONFIG_OUTPUT_FILE_PREFIX] config_file_prefix = service.data[ATTR_CONFIG_OUTPUT_FILE_PREFIX]
anonymize = service.data[ATTR_ANONYMIZE] anonymize = service.data[ATTR_ANONYMIZE]

View file

@ -34,7 +34,7 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up the HomematicIP switch from a config entry.""" """Set up the HomematicIP switch from a config entry."""
hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id] hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id]
entities = [] entities: list[HomematicipGenericEntity] = []
for device in hap.home.devices: for device in hap.home.devices:
if isinstance(device, AsyncBrandSwitchMeasuring): if isinstance(device, AsyncBrandSwitchMeasuring):
# BrandSwitchMeasuring inherits PlugableSwitchMeasuring # BrandSwitchMeasuring inherits PlugableSwitchMeasuring

View file

@ -1,4 +1,6 @@
"""Support for HomematicIP Cloud weather devices.""" """Support for HomematicIP Cloud weather devices."""
from __future__ import annotations
from homematicip.aio.device import ( from homematicip.aio.device import (
AsyncWeatherSensor, AsyncWeatherSensor,
AsyncWeatherSensorPlus, AsyncWeatherSensorPlus,
@ -50,7 +52,7 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up the HomematicIP weather sensor from a config entry.""" """Set up the HomematicIP weather sensor from a config entry."""
hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id] hap = hass.data[HMIPC_DOMAIN][config_entry.unique_id]
entities = [] entities: list[HomematicipGenericEntity] = []
for device in hap.home.devices: for device in hap.home.devices:
if isinstance(device, AsyncWeatherSensorPro): if isinstance(device, AsyncWeatherSensorPro):
entities.append(HomematicipWeatherSensorPro(hap, device)) entities.append(HomematicipWeatherSensorPro(hap, device))
@ -170,6 +172,6 @@ class HomematicipHomeWeather(HomematicipGenericEntity, WeatherEntity):
return "Powered by Homematic IP" return "Powered by Homematic IP"
@property @property
def condition(self) -> str: def condition(self) -> str | None:
"""Return the current condition.""" """Return the current condition."""
return HOME_WEATHER_CONDITION.get(self._device.weather.weatherCondition) return HOME_WEATHER_CONDITION.get(self._device.weather.weatherCondition)

View file

@ -1391,9 +1391,6 @@ ignore_errors = true
[mypy-homeassistant.components.homekit_controller.*] [mypy-homeassistant.components.homekit_controller.*]
ignore_errors = true ignore_errors = true
[mypy-homeassistant.components.homematicip_cloud.*]
ignore_errors = true
[mypy-homeassistant.components.honeywell.*] [mypy-homeassistant.components.honeywell.*]
ignore_errors = true ignore_errors = true

View file

@ -56,7 +56,6 @@ IGNORED_MODULES: Final[list[str]] = [
"homeassistant.components.home_plus_control.*", "homeassistant.components.home_plus_control.*",
"homeassistant.components.homekit.*", "homeassistant.components.homekit.*",
"homeassistant.components.homekit_controller.*", "homeassistant.components.homekit_controller.*",
"homeassistant.components.homematicip_cloud.*",
"homeassistant.components.honeywell.*", "homeassistant.components.honeywell.*",
"homeassistant.components.humidifier.*", "homeassistant.components.humidifier.*",
"homeassistant.components.iaqualink.*", "homeassistant.components.iaqualink.*",