Fix fan support in nest, removing FAN_ONLY which isn't supported (#73422)
* Fix fan support in nest, removing FAN_ONLY which isn't supported * Revert change to make supported features dynamic
This commit is contained in:
parent
e08465fe8c
commit
0b7a030bd4
2 changed files with 119 additions and 113 deletions
|
@ -33,15 +33,15 @@ from homeassistant.components.climate.const import (
|
|||
FAN_ON,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_DRY,
|
||||
HVAC_MODE_FAN_ONLY,
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_HEAT_COOL,
|
||||
HVAC_MODE_OFF,
|
||||
PRESET_ECO,
|
||||
PRESET_NONE,
|
||||
PRESET_SLEEP,
|
||||
ClimateEntityFeature,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE
|
||||
from homeassistant.const import ATTR_SUPPORTED_FEATURES, ATTR_TEMPERATURE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
|
@ -794,7 +794,7 @@ async def test_thermostat_fan_off(
|
|||
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
||||
"sdm.devices.traits.ThermostatMode": {
|
||||
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
||||
"mode": "OFF",
|
||||
"mode": "COOL",
|
||||
},
|
||||
"sdm.devices.traits.Temperature": {
|
||||
"ambientTemperatureCelsius": 16.2,
|
||||
|
@ -806,18 +806,22 @@ async def test_thermostat_fan_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.state == HVAC_MODE_COOL
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE
|
||||
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_FAN_ONLY,
|
||||
HVAC_MODE_OFF,
|
||||
}
|
||||
assert thermostat.attributes[ATTR_FAN_MODE] == FAN_OFF
|
||||
assert thermostat.attributes[ATTR_FAN_MODES] == [FAN_ON, FAN_OFF]
|
||||
assert thermostat.attributes[ATTR_SUPPORTED_FEATURES] == (
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
| ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
|
||||
| ClimateEntityFeature.FAN_MODE
|
||||
)
|
||||
|
||||
|
||||
async def test_thermostat_fan_on(
|
||||
|
@ -837,7 +841,7 @@ async def test_thermostat_fan_on(
|
|||
},
|
||||
"sdm.devices.traits.ThermostatMode": {
|
||||
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
||||
"mode": "OFF",
|
||||
"mode": "COOL",
|
||||
},
|
||||
"sdm.devices.traits.Temperature": {
|
||||
"ambientTemperatureCelsius": 16.2,
|
||||
|
@ -849,18 +853,22 @@ async def test_thermostat_fan_on(
|
|||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_FAN_ONLY
|
||||
assert thermostat.state == HVAC_MODE_COOL
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE
|
||||
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_FAN_ONLY,
|
||||
HVAC_MODE_OFF,
|
||||
}
|
||||
assert thermostat.attributes[ATTR_FAN_MODE] == FAN_ON
|
||||
assert thermostat.attributes[ATTR_FAN_MODES] == [FAN_ON, FAN_OFF]
|
||||
assert thermostat.attributes[ATTR_SUPPORTED_FEATURES] == (
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
| ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
|
||||
| ClimateEntityFeature.FAN_MODE
|
||||
)
|
||||
|
||||
|
||||
async def test_thermostat_cool_with_fan(
|
||||
|
@ -895,11 +903,15 @@ async def test_thermostat_cool_with_fan(
|
|||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_HEAT_COOL,
|
||||
HVAC_MODE_FAN_ONLY,
|
||||
HVAC_MODE_OFF,
|
||||
}
|
||||
assert thermostat.attributes[ATTR_FAN_MODE] == FAN_ON
|
||||
assert thermostat.attributes[ATTR_FAN_MODES] == [FAN_ON, FAN_OFF]
|
||||
assert thermostat.attributes[ATTR_SUPPORTED_FEATURES] == (
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
| ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
|
||||
| ClimateEntityFeature.FAN_MODE
|
||||
)
|
||||
|
||||
|
||||
async def test_thermostat_set_fan(
|
||||
|
@ -907,6 +919,68 @@ async def test_thermostat_set_fan(
|
|||
setup_platform: PlatformSetup,
|
||||
auth: FakeAuth,
|
||||
create_device: CreateDevice,
|
||||
) -> None:
|
||||
"""Test a thermostat enabling the fan."""
|
||||
create_device.create(
|
||||
{
|
||||
"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": "HEAT",
|
||||
},
|
||||
}
|
||||
)
|
||||
await setup_platform()
|
||||
|
||||
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_FAN_MODE] == FAN_ON
|
||||
assert thermostat.attributes[ATTR_FAN_MODES] == [FAN_ON, FAN_OFF]
|
||||
assert thermostat.attributes[ATTR_SUPPORTED_FEATURES] == (
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
| ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
|
||||
| ClimateEntityFeature.FAN_MODE
|
||||
)
|
||||
|
||||
# Turn off fan mode
|
||||
await common.async_set_fan_mode(hass, FAN_OFF)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert auth.method == "post"
|
||||
assert auth.url == DEVICE_COMMAND
|
||||
assert auth.json == {
|
||||
"command": "sdm.devices.commands.Fan.SetTimer",
|
||||
"params": {"timerMode": "OFF"},
|
||||
}
|
||||
|
||||
# Turn on fan mode
|
||||
await common.async_set_fan_mode(hass, FAN_ON)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert auth.method == "post"
|
||||
assert auth.url == DEVICE_COMMAND
|
||||
assert auth.json == {
|
||||
"command": "sdm.devices.commands.Fan.SetTimer",
|
||||
"params": {
|
||||
"duration": "43200s",
|
||||
"timerMode": "ON",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
async def test_thermostat_set_fan_when_off(
|
||||
hass: HomeAssistant,
|
||||
setup_platform: PlatformSetup,
|
||||
auth: FakeAuth,
|
||||
create_device: CreateDevice,
|
||||
) -> None:
|
||||
"""Test a thermostat enabling the fan."""
|
||||
create_device.create(
|
||||
|
@ -929,34 +1003,18 @@ async def test_thermostat_set_fan(
|
|||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_FAN_ONLY
|
||||
assert thermostat.state == HVAC_MODE_OFF
|
||||
assert thermostat.attributes[ATTR_FAN_MODE] == FAN_ON
|
||||
assert thermostat.attributes[ATTR_FAN_MODES] == [FAN_ON, FAN_OFF]
|
||||
assert thermostat.attributes[ATTR_SUPPORTED_FEATURES] == (
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
| ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
|
||||
| ClimateEntityFeature.FAN_MODE
|
||||
)
|
||||
|
||||
# Turn off fan mode
|
||||
await common.async_set_fan_mode(hass, FAN_OFF)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert auth.method == "post"
|
||||
assert auth.url == DEVICE_COMMAND
|
||||
assert auth.json == {
|
||||
"command": "sdm.devices.commands.Fan.SetTimer",
|
||||
"params": {"timerMode": "OFF"},
|
||||
}
|
||||
|
||||
# Turn on fan mode
|
||||
await common.async_set_fan_mode(hass, FAN_ON)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert auth.method == "post"
|
||||
assert auth.url == DEVICE_COMMAND
|
||||
assert auth.json == {
|
||||
"command": "sdm.devices.commands.Fan.SetTimer",
|
||||
"params": {
|
||||
"duration": "43200s",
|
||||
"timerMode": "ON",
|
||||
},
|
||||
}
|
||||
# Fan cannot be turned on when HVAC is off
|
||||
with pytest.raises(ValueError):
|
||||
await common.async_set_fan_mode(hass, FAN_ON, entity_id="climate.my_thermostat")
|
||||
|
||||
|
||||
async def test_thermostat_fan_empty(
|
||||
|
@ -994,6 +1052,10 @@ async def test_thermostat_fan_empty(
|
|||
}
|
||||
assert ATTR_FAN_MODE not in thermostat.attributes
|
||||
assert ATTR_FAN_MODES not in thermostat.attributes
|
||||
assert thermostat.attributes[ATTR_SUPPORTED_FEATURES] == (
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
| ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
|
||||
)
|
||||
|
||||
# Ignores set_fan_mode since it is lacking SUPPORT_FAN_MODE
|
||||
await common.async_set_fan_mode(hass, FAN_ON)
|
||||
|
@ -1018,7 +1080,7 @@ async def test_thermostat_invalid_fan_mode(
|
|||
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
||||
"sdm.devices.traits.ThermostatMode": {
|
||||
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
||||
"mode": "OFF",
|
||||
"mode": "COOL",
|
||||
},
|
||||
"sdm.devices.traits.Temperature": {
|
||||
"ambientTemperatureCelsius": 16.2,
|
||||
|
@ -1030,14 +1092,13 @@ async def test_thermostat_invalid_fan_mode(
|
|||
assert len(hass.states.async_all()) == 1
|
||||
thermostat = hass.states.get("climate.my_thermostat")
|
||||
assert thermostat is not None
|
||||
assert thermostat.state == HVAC_MODE_FAN_ONLY
|
||||
assert thermostat.state == HVAC_MODE_COOL
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE
|
||||
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_FAN_ONLY,
|
||||
HVAC_MODE_OFF,
|
||||
}
|
||||
assert thermostat.attributes[ATTR_FAN_MODE] == FAN_ON
|
||||
|
@ -1048,58 +1109,6 @@ async def test_thermostat_invalid_fan_mode(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
async def test_thermostat_set_hvac_fan_only(
|
||||
hass: HomeAssistant,
|
||||
setup_platform: PlatformSetup,
|
||||
auth: FakeAuth,
|
||||
create_device: CreateDevice,
|
||||
) -> None:
|
||||
"""Test a thermostat enabling the fan via hvac_mode."""
|
||||
create_device.create(
|
||||
{
|
||||
"sdm.devices.traits.Fan": {
|
||||
"timerMode": "OFF",
|
||||
"timerTimeout": "2019-05-10T03:22:54Z",
|
||||
},
|
||||
"sdm.devices.traits.ThermostatHvac": {
|
||||
"status": "OFF",
|
||||
},
|
||||
"sdm.devices.traits.ThermostatMode": {
|
||||
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
||||
"mode": "OFF",
|
||||
},
|
||||
}
|
||||
)
|
||||
await setup_platform()
|
||||
|
||||
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_FAN_MODE] == FAN_OFF
|
||||
assert thermostat.attributes[ATTR_FAN_MODES] == [FAN_ON, FAN_OFF]
|
||||
|
||||
await common.async_set_hvac_mode(hass, HVAC_MODE_FAN_ONLY)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(auth.captured_requests) == 2
|
||||
|
||||
(method, url, json, headers) = auth.captured_requests.pop(0)
|
||||
assert method == "post"
|
||||
assert url == DEVICE_COMMAND
|
||||
assert json == {
|
||||
"command": "sdm.devices.commands.Fan.SetTimer",
|
||||
"params": {"duration": "43200s", "timerMode": "ON"},
|
||||
}
|
||||
(method, url, json, headers) = auth.captured_requests.pop(0)
|
||||
assert method == "post"
|
||||
assert url == DEVICE_COMMAND
|
||||
assert json == {
|
||||
"command": "sdm.devices.commands.ThermostatMode.SetMode",
|
||||
"params": {"mode": "OFF"},
|
||||
}
|
||||
|
||||
|
||||
async def test_thermostat_target_temp(
|
||||
hass: HomeAssistant,
|
||||
setup_platform: PlatformSetup,
|
||||
|
@ -1397,7 +1406,7 @@ async def test_thermostat_hvac_mode_failure(
|
|||
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
||||
"sdm.devices.traits.ThermostatMode": {
|
||||
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
||||
"mode": "OFF",
|
||||
"mode": "COOL",
|
||||
},
|
||||
"sdm.devices.traits.Fan": {
|
||||
"timerMode": "OFF",
|
||||
|
@ -1416,8 +1425,8 @@ async def test_thermostat_hvac_mode_failure(
|
|||
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.state == HVAC_MODE_COOL
|
||||
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE
|
||||
|
||||
auth.responses = [aiohttp.web.Response(status=HTTPStatus.BAD_REQUEST)]
|
||||
with pytest.raises(HomeAssistantError):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue