mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Increase nest climate test coverage (#44146)
This commit is contained in:
parent
05f9fb80c8
commit
1a8123aba6
@ -580,7 +580,6 @@ omit =
|
||||
homeassistant/components/nest/camera_legacy.py
|
||||
homeassistant/components/nest/climate.py
|
||||
homeassistant/components/nest/climate_legacy.py
|
||||
homeassistant/components/nest/climate_sdm.py
|
||||
homeassistant/components/nest/local_auth.py
|
||||
homeassistant/components/nest/sensor.py
|
||||
homeassistant/components/nest/sensor_legacy.py
|
||||
|
@ -186,8 +186,6 @@ class ThermostatEntity(ClimateEntity):
|
||||
@property
|
||||
def _target_temperature_trait(self):
|
||||
"""Return the correct trait with a target temp depending on mode."""
|
||||
if not self.hvac_mode:
|
||||
return None
|
||||
if self.preset_mode == PRESET_ECO:
|
||||
if ThermostatEcoTrait.NAME in self._device.traits:
|
||||
return self._device.traits[ThermostatEcoTrait.NAME]
|
||||
@ -225,8 +223,6 @@ class ThermostatEntity(ClimateEntity):
|
||||
@property
|
||||
def hvac_action(self):
|
||||
"""Return the current HVAC action (heating, cooling)."""
|
||||
if ThermostatHvacTrait.NAME not in self._device.traits:
|
||||
return None
|
||||
trait = self._device.traits[ThermostatHvacTrait.NAME]
|
||||
if trait.status in THERMOSTAT_HVAC_STATUS_MAP:
|
||||
return THERMOSTAT_HVAC_STATUS_MAP[trait.status]
|
||||
@ -262,9 +258,10 @@ class ThermostatEntity(ClimateEntity):
|
||||
@property
|
||||
def fan_modes(self):
|
||||
"""Return the list of available fan modes."""
|
||||
modes = []
|
||||
if FanTrait.NAME in self._device.traits:
|
||||
return list(FAN_INV_MODE_MAP)
|
||||
return []
|
||||
modes = list(FAN_INV_MODE_MAP)
|
||||
return modes
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
@ -290,12 +287,8 @@ class ThermostatEntity(ClimateEntity):
|
||||
async def async_set_hvac_mode(self, hvac_mode):
|
||||
"""Set new target hvac mode."""
|
||||
if hvac_mode not in self.hvac_modes:
|
||||
return
|
||||
if hvac_mode not in THERMOSTAT_INV_MODE_MAP:
|
||||
return
|
||||
raise ValueError(f"Unsupported hvac_mode '{hvac_mode}'")
|
||||
api_mode = THERMOSTAT_INV_MODE_MAP[hvac_mode]
|
||||
if ThermostatModeTrait.NAME not in self._device.traits:
|
||||
return
|
||||
trait = self._device.traits[ThermostatModeTrait.NAME]
|
||||
await trait.set_mode(api_mode)
|
||||
|
||||
@ -318,17 +311,13 @@ class ThermostatEntity(ClimateEntity):
|
||||
async def async_set_preset_mode(self, preset_mode):
|
||||
"""Set new target preset mode."""
|
||||
if preset_mode not in self.preset_modes:
|
||||
return
|
||||
if ThermostatEcoTrait.NAME not in self._device.traits:
|
||||
return
|
||||
raise ValueError(f"Unsupported preset_mode '{preset_mode}'")
|
||||
trait = self._device.traits[ThermostatEcoTrait.NAME]
|
||||
await trait.set_mode(PRESET_INV_MODE_MAP[preset_mode])
|
||||
|
||||
async def async_set_fan_mode(self, fan_mode):
|
||||
"""Set new target fan mode."""
|
||||
if fan_mode not in self.fan_modes:
|
||||
return
|
||||
if FanTrait.NAME not in self._device.traits:
|
||||
return
|
||||
raise ValueError(f"Unsupported fan__mode '{fan_mode}'")
|
||||
trait = self._device.traits[FanTrait.NAME]
|
||||
await trait.set_timer(FAN_INV_MODE_MAP[fan_mode])
|
||||
|
@ -7,6 +7,7 @@ pubsub subscriber.
|
||||
|
||||
from google_nest_sdm.device import Device
|
||||
from google_nest_sdm.event import EventMessage
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.climate.const import (
|
||||
ATTR_CURRENT_TEMPERATURE,
|
||||
@ -21,14 +22,17 @@ from homeassistant.components.climate.const import (
|
||||
CURRENT_HVAC_COOL,
|
||||
CURRENT_HVAC_HEAT,
|
||||
CURRENT_HVAC_OFF,
|
||||
FAN_LOW,
|
||||
FAN_OFF,
|
||||
FAN_ON,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_DRY,
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_HEAT_COOL,
|
||||
HVAC_MODE_OFF,
|
||||
PRESET_ECO,
|
||||
PRESET_NONE,
|
||||
PRESET_SLEEP,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE
|
||||
|
||||
@ -450,6 +454,34 @@ async def test_thermostat_set_hvac_mode(hass, auth):
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_HEAT
|
||||
|
||||
|
||||
async def test_thermostat_invalid_hvac_mode(hass, auth):
|
||||
"""Test setting an hvac_mode that is not supported."""
|
||||
await setup_climate(
|
||||
hass,
|
||||
{
|
||||
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
||||
"sdm.devices.traits.ThermostatMode": {
|
||||
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
||||
"mode": "OFF",
|
||||
},
|
||||
},
|
||||
auth=auth,
|
||||
)
|
||||
|
||||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_OFF
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await common.async_set_hvac_mode(hass, HVAC_MODE_DRY)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert thermostat.state == HVAC_MODE_OFF
|
||||
assert auth.method is None # No communication with API
|
||||
|
||||
|
||||
async def test_thermostat_set_eco_preset(hass, auth):
|
||||
"""Test a thermostat put into eco mode."""
|
||||
subscriber = await setup_climate(
|
||||
@ -782,6 +814,53 @@ async def test_thermostat_fan_empty(hass):
|
||||
assert ATTR_FAN_MODE not in thermostat.attributes
|
||||
assert ATTR_FAN_MODES not in thermostat.attributes
|
||||
|
||||
# Ignores set_fan_mode since it is lacking SUPPORT_FAN_MODE
|
||||
await common.async_set_fan_mode(hass, FAN_ON)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert ATTR_FAN_MODE not in thermostat.attributes
|
||||
assert ATTR_FAN_MODES not in thermostat.attributes
|
||||
|
||||
|
||||
async def test_thermostat_invalid_fan_mode(hass):
|
||||
"""Test setting a fan mode that is not supported."""
|
||||
await setup_climate(
|
||||
hass,
|
||||
{
|
||||
"sdm.devices.traits.Fan": {
|
||||
"timerMode": "ON",
|
||||
"timerTimeout": "2019-05-10T03:22:54Z",
|
||||
},
|
||||
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
||||
"sdm.devices.traits.ThermostatMode": {
|
||||
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
||||
"mode": "OFF",
|
||||
},
|
||||
"sdm.devices.traits.Temperature": {
|
||||
"ambientTemperatureCelsius": 16.2,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_OFF
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
|
||||
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] == 16.2
|
||||
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_HEAT_COOL,
|
||||
HVAC_MODE_OFF,
|
||||
}
|
||||
assert thermostat.attributes[ATTR_FAN_MODE] == FAN_ON
|
||||
assert thermostat.attributes[ATTR_FAN_MODES] == [FAN_ON, FAN_OFF]
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await common.async_set_fan_mode(hass, FAN_LOW)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
async def test_thermostat_target_temp(hass, auth):
|
||||
"""Test a thermostat changing hvac modes and affected on target temps."""
|
||||
@ -843,3 +922,208 @@ async def test_thermostat_target_temp(hass, auth):
|
||||
assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] == 22.0
|
||||
assert thermostat.attributes[ATTR_TARGET_TEMP_HIGH] == 28.0
|
||||
assert thermostat.attributes[ATTR_TEMPERATURE] is None
|
||||
|
||||
|
||||
async def test_thermostat_missing_mode_traits(hass):
|
||||
"""Test a thermostat missing many thermostat traits in api response."""
|
||||
await setup_climate(
|
||||
hass,
|
||||
{
|
||||
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
||||
},
|
||||
)
|
||||
|
||||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_OFF
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
|
||||
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] is None
|
||||
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == set()
|
||||
assert ATTR_TEMPERATURE not in thermostat.attributes
|
||||
assert ATTR_TARGET_TEMP_LOW not in thermostat.attributes
|
||||
assert ATTR_TARGET_TEMP_HIGH not in thermostat.attributes
|
||||
assert ATTR_PRESET_MODE not in thermostat.attributes
|
||||
assert ATTR_PRESET_MODES not in thermostat.attributes
|
||||
assert ATTR_FAN_MODE not in thermostat.attributes
|
||||
assert ATTR_FAN_MODES not in thermostat.attributes
|
||||
|
||||
await common.async_set_temperature(hass, temperature=24.0)
|
||||
await hass.async_block_till_done()
|
||||
assert ATTR_TEMPERATURE not in thermostat.attributes
|
||||
|
||||
await common.async_set_preset_mode(hass, PRESET_ECO)
|
||||
await hass.async_block_till_done()
|
||||
assert ATTR_PRESET_MODE not in thermostat.attributes
|
||||
|
||||
|
||||
async def test_thermostat_missing_temperature_trait(hass):
|
||||
"""Test a thermostat missing many thermostat traits in api response."""
|
||||
await setup_climate(
|
||||
hass,
|
||||
{
|
||||
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
||||
"sdm.devices.traits.ThermostatMode": {
|
||||
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
||||
"mode": "HEAT",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_HEAT
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
|
||||
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] is None
|
||||
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_HEAT_COOL,
|
||||
HVAC_MODE_OFF,
|
||||
}
|
||||
assert thermostat.attributes[ATTR_TEMPERATURE] is None
|
||||
assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] is None
|
||||
assert thermostat.attributes[ATTR_TARGET_TEMP_HIGH] is None
|
||||
assert ATTR_PRESET_MODE not in thermostat.attributes
|
||||
assert ATTR_PRESET_MODES not in thermostat.attributes
|
||||
assert ATTR_FAN_MODE not in thermostat.attributes
|
||||
assert ATTR_FAN_MODES not in thermostat.attributes
|
||||
|
||||
await common.async_set_temperature(hass, temperature=24.0)
|
||||
await hass.async_block_till_done()
|
||||
assert thermostat.attributes[ATTR_TEMPERATURE] is None
|
||||
|
||||
|
||||
async def test_thermostat_unexpected_hvac_status(hass):
|
||||
"""Test a thermostat missing many thermostat traits in api response."""
|
||||
await setup_climate(
|
||||
hass,
|
||||
{
|
||||
"sdm.devices.traits.ThermostatHvac": {"status": "UNEXPECTED"},
|
||||
},
|
||||
)
|
||||
|
||||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_OFF
|
||||
assert ATTR_HVAC_ACTION not in thermostat.attributes
|
||||
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] is None
|
||||
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == set()
|
||||
assert ATTR_TEMPERATURE not in thermostat.attributes
|
||||
assert ATTR_TARGET_TEMP_LOW not in thermostat.attributes
|
||||
assert ATTR_TARGET_TEMP_HIGH not in thermostat.attributes
|
||||
assert ATTR_PRESET_MODE not in thermostat.attributes
|
||||
assert ATTR_PRESET_MODES not in thermostat.attributes
|
||||
assert ATTR_FAN_MODE not in thermostat.attributes
|
||||
assert ATTR_FAN_MODES not in thermostat.attributes
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await common.async_set_hvac_mode(hass, HVAC_MODE_DRY)
|
||||
await hass.async_block_till_done()
|
||||
assert thermostat.state == HVAC_MODE_OFF
|
||||
|
||||
|
||||
async def test_thermostat_missing_set_point(hass):
|
||||
"""Test a thermostat missing many thermostat traits in api response."""
|
||||
await setup_climate(
|
||||
hass,
|
||||
{
|
||||
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
||||
"sdm.devices.traits.ThermostatMode": {
|
||||
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
||||
"mode": "HEATCOOL",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_HEAT_COOL
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
|
||||
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] is None
|
||||
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_HEAT_COOL,
|
||||
HVAC_MODE_OFF,
|
||||
}
|
||||
assert thermostat.attributes[ATTR_TEMPERATURE] is None
|
||||
assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] is None
|
||||
assert thermostat.attributes[ATTR_TARGET_TEMP_HIGH] is None
|
||||
assert ATTR_PRESET_MODE not in thermostat.attributes
|
||||
assert ATTR_PRESET_MODES not in thermostat.attributes
|
||||
assert ATTR_FAN_MODE not in thermostat.attributes
|
||||
assert ATTR_FAN_MODES not in thermostat.attributes
|
||||
|
||||
|
||||
async def test_thermostat_unexepected_hvac_mode(hass):
|
||||
"""Test a thermostat missing many thermostat traits in api response."""
|
||||
await setup_climate(
|
||||
hass,
|
||||
{
|
||||
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
||||
"sdm.devices.traits.ThermostatMode": {
|
||||
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF", "UNEXPECTED"],
|
||||
"mode": "UNEXPECTED",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_OFF
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
|
||||
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] is None
|
||||
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_HEAT_COOL,
|
||||
HVAC_MODE_OFF,
|
||||
}
|
||||
assert thermostat.attributes[ATTR_TEMPERATURE] is None
|
||||
assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] is None
|
||||
assert thermostat.attributes[ATTR_TARGET_TEMP_HIGH] is None
|
||||
assert ATTR_PRESET_MODE not in thermostat.attributes
|
||||
assert ATTR_PRESET_MODES not in thermostat.attributes
|
||||
assert ATTR_FAN_MODE not in thermostat.attributes
|
||||
assert ATTR_FAN_MODES not in thermostat.attributes
|
||||
|
||||
|
||||
async def test_thermostat_invalid_set_preset_mode(hass, auth):
|
||||
"""Test a thermostat set with an invalid preset mode."""
|
||||
await setup_climate(
|
||||
hass,
|
||||
{
|
||||
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
||||
"sdm.devices.traits.ThermostatEco": {
|
||||
"availableModes": ["MANUAL_ECO", "OFF"],
|
||||
"mode": "OFF",
|
||||
"heatCelsius": 15.0,
|
||||
"coolCelsius": 28.0,
|
||||
},
|
||||
},
|
||||
auth=auth,
|
||||
)
|
||||
|
||||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_OFF
|
||||
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_NONE
|
||||
assert thermostat.attributes[ATTR_PRESET_MODES] == [PRESET_ECO, PRESET_NONE]
|
||||
|
||||
# Set preset mode that is invalid
|
||||
with pytest.raises(ValueError):
|
||||
await common.async_set_preset_mode(hass, PRESET_SLEEP)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# No RPC sent
|
||||
assert auth.method is None
|
||||
|
||||
# Preset is unchanged
|
||||
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_NONE
|
||||
assert thermostat.attributes[ATTR_PRESET_MODES] == [PRESET_ECO, PRESET_NONE]
|
||||
|
Loading…
x
Reference in New Issue
Block a user