diff --git a/.strict-typing b/.strict-typing index 3dc1bd50b7e..cb259dc1307 100644 --- a/.strict-typing +++ b/.strict-typing @@ -69,6 +69,7 @@ homeassistant.components.deconz.config_flow homeassistant.components.deconz.diagnostics homeassistant.components.deconz.gateway homeassistant.components.deconz.light +homeassistant.components.deconz.sensor homeassistant.components.deconz.services homeassistant.components.device_automation.* homeassistant.components.device_tracker.* diff --git a/homeassistant/components/deconz/sensor.py b/homeassistant/components/deconz/sensor.py index e9e71429c22..0e80cf5b456 100644 --- a/homeassistant/components/deconz/sensor.py +++ b/homeassistant/components/deconz/sensor.py @@ -14,7 +14,7 @@ from pydeconz.sensor import ( LightLevel, Power, Pressure, - SensorBase as PydeconzSensor, + SensorResources, Switch, Temperature, Time, @@ -75,7 +75,7 @@ class DeconzSensorDescriptionMixin: """Required values when describing secondary sensor attributes.""" update_key: str - value_fn: Callable[[PydeconzSensor], float | int | str | None] + value_fn: Callable[[SensorResources], float | int | str | None] @dataclass @@ -92,13 +92,17 @@ ENTITY_DESCRIPTIONS = { AirQuality: [ DeconzSensorDescription( 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", state_class=SensorStateClass.MEASUREMENT, ), DeconzSensorDescription( 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", update_key="airqualityppb", device_class=SensorDeviceClass.AQI, @@ -109,7 +113,9 @@ ENTITY_DESCRIPTIONS = { Consumption: [ DeconzSensorDescription( 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", device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, @@ -119,7 +125,9 @@ ENTITY_DESCRIPTIONS = { Daylight: [ DeconzSensorDescription( 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", icon="mdi:white-balance-sunny", entity_registry_enabled_default=False, @@ -128,14 +136,18 @@ ENTITY_DESCRIPTIONS = { GenericStatus: [ DeconzSensorDescription( 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", ) ], Humidity: [ DeconzSensorDescription( 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", device_class=SensorDeviceClass.HUMIDITY, state_class=SensorStateClass.MEASUREMENT, @@ -145,7 +157,9 @@ ENTITY_DESCRIPTIONS = { LightLevel: [ DeconzSensorDescription( 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", device_class=SensorDeviceClass.ILLUMINANCE, native_unit_of_measurement=LIGHT_LUX, @@ -154,7 +168,7 @@ ENTITY_DESCRIPTIONS = { Power: [ DeconzSensorDescription( 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", device_class=SensorDeviceClass.POWER, state_class=SensorStateClass.MEASUREMENT, @@ -164,7 +178,9 @@ ENTITY_DESCRIPTIONS = { Pressure: [ DeconzSensorDescription( 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", device_class=SensorDeviceClass.PRESSURE, state_class=SensorStateClass.MEASUREMENT, @@ -174,7 +190,9 @@ ENTITY_DESCRIPTIONS = { Temperature: [ DeconzSensorDescription( 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", device_class=SensorDeviceClass.TEMPERATURE, state_class=SensorStateClass.MEASUREMENT, @@ -184,7 +202,9 @@ ENTITY_DESCRIPTIONS = { Time: [ DeconzSensorDescription( 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", device_class=SensorDeviceClass.TIMESTAMP, state_class=SensorStateClass.TOTAL_INCREASING, @@ -192,6 +212,7 @@ ENTITY_DESCRIPTIONS = { ], } + SENSOR_DESCRIPTIONS = [ DeconzSensorDescription( key="battery", @@ -227,7 +248,7 @@ async def async_setup_entry( battery_handler = DeconzBatteryHandler(gateway) @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. Create DeconzBattery if sensor has a battery attribute. @@ -284,12 +305,12 @@ class DeconzSensor(DeconzDevice, SensorEntity): """Representation of a deCONZ sensor.""" TYPE = DOMAIN - _device: PydeconzSensor + _device: SensorResources entity_description: DeconzSensorDescription def __init__( self, - device: PydeconzSensor, + device: SensorResources, gateway: DeconzGateway, description: DeconzSensorDescription, ) -> None: @@ -381,7 +402,7 @@ class DeconzSensor(DeconzDevice, SensorEntity): class DeconzSensorStateTracker: """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.""" self.sensor = sensor self.gateway = gateway @@ -391,7 +412,6 @@ class DeconzSensorStateTracker: def close(self) -> None: """Clean up tracker.""" self.sensor.remove_callback(self.async_update_callback) - self.sensor = None @callback def async_update_callback(self) -> None: @@ -413,7 +433,7 @@ class DeconzBatteryHandler: self._trackers: set[DeconzSensorStateTracker] = set() @callback - def create_tracker(self, sensor: PydeconzSensor) -> None: + def create_tracker(self, sensor: SensorResources) -> None: """Create new tracker for battery state.""" for tracker in self._trackers: if sensor == tracker.sensor: @@ -421,7 +441,7 @@ class DeconzBatteryHandler: self._trackers.add(DeconzSensorStateTracker(sensor, self.gateway)) @callback - def remove_tracker(self, sensor: PydeconzSensor) -> None: + def remove_tracker(self, sensor: SensorResources) -> None: """Remove tracker of battery state.""" for tracker in self._trackers: if sensor == tracker.sensor: diff --git a/mypy.ini b/mypy.ini index 9499433a194..9400349f6d7 100644 --- a/mypy.ini +++ b/mypy.ini @@ -561,6 +561,17 @@ no_implicit_optional = true warn_return_any = 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] check_untyped_defs = true disallow_incomplete_defs = true @@ -2660,9 +2671,6 @@ ignore_errors = true [mypy-homeassistant.components.deconz.number] ignore_errors = true -[mypy-homeassistant.components.deconz.sensor] -ignore_errors = true - [mypy-homeassistant.components.deconz.siren] ignore_errors = true diff --git a/script/hassfest/mypy_config.py b/script/hassfest/mypy_config.py index c43cf47cd2e..53555e90fc0 100644 --- a/script/hassfest/mypy_config.py +++ b/script/hassfest/mypy_config.py @@ -29,7 +29,6 @@ IGNORED_MODULES: Final[list[str]] = [ "homeassistant.components.deconz.lock", "homeassistant.components.deconz.logbook", "homeassistant.components.deconz.number", - "homeassistant.components.deconz.sensor", "homeassistant.components.deconz.siren", "homeassistant.components.deconz.switch", "homeassistant.components.denonavr.config_flow",