Update nest climate tests to use shared fixtures for component setup. Add an additional fixture for creating devices shared between the climate and sensor tests.
1323 lines
44 KiB
Python
1323 lines
44 KiB
Python
"""
|
|
Test for Nest climate platform for the Smart Device Management API.
|
|
|
|
These tests fake out the subscriber/devicemanager, and are not using a real
|
|
pubsub subscriber.
|
|
"""
|
|
|
|
from collections.abc import Awaitable, Callable
|
|
from typing import Any
|
|
|
|
from google_nest_sdm.auth import AbstractAuth
|
|
from google_nest_sdm.event import EventMessage
|
|
import pytest
|
|
|
|
from homeassistant.components.climate.const import (
|
|
ATTR_CURRENT_TEMPERATURE,
|
|
ATTR_FAN_MODE,
|
|
ATTR_FAN_MODES,
|
|
ATTR_HVAC_ACTION,
|
|
ATTR_HVAC_MODES,
|
|
ATTR_PRESET_MODE,
|
|
ATTR_PRESET_MODES,
|
|
ATTR_TARGET_TEMP_HIGH,
|
|
ATTR_TARGET_TEMP_LOW,
|
|
CURRENT_HVAC_COOL,
|
|
CURRENT_HVAC_HEAT,
|
|
CURRENT_HVAC_IDLE,
|
|
CURRENT_HVAC_OFF,
|
|
FAN_LOW,
|
|
FAN_OFF,
|
|
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,
|
|
)
|
|
from homeassistant.const import ATTR_TEMPERATURE
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from .common import (
|
|
DEVICE_COMMAND,
|
|
DEVICE_ID,
|
|
CreateDevice,
|
|
FakeSubscriber,
|
|
PlatformSetup,
|
|
)
|
|
from .conftest import FakeAuth
|
|
|
|
from tests.components.climate import common
|
|
|
|
CreateEvent = Callable[[dict[str, Any]], Awaitable[None]]
|
|
|
|
EVENT_ID = "some-event-id"
|
|
|
|
|
|
@pytest.fixture
|
|
def platforms() -> list[str]:
|
|
"""Fixture to specify platforms to test."""
|
|
return ["climate"]
|
|
|
|
|
|
@pytest.fixture
|
|
def device_traits() -> dict[str, Any]:
|
|
"""Fixture that sets default traits used for devices."""
|
|
return {"sdm.devices.traits.Info": {"customName": "My Thermostat"}}
|
|
|
|
|
|
@pytest.fixture
|
|
async def create_event(
|
|
hass: HomeAssistant,
|
|
auth: AbstractAuth,
|
|
subscriber: FakeSubscriber,
|
|
) -> CreateEvent:
|
|
"""Fixture to send a pub/sub event."""
|
|
|
|
async def create_event(traits: dict[str, Any]) -> None:
|
|
await subscriber.async_receive_event(
|
|
EventMessage(
|
|
{
|
|
"eventId": EVENT_ID,
|
|
"timestamp": "2019-01-01T00:00:01Z",
|
|
"resourceUpdate": {
|
|
"name": DEVICE_ID,
|
|
"traits": traits,
|
|
},
|
|
},
|
|
auth=auth,
|
|
)
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
return create_event
|
|
|
|
|
|
async def test_no_devices(hass: HomeAssistant, setup_platform: PlatformSetup) -> None:
|
|
"""Test no devices returned by the api."""
|
|
await setup_platform()
|
|
assert len(hass.states.async_all()) == 0
|
|
|
|
|
|
async def test_climate_devices(
|
|
hass: HomeAssistant, setup_platform: PlatformSetup, create_device: CreateDevice
|
|
) -> None:
|
|
"""Test no eligible climate devices returned by the api."""
|
|
create_device.create({"sdm.devices.traits.CameraImage": {}})
|
|
await setup_platform()
|
|
assert len(hass.states.async_all()) == 0
|
|
|
|
|
|
async def test_thermostat_off(
|
|
hass: HomeAssistant, setup_platform: PlatformSetup, create_device: CreateDevice
|
|
):
|
|
"""Test a thermostat that is not running."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "OFF",
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 16.2,
|
|
},
|
|
},
|
|
)
|
|
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_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_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_heat(
|
|
hass: HomeAssistant, setup_platform: PlatformSetup, create_device: CreateDevice
|
|
):
|
|
"""Test a thermostat that is heating."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {
|
|
"status": "HEATING",
|
|
},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "HEAT",
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 16.2,
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
|
|
"heatCelsius": 22.0,
|
|
},
|
|
},
|
|
)
|
|
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_HVAC_ACTION] == CURRENT_HVAC_HEAT
|
|
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_TEMPERATURE] == 22.0
|
|
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
|
|
|
|
|
|
async def test_thermostat_cool(
|
|
hass: HomeAssistant, setup_platform: PlatformSetup, create_device: CreateDevice
|
|
):
|
|
"""Test a thermostat that is cooling."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {
|
|
"status": "COOLING",
|
|
},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "COOL",
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 29.9,
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
|
|
"coolCelsius": 28.0,
|
|
},
|
|
},
|
|
)
|
|
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_COOL
|
|
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_COOL
|
|
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] == 29.9
|
|
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] == 28.0
|
|
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
|
|
|
|
|
|
async def test_thermostat_heatcool(
|
|
hass: HomeAssistant, setup_platform: PlatformSetup, create_device: CreateDevice
|
|
):
|
|
"""Test a thermostat that is cooling in heatcool mode."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {
|
|
"status": "COOLING",
|
|
},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "HEATCOOL",
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 29.9,
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
|
|
"heatCelsius": 22.0,
|
|
"coolCelsius": 28.0,
|
|
},
|
|
},
|
|
)
|
|
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_COOL
|
|
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_COOL
|
|
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] == 29.9
|
|
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
|
|
HVAC_MODE_HEAT,
|
|
HVAC_MODE_COOL,
|
|
HVAC_MODE_HEAT_COOL,
|
|
HVAC_MODE_OFF,
|
|
}
|
|
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
|
|
assert ATTR_PRESET_MODE not in thermostat.attributes
|
|
assert ATTR_PRESET_MODES not in thermostat.attributes
|
|
|
|
|
|
async def test_thermostat_eco_off(
|
|
hass: HomeAssistant, setup_platform: PlatformSetup, create_device: CreateDevice
|
|
) -> None:
|
|
"""Test a thermostat cooling with eco off."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {
|
|
"status": "COOLING",
|
|
},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "HEATCOOL",
|
|
},
|
|
"sdm.devices.traits.ThermostatEco": {
|
|
"availableModes": ["MANUAL_ECO", "OFF"],
|
|
"mode": "OFF",
|
|
"heatCelsius": 20.0,
|
|
"coolCelsius": 22.0,
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 29.9,
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
|
|
"heatCelsius": 22.0,
|
|
"coolCelsius": 28.0,
|
|
},
|
|
},
|
|
)
|
|
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_COOL
|
|
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_COOL
|
|
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] == 29.9
|
|
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
|
|
HVAC_MODE_HEAT,
|
|
HVAC_MODE_COOL,
|
|
HVAC_MODE_HEAT_COOL,
|
|
HVAC_MODE_OFF,
|
|
}
|
|
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
|
|
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_NONE
|
|
assert thermostat.attributes[ATTR_PRESET_MODES] == [PRESET_ECO, PRESET_NONE]
|
|
|
|
|
|
async def test_thermostat_eco_on(
|
|
hass: HomeAssistant, setup_platform: PlatformSetup, create_device: CreateDevice
|
|
) -> None:
|
|
"""Test a thermostat in eco mode."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {
|
|
"status": "COOLING",
|
|
},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "HEATCOOL",
|
|
},
|
|
"sdm.devices.traits.ThermostatEco": {
|
|
"availableModes": ["MANUAL_ECO", "OFF"],
|
|
"mode": "MANUAL_ECO",
|
|
"heatCelsius": 21.0,
|
|
"coolCelsius": 29.0,
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 29.9,
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
|
|
"heatCelsius": 22.0,
|
|
"coolCelsius": 28.0,
|
|
},
|
|
},
|
|
)
|
|
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_COOL
|
|
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_COOL
|
|
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] == 29.9
|
|
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
|
|
HVAC_MODE_HEAT,
|
|
HVAC_MODE_COOL,
|
|
HVAC_MODE_HEAT_COOL,
|
|
HVAC_MODE_OFF,
|
|
}
|
|
assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] == 21.0
|
|
assert thermostat.attributes[ATTR_TARGET_TEMP_HIGH] == 29.0
|
|
assert thermostat.attributes[ATTR_TEMPERATURE] is None
|
|
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_ECO
|
|
assert thermostat.attributes[ATTR_PRESET_MODES] == [PRESET_ECO, PRESET_NONE]
|
|
|
|
|
|
async def test_thermostat_eco_heat_only(
|
|
hass: HomeAssistant, setup_platform: PlatformSetup, create_device: CreateDevice
|
|
) -> None:
|
|
"""Test a thermostat in eco mode that only supports heat."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {
|
|
"status": "OFF",
|
|
},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "OFF"],
|
|
"mode": "HEAT",
|
|
},
|
|
"sdm.devices.traits.ThermostatEco": {
|
|
"availableModes": ["MANUAL_ECO", "OFF"],
|
|
"mode": "MANUAL_ECO",
|
|
"heatCelsius": 21.0,
|
|
"coolCelsius": 29.0,
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 29.9,
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {},
|
|
},
|
|
)
|
|
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_HVAC_ACTION] == CURRENT_HVAC_IDLE
|
|
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] == 29.9
|
|
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
|
|
HVAC_MODE_HEAT,
|
|
HVAC_MODE_OFF,
|
|
}
|
|
assert thermostat.attributes[ATTR_TEMPERATURE] == 21.0
|
|
assert ATTR_TARGET_TEMP_LOW not in thermostat.attributes
|
|
assert ATTR_TARGET_TEMP_HIGH not in thermostat.attributes
|
|
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_ECO
|
|
assert thermostat.attributes[ATTR_PRESET_MODES] == [PRESET_ECO, PRESET_NONE]
|
|
|
|
|
|
async def test_thermostat_set_hvac_mode(
|
|
hass: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
auth: FakeAuth,
|
|
create_device: CreateDevice,
|
|
create_event: CreateEvent,
|
|
) -> None:
|
|
"""Test a thermostat changing hvac modes."""
|
|
create_device.create(
|
|
{
|
|
"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_HVAC_ACTION] == CURRENT_HVAC_OFF
|
|
|
|
await common.async_set_hvac_mode(hass, HVAC_MODE_HEAT)
|
|
await hass.async_block_till_done()
|
|
|
|
assert auth.method == "post"
|
|
assert auth.url == DEVICE_COMMAND
|
|
assert auth.json == {
|
|
"command": "sdm.devices.commands.ThermostatMode.SetMode",
|
|
"params": {"mode": "HEAT"},
|
|
}
|
|
|
|
# Local state does not reflect the update
|
|
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
|
|
|
|
# Simulate pubsub message when mode changes
|
|
await create_event(
|
|
{
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "HEAT",
|
|
},
|
|
}
|
|
)
|
|
|
|
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_IDLE
|
|
|
|
# Simulate pubsub message when the thermostat starts heating
|
|
await create_event(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {
|
|
"status": "HEATING",
|
|
},
|
|
}
|
|
)
|
|
|
|
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_HEAT
|
|
|
|
|
|
async def test_thermostat_invalid_hvac_mode(
|
|
hass: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
auth: FakeAuth,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test setting an hvac_mode that is not supported."""
|
|
create_device.create(
|
|
{
|
|
"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_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: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
auth: FakeAuth,
|
|
create_device: CreateDevice,
|
|
create_event: CreateEvent,
|
|
) -> None:
|
|
"""Test a thermostat put into eco mode."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
|
"sdm.devices.traits.ThermostatEco": {
|
|
"availableModes": ["MANUAL_ECO", "OFF"],
|
|
"mode": "OFF",
|
|
"heatCelsius": 15.0,
|
|
"coolCelsius": 28.0,
|
|
},
|
|
"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_HVAC_ACTION] == CURRENT_HVAC_OFF
|
|
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_NONE
|
|
|
|
# Turn on eco mode
|
|
await common.async_set_preset_mode(hass, PRESET_ECO)
|
|
await hass.async_block_till_done()
|
|
|
|
assert auth.method == "post"
|
|
assert auth.url == DEVICE_COMMAND
|
|
assert auth.json == {
|
|
"command": "sdm.devices.commands.ThermostatEco.SetMode",
|
|
"params": {"mode": "MANUAL_ECO"},
|
|
}
|
|
|
|
# Local state does not reflect the update
|
|
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_PRESET_MODE] == PRESET_NONE
|
|
|
|
# Simulate pubsub message when mode changes
|
|
await create_event(
|
|
{
|
|
"sdm.devices.traits.ThermostatEco": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "MANUAL_ECO",
|
|
"heatCelsius": 15.0,
|
|
"coolCelsius": 28.0,
|
|
},
|
|
}
|
|
)
|
|
|
|
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_PRESET_MODE] == PRESET_ECO
|
|
|
|
# Turn off eco mode
|
|
await common.async_set_preset_mode(hass, PRESET_NONE)
|
|
await hass.async_block_till_done()
|
|
|
|
assert auth.method == "post"
|
|
assert auth.url == DEVICE_COMMAND
|
|
assert auth.json == {
|
|
"command": "sdm.devices.commands.ThermostatEco.SetMode",
|
|
"params": {"mode": "OFF"},
|
|
}
|
|
|
|
|
|
async def test_thermostat_set_cool(
|
|
hass: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
auth: FakeAuth,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat in cool mode with a temperature change."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "COOL",
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
|
|
"coolCelsius": 25.0,
|
|
},
|
|
},
|
|
)
|
|
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_COOL
|
|
|
|
await common.async_set_temperature(hass, temperature=24.0)
|
|
await hass.async_block_till_done()
|
|
|
|
assert auth.method == "post"
|
|
assert auth.url == DEVICE_COMMAND
|
|
assert auth.json == {
|
|
"command": "sdm.devices.commands.ThermostatTemperatureSetpoint.SetCool",
|
|
"params": {"coolCelsius": 24.0},
|
|
}
|
|
|
|
|
|
async def test_thermostat_set_heat(
|
|
hass: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
auth: FakeAuth,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat heating mode with a temperature change."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "HEAT",
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
|
|
"heatCelsius": 19.0,
|
|
},
|
|
}
|
|
)
|
|
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
|
|
|
|
await common.async_set_temperature(hass, temperature=20.0)
|
|
await hass.async_block_till_done()
|
|
|
|
assert auth.method == "post"
|
|
assert auth.url == DEVICE_COMMAND
|
|
assert auth.json == {
|
|
"command": "sdm.devices.commands.ThermostatTemperatureSetpoint.SetHeat",
|
|
"params": {"heatCelsius": 20.0},
|
|
}
|
|
|
|
|
|
async def test_thermostat_set_heat_cool(
|
|
hass: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
auth: FakeAuth,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat in heatcool mode with a temperature change."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "HEATCOOL",
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
|
|
"heatCelsius": 19.0,
|
|
"coolCelsius": 25.0,
|
|
},
|
|
}
|
|
)
|
|
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_COOL
|
|
|
|
await common.async_set_temperature(
|
|
hass, target_temp_low=20.0, target_temp_high=24.0
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert auth.method == "post"
|
|
assert auth.url == DEVICE_COMMAND
|
|
assert auth.json == {
|
|
"command": "sdm.devices.commands.ThermostatTemperatureSetpoint.SetRange",
|
|
"params": {"heatCelsius": 20.0, "coolCelsius": 24.0},
|
|
}
|
|
|
|
|
|
async def test_thermostat_fan_off(
|
|
hass: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat with the fan not running."""
|
|
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",
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 16.2,
|
|
},
|
|
}
|
|
)
|
|
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_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_FAN_ONLY,
|
|
HVAC_MODE_OFF,
|
|
}
|
|
assert thermostat.attributes[ATTR_FAN_MODE] == FAN_OFF
|
|
assert thermostat.attributes[ATTR_FAN_MODES] == [FAN_ON, FAN_OFF]
|
|
|
|
|
|
async def test_thermostat_fan_on(
|
|
hass: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat with the fan running."""
|
|
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": "OFF",
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 16.2,
|
|
},
|
|
}
|
|
)
|
|
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_FAN_ONLY
|
|
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]
|
|
|
|
|
|
async def test_thermostat_cool_with_fan(
|
|
hass: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat cooling while the fan is on."""
|
|
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": "COOL",
|
|
},
|
|
},
|
|
)
|
|
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_COOL
|
|
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE
|
|
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]
|
|
|
|
|
|
async def test_thermostat_set_fan(
|
|
hass: HomeAssistant,
|
|
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": "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_FAN_ONLY
|
|
assert thermostat.attributes[ATTR_FAN_MODE] == FAN_ON
|
|
assert thermostat.attributes[ATTR_FAN_MODES] == [FAN_ON, FAN_OFF]
|
|
|
|
# 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_fan_empty(
|
|
hass: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a fan trait with an empty response."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.Fan": {},
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "OFF",
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 16.2,
|
|
},
|
|
}
|
|
)
|
|
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_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 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: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test setting a fan mode that is not supported."""
|
|
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": "OFF",
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 16.2,
|
|
},
|
|
}
|
|
)
|
|
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_FAN_ONLY
|
|
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]
|
|
|
|
with pytest.raises(ValueError):
|
|
await common.async_set_fan_mode(hass, FAN_LOW)
|
|
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,
|
|
create_device: CreateDevice,
|
|
create_event: CreateEvent,
|
|
) -> None:
|
|
"""Test a thermostat changing hvac modes and affected on target temps."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {
|
|
"status": "HEATING",
|
|
},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "HEAT",
|
|
},
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 20.1,
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
|
|
"heatCelsius": 23.0,
|
|
},
|
|
}
|
|
)
|
|
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_TEMPERATURE] == 23.0
|
|
assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] is None
|
|
assert thermostat.attributes[ATTR_TARGET_TEMP_HIGH] is None
|
|
|
|
# Simulate pubsub message changing modes
|
|
await create_event(
|
|
{
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "HEATCOOL",
|
|
},
|
|
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
|
|
"heatCelsius": 22.0,
|
|
"coolCelsius": 28.0,
|
|
},
|
|
}
|
|
)
|
|
|
|
thermostat = hass.states.get("climate.my_thermostat")
|
|
assert thermostat is not None
|
|
assert thermostat.state == HVAC_MODE_HEAT_COOL
|
|
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: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat missing many thermostat traits in api response."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "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_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: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat missing many thermostat traits in api response."""
|
|
create_device.create(
|
|
{
|
|
"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_HVAC_ACTION] == CURRENT_HVAC_IDLE
|
|
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: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat missing many thermostat traits in api response."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "UNEXPECTED"},
|
|
}
|
|
)
|
|
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 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: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat missing many thermostat traits in api response."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
|
|
"mode": "HEATCOOL",
|
|
},
|
|
},
|
|
)
|
|
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_COOL
|
|
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_IDLE
|
|
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: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat missing many thermostat traits in api response."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
|
"sdm.devices.traits.ThermostatMode": {
|
|
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF", "UNEXPECTED"],
|
|
"mode": "UNEXPECTED",
|
|
},
|
|
}
|
|
)
|
|
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_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: HomeAssistant,
|
|
setup_platform: PlatformSetup,
|
|
auth: FakeAuth,
|
|
create_device: CreateDevice,
|
|
) -> None:
|
|
"""Test a thermostat set with an invalid preset mode."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
|
|
"sdm.devices.traits.ThermostatEco": {
|
|
"availableModes": ["MANUAL_ECO", "OFF"],
|
|
"mode": "OFF",
|
|
"heatCelsius": 15.0,
|
|
"coolCelsius": 28.0,
|
|
},
|
|
}
|
|
)
|
|
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_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]
|