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

View File

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

View File

@ -24,7 +24,6 @@ IGNORED_MODULES: Final[list[str]] = [
"homeassistant.components.conversation", "homeassistant.components.conversation",
"homeassistant.components.conversation.default_agent", "homeassistant.components.conversation.default_agent",
"homeassistant.components.deconz.binary_sensor", "homeassistant.components.deconz.binary_sensor",
"homeassistant.components.deconz.climate",
"homeassistant.components.deconz.cover", "homeassistant.components.deconz.cover",
"homeassistant.components.deconz.fan", "homeassistant.components.deconz.fan",
"homeassistant.components.deconz.light", "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") climate_thermostat = hass.states.get("climate.thermostat")
assert climate_thermostat.state == HVAC_MODE_AUTO assert climate_thermostat.state == HVAC_MODE_AUTO
assert climate_thermostat.attributes["hvac_modes"] == [ assert climate_thermostat.attributes["hvac_modes"] == [
HVAC_MODE_AUTO,
HVAC_MODE_HEAT, HVAC_MODE_HEAT,
HVAC_MODE_OFF, HVAC_MODE_OFF,
HVAC_MODE_AUTO,
] ]
assert climate_thermostat.attributes["current_temperature"] == 22.6 assert climate_thermostat.attributes["current_temperature"] == 22.6
assert climate_thermostat.attributes["temperature"] == 22.0 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") climate_thermostat = hass.states.get("climate.zen_01")
assert climate_thermostat.state == HVAC_MODE_HEAT assert climate_thermostat.state == HVAC_MODE_HEAT
assert climate_thermostat.attributes["hvac_modes"] == [ assert climate_thermostat.attributes["hvac_modes"] == [
HVAC_MODE_AUTO,
HVAC_MODE_COOL,
HVAC_MODE_HEAT, HVAC_MODE_HEAT,
HVAC_MODE_OFF, HVAC_MODE_OFF,
HVAC_MODE_AUTO,
HVAC_MODE_COOL,
] ]
assert climate_thermostat.attributes["current_temperature"] == 23.2 assert climate_thermostat.attributes["current_temperature"] == 23.2
assert climate_thermostat.attributes["temperature"] == 22.2 assert climate_thermostat.attributes["temperature"] == 22.2