mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Add static typing to devolo_home_control (#52396)
This commit is contained in:
parent
e435ac6fcd
commit
8c7ef5b1b9
@ -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.*
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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])
|
||||
|
@ -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,
|
||||
|
@ -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"])
|
||||
|
@ -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]
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
14
mypy.ini
14
mypy.ini
@ -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
|
||||
|
||||
|
@ -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.*",
|
||||
|
Loading…
x
Reference in New Issue
Block a user