Use climate enums in zha (#70754)

This commit is contained in:
epenet 2022-04-26 10:09:13 +02:00 committed by GitHub
parent ca01183375
commit 8745401af5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 142 additions and 161 deletions

View File

@ -12,29 +12,21 @@ from random import randint
from zigpy.zcl.clusters.hvac import Fan as F, Thermostat as T from zigpy.zcl.clusters.hvac import Fan as F, Thermostat as T
from homeassistant.components.climate import ClimateEntity, ClimateEntityFeature from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import (
ATTR_HVAC_MODE, ATTR_HVAC_MODE,
ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_HIGH,
ATTR_TARGET_TEMP_LOW, ATTR_TARGET_TEMP_LOW,
CURRENT_HVAC_COOL,
CURRENT_HVAC_FAN,
CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE,
CURRENT_HVAC_OFF,
FAN_AUTO, FAN_AUTO,
FAN_ON, FAN_ON,
HVAC_MODE_COOL,
HVAC_MODE_DRY,
HVAC_MODE_FAN_ONLY,
HVAC_MODE_HEAT,
HVAC_MODE_HEAT_COOL,
HVAC_MODE_OFF,
PRESET_AWAY, PRESET_AWAY,
PRESET_BOOST, PRESET_BOOST,
PRESET_COMFORT, PRESET_COMFORT,
PRESET_ECO, PRESET_ECO,
PRESET_NONE, PRESET_NONE,
ClimateEntityFeature,
HVACAction,
HVACMode,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
@ -78,40 +70,40 @@ ATTR_UNOCCP_COOL_SETPT = "unoccupied_cooling_setpoint"
STRICT_MATCH = functools.partial(ZHA_ENTITIES.strict_match, Platform.CLIMATE) STRICT_MATCH = functools.partial(ZHA_ENTITIES.strict_match, Platform.CLIMATE)
MULTI_MATCH = functools.partial(ZHA_ENTITIES.multipass_match, Platform.CLIMATE) MULTI_MATCH = functools.partial(ZHA_ENTITIES.multipass_match, Platform.CLIMATE)
RUNNING_MODE = {0x00: HVAC_MODE_OFF, 0x03: HVAC_MODE_COOL, 0x04: HVAC_MODE_HEAT} RUNNING_MODE = {0x00: HVACMode.OFF, 0x03: HVACMode.COOL, 0x04: HVACMode.HEAT}
SEQ_OF_OPERATION = { SEQ_OF_OPERATION = {
0x00: (HVAC_MODE_OFF, HVAC_MODE_COOL), # cooling only 0x00: (HVACMode.OFF, HVACMode.COOL), # cooling only
0x01: (HVAC_MODE_OFF, HVAC_MODE_COOL), # cooling with reheat 0x01: (HVACMode.OFF, HVACMode.COOL), # cooling with reheat
0x02: (HVAC_MODE_OFF, HVAC_MODE_HEAT), # heating only 0x02: (HVACMode.OFF, HVACMode.HEAT), # heating only
0x03: (HVAC_MODE_OFF, HVAC_MODE_HEAT), # heating with reheat 0x03: (HVACMode.OFF, HVACMode.HEAT), # heating with reheat
# cooling and heating 4-pipes # cooling and heating 4-pipes
0x04: (HVAC_MODE_OFF, HVAC_MODE_HEAT_COOL, HVAC_MODE_COOL, HVAC_MODE_HEAT), 0x04: (HVACMode.OFF, HVACMode.HEAT_COOL, HVACMode.COOL, HVACMode.HEAT),
# cooling and heating 4-pipes # cooling and heating 4-pipes
0x05: (HVAC_MODE_OFF, HVAC_MODE_HEAT_COOL, HVAC_MODE_COOL, HVAC_MODE_HEAT), 0x05: (HVACMode.OFF, HVACMode.HEAT_COOL, HVACMode.COOL, HVACMode.HEAT),
0x06: (HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_OFF), # centralite specific 0x06: (HVACMode.COOL, HVACMode.HEAT, HVACMode.OFF), # centralite specific
0x07: (HVAC_MODE_HEAT_COOL, HVAC_MODE_OFF), # centralite specific 0x07: (HVACMode.HEAT_COOL, HVACMode.OFF), # centralite specific
} }
HVAC_MODE_2_SYSTEM = { HVAC_MODE_2_SYSTEM = {
HVAC_MODE_OFF: T.SystemMode.Off, HVACMode.OFF: T.SystemMode.Off,
HVAC_MODE_HEAT_COOL: T.SystemMode.Auto, HVACMode.HEAT_COOL: T.SystemMode.Auto,
HVAC_MODE_COOL: T.SystemMode.Cool, HVACMode.COOL: T.SystemMode.Cool,
HVAC_MODE_HEAT: T.SystemMode.Heat, HVACMode.HEAT: T.SystemMode.Heat,
HVAC_MODE_FAN_ONLY: T.SystemMode.Fan_only, HVACMode.FAN_ONLY: T.SystemMode.Fan_only,
HVAC_MODE_DRY: T.SystemMode.Dry, HVACMode.DRY: T.SystemMode.Dry,
} }
SYSTEM_MODE_2_HVAC = { SYSTEM_MODE_2_HVAC = {
T.SystemMode.Off: HVAC_MODE_OFF, T.SystemMode.Off: HVACMode.OFF,
T.SystemMode.Auto: HVAC_MODE_HEAT_COOL, T.SystemMode.Auto: HVACMode.HEAT_COOL,
T.SystemMode.Cool: HVAC_MODE_COOL, T.SystemMode.Cool: HVACMode.COOL,
T.SystemMode.Heat: HVAC_MODE_HEAT, T.SystemMode.Heat: HVACMode.HEAT,
T.SystemMode.Emergency_Heating: HVAC_MODE_HEAT, T.SystemMode.Emergency_Heating: HVACMode.HEAT,
T.SystemMode.Pre_cooling: HVAC_MODE_COOL, # this is 'precooling'. is it the same? T.SystemMode.Pre_cooling: HVACMode.COOL, # this is 'precooling'. is it the same?
T.SystemMode.Fan_only: HVAC_MODE_FAN_ONLY, T.SystemMode.Fan_only: HVACMode.FAN_ONLY,
T.SystemMode.Dry: HVAC_MODE_DRY, T.SystemMode.Dry: HVACMode.DRY,
T.SystemMode.Sleep: HVAC_MODE_OFF, T.SystemMode.Sleep: HVACMode.OFF,
} }
ZCL_TEMP = 100 ZCL_TEMP = 100
@ -210,7 +202,7 @@ class Thermostat(ZhaEntity, ClimateEntity):
return [FAN_AUTO, FAN_ON] return [FAN_AUTO, FAN_ON]
@property @property
def hvac_action(self) -> str | None: def hvac_action(self) -> HVACAction | None:
"""Return the current HVAC action.""" """Return the current HVAC action."""
if ( if (
self._thrm.pi_heating_demand is None self._thrm.pi_heating_demand is None
@ -220,7 +212,7 @@ class Thermostat(ZhaEntity, ClimateEntity):
return self._pi_demand_action return self._pi_demand_action
@property @property
def _rm_rs_action(self) -> str | None: def _rm_rs_action(self) -> HVACAction | None:
"""Return the current HVAC action based on running mode and running state.""" """Return the current HVAC action based on running mode and running state."""
if (running_state := self._thrm.running_state) is None: if (running_state := self._thrm.running_state) is None:
@ -228,47 +220,47 @@ class Thermostat(ZhaEntity, ClimateEntity):
if running_state & ( if running_state & (
T.RunningState.Heat_State_On | T.RunningState.Heat_2nd_Stage_On T.RunningState.Heat_State_On | T.RunningState.Heat_2nd_Stage_On
): ):
return CURRENT_HVAC_HEAT return HVACAction.HEATING
if running_state & ( if running_state & (
T.RunningState.Cool_State_On | T.RunningState.Cool_2nd_Stage_On T.RunningState.Cool_State_On | T.RunningState.Cool_2nd_Stage_On
): ):
return CURRENT_HVAC_COOL return HVACAction.COOLING
if running_state & ( if running_state & (
T.RunningState.Fan_State_On T.RunningState.Fan_State_On
| T.RunningState.Fan_2nd_Stage_On | T.RunningState.Fan_2nd_Stage_On
| T.RunningState.Fan_3rd_Stage_On | T.RunningState.Fan_3rd_Stage_On
): ):
return CURRENT_HVAC_FAN return HVACAction.FAN
if running_state & T.RunningState.Idle: if running_state & T.RunningState.Idle:
return CURRENT_HVAC_IDLE return HVACAction.IDLE
if self.hvac_mode != HVAC_MODE_OFF: if self.hvac_mode != HVACMode.OFF:
return CURRENT_HVAC_IDLE return HVACAction.IDLE
return CURRENT_HVAC_OFF return HVACAction.OFF
@property @property
def _pi_demand_action(self) -> str | None: def _pi_demand_action(self) -> HVACAction | None:
"""Return the current HVAC action based on pi_demands.""" """Return the current HVAC action based on pi_demands."""
heating_demand = self._thrm.pi_heating_demand heating_demand = self._thrm.pi_heating_demand
if heating_demand is not None and heating_demand > 0: if heating_demand is not None and heating_demand > 0:
return CURRENT_HVAC_HEAT return HVACAction.HEATING
cooling_demand = self._thrm.pi_cooling_demand cooling_demand = self._thrm.pi_cooling_demand
if cooling_demand is not None and cooling_demand > 0: if cooling_demand is not None and cooling_demand > 0:
return CURRENT_HVAC_COOL return HVACAction.COOLING
if self.hvac_mode != HVAC_MODE_OFF: if self.hvac_mode != HVACMode.OFF:
return CURRENT_HVAC_IDLE return HVACAction.IDLE
return CURRENT_HVAC_OFF return HVACAction.OFF
@property @property
def hvac_mode(self) -> str | None: def hvac_mode(self) -> HVACMode | None:
"""Return HVAC operation mode.""" """Return HVAC operation mode."""
return SYSTEM_MODE_2_HVAC.get(self._thrm.system_mode) return SYSTEM_MODE_2_HVAC.get(self._thrm.system_mode)
@property @property
def hvac_modes(self) -> tuple[str, ...]: def hvac_modes(self) -> list[HVACMode]:
"""Return the list of available HVAC operation modes.""" """Return the list of available HVAC operation modes."""
return SEQ_OF_OPERATION.get(self._thrm.ctrl_sequence_of_oper, (HVAC_MODE_OFF,)) return SEQ_OF_OPERATION.get(self._thrm.ctrl_sequence_of_oper, [HVACMode.OFF])
@property @property
def precision(self): def precision(self):
@ -289,7 +281,7 @@ class Thermostat(ZhaEntity, ClimateEntity):
def supported_features(self): def supported_features(self):
"""Return the list of supported features.""" """Return the list of supported features."""
features = self._supported_flags features = self._supported_flags
if HVAC_MODE_HEAT_COOL in self.hvac_modes: if HVACMode.HEAT_COOL in self.hvac_modes:
features |= ClimateEntityFeature.TARGET_TEMPERATURE_RANGE features |= ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
if self._fan is not None: if self._fan is not None:
self._supported_flags |= ClimateEntityFeature.FAN_MODE self._supported_flags |= ClimateEntityFeature.FAN_MODE
@ -299,12 +291,12 @@ class Thermostat(ZhaEntity, ClimateEntity):
def target_temperature(self): def target_temperature(self):
"""Return the temperature we try to reach.""" """Return the temperature we try to reach."""
temp = None temp = None
if self.hvac_mode == HVAC_MODE_COOL: if self.hvac_mode == HVACMode.COOL:
if self.preset_mode == PRESET_AWAY: if self.preset_mode == PRESET_AWAY:
temp = self._thrm.unoccupied_cooling_setpoint temp = self._thrm.unoccupied_cooling_setpoint
else: else:
temp = self._thrm.occupied_cooling_setpoint temp = self._thrm.occupied_cooling_setpoint
elif self.hvac_mode == HVAC_MODE_HEAT: elif self.hvac_mode == HVACMode.HEAT:
if self.preset_mode == PRESET_AWAY: if self.preset_mode == PRESET_AWAY:
temp = self._thrm.unoccupied_heating_setpoint temp = self._thrm.unoccupied_heating_setpoint
else: else:
@ -316,7 +308,7 @@ class Thermostat(ZhaEntity, ClimateEntity):
@property @property
def target_temperature_high(self): def target_temperature_high(self):
"""Return the upper bound temperature we try to reach.""" """Return the upper bound temperature we try to reach."""
if self.hvac_mode != HVAC_MODE_HEAT_COOL: if self.hvac_mode != HVACMode.HEAT_COOL:
return None return None
if self.preset_mode == PRESET_AWAY: if self.preset_mode == PRESET_AWAY:
temp = self._thrm.unoccupied_cooling_setpoint temp = self._thrm.unoccupied_cooling_setpoint
@ -331,7 +323,7 @@ class Thermostat(ZhaEntity, ClimateEntity):
@property @property
def target_temperature_low(self): def target_temperature_low(self):
"""Return the lower bound temperature we try to reach.""" """Return the lower bound temperature we try to reach."""
if self.hvac_mode != HVAC_MODE_HEAT_COOL: if self.hvac_mode != HVACMode.HEAT_COOL:
return None return None
if self.preset_mode == PRESET_AWAY: if self.preset_mode == PRESET_AWAY:
temp = self._thrm.unoccupied_heating_setpoint temp = self._thrm.unoccupied_heating_setpoint
@ -351,9 +343,9 @@ class Thermostat(ZhaEntity, ClimateEntity):
def max_temp(self) -> float: def max_temp(self) -> float:
"""Return the maximum temperature.""" """Return the maximum temperature."""
temps = [] temps = []
if HVAC_MODE_HEAT in self.hvac_modes: if HVACMode.HEAT in self.hvac_modes:
temps.append(self._thrm.max_heat_setpoint_limit) temps.append(self._thrm.max_heat_setpoint_limit)
if HVAC_MODE_COOL in self.hvac_modes: if HVACMode.COOL in self.hvac_modes:
temps.append(self._thrm.max_cool_setpoint_limit) temps.append(self._thrm.max_cool_setpoint_limit)
if not temps: if not temps:
@ -364,9 +356,9 @@ class Thermostat(ZhaEntity, ClimateEntity):
def min_temp(self) -> float: def min_temp(self) -> float:
"""Return the minimum temperature.""" """Return the minimum temperature."""
temps = [] temps = []
if HVAC_MODE_HEAT in self.hvac_modes: if HVACMode.HEAT in self.hvac_modes:
temps.append(self._thrm.min_heat_setpoint_limit) temps.append(self._thrm.min_heat_setpoint_limit)
if HVAC_MODE_COOL in self.hvac_modes: if HVACMode.COOL in self.hvac_modes:
temps.append(self._thrm.min_cool_setpoint_limit) temps.append(self._thrm.min_cool_setpoint_limit)
if not temps: if not temps:
@ -408,7 +400,7 @@ class Thermostat(ZhaEntity, ClimateEntity):
await self._fan.async_set_speed(mode) await self._fan.async_set_speed(mode)
async def async_set_hvac_mode(self, hvac_mode: str) -> None: async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set new target operation mode.""" """Set new target operation mode."""
if hvac_mode not in self.hvac_modes: if hvac_mode not in self.hvac_modes:
self.warning( self.warning(
@ -453,7 +445,7 @@ class Thermostat(ZhaEntity, ClimateEntity):
await self.async_set_hvac_mode(hvac_mode) await self.async_set_hvac_mode(hvac_mode)
thrm = self._thrm thrm = self._thrm
if self.hvac_mode == HVAC_MODE_HEAT_COOL: if self.hvac_mode == HVACMode.HEAT_COOL:
success = True success = True
if low_temp is not None: if low_temp is not None:
low_temp = int(low_temp * ZCL_TEMP) low_temp = int(low_temp * ZCL_TEMP)
@ -469,11 +461,11 @@ class Thermostat(ZhaEntity, ClimateEntity):
self.debug("Setting cooling %s setpoint: %s", low_temp, success) self.debug("Setting cooling %s setpoint: %s", low_temp, success)
elif temp is not None: elif temp is not None:
temp = int(temp * ZCL_TEMP) temp = int(temp * ZCL_TEMP)
if self.hvac_mode == HVAC_MODE_COOL: if self.hvac_mode == HVACMode.COOL:
success = await thrm.async_set_cooling_setpoint( success = await thrm.async_set_cooling_setpoint(
temp, self.preset_mode == PRESET_AWAY temp, self.preset_mode == PRESET_AWAY
) )
elif self.hvac_mode == HVAC_MODE_HEAT: elif self.hvac_mode == HVACMode.HEAT:
success = await thrm.async_set_heating_setpoint( success = await thrm.async_set_heating_setpoint(
temp, self.preset_mode == PRESET_AWAY temp, self.preset_mode == PRESET_AWAY
) )
@ -518,9 +510,9 @@ class SinopeTechnologiesThermostat(Thermostat):
running_mode = self._thrm.running_mode running_mode = self._thrm.running_mode
if running_mode == T.SystemMode.Heat: if running_mode == T.SystemMode.Heat:
return CURRENT_HVAC_HEAT return HVACAction.HEATING
if running_mode == T.SystemMode.Cool: if running_mode == T.SystemMode.Cool:
return CURRENT_HVAC_COOL return HVACAction.COOLING
running_state = self._thrm.running_state running_state = self._thrm.running_state
if running_state and running_state & ( if running_state and running_state & (
@ -528,10 +520,10 @@ class SinopeTechnologiesThermostat(Thermostat):
| T.RunningState.Fan_2nd_Stage_On | T.RunningState.Fan_2nd_Stage_On
| T.RunningState.Fan_3rd_Stage_On | T.RunningState.Fan_3rd_Stage_On
): ):
return CURRENT_HVAC_FAN return HVACAction.FAN
if self.hvac_mode != HVAC_MODE_OFF and running_mode == T.SystemMode.Off: if self.hvac_mode != HVACMode.OFF and running_mode == T.SystemMode.Off:
return CURRENT_HVAC_IDLE return HVACAction.IDLE
return CURRENT_HVAC_OFF return HVACAction.OFF
@callback @callback
def _async_update_time(self, timestamp=None) -> None: def _async_update_time(self, timestamp=None) -> None:
@ -623,9 +615,9 @@ class MoesThermostat(Thermostat):
self._supported_flags |= ClimateEntityFeature.PRESET_MODE self._supported_flags |= ClimateEntityFeature.PRESET_MODE
@property @property
def hvac_modes(self) -> tuple[str, ...]: def hvac_modes(self) -> list[HVACMode]:
"""Return only the heat mode, because the device can't be turned off.""" """Return only the heat mode, because the device can't be turned off."""
return (HVAC_MODE_HEAT,) return [HVACMode.HEAT]
async def async_attribute_updated(self, record): async def async_attribute_updated(self, record):
"""Handle attribute update from device.""" """Handle attribute update from device."""
@ -704,9 +696,9 @@ class BecaThermostat(Thermostat):
self._supported_flags |= ClimateEntityFeature.PRESET_MODE self._supported_flags |= ClimateEntityFeature.PRESET_MODE
@property @property
def hvac_modes(self) -> tuple[str, ...]: def hvac_modes(self) -> list[HVACMode]:
"""Return only the heat mode, because the device can't be turned off.""" """Return only the heat mode, because the device can't be turned off."""
return (HVAC_MODE_HEAT,) return [HVACMode.HEAT]
async def async_attribute_updated(self, record): async def async_attribute_updated(self, record):
"""Handle attribute update from device.""" """Handle attribute update from device."""
@ -766,9 +758,9 @@ class StelproFanHeater(Thermostat):
"""Stelpro Fan Heater implementation.""" """Stelpro Fan Heater implementation."""
@property @property
def hvac_modes(self) -> tuple[str, ...]: def hvac_modes(self) -> list[HVACMode]:
"""Return only the heat mode, because the device can't be turned off.""" """Return only the heat mode, because the device can't be turned off."""
return (HVAC_MODE_HEAT,) return [HVACMode.HEAT]
@STRICT_MATCH( @STRICT_MATCH(

View File

@ -1,5 +1,4 @@
"""Test zha climate.""" """Test zha climate."""
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
@ -21,22 +20,10 @@ from homeassistant.components.climate.const import (
ATTR_PRESET_MODE, ATTR_PRESET_MODE,
ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_HIGH,
ATTR_TARGET_TEMP_LOW, ATTR_TARGET_TEMP_LOW,
CURRENT_HVAC_COOL,
CURRENT_HVAC_FAN,
CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE,
CURRENT_HVAC_OFF,
DOMAIN as CLIMATE_DOMAIN, DOMAIN as CLIMATE_DOMAIN,
FAN_AUTO, FAN_AUTO,
FAN_LOW, FAN_LOW,
FAN_ON, FAN_ON,
HVAC_MODE_AUTO,
HVAC_MODE_COOL,
HVAC_MODE_DRY,
HVAC_MODE_FAN_ONLY,
HVAC_MODE_HEAT,
HVAC_MODE_HEAT_COOL,
HVAC_MODE_OFF,
PRESET_AWAY, PRESET_AWAY,
PRESET_BOOST, PRESET_BOOST,
PRESET_COMFORT, PRESET_COMFORT,
@ -46,6 +33,8 @@ from homeassistant.components.climate.const import (
SERVICE_SET_HVAC_MODE, SERVICE_SET_HVAC_MODE,
SERVICE_SET_PRESET_MODE, SERVICE_SET_PRESET_MODE,
SERVICE_SET_TEMPERATURE, SERVICE_SET_TEMPERATURE,
HVACAction,
HVACMode,
) )
from homeassistant.components.zha.climate import HVAC_MODE_2_SYSTEM, SEQ_OF_OPERATION from homeassistant.components.zha.climate import HVAC_MODE_2_SYSTEM, SEQ_OF_OPERATION
from homeassistant.components.zha.core.const import PRESET_COMPLEX, PRESET_SCHEDULE from homeassistant.components.zha.core.const import PRESET_COMPLEX, PRESET_SCHEDULE
@ -293,57 +282,57 @@ async def test_climate_hvac_action_running_state(hass, device_climate_sinope):
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.OFF
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_OFF assert hvac_sensor_state.state == HVACAction.OFF
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x001E: Thermostat.RunningMode.Off} hass, thrm_cluster, {0x001E: Thermostat.RunningMode.Off}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.OFF
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_OFF assert hvac_sensor_state.state == HVACAction.OFF
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x001C: Thermostat.SystemMode.Auto} hass, thrm_cluster, {0x001C: Thermostat.SystemMode.Auto}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.IDLE
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_IDLE assert hvac_sensor_state.state == HVACAction.IDLE
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x001E: Thermostat.RunningMode.Cool} hass, thrm_cluster, {0x001E: Thermostat.RunningMode.Cool}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_COOL assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.COOLING
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_COOL assert hvac_sensor_state.state == HVACAction.COOLING
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x001E: Thermostat.RunningMode.Heat} hass, thrm_cluster, {0x001E: Thermostat.RunningMode.Heat}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_HEAT assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.HEATING
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_HEAT assert hvac_sensor_state.state == HVACAction.HEATING
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x001E: Thermostat.RunningMode.Off} hass, thrm_cluster, {0x001E: Thermostat.RunningMode.Off}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.IDLE
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_IDLE assert hvac_sensor_state.state == HVACAction.IDLE
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x0029: Thermostat.RunningState.Fan_State_On} hass, thrm_cluster, {0x0029: Thermostat.RunningState.Fan_State_On}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_FAN assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.FAN
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_FAN assert hvac_sensor_state.state == HVACAction.FAN
async def test_climate_hvac_action_running_state_zen(hass, device_climate_zen): async def test_climate_hvac_action_running_state_zen(hass, device_climate_zen):
@ -362,73 +351,73 @@ async def test_climate_hvac_action_running_state_zen(hass, device_climate_zen):
hass, thrm_cluster, {0x0029: Thermostat.RunningState.Cool_2nd_Stage_On} hass, thrm_cluster, {0x0029: Thermostat.RunningState.Cool_2nd_Stage_On}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_COOL assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.COOLING
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_COOL assert hvac_sensor_state.state == HVACAction.COOLING
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x0029: Thermostat.RunningState.Fan_State_On} hass, thrm_cluster, {0x0029: Thermostat.RunningState.Fan_State_On}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_FAN assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.FAN
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_FAN assert hvac_sensor_state.state == HVACAction.FAN
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x0029: Thermostat.RunningState.Heat_2nd_Stage_On} hass, thrm_cluster, {0x0029: Thermostat.RunningState.Heat_2nd_Stage_On}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_HEAT assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.HEATING
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_HEAT assert hvac_sensor_state.state == HVACAction.HEATING
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x0029: Thermostat.RunningState.Fan_2nd_Stage_On} hass, thrm_cluster, {0x0029: Thermostat.RunningState.Fan_2nd_Stage_On}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_FAN assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.FAN
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_FAN assert hvac_sensor_state.state == HVACAction.FAN
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x0029: Thermostat.RunningState.Cool_State_On} hass, thrm_cluster, {0x0029: Thermostat.RunningState.Cool_State_On}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_COOL assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.COOLING
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_COOL assert hvac_sensor_state.state == HVACAction.COOLING
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x0029: Thermostat.RunningState.Fan_3rd_Stage_On} hass, thrm_cluster, {0x0029: Thermostat.RunningState.Fan_3rd_Stage_On}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_FAN assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.FAN
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_FAN assert hvac_sensor_state.state == HVACAction.FAN
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x0029: Thermostat.RunningState.Heat_State_On} hass, thrm_cluster, {0x0029: Thermostat.RunningState.Heat_State_On}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_HEAT assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.HEATING
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_HEAT assert hvac_sensor_state.state == HVACAction.HEATING
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x0029: Thermostat.RunningState.Idle} hass, thrm_cluster, {0x0029: Thermostat.RunningState.Idle}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.OFF
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_OFF assert hvac_sensor_state.state == HVACAction.OFF
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x001C: Thermostat.SystemMode.Heat} hass, thrm_cluster, {0x001C: Thermostat.SystemMode.Heat}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.IDLE
hvac_sensor_state = hass.states.get(sensor_entity_id) hvac_sensor_state = hass.states.get(sensor_entity_id)
assert hvac_sensor_state.state == CURRENT_HVAC_IDLE assert hvac_sensor_state.state == HVACAction.IDLE
async def test_climate_hvac_action_pi_demand(hass, device_climate): async def test_climate_hvac_action_pi_demand(hass, device_climate):
@ -442,40 +431,40 @@ async def test_climate_hvac_action_pi_demand(hass, device_climate):
await send_attributes_report(hass, thrm_cluster, {0x0007: 10}) await send_attributes_report(hass, thrm_cluster, {0x0007: 10})
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_COOL assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.COOLING
await send_attributes_report(hass, thrm_cluster, {0x0008: 20}) await send_attributes_report(hass, thrm_cluster, {0x0008: 20})
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_HEAT assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.HEATING
await send_attributes_report(hass, thrm_cluster, {0x0007: 0}) await send_attributes_report(hass, thrm_cluster, {0x0007: 0})
await send_attributes_report(hass, thrm_cluster, {0x0008: 0}) await send_attributes_report(hass, thrm_cluster, {0x0008: 0})
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.OFF
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x001C: Thermostat.SystemMode.Heat} hass, thrm_cluster, {0x001C: Thermostat.SystemMode.Heat}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.IDLE
await send_attributes_report( await send_attributes_report(
hass, thrm_cluster, {0x001C: Thermostat.SystemMode.Cool} hass, thrm_cluster, {0x001C: Thermostat.SystemMode.Cool}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.IDLE
@pytest.mark.parametrize( @pytest.mark.parametrize(
"sys_mode, hvac_mode", "sys_mode, hvac_mode",
( (
(Thermostat.SystemMode.Auto, HVAC_MODE_HEAT_COOL), (Thermostat.SystemMode.Auto, HVACMode.HEAT_COOL),
(Thermostat.SystemMode.Cool, HVAC_MODE_COOL), (Thermostat.SystemMode.Cool, HVACMode.COOL),
(Thermostat.SystemMode.Heat, HVAC_MODE_HEAT), (Thermostat.SystemMode.Heat, HVACMode.HEAT),
(Thermostat.SystemMode.Pre_cooling, HVAC_MODE_COOL), (Thermostat.SystemMode.Pre_cooling, HVACMode.COOL),
(Thermostat.SystemMode.Fan_only, HVAC_MODE_FAN_ONLY), (Thermostat.SystemMode.Fan_only, HVACMode.FAN_ONLY),
(Thermostat.SystemMode.Dry, HVAC_MODE_DRY), (Thermostat.SystemMode.Dry, HVACMode.DRY),
), ),
) )
async def test_hvac_mode(hass, device_climate, sys_mode, hvac_mode): async def test_hvac_mode(hass, device_climate, sys_mode, hvac_mode):
@ -485,7 +474,7 @@ async def test_hvac_mode(hass, device_climate, sys_mode, hvac_mode):
entity_id = await find_entity_id(Platform.CLIMATE, device_climate, hass) entity_id = await find_entity_id(Platform.CLIMATE, device_climate, hass)
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.state == HVAC_MODE_OFF assert state.state == HVACMode.OFF
await send_attributes_report(hass, thrm_cluster, {0x001C: sys_mode}) await send_attributes_report(hass, thrm_cluster, {0x001C: sys_mode})
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
@ -495,7 +484,7 @@ async def test_hvac_mode(hass, device_climate, sys_mode, hvac_mode):
hass, thrm_cluster, {0x001C: Thermostat.SystemMode.Off} hass, thrm_cluster, {0x001C: Thermostat.SystemMode.Off}
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.state == HVAC_MODE_OFF assert state.state == HVACMode.OFF
await send_attributes_report(hass, thrm_cluster, {0x001C: 0xFF}) await send_attributes_report(hass, thrm_cluster, {0x001C: 0xFF})
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
@ -505,13 +494,13 @@ async def test_hvac_mode(hass, device_climate, sys_mode, hvac_mode):
@pytest.mark.parametrize( @pytest.mark.parametrize(
"seq_of_op, modes", "seq_of_op, modes",
( (
(0xFF, {HVAC_MODE_OFF}), (0xFF, {HVACMode.OFF}),
(0x00, {HVAC_MODE_OFF, HVAC_MODE_COOL}), (0x00, {HVACMode.OFF, HVACMode.COOL}),
(0x01, {HVAC_MODE_OFF, HVAC_MODE_COOL}), (0x01, {HVACMode.OFF, HVACMode.COOL}),
(0x02, {HVAC_MODE_OFF, HVAC_MODE_HEAT}), (0x02, {HVACMode.OFF, HVACMode.HEAT}),
(0x03, {HVAC_MODE_OFF, HVAC_MODE_HEAT}), (0x03, {HVACMode.OFF, HVACMode.HEAT}),
(0x04, {HVAC_MODE_OFF, HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_HEAT_COOL}), (0x04, {HVACMode.OFF, HVACMode.COOL, HVACMode.HEAT, HVACMode.HEAT_COOL}),
(0x05, {HVAC_MODE_OFF, HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_HEAT_COOL}), (0x05, {HVACMode.OFF, HVACMode.COOL, HVACMode.HEAT, HVACMode.HEAT_COOL}),
), ),
) )
async def test_hvac_modes(hass, device_climate_mock, seq_of_op, modes): async def test_hvac_modes(hass, device_climate_mock, seq_of_op, modes):
@ -639,12 +628,12 @@ async def test_target_temperature_low(
@pytest.mark.parametrize( @pytest.mark.parametrize(
"hvac_mode, sys_mode", "hvac_mode, sys_mode",
( (
(HVAC_MODE_AUTO, None), (HVACMode.AUTO, None),
(HVAC_MODE_COOL, Thermostat.SystemMode.Cool), (HVACMode.COOL, Thermostat.SystemMode.Cool),
(HVAC_MODE_DRY, None), (HVACMode.DRY, None),
(HVAC_MODE_FAN_ONLY, None), (HVACMode.FAN_ONLY, None),
(HVAC_MODE_HEAT, Thermostat.SystemMode.Heat), (HVACMode.HEAT, Thermostat.SystemMode.Heat),
(HVAC_MODE_HEAT_COOL, Thermostat.SystemMode.Auto), (HVACMode.HEAT_COOL, Thermostat.SystemMode.Auto),
), ),
) )
async def test_set_hvac_mode(hass, device_climate, hvac_mode, sys_mode): async def test_set_hvac_mode(hass, device_climate, hvac_mode, sys_mode):
@ -654,7 +643,7 @@ async def test_set_hvac_mode(hass, device_climate, hvac_mode, sys_mode):
entity_id = await find_entity_id(Platform.CLIMATE, device_climate, hass) entity_id = await find_entity_id(Platform.CLIMATE, device_climate, hass)
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.state == HVAC_MODE_OFF assert state.state == HVACMode.OFF
await hass.services.async_call( await hass.services.async_call(
CLIMATE_DOMAIN, CLIMATE_DOMAIN,
@ -671,18 +660,18 @@ async def test_set_hvac_mode(hass, device_climate, hvac_mode, sys_mode):
} }
else: else:
assert thrm_cluster.write_attributes.call_count == 0 assert thrm_cluster.write_attributes.call_count == 0
assert state.state == HVAC_MODE_OFF assert state.state == HVACMode.OFF
# turn off # turn off
thrm_cluster.write_attributes.reset_mock() thrm_cluster.write_attributes.reset_mock()
await hass.services.async_call( await hass.services.async_call(
CLIMATE_DOMAIN, CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE, SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVAC_MODE_OFF}, {ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.OFF},
blocking=True, blocking=True,
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.state == HVAC_MODE_OFF assert state.state == HVACMode.OFF
assert thrm_cluster.write_attributes.call_count == 1 assert thrm_cluster.write_attributes.call_count == 1
assert thrm_cluster.write_attributes.call_args[0][0] == { assert thrm_cluster.write_attributes.call_args[0][0] == {
"system_mode": Thermostat.SystemMode.Off "system_mode": Thermostat.SystemMode.Off
@ -795,21 +784,21 @@ async def test_set_temperature_hvac_mode(hass, device_climate):
thrm_cluster = device_climate.device.endpoints[1].thermostat thrm_cluster = device_climate.device.endpoints[1].thermostat
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.state == HVAC_MODE_OFF assert state.state == HVACMode.OFF
await hass.services.async_call( await hass.services.async_call(
CLIMATE_DOMAIN, CLIMATE_DOMAIN,
SERVICE_SET_TEMPERATURE, SERVICE_SET_TEMPERATURE,
{ {
ATTR_ENTITY_ID: entity_id, ATTR_ENTITY_ID: entity_id,
ATTR_HVAC_MODE: HVAC_MODE_HEAT_COOL, ATTR_HVAC_MODE: HVACMode.HEAT_COOL,
ATTR_TEMPERATURE: 20, ATTR_TEMPERATURE: 20,
}, },
blocking=True, blocking=True,
) )
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.state == HVAC_MODE_HEAT_COOL assert state.state == HVACMode.HEAT_COOL
assert thrm_cluster.write_attributes.await_count == 1 assert thrm_cluster.write_attributes.await_count == 1
assert thrm_cluster.write_attributes.call_args[0][0] == { assert thrm_cluster.write_attributes.call_args[0][0] == {
"system_mode": Thermostat.SystemMode.Auto "system_mode": Thermostat.SystemMode.Auto
@ -835,7 +824,7 @@ async def test_set_temperature_heat_cool(hass, device_climate_mock):
thrm_cluster = device_climate.device.endpoints[1].thermostat thrm_cluster = device_climate.device.endpoints[1].thermostat
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.state == HVAC_MODE_HEAT_COOL assert state.state == HVACMode.HEAT_COOL
await hass.services.async_call( await hass.services.async_call(
CLIMATE_DOMAIN, CLIMATE_DOMAIN,
@ -921,7 +910,7 @@ async def test_set_temperature_heat(hass, device_climate_mock):
thrm_cluster = device_climate.device.endpoints[1].thermostat thrm_cluster = device_climate.device.endpoints[1].thermostat
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.state == HVAC_MODE_HEAT assert state.state == HVACMode.HEAT
await hass.services.async_call( await hass.services.async_call(
CLIMATE_DOMAIN, CLIMATE_DOMAIN,
@ -1000,7 +989,7 @@ async def test_set_temperature_cool(hass, device_climate_mock):
thrm_cluster = device_climate.device.endpoints[1].thermostat thrm_cluster = device_climate.device.endpoints[1].thermostat
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.state == HVAC_MODE_COOL assert state.state == HVACMode.COOL
await hass.services.async_call( await hass.services.async_call(
CLIMATE_DOMAIN, CLIMATE_DOMAIN,
@ -1083,7 +1072,7 @@ async def test_set_temperature_wrong_mode(hass, device_climate_mock):
thrm_cluster = device_climate.device.endpoints[1].thermostat thrm_cluster = device_climate.device.endpoints[1].thermostat
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state.state == HVAC_MODE_DRY assert state.state == HVACMode.DRY
await hass.services.async_call( await hass.services.async_call(
CLIMATE_DOMAIN, CLIMATE_DOMAIN,