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
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 65 additions and 59 deletions

View File

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

View File

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