mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 01:08:12 +00:00
Enable strict typing for generic_thermostat (#108024)
This commit is contained in:
parent
9bca09a513
commit
84038fb119
@ -183,6 +183,7 @@ homeassistant.components.fronius.*
|
||||
homeassistant.components.frontend.*
|
||||
homeassistant.components.fully_kiosk.*
|
||||
homeassistant.components.generic_hygrostat.*
|
||||
homeassistant.components.generic_thermostat.*
|
||||
homeassistant.components.geo_location.*
|
||||
homeassistant.components.geocaching.*
|
||||
homeassistant.components.gios.*
|
||||
|
@ -2,6 +2,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
import math
|
||||
from typing import Any
|
||||
@ -36,10 +37,12 @@ from homeassistant.const import (
|
||||
STATE_ON,
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import (
|
||||
DOMAIN as HA_DOMAIN,
|
||||
CoreState,
|
||||
Event,
|
||||
HomeAssistant,
|
||||
State,
|
||||
callback,
|
||||
@ -126,25 +129,25 @@ async def async_setup_platform(
|
||||
|
||||
await async_setup_reload_service(hass, DOMAIN, PLATFORMS)
|
||||
|
||||
name = config.get(CONF_NAME)
|
||||
heater_entity_id = config.get(CONF_HEATER)
|
||||
sensor_entity_id = config.get(CONF_SENSOR)
|
||||
min_temp = config.get(CONF_MIN_TEMP)
|
||||
max_temp = config.get(CONF_MAX_TEMP)
|
||||
target_temp = config.get(CONF_TARGET_TEMP)
|
||||
ac_mode = config.get(CONF_AC_MODE)
|
||||
min_cycle_duration = config.get(CONF_MIN_DUR)
|
||||
cold_tolerance = config.get(CONF_COLD_TOLERANCE)
|
||||
hot_tolerance = config.get(CONF_HOT_TOLERANCE)
|
||||
keep_alive = config.get(CONF_KEEP_ALIVE)
|
||||
initial_hvac_mode = config.get(CONF_INITIAL_HVAC_MODE)
|
||||
presets = {
|
||||
name: str = config[CONF_NAME]
|
||||
heater_entity_id: str = config[CONF_HEATER]
|
||||
sensor_entity_id: str = config[CONF_SENSOR]
|
||||
min_temp: float | None = config.get(CONF_MIN_TEMP)
|
||||
max_temp: float | None = config.get(CONF_MAX_TEMP)
|
||||
target_temp: float | None = config.get(CONF_TARGET_TEMP)
|
||||
ac_mode: bool | None = config.get(CONF_AC_MODE)
|
||||
min_cycle_duration: timedelta | None = config.get(CONF_MIN_DUR)
|
||||
cold_tolerance: float = config[CONF_COLD_TOLERANCE]
|
||||
hot_tolerance: float = config[CONF_HOT_TOLERANCE]
|
||||
keep_alive: timedelta | None = config.get(CONF_KEEP_ALIVE)
|
||||
initial_hvac_mode: HVACMode | None = config.get(CONF_INITIAL_HVAC_MODE)
|
||||
presets: dict[str, float] = {
|
||||
key: config[value] for key, value in CONF_PRESETS.items() if value in config
|
||||
}
|
||||
precision = config.get(CONF_PRECISION)
|
||||
target_temperature_step = config.get(CONF_TEMP_STEP)
|
||||
precision: float | None = config.get(CONF_PRECISION)
|
||||
target_temperature_step: float | None = config.get(CONF_TEMP_STEP)
|
||||
unit = hass.config.units.temperature_unit
|
||||
unique_id = config.get(CONF_UNIQUE_ID)
|
||||
unique_id: str | None = config.get(CONF_UNIQUE_ID)
|
||||
|
||||
async_add_entities(
|
||||
[
|
||||
@ -178,24 +181,24 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
heater_entity_id,
|
||||
sensor_entity_id,
|
||||
min_temp,
|
||||
max_temp,
|
||||
target_temp,
|
||||
ac_mode,
|
||||
min_cycle_duration,
|
||||
cold_tolerance,
|
||||
hot_tolerance,
|
||||
keep_alive,
|
||||
initial_hvac_mode,
|
||||
presets,
|
||||
precision,
|
||||
target_temperature_step,
|
||||
unit,
|
||||
unique_id,
|
||||
):
|
||||
name: str,
|
||||
heater_entity_id: str,
|
||||
sensor_entity_id: str,
|
||||
min_temp: float | None,
|
||||
max_temp: float | None,
|
||||
target_temp: float | None,
|
||||
ac_mode: bool | None,
|
||||
min_cycle_duration: timedelta | None,
|
||||
cold_tolerance: float,
|
||||
hot_tolerance: float,
|
||||
keep_alive: timedelta | None,
|
||||
initial_hvac_mode: HVACMode | None,
|
||||
presets: dict[str, float],
|
||||
precision: float | None,
|
||||
target_temperature_step: float | None,
|
||||
unit: UnitOfTemperature,
|
||||
unique_id: str | None,
|
||||
) -> None:
|
||||
"""Initialize the thermostat."""
|
||||
self._attr_name = name
|
||||
self.heater_entity_id = heater_entity_id
|
||||
@ -214,7 +217,7 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
else:
|
||||
self._attr_hvac_modes = [HVACMode.HEAT, HVACMode.OFF]
|
||||
self._active = False
|
||||
self._cur_temp = None
|
||||
self._cur_temp: float | None = None
|
||||
self._temp_lock = asyncio.Lock()
|
||||
self._min_temp = min_temp
|
||||
self._max_temp = max_temp
|
||||
@ -254,7 +257,7 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
)
|
||||
|
||||
@callback
|
||||
def _async_startup(*_):
|
||||
def _async_startup(_: Event | None = None) -> None:
|
||||
"""Init on startup."""
|
||||
sensor_state = self.hass.states.get(self.sensor_entity_id)
|
||||
if sensor_state and sensor_state.state not in (
|
||||
@ -297,7 +300,7 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
):
|
||||
self._attr_preset_mode = old_state.attributes.get(ATTR_PRESET_MODE)
|
||||
if not self._hvac_mode and old_state.state:
|
||||
self._hvac_mode = old_state.state
|
||||
self._hvac_mode = HVACMode(old_state.state)
|
||||
|
||||
else:
|
||||
# No previous state, try and restore defaults
|
||||
@ -315,14 +318,14 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
self._hvac_mode = HVACMode.OFF
|
||||
|
||||
@property
|
||||
def precision(self):
|
||||
def precision(self) -> float:
|
||||
"""Return the precision of the system."""
|
||||
if self._temp_precision is not None:
|
||||
return self._temp_precision
|
||||
return super().precision
|
||||
|
||||
@property
|
||||
def target_temperature_step(self):
|
||||
def target_temperature_step(self) -> float:
|
||||
"""Return the supported step of target temperature."""
|
||||
if self._temp_target_temperature_step is not None:
|
||||
return self._temp_target_temperature_step
|
||||
@ -330,17 +333,17 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
return self.precision
|
||||
|
||||
@property
|
||||
def current_temperature(self):
|
||||
def current_temperature(self) -> float | None:
|
||||
"""Return the sensor temperature."""
|
||||
return self._cur_temp
|
||||
|
||||
@property
|
||||
def hvac_mode(self):
|
||||
def hvac_mode(self) -> HVACMode | None:
|
||||
"""Return current operation."""
|
||||
return self._hvac_mode
|
||||
|
||||
@property
|
||||
def hvac_action(self):
|
||||
def hvac_action(self) -> HVACAction:
|
||||
"""Return the current running hvac operation if supported.
|
||||
|
||||
Need to be one of CURRENT_HVAC_*.
|
||||
@ -354,7 +357,7 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
return HVACAction.HEATING
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
def target_temperature(self) -> float | None:
|
||||
"""Return the temperature we try to reach."""
|
||||
return self._target_temp
|
||||
|
||||
@ -385,7 +388,7 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
self.async_write_ha_state()
|
||||
|
||||
@property
|
||||
def min_temp(self):
|
||||
def min_temp(self) -> float:
|
||||
"""Return the minimum temperature."""
|
||||
if self._min_temp is not None:
|
||||
return self._min_temp
|
||||
@ -394,7 +397,7 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
return super().min_temp
|
||||
|
||||
@property
|
||||
def max_temp(self):
|
||||
def max_temp(self) -> float:
|
||||
"""Return the maximum temperature."""
|
||||
if self._max_temp is not None:
|
||||
return self._max_temp
|
||||
@ -414,7 +417,7 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
await self._async_control_heating()
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def _check_switch_initial_state(self):
|
||||
async def _check_switch_initial_state(self) -> None:
|
||||
"""Prevent the device from keep running if HVACMode.OFF."""
|
||||
if self._hvac_mode == HVACMode.OFF and self._is_device_active:
|
||||
_LOGGER.warning(
|
||||
@ -448,7 +451,9 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
except ValueError as ex:
|
||||
_LOGGER.error("Unable to update from sensor: %s", ex)
|
||||
|
||||
async def _async_control_heating(self, time=None, force=False):
|
||||
async def _async_control_heating(
|
||||
self, time: datetime | None = None, force: bool = False
|
||||
) -> None:
|
||||
"""Check if we need to turn heating on or off."""
|
||||
async with self._temp_lock:
|
||||
if not self._active and None not in (
|
||||
@ -490,6 +495,7 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
if not long_enough:
|
||||
return
|
||||
|
||||
assert self._cur_temp is not None and self._target_temp is not None
|
||||
too_cold = self._target_temp >= self._cur_temp + self._cold_tolerance
|
||||
too_hot = self._cur_temp >= self._target_temp + self._hot_tolerance
|
||||
if self._is_device_active:
|
||||
@ -514,21 +520,21 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
||||
await self._async_heater_turn_off()
|
||||
|
||||
@property
|
||||
def _is_device_active(self):
|
||||
def _is_device_active(self) -> bool | None:
|
||||
"""If the toggleable device is currently active."""
|
||||
if not self.hass.states.get(self.heater_entity_id):
|
||||
return None
|
||||
|
||||
return self.hass.states.is_state(self.heater_entity_id, STATE_ON)
|
||||
|
||||
async def _async_heater_turn_on(self):
|
||||
async def _async_heater_turn_on(self) -> None:
|
||||
"""Turn heater toggleable device on."""
|
||||
data = {ATTR_ENTITY_ID: self.heater_entity_id}
|
||||
await self.hass.services.async_call(
|
||||
HA_DOMAIN, SERVICE_TURN_ON, data, context=self._context
|
||||
)
|
||||
|
||||
async def _async_heater_turn_off(self):
|
||||
async def _async_heater_turn_off(self) -> None:
|
||||
"""Turn heater toggleable device off."""
|
||||
data = {ATTR_ENTITY_ID: self.heater_entity_id}
|
||||
await self.hass.services.async_call(
|
||||
|
10
mypy.ini
10
mypy.ini
@ -1591,6 +1591,16 @@ disallow_untyped_defs = true
|
||||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.generic_thermostat.*]
|
||||
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.geo_location.*]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
|
Loading…
x
Reference in New Issue
Block a user