Enable strict typing for Overkiz integration (#63108)

This commit is contained in:
Mick Vleeshouwer 2021-12-31 09:35:15 -08:00 committed by GitHub
parent 0da53bad90
commit 4eb077b6b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 47 additions and 28 deletions

View File

@ -101,6 +101,7 @@ homeassistant.components.number.*
homeassistant.components.onewire.* homeassistant.components.onewire.*
homeassistant.components.open_meteo.* homeassistant.components.open_meteo.*
homeassistant.components.openuv.* homeassistant.components.openuv.*
homeassistant.components.overkiz.*
homeassistant.components.persistent_notification.* homeassistant.components.persistent_notification.*
homeassistant.components.pi_hole.* homeassistant.components.pi_hole.*
homeassistant.components.proximity.* homeassistant.components.proximity.*

View File

@ -3,6 +3,7 @@ from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import cast
from pyoverkiz.enums import OverkizCommandParam, OverkizState from pyoverkiz.enums import OverkizCommandParam, OverkizState
@ -40,28 +41,28 @@ BINARY_SENSOR_DESCRIPTIONS: list[OverkizBinarySensorDescription] = [
key=OverkizState.CORE_RAIN, key=OverkizState.CORE_RAIN,
name="Rain", name="Rain",
icon="mdi:weather-rainy", icon="mdi:weather-rainy",
value_fn=lambda state: state == OverkizCommandParam.DETECTED, value_fn=lambda state: state == cast(str, OverkizCommandParam.DETECTED),
), ),
# SmokeSensor/SmokeSensor # SmokeSensor/SmokeSensor
OverkizBinarySensorDescription( OverkizBinarySensorDescription(
key=OverkizState.CORE_SMOKE, key=OverkizState.CORE_SMOKE,
name="Smoke", name="Smoke",
device_class=BinarySensorDeviceClass.SMOKE, device_class=BinarySensorDeviceClass.SMOKE,
value_fn=lambda state: state == OverkizCommandParam.DETECTED, value_fn=lambda state: state == cast(str, OverkizCommandParam.DETECTED),
), ),
# WaterSensor/WaterDetectionSensor # WaterSensor/WaterDetectionSensor
OverkizBinarySensorDescription( OverkizBinarySensorDescription(
key=OverkizState.CORE_WATER_DETECTION, key=OverkizState.CORE_WATER_DETECTION,
name="Water", name="Water",
icon="mdi:water", icon="mdi:water",
value_fn=lambda state: state == OverkizCommandParam.DETECTED, value_fn=lambda state: state == cast(str, OverkizCommandParam.DETECTED),
), ),
# AirSensor/AirFlowSensor # AirSensor/AirFlowSensor
OverkizBinarySensorDescription( OverkizBinarySensorDescription(
key=OverkizState.CORE_GAS_DETECTION, key=OverkizState.CORE_GAS_DETECTION,
name="Gas", name="Gas",
device_class=BinarySensorDeviceClass.GAS, device_class=BinarySensorDeviceClass.GAS,
value_fn=lambda state: state == OverkizCommandParam.DETECTED, value_fn=lambda state: state == cast(str, OverkizCommandParam.DETECTED),
), ),
# OccupancySensor/OccupancySensor # OccupancySensor/OccupancySensor
# OccupancySensor/MotionSensor # OccupancySensor/MotionSensor
@ -69,35 +70,35 @@ BINARY_SENSOR_DESCRIPTIONS: list[OverkizBinarySensorDescription] = [
key=OverkizState.CORE_OCCUPANCY, key=OverkizState.CORE_OCCUPANCY,
name="Occupancy", name="Occupancy",
device_class=BinarySensorDeviceClass.OCCUPANCY, device_class=BinarySensorDeviceClass.OCCUPANCY,
value_fn=lambda state: state == OverkizCommandParam.PERSON_INSIDE, value_fn=lambda state: state == cast(str, OverkizCommandParam.PERSON_INSIDE),
), ),
# ContactSensor/WindowWithTiltSensor # ContactSensor/WindowWithTiltSensor
OverkizBinarySensorDescription( OverkizBinarySensorDescription(
key=OverkizState.CORE_VIBRATION, key=OverkizState.CORE_VIBRATION,
name="Vibration", name="Vibration",
device_class=BinarySensorDeviceClass.VIBRATION, device_class=BinarySensorDeviceClass.VIBRATION,
value_fn=lambda state: state == OverkizCommandParam.DETECTED, value_fn=lambda state: state == cast(str, OverkizCommandParam.DETECTED),
), ),
# ContactSensor/ContactSensor # ContactSensor/ContactSensor
OverkizBinarySensorDescription( OverkizBinarySensorDescription(
key=OverkizState.CORE_CONTACT, key=OverkizState.CORE_CONTACT,
name="Contact", name="Contact",
device_class=BinarySensorDeviceClass.DOOR, device_class=BinarySensorDeviceClass.DOOR,
value_fn=lambda state: state == OverkizCommandParam.OPEN, value_fn=lambda state: state == cast(str, OverkizCommandParam.OPEN),
), ),
# Siren/SirenStatus # Siren/SirenStatus
OverkizBinarySensorDescription( OverkizBinarySensorDescription(
key=OverkizState.CORE_ASSEMBLY, key=OverkizState.CORE_ASSEMBLY,
name="Assembly", name="Assembly",
device_class=BinarySensorDeviceClass.PROBLEM, device_class=BinarySensorDeviceClass.PROBLEM,
value_fn=lambda state: state == OverkizCommandParam.OPEN, value_fn=lambda state: state == cast(str, OverkizCommandParam.OPEN),
), ),
# Unknown # Unknown
OverkizBinarySensorDescription( OverkizBinarySensorDescription(
key=OverkizState.IO_VIBRATION_DETECTED, key=OverkizState.IO_VIBRATION_DETECTED,
name="Vibration", name="Vibration",
device_class=BinarySensorDeviceClass.VIBRATION, device_class=BinarySensorDeviceClass.VIBRATION,
value_fn=lambda state: state == OverkizCommandParam.DETECTED, value_fn=lambda state: state == cast(str, OverkizCommandParam.DETECTED),
), ),
] ]
@ -106,7 +107,7 @@ async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
entry: ConfigEntry, entry: ConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
): ) -> None:
"""Set up the Overkiz binary sensors from a config entry.""" """Set up the Overkiz binary sensors from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id] data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]
entities: list[OverkizBinarySensor] = [] entities: list[OverkizBinarySensor] = []

View File

@ -5,7 +5,7 @@ from collections.abc import Callable
from datetime import timedelta from datetime import timedelta
import json import json
import logging import logging
from typing import Any from typing import Any, cast
from aiohttp import ServerDisconnectedError from aiohttp import ServerDisconnectedError
from pyoverkiz.client import OverkizClient from pyoverkiz.client import OverkizClient
@ -168,10 +168,14 @@ class OverkizDataUpdateCoordinator(DataUpdateCoordinator):
data_type = DataType(state.type) data_type = DataType(state.type)
if data_type == DataType.NONE: if data_type == DataType.NONE:
return state.value return cast(None, state.value)
cast_to_python = DATA_TYPE_TO_PYTHON[data_type] cast_to_python = DATA_TYPE_TO_PYTHON[data_type]
return cast_to_python(state.value) value = cast_to_python(state.value)
assert isinstance(value, (str, float, int, bool))
return value
def places_to_area(self, place: Place) -> dict[str, str]: def places_to_area(self, place: Place) -> dict[str, str]:
"""Convert places with sub_places to a flat dictionary.""" """Convert places with sub_places to a flat dictionary."""

View File

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
import logging import logging
from typing import Any from typing import Any, cast
from urllib.parse import urlparse from urllib.parse import urlparse
from pyoverkiz.models import Command, Device from pyoverkiz.models import Command, Device
@ -41,7 +41,7 @@ class OverkizExecutor:
"""Select first existing active state in a list of states.""" """Select first existing active state in a list of states."""
for state in states: for state in states:
if current_state := self.device.states[state]: if current_state := self.device.states[state]:
return current_state.value return cast(str, current_state.value)
return None return None
@ -53,7 +53,7 @@ class OverkizExecutor:
"""Select first existing active state in a list of states.""" """Select first existing active state in a list of states."""
for attribute in attributes: for attribute in attributes:
if current_attribute := self.device.attributes[attribute]: if current_attribute := self.device.attributes[attribute]:
return current_attribute.value return cast(str, current_attribute.value)
return None return None

View File

@ -1,7 +1,7 @@
"""Support for Overkiz lights.""" """Support for Overkiz lights."""
from __future__ import annotations from __future__ import annotations
from typing import Any from typing import Any, cast
from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState
@ -59,9 +59,8 @@ class OverkizLight(OverkizEntity, LightEntity):
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
"""Return true if light is on.""" """Return true if light is on."""
return ( return self.executor.select_state(OverkizState.CORE_ON_OFF) == cast(
self.executor.select_state(OverkizState.CORE_ON_OFF) str, OverkizCommandParam.ON
== OverkizCommandParam.ON
) )
@property @property

View File

@ -1,7 +1,7 @@
"""Support for Overkiz locks.""" """Support for Overkiz locks."""
from __future__ import annotations from __future__ import annotations
from typing import Any from typing import Any, cast
from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState
@ -44,7 +44,6 @@ class OverkizLock(OverkizEntity, LockEntity):
@property @property
def is_locked(self) -> bool | None: def is_locked(self) -> bool | None:
"""Return a boolean for the state of the lock.""" """Return a boolean for the state of the lock."""
return ( return self.executor.select_state(OverkizState.CORE_LOCKED_UNLOCKED) == cast(
self.executor.select_state(OverkizState.CORE_LOCKED_UNLOCKED) str, OverkizCommandParam.LOCKED
== OverkizCommandParam.LOCKED
) )

View File

@ -2,6 +2,7 @@
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from typing import cast
from pyoverkiz.enums import OverkizCommand, OverkizState from pyoverkiz.enums import OverkizCommand, OverkizState
@ -92,7 +93,7 @@ class OverkizNumber(OverkizDescriptiveEntity, NumberEntity):
def value(self) -> float | None: def value(self) -> float | None:
"""Return the entity value to represent the entity state.""" """Return the entity value to represent the entity state."""
if state := self.device.states.get(self.entity_description.key): if state := self.device.states.get(self.entity_description.key):
return state.value return cast(float, state.value)
return None return None

View File

@ -3,6 +3,7 @@ from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import cast
from pyoverkiz.enums import OverkizAttribute, OverkizState, UIWidget from pyoverkiz.enums import OverkizAttribute, OverkizState, UIWidget
@ -401,7 +402,7 @@ class OverkizStateSensor(OverkizDescriptiveEntity, SensorEntity):
if self.entity_description.native_value: if self.entity_description.native_value:
return self.entity_description.native_value(state.value) return self.entity_description.native_value(state.value)
return state.value return cast(str, state.value)
class OverkizHomeKitSetupCodeSensor(OverkizEntity, SensorEntity): class OverkizHomeKitSetupCodeSensor(OverkizEntity, SensorEntity):
@ -418,9 +419,11 @@ class OverkizHomeKitSetupCodeSensor(OverkizEntity, SensorEntity):
self._attr_name = "HomeKit Setup Code" self._attr_name = "HomeKit Setup Code"
@property @property
def native_value(self) -> str: def native_value(self) -> str | None:
"""Return the value of the sensor.""" """Return the value of the sensor."""
return self.device.attributes.get(OverkizAttribute.HOMEKIT_SETUP_CODE).value if state := self.device.attributes.get(OverkizAttribute.HOMEKIT_SETUP_CODE):
return cast(str, state.value)
return None
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:

View File

@ -1122,6 +1122,17 @@ no_implicit_optional = true
warn_return_any = true warn_return_any = true
warn_unreachable = true warn_unreachable = true
[mypy-homeassistant.components.overkiz.*]
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.persistent_notification.*] [mypy-homeassistant.components.persistent_notification.*]
check_untyped_defs = true check_untyped_defs = true
disallow_incomplete_defs = true disallow_incomplete_defs = true