Add static typing to devolo_home_control (#52396)

This commit is contained in:
Guido Schmitz 2021-07-02 18:37:18 +02:00 committed by GitHub
parent e435ac6fcd
commit 8c7ef5b1b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 186 additions and 84 deletions

View File

@ -25,6 +25,7 @@ homeassistant.components.canary.*
homeassistant.components.cover.*
homeassistant.components.device_automation.*
homeassistant.components.device_tracker.*
homeassistant.components.devolo_home_control.*
homeassistant.components.dnsip.*
homeassistant.components.dsmr.*
homeassistant.components.dunehd.*

View File

@ -1,6 +1,10 @@
"""The devolo_home_control integration."""
from __future__ import annotations
import asyncio
from functools import partial
from types import MappingProxyType
from typing import Any
from devolo_home_control_api.exceptions.gateway import GatewayOfflineError
from devolo_home_control_api.homecontrol import HomeControl
@ -9,7 +13,7 @@ from devolo_home_control_api.mydevolo import Mydevolo
from homeassistant.components import zeroconf
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import HomeAssistant
from homeassistant.core import Event, HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from .const import (
@ -37,7 +41,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
gateway_ids = await hass.async_add_executor_job(mydevolo.get_gateway_ids)
if GATEWAY_SERIAL_PATTERN.match(entry.unique_id):
if entry.unique_id and GATEWAY_SERIAL_PATTERN.match(entry.unique_id):
uuid = await hass.async_add_executor_job(mydevolo.uuid)
hass.config_entries.async_update_entry(entry, unique_id=uuid)
@ -60,7 +64,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
def shutdown(event):
def shutdown(event: Event) -> None:
for gateway in hass.data[DOMAIN][entry.entry_id]["gateways"]:
gateway.websocket_disconnect(
f"websocket disconnect requested by {EVENT_HOMEASSISTANT_STOP}"
@ -88,7 +92,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return unload
def configure_mydevolo(conf: dict) -> Mydevolo:
def configure_mydevolo(conf: dict[str, Any] | MappingProxyType[str, Any]) -> Mydevolo:
"""Configure mydevolo."""
mydevolo = Mydevolo()
mydevolo.user = conf[CONF_USERNAME]

View File

@ -1,4 +1,9 @@
"""Platform for binary sensor integration."""
from __future__ import annotations
from devolo_home_control_api.devices.zwave import Zwave
from devolo_home_control_api.homecontrol import HomeControl
from homeassistant.components.binary_sensor import (
DEVICE_CLASS_DOOR,
DEVICE_CLASS_HEAT,
@ -11,6 +16,7 @@ from homeassistant.components.binary_sensor import (
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .devolo_device import DevoloDeviceEntity
@ -26,10 +32,10 @@ DEVICE_CLASS_MAPPING = {
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Get all binary sensor and multi level sensor devices and setup them via config entry."""
entities = []
entities: list[BinarySensorEntity] = []
for gateway in hass.data[DOMAIN][entry.entry_id]["gateways"]:
for device in gateway.binary_sensor_devices:
@ -61,7 +67,9 @@ async def async_setup_entry(
class DevoloBinaryDeviceEntity(DevoloDeviceEntity, BinarySensorEntity):
"""Representation of a binary sensor within devolo Home Control."""
def __init__(self, homecontrol, device_instance, element_uid):
def __init__(
self, homecontrol: HomeControl, device_instance: Zwave, element_uid: str
) -> None:
"""Initialize a devolo binary sensor."""
self._binary_sensor_property = device_instance.binary_sensor_property.get(
element_uid
@ -91,12 +99,12 @@ class DevoloBinaryDeviceEntity(DevoloDeviceEntity, BinarySensorEntity):
self._enabled_default = False
@property
def is_on(self):
def is_on(self) -> bool:
"""Return the state."""
return self._value
return bool(self._value)
@property
def device_class(self):
def device_class(self) -> str | None:
"""Return device class."""
return self._device_class
@ -104,7 +112,13 @@ class DevoloBinaryDeviceEntity(DevoloDeviceEntity, BinarySensorEntity):
class DevoloRemoteControl(DevoloDeviceEntity, BinarySensorEntity):
"""Representation of a remote control within devolo Home Control."""
def __init__(self, homecontrol, device_instance, element_uid, key):
def __init__(
self,
homecontrol: HomeControl,
device_instance: Zwave,
element_uid: str,
key: int,
) -> None:
"""Initialize a devolo remote control."""
self._remote_control_property = device_instance.remote_control_property.get(
element_uid
@ -120,11 +134,11 @@ class DevoloRemoteControl(DevoloDeviceEntity, BinarySensorEntity):
self._state = False
@property
def is_on(self):
def is_on(self) -> bool:
"""Return the state."""
return self._state
def _sync(self, message):
def _sync(self, message: tuple) -> None:
"""Update the binary sensor state."""
if (
message[0] == self._remote_control_property.element_uid

View File

@ -1,6 +1,8 @@
"""Platform for climate integration."""
from __future__ import annotations
from typing import Any
from homeassistant.components.climate import (
ATTR_TEMPERATURE,
HVAC_MODE_HEAT,
@ -11,13 +13,14 @@ from homeassistant.components.climate import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PRECISION_HALVES, PRECISION_TENTHS
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Get all cover devices and setup them via config entry."""
entities = []
@ -82,12 +85,14 @@ class DevoloClimateDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, ClimateEntit
@property
def min_temp(self) -> float:
"""Return the minimum set temperature value."""
return self._multi_level_switch_property.min
min_temp: float = self._multi_level_switch_property.min
return min_temp
@property
def max_temp(self) -> float:
"""Return the maximum set temperature value."""
return self._multi_level_switch_property.max
max_temp: float = self._multi_level_switch_property.max
return max_temp
@property
def precision(self) -> float:
@ -95,7 +100,7 @@ class DevoloClimateDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, ClimateEntit
return PRECISION_TENTHS
@property
def supported_features(self):
def supported_features(self) -> int:
"""Flag supported features."""
return SUPPORT_TARGET_TEMPERATURE
@ -107,6 +112,6 @@ class DevoloClimateDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, ClimateEntit
def set_hvac_mode(self, hvac_mode: str) -> None:
"""Do nothing as devolo devices do not support changing the hvac mode."""
def set_temperature(self, **kwargs):
def set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
self._multi_level_switch_property.set(kwargs[ATTR_TEMPERATURE])

View File

@ -1,9 +1,15 @@
"""Config flow to configure the devolo home control integration."""
from __future__ import annotations
from typing import Any
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.typing import DiscoveryInfoType
from . import configure_mydevolo
@ -16,16 +22,18 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 1
def __init__(self):
def __init__(self) -> None:
"""Initialize devolo Home Control flow."""
self.data_schema = {
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
}
self._reauth_entry = None
self._reauth_entry: ConfigEntry | None = None
self._url = DEFAULT_MYDEVOLO
async def async_step_user(self, user_input=None):
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle a flow initiated by the user."""
if self.show_advanced_options:
self.data_schema[vol.Required(CONF_MYDEVOLO, default=self._url)] = str
@ -36,7 +44,9 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
except CredentialsInvalid:
return self._show_form(step_id="user", errors={"base": "invalid_auth"})
async def async_step_zeroconf(self, discovery_info: DiscoveryInfoType):
async def async_step_zeroconf(
self, discovery_info: DiscoveryInfoType
) -> FlowResult:
"""Handle zeroconf discovery."""
# Check if it is a gateway
if discovery_info.get("properties", {}).get("MT") in SUPPORTED_MODEL_TYPES:
@ -44,7 +54,9 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
return await self.async_step_zeroconf_confirm()
return self.async_abort(reason="Not a devolo Home Control gateway.")
async def async_step_zeroconf_confirm(self, user_input=None):
async def async_step_zeroconf_confirm(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle a flow initiated by zeroconf."""
if user_input is None:
return self._show_form(step_id="zeroconf_confirm")
@ -55,7 +67,7 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
step_id="zeroconf_confirm", errors={"base": "invalid_auth"}
)
async def async_step_reauth(self, user_input):
async def async_step_reauth(self, user_input: dict[str, Any]) -> FlowResult:
"""Handle reauthentication."""
self._reauth_entry = self.hass.config_entries.async_get_entry(
self.context["entry_id"]
@ -67,7 +79,9 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
}
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(self, user_input=None):
async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle a flow initiated by reauthentication."""
if user_input is None:
return self._show_form(step_id="reauth_confirm")
@ -82,7 +96,7 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
step_id="reauth_confirm", errors={"base": "reauth_failed"}
)
async def _connect_mydevolo(self, user_input):
async def _connect_mydevolo(self, user_input: dict[str, Any]) -> FlowResult:
"""Connect to mydevolo."""
user_input[CONF_MYDEVOLO] = user_input.get(CONF_MYDEVOLO, self._url)
mydevolo = configure_mydevolo(conf=user_input)
@ -118,7 +132,9 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_abort(reason="reauth_successful")
@callback
def _show_form(self, step_id, errors=None):
def _show_form(
self, step_id: str, errors: dict[str, str] | None = None
) -> FlowResult:
"""Show the form to the user."""
return self.async_show_form(
step_id=step_id,

View File

@ -1,4 +1,8 @@
"""Platform for cover integration."""
from __future__ import annotations
from typing import Any
from homeassistant.components.cover import (
DEVICE_CLASS_BLIND,
SUPPORT_CLOSE,
@ -8,13 +12,14 @@ from homeassistant.components.cover import (
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Get all cover devices and setup them via config entry."""
entities = []
@ -38,33 +43,33 @@ class DevoloCoverDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, CoverEntity):
"""Representation of a cover device within devolo Home Control."""
@property
def current_cover_position(self):
def current_cover_position(self) -> int:
"""Return the current position. 0 is closed. 100 is open."""
return self._value
@property
def device_class(self):
def device_class(self) -> str:
"""Return the class of the device."""
return DEVICE_CLASS_BLIND
@property
def is_closed(self):
def is_closed(self) -> bool:
"""Return if the blind is closed or not."""
return not bool(self._value)
@property
def supported_features(self):
def supported_features(self) -> int:
"""Flag supported features."""
return SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_SET_POSITION
def open_cover(self, **kwargs):
def open_cover(self, **kwargs: Any) -> None:
"""Open the blind."""
self._multi_level_switch_property.set(100)
def close_cover(self, **kwargs):
def close_cover(self, **kwargs: Any) -> None:
"""Close the blind."""
self._multi_level_switch_property.set(0)
def set_cover_position(self, **kwargs):
def set_cover_position(self, **kwargs: Any) -> None:
"""Set the blind to the given position."""
self._multi_level_switch_property.set(kwargs["position"])

View File

@ -1,7 +1,12 @@
"""Base class for a device entity integrated in devolo Home Control."""
from __future__ import annotations
import logging
from homeassistant.helpers.entity import Entity
from devolo_home_control_api.devices.zwave import Zwave
from devolo_home_control_api.homecontrol import HomeControl
from homeassistant.helpers.entity import DeviceInfo, Entity
from .const import DOMAIN
from .subscriber import Subscriber
@ -12,26 +17,30 @@ _LOGGER = logging.getLogger(__name__)
class DevoloDeviceEntity(Entity):
"""Abstract representation of a device within devolo Home Control."""
def __init__(self, homecontrol, device_instance, element_uid):
def __init__(
self, homecontrol: HomeControl, device_instance: Zwave, element_uid: str
) -> None:
"""Initialize a devolo device entity."""
self._device_instance = device_instance
self._unique_id = element_uid
self._homecontrol = homecontrol
self._name = device_instance.settings_property["general_device_settings"].name
self._name: str = device_instance.settings_property[
"general_device_settings"
].name
self._area = device_instance.settings_property["general_device_settings"].zone
self._device_class = None
self._value = None
self._unit = None
self._device_class: str | None = None
self._value: int
self._unit = ""
self._enabled_default = True
# This is not doing I/O. It fetches an internal state of the API
self._available = device_instance.is_online()
self._available: bool = device_instance.is_online()
# Get the brand and model information
self._brand = device_instance.brand
self._model = device_instance.name
self.subscriber = None
self.subscriber: Subscriber | None = None
self.sync_callback = self._sync
async def async_added_to_hass(self) -> None:
@ -48,12 +57,12 @@ class DevoloDeviceEntity(Entity):
)
@property
def unique_id(self):
def unique_id(self) -> str:
"""Return the unique ID of the entity."""
return self._unique_id
@property
def device_info(self):
def device_info(self) -> DeviceInfo:
"""Return the device info."""
return {
"identifiers": {(DOMAIN, self._device_instance.uid)},
@ -69,12 +78,12 @@ class DevoloDeviceEntity(Entity):
return self._enabled_default
@property
def should_poll(self):
def should_poll(self) -> bool:
"""Return the polling state."""
return False
@property
def name(self):
def name(self) -> str:
"""Return the display name of this entity."""
return self._name
@ -83,7 +92,7 @@ class DevoloDeviceEntity(Entity):
"""Return the online state."""
return self._available
def _sync(self, message):
def _sync(self, message: tuple) -> None:
"""Update the state."""
if message[0] == self._unique_id:
self._value = message[1]
@ -91,7 +100,7 @@ class DevoloDeviceEntity(Entity):
self._generic_message(message)
self.schedule_update_ha_state()
def _generic_message(self, message):
def _generic_message(self, message: tuple) -> None:
"""Handle generic messages."""
if len(message) == 3 and message[2] == "battery_level":
self._value = message[1]

View File

@ -1,11 +1,16 @@
"""Base class for multi level switches in devolo Home Control."""
from devolo_home_control_api.devices.zwave import Zwave
from devolo_home_control_api.homecontrol import HomeControl
from .devolo_device import DevoloDeviceEntity
class DevoloMultiLevelSwitchDeviceEntity(DevoloDeviceEntity):
"""Representation of a multi level switch device within devolo Home Control. Something like a dimmer or a thermostat."""
def __init__(self, homecontrol, device_instance, element_uid):
def __init__(
self, homecontrol: HomeControl, device_instance: Zwave, element_uid: str
) -> None:
"""Initialize a multi level switch within devolo Home Control."""
super().__init__(
homecontrol=homecontrol,

View File

@ -1,4 +1,11 @@
"""Platform for light integration."""
from __future__ import annotations
from typing import Any
from devolo_home_control_api.devices.zwave import Zwave
from devolo_home_control_api.homecontrol import HomeControl
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
SUPPORT_BRIGHTNESS,
@ -6,13 +13,14 @@ from homeassistant.components.light import (
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Get all light devices and setup them via config entry."""
entities = []
@ -35,7 +43,9 @@ async def async_setup_entry(
class DevoloLightDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, LightEntity):
"""Representation of a light within devolo Home Control."""
def __init__(self, homecontrol, device_instance, element_uid):
def __init__(
self, homecontrol: HomeControl, device_instance: Zwave, element_uid: str
) -> None:
"""Initialize a devolo multi level switch."""
super().__init__(
homecontrol=homecontrol,
@ -48,21 +58,21 @@ class DevoloLightDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, LightEntity):
)
@property
def brightness(self):
def brightness(self) -> int:
"""Return the brightness value of the light."""
return round(self._value / 100 * 255)
@property
def is_on(self):
def is_on(self) -> bool:
"""Return the state of the light."""
return bool(self._value)
@property
def supported_features(self):
def supported_features(self) -> int:
"""Return the supported features."""
return SUPPORT_BRIGHTNESS
def turn_on(self, **kwargs) -> None:
def turn_on(self, **kwargs: Any) -> None:
"""Turn device on."""
if kwargs.get(ATTR_BRIGHTNESS) is not None:
self._multi_level_switch_property.set(
@ -76,7 +86,7 @@ class DevoloLightDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, LightEntity):
# If there is no binary switch attached to the device, turn it on to 100 %.
self._multi_level_switch_property.set(100)
def turn_off(self, **kwargs) -> None:
def turn_off(self, **kwargs: Any) -> None:
"""Turn device off."""
if self._binary_switch_property is not None:
self._binary_switch_property.set(False)

View File

@ -1,4 +1,9 @@
"""Platform for sensor integration."""
from __future__ import annotations
from devolo_home_control_api.devices.zwave import Zwave
from devolo_home_control_api.homecontrol import HomeControl
from homeassistant.components.sensor import (
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_ENERGY,
@ -12,6 +17,7 @@ from homeassistant.components.sensor import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .devolo_device import DevoloDeviceEntity
@ -28,10 +34,10 @@ DEVICE_CLASS_MAPPING = {
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Get all sensor devices and setup them via config entry."""
entities = []
entities: list[SensorEntity] = []
for gateway in hass.data[DOMAIN][entry.entry_id]["gateways"]:
for device in gateway.multi_level_sensor_devices:
@ -71,17 +77,17 @@ class DevoloMultiLevelDeviceEntity(DevoloDeviceEntity, SensorEntity):
"""Abstract representation of a multi level sensor within devolo Home Control."""
@property
def device_class(self) -> str:
def device_class(self) -> str | None:
"""Return device class."""
return self._device_class
@property
def state(self):
def state(self) -> int:
"""Return the state of the sensor."""
return self._value
@property
def unit_of_measurement(self):
def unit_of_measurement(self) -> str:
"""Return the unit of measurement of this entity."""
return self._unit
@ -91,10 +97,10 @@ class DevoloGenericMultiLevelDeviceEntity(DevoloMultiLevelDeviceEntity):
def __init__(
self,
homecontrol,
device_instance,
element_uid,
):
homecontrol: HomeControl,
device_instance: Zwave,
element_uid: str,
) -> None:
"""Initialize a devolo multi level sensor."""
self._multi_level_sensor_property = device_instance.multi_level_sensor_property[
element_uid
@ -123,7 +129,9 @@ class DevoloGenericMultiLevelDeviceEntity(DevoloMultiLevelDeviceEntity):
class DevoloBatteryEntity(DevoloMultiLevelDeviceEntity):
"""Representation of a battery entity within devolo Home Control."""
def __init__(self, homecontrol, device_instance, element_uid):
def __init__(
self, homecontrol: HomeControl, device_instance: Zwave, element_uid: str
) -> None:
"""Initialize a battery sensor."""
super().__init__(
@ -141,7 +149,13 @@ class DevoloBatteryEntity(DevoloMultiLevelDeviceEntity):
class DevoloConsumptionEntity(DevoloMultiLevelDeviceEntity):
"""Representation of a consumption entity within devolo Home Control."""
def __init__(self, homecontrol, device_instance, element_uid, consumption):
def __init__(
self,
homecontrol: HomeControl,
device_instance: Zwave,
element_uid: str,
consumption: str,
) -> None:
"""Initialize a devolo consumption sensor."""
super().__init__(
@ -163,11 +177,11 @@ class DevoloConsumptionEntity(DevoloMultiLevelDeviceEntity):
self._name += f" {consumption}"
@property
def unique_id(self):
def unique_id(self) -> str:
"""Return the unique ID of the entity."""
return f"{self._unique_id}_{self._sensor_type}"
def _sync(self, message):
def _sync(self, message: tuple) -> None:
"""Update the consumption sensor state."""
if message[0] == self._unique_id:
self._value = getattr(

View File

@ -1,6 +1,7 @@
"""Subscriber for devolo home control API publisher."""
import logging
from typing import Callable
_LOGGER = logging.getLogger(__name__)
@ -8,12 +9,12 @@ _LOGGER = logging.getLogger(__name__)
class Subscriber:
"""Subscriber class for the publisher in mprm websocket class."""
def __init__(self, name, callback):
def __init__(self, name: str, callback: Callable) -> None:
"""Initiate the subscriber."""
self.name = name
self.callback = callback
def update(self, message):
def update(self, message: str) -> None:
"""Trigger hass to update the device."""
_LOGGER.debug('%s got message "%s"', self.name, message)
self.callback(message)

View File

@ -1,14 +1,22 @@
"""Platform for switch integration."""
from __future__ import annotations
from typing import Any
from devolo_home_control_api.devices.zwave import Zwave
from devolo_home_control_api.homecontrol import HomeControl
from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .devolo_device import DevoloDeviceEntity
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Get all devices and setup the switch devices via config entry."""
entities = []
@ -33,7 +41,9 @@ async def async_setup_entry(
class DevoloSwitch(DevoloDeviceEntity, SwitchEntity):
"""Representation of a switch."""
def __init__(self, homecontrol, device_instance, element_uid):
def __init__(
self, homecontrol: HomeControl, device_instance: Zwave, element_uid: str
) -> None:
"""Initialize an devolo Switch."""
super().__init__(
homecontrol=homecontrol,
@ -43,7 +53,8 @@ class DevoloSwitch(DevoloDeviceEntity, SwitchEntity):
self._binary_switch_property = self._device_instance.binary_switch_property.get(
self._unique_id
)
self._is_on = self._binary_switch_property.state
self._is_on: bool = self._binary_switch_property.state
self._consumption: float | None
if hasattr(self._device_instance, "consumption_property"):
self._consumption = self._device_instance.consumption_property.get(
@ -53,26 +64,26 @@ class DevoloSwitch(DevoloDeviceEntity, SwitchEntity):
self._consumption = None
@property
def is_on(self):
def is_on(self) -> bool:
"""Return the state."""
return self._is_on
@property
def current_power_w(self):
def current_power_w(self) -> float | None:
"""Return the current consumption."""
return self._consumption
def turn_on(self, **kwargs):
def turn_on(self, **kwargs: Any) -> None:
"""Switch on the device."""
self._is_on = True
self._binary_switch_property.set(state=True)
def turn_off(self, **kwargs):
def turn_off(self, **kwargs: Any) -> None:
"""Switch off the device."""
self._is_on = False
self._binary_switch_property.set(state=False)
def _sync(self, message):
def _sync(self, message: tuple) -> None:
"""Update the binary switch state and consumption."""
if message[0].startswith("devolo.BinarySwitch"):
self._is_on = self._device_instance.binary_switch_property[message[0]].state

View File

@ -286,6 +286,17 @@ no_implicit_optional = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.devolo_home_control.*]
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
no_implicit_optional = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.dnsip.*]
check_untyped_defs = true
disallow_incomplete_defs = true
@ -1063,9 +1074,6 @@ ignore_errors = true
[mypy-homeassistant.components.denonavr.*]
ignore_errors = true
[mypy-homeassistant.components.devolo_home_control.*]
ignore_errors = true
[mypy-homeassistant.components.dhcp.*]
ignore_errors = true

View File

@ -42,7 +42,6 @@ IGNORED_MODULES: Final[list[str]] = [
"homeassistant.components.deconz.*",
"homeassistant.components.demo.*",
"homeassistant.components.denonavr.*",
"homeassistant.components.devolo_home_control.*",
"homeassistant.components.dhcp.*",
"homeassistant.components.directv.*",
"homeassistant.components.doorbird.*",