Improve typing of deCONZ climate platform (#69882)

* Improve typing of deCONZ climate platform

homeassistant/components/deconz/climate.py:153: error: Dict entry 0 has incompatible type "str": "bool"; expected "str": "str"  [dict-item]
homeassistant/components/deconz/climate.py:154: error: Dict entry 1 has incompatible type "str": "bool"; expected "str": "str"  [dict-item]
homeassistant/components/deconz/climate.py:176: error: Argument 1 to "get" of "Mapping" has incompatible type "Optional[Literal['off', 'low', 'medium', 'high', 'on', 'auto', 'smart']]"; expected "str"  [arg-type]
homeassistant/components/deconz/climate.py:200: error: Argument 1 to "get" of "Mapping" has incompatible type "Optional[Literal['off', 'auto', 'cool', 'heat', 'emergency heating', 'precooling', 'fan only', 'dry', 'sleep']]"; expected "str"  [arg-type]
homeassistant/components/deconz/climate.py:218: error: Argument 1 to "set_config" of "Thermostat" has incompatible type "**Dict[str, str]"; expected "Optional[int]"  [arg-type]
homeassistant/components/deconz/climate.py:218: error: Argument 1 to "set_config" of "Thermostat" has incompatible type "**Dict[str, str]"; expected "Optional[bool]"  [arg-type]
homeassistant/components/deconz/climate.py:218: error: Argument 1 to "set_config" of "Thermostat" has incompatible type "**Dict[str, str]"; expected "Optional[List[str]]"  [arg-type]
homeassistant/components/deconz/climate.py:225: error: Argument 1 to "get" of "Mapping" has incompatible type "Optional[Literal['holiday', 'auto', 'manual', 'comfort', 'eco', 'boost', 'complex']]"; expected "str"  [arg-type]
homeassistant/components/deconz/climate.py:244: error: Unused "type: ignore" comment
homeassistant/components/deconz/climate.py:250: error: Unused "type: ignore" comment
homeassistant/components/deconz/climate.py:253: error: Unused "type: ignore" comment

* Simplify populating supported_hvac_modes
Fix tests
This commit is contained in:
Robert Svensson 2022-04-14 22:19:42 +02:00 committed by GitHub
parent a275b6a9ec
commit 87551b7880
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 35 deletions

View File

@ -64,6 +64,7 @@ homeassistant.components.crownstone.*
homeassistant.components.cpuspeed.*
homeassistant.components.deconz
homeassistant.components.deconz.alarm_control_panel
homeassistant.components.deconz.climate
homeassistant.components.deconz.config_flow
homeassistant.components.deconz.diagnostics
homeassistant.components.deconz.gateway

View File

@ -65,7 +65,7 @@ FAN_MODE_TO_DECONZ = {
DECONZ_TO_FAN_MODE = {value: key for key, value in FAN_MODE_TO_DECONZ.items()}
HVAC_MODE_TO_DECONZ = {
HVAC_MODE_TO_DECONZ: dict[str, str] = {
HVAC_MODE_AUTO: THERMOSTAT_MODE_AUTO,
HVAC_MODE_COOL: THERMOSTAT_MODE_COOL,
HVAC_MODE_HEAT: THERMOSTAT_MODE_HEAT,
@ -147,17 +147,15 @@ class DeconzThermostat(DeconzDevice, ClimateEntity):
"""Set up thermostat device."""
super().__init__(device, gateway)
self._hvac_mode_to_deconz = dict(HVAC_MODE_TO_DECONZ)
if not device.mode:
self._hvac_mode_to_deconz = {
HVAC_MODE_HEAT: True,
HVAC_MODE_OFF: False,
}
elif "coolsetpoint" not in device.raw["config"]:
self._hvac_mode_to_deconz.pop(HVAC_MODE_COOL)
self._deconz_to_hvac_mode = {
value: key for key, value in self._hvac_mode_to_deconz.items()
}
self.supported_hvac_modes = [
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
]
if device.mode:
self.supported_hvac_modes.append(HVAC_MODE_AUTO)
if "coolsetpoint" in device.raw["config"]:
self.supported_hvac_modes.append(HVAC_MODE_COOL)
self._attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
@ -172,9 +170,9 @@ class DeconzThermostat(DeconzDevice, ClimateEntity):
@property
def fan_mode(self) -> str:
"""Return fan operation."""
return DECONZ_TO_FAN_MODE.get(
self._device.fan_mode, FAN_ON if self._device.state_on else FAN_OFF
)
if self._device.fan_mode in DECONZ_TO_FAN_MODE:
return DECONZ_TO_FAN_MODE[self._device.fan_mode]
return DECONZ_TO_FAN_MODE[FAN_ON if self._device.state_on else FAN_OFF]
@property
def fan_modes(self) -> list[str]:
@ -196,36 +194,36 @@ class DeconzThermostat(DeconzDevice, ClimateEntity):
Need to be one of HVAC_MODE_*.
"""
return self._deconz_to_hvac_mode.get(
self._device.mode,
HVAC_MODE_HEAT if self._device.state_on else HVAC_MODE_OFF,
)
if self._device.mode in self.supported_hvac_modes:
return HVAC_MODE_TO_DECONZ[self._device.mode]
return HVAC_MODE_HEAT if self._device.state_on else HVAC_MODE_OFF
@property
def hvac_modes(self) -> list[str]:
"""Return the list of available hvac operation modes."""
return list(self._hvac_mode_to_deconz)
return self.supported_hvac_modes
async def async_set_hvac_mode(self, hvac_mode: str) -> None:
"""Set new target hvac mode."""
if hvac_mode not in self._hvac_mode_to_deconz:
if hvac_mode not in self.supported_hvac_modes:
raise ValueError(f"Unsupported HVAC mode {hvac_mode}")
data = {"mode": self._hvac_mode_to_deconz[hvac_mode]}
if len(self._hvac_mode_to_deconz) == 2: # Only allow turn on and off thermostat
data = {"on": self._hvac_mode_to_deconz[hvac_mode]}
await self._device.set_config(**data)
if len(self.supported_hvac_modes) == 2: # Only allow turn on and off thermostat
await self._device.set_config(on=hvac_mode != HVAC_MODE_OFF)
else:
await self._device.set_config(mode=HVAC_MODE_TO_DECONZ[hvac_mode])
# Preset control
@property
def preset_mode(self) -> str | None:
"""Return preset mode."""
return DECONZ_TO_PRESET_MODE.get(self._device.preset)
if self._device.preset in DECONZ_TO_PRESET_MODE:
return DECONZ_TO_PRESET_MODE[self._device.preset]
return None
@property
def preset_modes(self) -> list:
def preset_modes(self) -> list[str]:
"""Return the list of available preset modes."""
return list(PRESET_MODE_TO_DECONZ)

View File

@ -506,6 +506,17 @@ no_implicit_optional = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.deconz.climate]
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.config_flow]
check_untyped_defs = true
disallow_incomplete_defs = true
@ -2601,9 +2612,6 @@ ignore_errors = true
[mypy-homeassistant.components.deconz.binary_sensor]
ignore_errors = true
[mypy-homeassistant.components.deconz.climate]
ignore_errors = true
[mypy-homeassistant.components.deconz.cover]
ignore_errors = true

View File

@ -24,7 +24,6 @@ IGNORED_MODULES: Final[list[str]] = [
"homeassistant.components.conversation",
"homeassistant.components.conversation.default_agent",
"homeassistant.components.deconz.binary_sensor",
"homeassistant.components.deconz.climate",
"homeassistant.components.deconz.cover",
"homeassistant.components.deconz.fan",
"homeassistant.components.deconz.light",

View File

@ -204,9 +204,9 @@ async def test_climate_device_without_cooling_support(
climate_thermostat = hass.states.get("climate.thermostat")
assert climate_thermostat.state == HVAC_MODE_AUTO
assert climate_thermostat.attributes["hvac_modes"] == [
HVAC_MODE_AUTO,
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
HVAC_MODE_AUTO,
]
assert climate_thermostat.attributes["current_temperature"] == 22.6
assert climate_thermostat.attributes["temperature"] == 22.0
@ -378,10 +378,10 @@ async def test_climate_device_with_cooling_support(
climate_thermostat = hass.states.get("climate.zen_01")
assert climate_thermostat.state == HVAC_MODE_HEAT
assert climate_thermostat.attributes["hvac_modes"] == [
HVAC_MODE_AUTO,
HVAC_MODE_COOL,
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
HVAC_MODE_AUTO,
HVAC_MODE_COOL,
]
assert climate_thermostat.attributes["current_temperature"] == 23.2
assert climate_thermostat.attributes["temperature"] == 22.2