Add nest.set_fan_timer service action (#170367)

This commit is contained in:
tronikos
2026-05-12 22:41:03 -07:00
committed by GitHub
parent 894ee88033
commit f756392b6a
7 changed files with 280 additions and 2 deletions
+191 -1
View File
@@ -39,11 +39,16 @@ from homeassistant.const import (
STATE_UNAVAILABLE,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.exceptions import (
HomeAssistantError,
ServiceNotSupported,
ServiceValidationError,
)
from .common import (
DEVICE_COMMAND,
DEVICE_ID,
DOMAIN,
CreateDevice,
PlatformSetup,
create_nest_event,
@@ -1085,6 +1090,191 @@ async def test_thermostat_set_fan(
}
async def test_set_fan_timer(
hass: HomeAssistant,
setup_platform: PlatformSetup,
auth: FakeAuth,
create_device: CreateDevice,
) -> None:
"""Test the set_fan_timer service."""
create_device.create(
{
"sdm.devices.traits.Fan": {
"timerMode": "OFF",
},
"sdm.devices.traits.ThermostatHvac": {"status": "HEATING"},
"sdm.devices.traits.ThermostatMode": {
"availableModes": ["HEAT", "OFF"],
"mode": "HEAT",
},
"sdm.devices.traits.TemperatureTrait": {"ambientTemperatureCelsius": 20.0},
}
)
await setup_platform()
# Call the set_fan_timer service
await hass.services.async_call(
DOMAIN,
"set_fan_timer",
{
"entity_id": "climate.my_thermostat",
"duration": {"minutes": 15},
},
blocking=True,
)
assert auth.method == "post"
assert auth.url == DEVICE_COMMAND
assert auth.json == {
"command": "sdm.devices.commands.Fan.SetTimer",
"params": {
"duration": "900s",
"timerMode": "ON",
},
}
async def test_set_fan_timer_hvac_off(
hass: HomeAssistant,
setup_platform: PlatformSetup,
auth: FakeAuth,
create_device: CreateDevice,
) -> None:
"""Test the set_fan_timer service when HVAC is off."""
create_device.create(
{
"sdm.devices.traits.Fan": {
"timerMode": "OFF",
},
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
"sdm.devices.traits.ThermostatMode": {
"availableModes": ["HEAT", "OFF"],
"mode": "OFF",
},
}
)
await setup_platform()
with pytest.raises(HomeAssistantError, match="Cannot turn on fan"):
await hass.services.async_call(
DOMAIN,
"set_fan_timer",
{
"entity_id": "climate.my_thermostat",
"duration": {"minutes": 15},
},
blocking=True,
)
async def test_set_fan_timer_no_fan(
hass: HomeAssistant,
setup_platform: PlatformSetup,
create_device: CreateDevice,
) -> None:
"""Test the set_fan_timer service when device does not support fan."""
create_device.create(
{
"sdm.devices.traits.ThermostatHvac": {"status": "HEATING"},
"sdm.devices.traits.ThermostatMode": {
"availableModes": ["HEAT", "OFF"],
"mode": "HEAT",
},
}
)
await setup_platform()
with pytest.raises(ServiceNotSupported, match="does not support action"):
await hass.services.async_call(
DOMAIN,
"set_fan_timer",
{
"entity_id": "climate.my_thermostat",
"duration": {"minutes": 15},
},
blocking=True,
)
async def test_set_fan_timer_api_error(
hass: HomeAssistant,
setup_platform: PlatformSetup,
auth: FakeAuth,
create_device: CreateDevice,
) -> None:
"""Test the set_fan_timer service with an API error."""
create_device.create(
{
"sdm.devices.traits.Fan": {
"timerMode": "OFF",
},
"sdm.devices.traits.ThermostatHvac": {"status": "HEATING"},
"sdm.devices.traits.ThermostatMode": {
"availableModes": ["HEAT", "OFF"],
"mode": "HEAT",
},
}
)
await setup_platform()
auth.responses = [aiohttp.web.Response(status=HTTPStatus.INTERNAL_SERVER_ERROR)]
with pytest.raises(HomeAssistantError, match="Error setting .* fan timer"):
await hass.services.async_call(
DOMAIN,
"set_fan_timer",
{
"entity_id": "climate.my_thermostat",
"duration": {"minutes": 15},
},
blocking=True,
)
async def test_set_fan_timer_invalid_duration(
hass: HomeAssistant,
setup_platform: PlatformSetup,
create_device: CreateDevice,
) -> None:
"""Test the set_fan_timer service with invalid durations."""
create_device.create(
{
"sdm.devices.traits.Fan": {
"timerMode": "OFF",
},
"sdm.devices.traits.ThermostatHvac": {"status": "HEATING"},
"sdm.devices.traits.ThermostatMode": {
"availableModes": ["HEAT", "OFF"],
"mode": "HEAT",
},
}
)
await setup_platform()
# Duration too long (over 12 hours)
with pytest.raises(ValueError, match="must be between 1 and 43200 seconds"):
await hass.services.async_call(
DOMAIN,
"set_fan_timer",
{
"entity_id": "climate.my_thermostat",
"duration": {"hours": 16},
},
blocking=True,
)
# Duration zero
with pytest.raises(ValueError, match="must be between 1 and 43200 seconds"):
await hass.services.async_call(
DOMAIN,
"set_fan_timer",
{
"entity_id": "climate.my_thermostat",
"duration": {"seconds": 0},
},
blocking=True,
)
async def test_thermostat_set_fan_when_off(
hass: HomeAssistant,
setup_platform: PlatformSetup,