Clean up Mold indicator (#123080)

* Improve code quality on mold_indicator

* mypy

* Fix mypy
This commit is contained in:
G Johansson
2024-09-08 13:11:57 +02:00
committed by GitHub
parent 8acc027f38
commit 1ffd797e0a
3 changed files with 65 additions and 59 deletions

View File

@ -316,6 +316,7 @@ homeassistant.components.minecraft_server.*
homeassistant.components.mjpeg.*
homeassistant.components.modbus.*
homeassistant.components.modem_callerid.*
homeassistant.components.mold_indicator.*
homeassistant.components.monzo.*
homeassistant.components.moon.*
homeassistant.components.mopeka.*

View File

@ -4,13 +4,16 @@ from __future__ import annotations
import logging
import math
from typing import TYPE_CHECKING, Any
import voluptuous as vol
from homeassistant import util
from homeassistant.components.sensor import (
PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
SensorDeviceClass,
SensorEntity,
SensorStateClass,
)
from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT,
@ -30,7 +33,7 @@ from homeassistant.core import (
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_state_change_event
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType
from homeassistant.util.unit_conversion import TemperatureConverter
from homeassistant.util.unit_system import METRIC_SYSTEM
@ -67,11 +70,11 @@ async def async_setup_platform(
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Set up MoldIndicator sensor."""
name = config.get(CONF_NAME, DEFAULT_NAME)
indoor_temp_sensor = config.get(CONF_INDOOR_TEMP)
outdoor_temp_sensor = config.get(CONF_OUTDOOR_TEMP)
indoor_humidity_sensor = config.get(CONF_INDOOR_HUMIDITY)
calib_factor = config.get(CONF_CALIBRATION_FACTOR)
name: str = config[CONF_NAME]
indoor_temp_sensor: str = config[CONF_INDOOR_TEMP]
outdoor_temp_sensor: str = config[CONF_OUTDOOR_TEMP]
indoor_humidity_sensor: str = config[CONF_INDOOR_HUMIDITY]
calib_factor: float = config[CONF_CALIBRATION_FACTOR]
async_add_entities(
[
@ -92,36 +95,39 @@ class MoldIndicator(SensorEntity):
"""Represents a MoldIndication sensor."""
_attr_should_poll = False
_attr_native_unit_of_measurement = PERCENTAGE
_attr_device_class = SensorDeviceClass.HUMIDITY
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(
self,
name,
is_metric,
indoor_temp_sensor,
outdoor_temp_sensor,
indoor_humidity_sensor,
calib_factor,
):
name: str,
is_metric: bool,
indoor_temp_sensor: str,
outdoor_temp_sensor: str,
indoor_humidity_sensor: str,
calib_factor: float,
) -> None:
"""Initialize the sensor."""
self._state = None
self._name = name
self._state: str | None = None
self._attr_name = name
self._indoor_temp_sensor = indoor_temp_sensor
self._indoor_humidity_sensor = indoor_humidity_sensor
self._outdoor_temp_sensor = outdoor_temp_sensor
self._calib_factor = calib_factor
self._is_metric = is_metric
self._available = False
self._attr_available = False
self._entities = {
self._indoor_temp_sensor,
self._indoor_humidity_sensor,
self._outdoor_temp_sensor,
indoor_temp_sensor,
indoor_humidity_sensor,
outdoor_temp_sensor,
}
self._dewpoint = None
self._indoor_temp = None
self._outdoor_temp = None
self._indoor_hum = None
self._crit_temp = None
self._dewpoint: float | None = None
self._indoor_temp: float | None = None
self._outdoor_temp: float | None = None
self._indoor_hum: float | None = None
self._crit_temp: float | None = None
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
@ -145,7 +151,7 @@ class MoldIndicator(SensorEntity):
self.async_schedule_update_ha_state(True)
@callback
def mold_indicator_startup(event):
def mold_indicator_startup(event: Event) -> None:
"""Add listeners and get 1st state."""
_LOGGER.debug("Startup for %s", self.entity_id)
@ -199,11 +205,11 @@ class MoldIndicator(SensorEntity):
return False
if entity == self._indoor_temp_sensor:
self._indoor_temp = MoldIndicator._update_temp_sensor(new_state)
self._indoor_temp = self._update_temp_sensor(new_state)
elif entity == self._outdoor_temp_sensor:
self._outdoor_temp = MoldIndicator._update_temp_sensor(new_state)
self._outdoor_temp = self._update_temp_sensor(new_state)
elif entity == self._indoor_humidity_sensor:
self._indoor_hum = MoldIndicator._update_hum_sensor(new_state)
self._indoor_hum = self._update_hum_sensor(new_state)
return True
@ -295,7 +301,7 @@ class MoldIndicator(SensorEntity):
_LOGGER.debug("Update state for %s", self.entity_id)
# check all sensors
if None in (self._indoor_temp, self._indoor_hum, self._outdoor_temp):
self._available = False
self._attr_available = False
self._dewpoint = None
self._crit_temp = None
return
@ -304,15 +310,17 @@ class MoldIndicator(SensorEntity):
self._calc_dewpoint()
self._calc_moldindicator()
if self._state is None:
self._available = False
self._attr_available = False
self._dewpoint = None
self._crit_temp = None
else:
self._available = True
self._attr_available = True
def _calc_dewpoint(self):
def _calc_dewpoint(self) -> None:
"""Calculate the dewpoint for the indoor air."""
# Use magnus approximation to calculate the dew point
if TYPE_CHECKING:
assert self._indoor_temp and self._indoor_hum
alpha = MAGNUS_K2 * self._indoor_temp / (MAGNUS_K3 + self._indoor_temp)
beta = MAGNUS_K2 * MAGNUS_K3 / (MAGNUS_K3 + self._indoor_temp)
@ -326,8 +334,11 @@ class MoldIndicator(SensorEntity):
)
_LOGGER.debug("Dewpoint: %f %s", self._dewpoint, UnitOfTemperature.CELSIUS)
def _calc_moldindicator(self):
def _calc_moldindicator(self) -> None:
"""Calculate the humidity at the (cold) calibration point."""
if TYPE_CHECKING:
assert self._outdoor_temp and self._indoor_temp and self._dewpoint
if None in (self._dewpoint, self._calib_factor) or self._calib_factor == 0:
_LOGGER.debug(
"Invalid inputs - dewpoint: %s, calibration-factor: %s",
@ -335,7 +346,7 @@ class MoldIndicator(SensorEntity):
self._calib_factor,
)
self._state = None
self._available = False
self._attr_available = False
self._crit_temp = None
return
@ -374,37 +385,21 @@ class MoldIndicator(SensorEntity):
_LOGGER.debug("Mold indicator humidity: %s", self._state)
@property
def name(self):
"""Return the name."""
return self._name
@property
def native_unit_of_measurement(self):
"""Return the unit of measurement."""
return PERCENTAGE
@property
def native_value(self):
def native_value(self) -> StateType:
"""Return the state of the entity."""
return self._state
@property
def available(self):
"""Return the availability of this sensor."""
return self._available
@property
def extra_state_attributes(self):
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes."""
if self._is_metric:
return {
ATTR_DEWPOINT: round(self._dewpoint, 2),
ATTR_CRITICAL_TEMP: round(self._crit_temp, 2),
}
convert_to = UnitOfTemperature.CELSIUS
else:
convert_to = UnitOfTemperature.FAHRENHEIT
dewpoint = (
TemperatureConverter.convert(
self._dewpoint, UnitOfTemperature.CELSIUS, UnitOfTemperature.FAHRENHEIT
self._dewpoint, UnitOfTemperature.CELSIUS, convert_to
)
if self._dewpoint is not None
else None
@ -412,13 +407,13 @@ class MoldIndicator(SensorEntity):
crit_temp = (
TemperatureConverter.convert(
self._crit_temp, UnitOfTemperature.CELSIUS, UnitOfTemperature.FAHRENHEIT
self._crit_temp, UnitOfTemperature.CELSIUS, convert_to
)
if self._crit_temp is not None
else None
)
return {
ATTR_DEWPOINT: round(dewpoint, 2),
ATTR_CRITICAL_TEMP: round(crit_temp, 2),
ATTR_DEWPOINT: round(dewpoint, 2) if dewpoint else None,
ATTR_CRITICAL_TEMP: round(crit_temp, 2) if crit_temp else None,
}

View File

@ -2916,6 +2916,16 @@ disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.mold_indicator.*]
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.monzo.*]
check_untyped_defs = true
disallow_incomplete_defs = true