Improve typing of deCONZ sensor platform (#70161)

This commit is contained in:
Robert Svensson 2022-04-17 19:58:42 +02:00 committed by GitHub
parent 2af1b7d974
commit b6cf65decb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 24 deletions

View File

@ -69,6 +69,7 @@ homeassistant.components.deconz.config_flow
homeassistant.components.deconz.diagnostics homeassistant.components.deconz.diagnostics
homeassistant.components.deconz.gateway homeassistant.components.deconz.gateway
homeassistant.components.deconz.light homeassistant.components.deconz.light
homeassistant.components.deconz.sensor
homeassistant.components.deconz.services homeassistant.components.deconz.services
homeassistant.components.device_automation.* homeassistant.components.device_automation.*
homeassistant.components.device_tracker.* homeassistant.components.device_tracker.*

View File

@ -14,7 +14,7 @@ from pydeconz.sensor import (
LightLevel, LightLevel,
Power, Power,
Pressure, Pressure,
SensorBase as PydeconzSensor, SensorResources,
Switch, Switch,
Temperature, Temperature,
Time, Time,
@ -75,7 +75,7 @@ class DeconzSensorDescriptionMixin:
"""Required values when describing secondary sensor attributes.""" """Required values when describing secondary sensor attributes."""
update_key: str update_key: str
value_fn: Callable[[PydeconzSensor], float | int | str | None] value_fn: Callable[[SensorResources], float | int | str | None]
@dataclass @dataclass
@ -92,13 +92,17 @@ ENTITY_DESCRIPTIONS = {
AirQuality: [ AirQuality: [
DeconzSensorDescription( DeconzSensorDescription(
key="air_quality", key="air_quality",
value_fn=lambda device: device.air_quality, # type: ignore[no-any-return] value_fn=lambda device: device.air_quality
if isinstance(device, AirQuality)
else None,
update_key="airquality", update_key="airquality",
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
), ),
DeconzSensorDescription( DeconzSensorDescription(
key="air_quality_ppb", key="air_quality_ppb",
value_fn=lambda device: device.air_quality_ppb, # type: ignore[no-any-return] value_fn=lambda device: device.air_quality_ppb
if isinstance(device, AirQuality)
else None,
suffix="PPB", suffix="PPB",
update_key="airqualityppb", update_key="airqualityppb",
device_class=SensorDeviceClass.AQI, device_class=SensorDeviceClass.AQI,
@ -109,7 +113,9 @@ ENTITY_DESCRIPTIONS = {
Consumption: [ Consumption: [
DeconzSensorDescription( DeconzSensorDescription(
key="consumption", key="consumption",
value_fn=lambda device: device.scaled_consumption, # type: ignore[no-any-return] value_fn=lambda device: device.scaled_consumption
if isinstance(device, Consumption)
else None,
update_key="consumption", update_key="consumption",
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING, state_class=SensorStateClass.TOTAL_INCREASING,
@ -119,7 +125,9 @@ ENTITY_DESCRIPTIONS = {
Daylight: [ Daylight: [
DeconzSensorDescription( DeconzSensorDescription(
key="status", key="status",
value_fn=lambda device: device.status, # type: ignore[no-any-return] value_fn=lambda device: device.status
if isinstance(device, Daylight)
else None,
update_key="status", update_key="status",
icon="mdi:white-balance-sunny", icon="mdi:white-balance-sunny",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -128,14 +136,18 @@ ENTITY_DESCRIPTIONS = {
GenericStatus: [ GenericStatus: [
DeconzSensorDescription( DeconzSensorDescription(
key="status", key="status",
value_fn=lambda device: device.status, # type: ignore[no-any-return] value_fn=lambda device: device.status
if isinstance(device, GenericStatus)
else None,
update_key="status", update_key="status",
) )
], ],
Humidity: [ Humidity: [
DeconzSensorDescription( DeconzSensorDescription(
key="humidity", key="humidity",
value_fn=lambda device: device.scaled_humidity, # type: ignore[no-any-return] value_fn=lambda device: device.scaled_humidity
if isinstance(device, Humidity)
else None,
update_key="humidity", update_key="humidity",
device_class=SensorDeviceClass.HUMIDITY, device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
@ -145,7 +157,9 @@ ENTITY_DESCRIPTIONS = {
LightLevel: [ LightLevel: [
DeconzSensorDescription( DeconzSensorDescription(
key="light_level", key="light_level",
value_fn=lambda device: device.scaled_light_level, # type: ignore[no-any-return] value_fn=lambda device: device.scaled_light_level
if isinstance(device, LightLevel)
else None,
update_key="lightlevel", update_key="lightlevel",
device_class=SensorDeviceClass.ILLUMINANCE, device_class=SensorDeviceClass.ILLUMINANCE,
native_unit_of_measurement=LIGHT_LUX, native_unit_of_measurement=LIGHT_LUX,
@ -154,7 +168,7 @@ ENTITY_DESCRIPTIONS = {
Power: [ Power: [
DeconzSensorDescription( DeconzSensorDescription(
key="power", key="power",
value_fn=lambda device: device.power, # type: ignore[no-any-return] value_fn=lambda device: device.power if isinstance(device, Power) else None,
update_key="power", update_key="power",
device_class=SensorDeviceClass.POWER, device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
@ -164,7 +178,9 @@ ENTITY_DESCRIPTIONS = {
Pressure: [ Pressure: [
DeconzSensorDescription( DeconzSensorDescription(
key="pressure", key="pressure",
value_fn=lambda device: device.pressure, # type: ignore[no-any-return] value_fn=lambda device: device.pressure
if isinstance(device, Pressure)
else None,
update_key="pressure", update_key="pressure",
device_class=SensorDeviceClass.PRESSURE, device_class=SensorDeviceClass.PRESSURE,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
@ -174,7 +190,9 @@ ENTITY_DESCRIPTIONS = {
Temperature: [ Temperature: [
DeconzSensorDescription( DeconzSensorDescription(
key="temperature", key="temperature",
value_fn=lambda device: device.scaled_temperature, # type: ignore[no-any-return] value_fn=lambda device: device.scaled_temperature
if isinstance(device, Temperature)
else None,
update_key="temperature", update_key="temperature",
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
@ -184,7 +202,9 @@ ENTITY_DESCRIPTIONS = {
Time: [ Time: [
DeconzSensorDescription( DeconzSensorDescription(
key="last_set", key="last_set",
value_fn=lambda device: device.last_set, # type: ignore[no-any-return] value_fn=lambda device: device.last_set
if isinstance(device, Time)
else None,
update_key="lastset", update_key="lastset",
device_class=SensorDeviceClass.TIMESTAMP, device_class=SensorDeviceClass.TIMESTAMP,
state_class=SensorStateClass.TOTAL_INCREASING, state_class=SensorStateClass.TOTAL_INCREASING,
@ -192,6 +212,7 @@ ENTITY_DESCRIPTIONS = {
], ],
} }
SENSOR_DESCRIPTIONS = [ SENSOR_DESCRIPTIONS = [
DeconzSensorDescription( DeconzSensorDescription(
key="battery", key="battery",
@ -227,7 +248,7 @@ async def async_setup_entry(
battery_handler = DeconzBatteryHandler(gateway) battery_handler = DeconzBatteryHandler(gateway)
@callback @callback
def async_add_sensor(sensors: list[PydeconzSensor] | None = None) -> None: def async_add_sensor(sensors: list[SensorResources] | None = None) -> None:
"""Add sensors from deCONZ. """Add sensors from deCONZ.
Create DeconzBattery if sensor has a battery attribute. Create DeconzBattery if sensor has a battery attribute.
@ -284,12 +305,12 @@ class DeconzSensor(DeconzDevice, SensorEntity):
"""Representation of a deCONZ sensor.""" """Representation of a deCONZ sensor."""
TYPE = DOMAIN TYPE = DOMAIN
_device: PydeconzSensor _device: SensorResources
entity_description: DeconzSensorDescription entity_description: DeconzSensorDescription
def __init__( def __init__(
self, self,
device: PydeconzSensor, device: SensorResources,
gateway: DeconzGateway, gateway: DeconzGateway,
description: DeconzSensorDescription, description: DeconzSensorDescription,
) -> None: ) -> None:
@ -381,7 +402,7 @@ class DeconzSensor(DeconzDevice, SensorEntity):
class DeconzSensorStateTracker: class DeconzSensorStateTracker:
"""Track sensors without a battery state and signal when battery state exist.""" """Track sensors without a battery state and signal when battery state exist."""
def __init__(self, sensor: PydeconzSensor, gateway: DeconzGateway) -> None: def __init__(self, sensor: SensorResources, gateway: DeconzGateway) -> None:
"""Set up tracker.""" """Set up tracker."""
self.sensor = sensor self.sensor = sensor
self.gateway = gateway self.gateway = gateway
@ -391,7 +412,6 @@ class DeconzSensorStateTracker:
def close(self) -> None: def close(self) -> None:
"""Clean up tracker.""" """Clean up tracker."""
self.sensor.remove_callback(self.async_update_callback) self.sensor.remove_callback(self.async_update_callback)
self.sensor = None
@callback @callback
def async_update_callback(self) -> None: def async_update_callback(self) -> None:
@ -413,7 +433,7 @@ class DeconzBatteryHandler:
self._trackers: set[DeconzSensorStateTracker] = set() self._trackers: set[DeconzSensorStateTracker] = set()
@callback @callback
def create_tracker(self, sensor: PydeconzSensor) -> None: def create_tracker(self, sensor: SensorResources) -> None:
"""Create new tracker for battery state.""" """Create new tracker for battery state."""
for tracker in self._trackers: for tracker in self._trackers:
if sensor == tracker.sensor: if sensor == tracker.sensor:
@ -421,7 +441,7 @@ class DeconzBatteryHandler:
self._trackers.add(DeconzSensorStateTracker(sensor, self.gateway)) self._trackers.add(DeconzSensorStateTracker(sensor, self.gateway))
@callback @callback
def remove_tracker(self, sensor: PydeconzSensor) -> None: def remove_tracker(self, sensor: SensorResources) -> None:
"""Remove tracker of battery state.""" """Remove tracker of battery state."""
for tracker in self._trackers: for tracker in self._trackers:
if sensor == tracker.sensor: if sensor == tracker.sensor:

View File

@ -561,6 +561,17 @@ no_implicit_optional = true
warn_return_any = true warn_return_any = true
warn_unreachable = true warn_unreachable = true
[mypy-homeassistant.components.deconz.sensor]
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.deconz.services] [mypy-homeassistant.components.deconz.services]
check_untyped_defs = true check_untyped_defs = true
disallow_incomplete_defs = true disallow_incomplete_defs = true
@ -2660,9 +2671,6 @@ ignore_errors = true
[mypy-homeassistant.components.deconz.number] [mypy-homeassistant.components.deconz.number]
ignore_errors = true ignore_errors = true
[mypy-homeassistant.components.deconz.sensor]
ignore_errors = true
[mypy-homeassistant.components.deconz.siren] [mypy-homeassistant.components.deconz.siren]
ignore_errors = true ignore_errors = true

View File

@ -29,7 +29,6 @@ IGNORED_MODULES: Final[list[str]] = [
"homeassistant.components.deconz.lock", "homeassistant.components.deconz.lock",
"homeassistant.components.deconz.logbook", "homeassistant.components.deconz.logbook",
"homeassistant.components.deconz.number", "homeassistant.components.deconz.number",
"homeassistant.components.deconz.sensor",
"homeassistant.components.deconz.siren", "homeassistant.components.deconz.siren",
"homeassistant.components.deconz.switch", "homeassistant.components.deconz.switch",
"homeassistant.components.denonavr.config_flow", "homeassistant.components.denonavr.config_flow",