860 lines
24 KiB
Python
860 lines
24 KiB
Python
"""Test for the SmartThings climate platform."""
|
|
|
|
from typing import Any
|
|
from unittest.mock import AsyncMock, call
|
|
|
|
from pysmartthings import Attribute, Capability, Command, Status
|
|
import pytest
|
|
from syrupy import SnapshotAssertion
|
|
|
|
from homeassistant.components.climate import (
|
|
ATTR_CURRENT_HUMIDITY,
|
|
ATTR_CURRENT_TEMPERATURE,
|
|
ATTR_FAN_MODE,
|
|
ATTR_FAN_MODES,
|
|
ATTR_HVAC_ACTION,
|
|
ATTR_HVAC_MODE,
|
|
ATTR_HVAC_MODES,
|
|
ATTR_PRESET_MODE,
|
|
ATTR_SWING_MODE,
|
|
ATTR_TARGET_TEMP_HIGH,
|
|
ATTR_TARGET_TEMP_LOW,
|
|
DOMAIN as CLIMATE_DOMAIN,
|
|
SERVICE_SET_FAN_MODE,
|
|
SERVICE_SET_HVAC_MODE,
|
|
SERVICE_SET_PRESET_MODE,
|
|
SERVICE_SET_SWING_MODE,
|
|
SERVICE_SET_TEMPERATURE,
|
|
SWING_HORIZONTAL,
|
|
SWING_OFF,
|
|
HVACAction,
|
|
HVACMode,
|
|
)
|
|
from homeassistant.components.smartthings.const import MAIN
|
|
from homeassistant.const import (
|
|
ATTR_ENTITY_ID,
|
|
ATTR_TEMPERATURE,
|
|
SERVICE_TURN_OFF,
|
|
SERVICE_TURN_ON,
|
|
Platform,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import entity_registry as er
|
|
|
|
from . import (
|
|
set_attribute_value,
|
|
setup_integration,
|
|
snapshot_smartthings_entities,
|
|
trigger_update,
|
|
)
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
|
|
async def test_all_entities(
|
|
hass: HomeAssistant,
|
|
snapshot: SnapshotAssertion,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
entity_registry: er.EntityRegistry,
|
|
) -> None:
|
|
"""Test all entities."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
snapshot_smartthings_entities(hass, entity_registry, snapshot, Platform.CLIMATE)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_set_fan_mode(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test climate set fan mode."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_FAN_MODE,
|
|
{ATTR_ENTITY_ID: "climate.ac_office_granit", ATTR_FAN_MODE: "auto"},
|
|
blocking=True,
|
|
)
|
|
devices.execute_device_command.assert_called_once_with(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.AIR_CONDITIONER_FAN_MODE,
|
|
Command.SET_FAN_MODE,
|
|
MAIN,
|
|
argument="auto",
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_set_hvac_mode_off(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test setting AC HVAC mode to off."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_ENTITY_ID: "climate.ac_office_granit", ATTR_HVAC_MODE: HVACMode.OFF},
|
|
blocking=True,
|
|
)
|
|
devices.execute_device_command.assert_called_once_with(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.SWITCH,
|
|
Command.OFF,
|
|
MAIN,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
@pytest.mark.parametrize(
|
|
("hvac_mode", "argument"),
|
|
[
|
|
(HVACMode.HEAT_COOL, "auto"),
|
|
(HVACMode.COOL, "cool"),
|
|
(HVACMode.DRY, "dry"),
|
|
(HVACMode.HEAT, "heat"),
|
|
(HVACMode.FAN_ONLY, "fanOnly"),
|
|
],
|
|
)
|
|
async def test_ac_set_hvac_mode(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
hvac_mode: HVACMode,
|
|
argument: str,
|
|
) -> None:
|
|
"""Test setting AC HVAC mode."""
|
|
set_attribute_value(
|
|
devices,
|
|
Capability.AIR_CONDITIONER_MODE,
|
|
Attribute.SUPPORTED_AC_MODES,
|
|
["auto", "cool", "dry", "heat", "fanOnly"],
|
|
)
|
|
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
|
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_ENTITY_ID: "climate.ac_office_granit", ATTR_HVAC_MODE: hvac_mode},
|
|
blocking=True,
|
|
)
|
|
devices.execute_device_command.assert_called_once_with(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.AIR_CONDITIONER_MODE,
|
|
Command.SET_AIR_CONDITIONER_MODE,
|
|
MAIN,
|
|
argument=argument,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_set_hvac_mode_turns_on(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test setting AC HVAC mode turns on the device if it is off."""
|
|
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_HVAC_MODE,
|
|
{
|
|
ATTR_ENTITY_ID: "climate.ac_office_granit",
|
|
ATTR_HVAC_MODE: HVACMode.HEAT_COOL,
|
|
},
|
|
blocking=True,
|
|
)
|
|
assert devices.execute_device_command.mock_calls == [
|
|
call(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.SWITCH,
|
|
Command.ON,
|
|
MAIN,
|
|
),
|
|
call(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.AIR_CONDITIONER_MODE,
|
|
Command.SET_AIR_CONDITIONER_MODE,
|
|
MAIN,
|
|
argument="auto",
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_set_hvac_mode_wind(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test setting AC HVAC mode to wind if the device supports it."""
|
|
set_attribute_value(
|
|
devices,
|
|
Capability.AIR_CONDITIONER_MODE,
|
|
Attribute.SUPPORTED_AC_MODES,
|
|
["auto", "cool", "dry", "heat", "wind"],
|
|
)
|
|
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
|
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_ENTITY_ID: "climate.ac_office_granit", ATTR_HVAC_MODE: HVACMode.FAN_ONLY},
|
|
blocking=True,
|
|
)
|
|
devices.execute_device_command.assert_called_once_with(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.AIR_CONDITIONER_MODE,
|
|
Command.SET_AIR_CONDITIONER_MODE,
|
|
MAIN,
|
|
argument="wind",
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_set_temperature(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test setting AC temperature."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_TEMPERATURE,
|
|
{ATTR_ENTITY_ID: "climate.ac_office_granit", ATTR_TEMPERATURE: 23},
|
|
blocking=True,
|
|
)
|
|
devices.execute_device_command.assert_called_once_with(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.THERMOSTAT_COOLING_SETPOINT,
|
|
Command.SET_COOLING_SETPOINT,
|
|
MAIN,
|
|
argument=23,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_set_temperature_and_hvac_mode_while_off(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test setting AC temperature and HVAC mode while off."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_TEMPERATURE,
|
|
{
|
|
ATTR_ENTITY_ID: "climate.ac_office_granit",
|
|
ATTR_TEMPERATURE: 23,
|
|
ATTR_HVAC_MODE: HVACMode.HEAT_COOL,
|
|
},
|
|
blocking=True,
|
|
)
|
|
assert devices.execute_device_command.mock_calls == [
|
|
call(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.SWITCH,
|
|
Command.ON,
|
|
MAIN,
|
|
),
|
|
call(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.THERMOSTAT_COOLING_SETPOINT,
|
|
Command.SET_COOLING_SETPOINT,
|
|
MAIN,
|
|
argument=23.0,
|
|
),
|
|
call(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.SWITCH,
|
|
Command.ON,
|
|
MAIN,
|
|
),
|
|
call(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.AIR_CONDITIONER_MODE,
|
|
Command.SET_AIR_CONDITIONER_MODE,
|
|
MAIN,
|
|
argument="auto",
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_set_temperature_and_hvac_mode(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test setting AC temperature and HVAC mode."""
|
|
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_TEMPERATURE,
|
|
{
|
|
ATTR_ENTITY_ID: "climate.ac_office_granit",
|
|
ATTR_TEMPERATURE: 23,
|
|
ATTR_HVAC_MODE: HVACMode.HEAT_COOL,
|
|
},
|
|
blocking=True,
|
|
)
|
|
assert devices.execute_device_command.mock_calls == [
|
|
call(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.THERMOSTAT_COOLING_SETPOINT,
|
|
Command.SET_COOLING_SETPOINT,
|
|
MAIN,
|
|
argument=23.0,
|
|
),
|
|
call(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.AIR_CONDITIONER_MODE,
|
|
Command.SET_AIR_CONDITIONER_MODE,
|
|
MAIN,
|
|
argument="auto",
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_set_temperature_and_hvac_mode_off(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test setting AC temperature and HVAC mode OFF."""
|
|
set_attribute_value(devices, Capability.SWITCH, Attribute.SWITCH, "on")
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_TEMPERATURE,
|
|
{
|
|
ATTR_ENTITY_ID: "climate.ac_office_granit",
|
|
ATTR_TEMPERATURE: 23,
|
|
ATTR_HVAC_MODE: HVACMode.OFF,
|
|
},
|
|
blocking=True,
|
|
)
|
|
assert devices.execute_device_command.mock_calls == [
|
|
call(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.SWITCH,
|
|
Command.OFF,
|
|
MAIN,
|
|
),
|
|
call(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.THERMOSTAT_COOLING_SETPOINT,
|
|
Command.SET_COOLING_SETPOINT,
|
|
MAIN,
|
|
argument=23.0,
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
@pytest.mark.parametrize(
|
|
("service", "command"),
|
|
[
|
|
(SERVICE_TURN_ON, Command.ON),
|
|
(SERVICE_TURN_OFF, Command.OFF),
|
|
],
|
|
)
|
|
async def test_ac_toggle_power(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
service: str,
|
|
command: Command,
|
|
) -> None:
|
|
"""Test toggling AC power."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
service,
|
|
{ATTR_ENTITY_ID: "climate.ac_office_granit"},
|
|
blocking=True,
|
|
)
|
|
devices.execute_device_command.assert_called_once_with(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.SWITCH,
|
|
command,
|
|
MAIN,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_set_swing_mode(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test climate set swing mode."""
|
|
set_attribute_value(
|
|
devices,
|
|
Capability.FAN_OSCILLATION_MODE,
|
|
Attribute.SUPPORTED_FAN_OSCILLATION_MODES,
|
|
["fixed"],
|
|
)
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_SWING_MODE,
|
|
{ATTR_ENTITY_ID: "climate.ac_office_granit", ATTR_SWING_MODE: SWING_OFF},
|
|
blocking=True,
|
|
)
|
|
devices.execute_device_command.assert_called_once_with(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.FAN_OSCILLATION_MODE,
|
|
Command.SET_FAN_OSCILLATION_MODE,
|
|
MAIN,
|
|
argument="fixed",
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_set_preset_mode(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test climate set preset mode."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_PRESET_MODE,
|
|
{ATTR_ENTITY_ID: "climate.ac_office_granit", ATTR_PRESET_MODE: "windFree"},
|
|
blocking=True,
|
|
)
|
|
devices.execute_device_command.assert_called_once_with(
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.CUSTOM_AIR_CONDITIONER_OPTIONAL_MODE,
|
|
Command.SET_AC_OPTIONAL_MODE,
|
|
MAIN,
|
|
argument="windFree",
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
async def test_ac_state_update(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test state update."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
assert hass.states.get("climate.ac_office_granit").state == HVACMode.OFF
|
|
|
|
await trigger_update(
|
|
hass,
|
|
devices,
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
Capability.SWITCH,
|
|
Attribute.SWITCH,
|
|
"on",
|
|
)
|
|
|
|
assert hass.states.get("climate.ac_office_granit").state == HVACMode.HEAT
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
|
@pytest.mark.parametrize(
|
|
(
|
|
"capability",
|
|
"attribute",
|
|
"value",
|
|
"state_attribute",
|
|
"original_value",
|
|
"expected_value",
|
|
),
|
|
[
|
|
(
|
|
Capability.TEMPERATURE_MEASUREMENT,
|
|
Attribute.TEMPERATURE,
|
|
20,
|
|
ATTR_CURRENT_TEMPERATURE,
|
|
25,
|
|
20,
|
|
),
|
|
(
|
|
Capability.AIR_CONDITIONER_FAN_MODE,
|
|
Attribute.FAN_MODE,
|
|
"auto",
|
|
ATTR_FAN_MODE,
|
|
"low",
|
|
"auto",
|
|
),
|
|
(
|
|
Capability.AIR_CONDITIONER_FAN_MODE,
|
|
Attribute.SUPPORTED_AC_FAN_MODES,
|
|
["low", "auto"],
|
|
ATTR_FAN_MODES,
|
|
["auto", "low", "medium", "high", "turbo"],
|
|
["low", "auto"],
|
|
),
|
|
(
|
|
Capability.THERMOSTAT_COOLING_SETPOINT,
|
|
Attribute.COOLING_SETPOINT,
|
|
23,
|
|
ATTR_TEMPERATURE,
|
|
25,
|
|
23,
|
|
),
|
|
(
|
|
Capability.FAN_OSCILLATION_MODE,
|
|
Attribute.FAN_OSCILLATION_MODE,
|
|
"horizontal",
|
|
ATTR_SWING_MODE,
|
|
SWING_OFF,
|
|
SWING_HORIZONTAL,
|
|
),
|
|
(
|
|
Capability.FAN_OSCILLATION_MODE,
|
|
Attribute.FAN_OSCILLATION_MODE,
|
|
"direct",
|
|
ATTR_SWING_MODE,
|
|
SWING_OFF,
|
|
SWING_OFF,
|
|
),
|
|
],
|
|
ids=[
|
|
ATTR_CURRENT_TEMPERATURE,
|
|
ATTR_FAN_MODE,
|
|
ATTR_FAN_MODES,
|
|
ATTR_TEMPERATURE,
|
|
ATTR_SWING_MODE,
|
|
f"{ATTR_SWING_MODE}_off",
|
|
],
|
|
)
|
|
async def test_ac_state_attributes_update(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
capability: Capability,
|
|
attribute: Attribute,
|
|
value: Any,
|
|
state_attribute: str,
|
|
original_value: Any,
|
|
expected_value: Any,
|
|
) -> None:
|
|
"""Test state attributes update."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
assert (
|
|
hass.states.get("climate.ac_office_granit").attributes[state_attribute]
|
|
== original_value
|
|
)
|
|
|
|
await trigger_update(
|
|
hass,
|
|
devices,
|
|
"96a5ef74-5832-a84b-f1f7-ca799957065d",
|
|
capability,
|
|
attribute,
|
|
value,
|
|
)
|
|
|
|
assert (
|
|
hass.states.get("climate.ac_office_granit").attributes[state_attribute]
|
|
== expected_value
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["virtual_thermostat"])
|
|
async def test_thermostat_set_fan_mode(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test thermostat set fan mode."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_FAN_MODE,
|
|
{ATTR_ENTITY_ID: "climate.asd", ATTR_FAN_MODE: "on"},
|
|
blocking=True,
|
|
)
|
|
devices.execute_device_command.assert_called_once_with(
|
|
"2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
|
Capability.THERMOSTAT_FAN_MODE,
|
|
Command.SET_THERMOSTAT_FAN_MODE,
|
|
MAIN,
|
|
argument="on",
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["virtual_thermostat"])
|
|
async def test_thermostat_set_hvac_mode(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test thermostat set HVAC mode."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_ENTITY_ID: "climate.asd", ATTR_HVAC_MODE: HVACMode.HEAT_COOL},
|
|
blocking=True,
|
|
)
|
|
devices.execute_device_command.assert_called_once_with(
|
|
"2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
|
Capability.THERMOSTAT_MODE,
|
|
Command.SET_THERMOSTAT_MODE,
|
|
MAIN,
|
|
argument="auto",
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["virtual_thermostat"])
|
|
@pytest.mark.parametrize(
|
|
("state", "data", "calls"),
|
|
[
|
|
(
|
|
"auto",
|
|
{ATTR_TARGET_TEMP_LOW: 15, ATTR_TARGET_TEMP_HIGH: 23},
|
|
[
|
|
call(
|
|
"2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
|
Capability.THERMOSTAT_HEATING_SETPOINT,
|
|
Command.SET_HEATING_SETPOINT,
|
|
MAIN,
|
|
argument=59.0,
|
|
),
|
|
call(
|
|
"2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
|
Capability.THERMOSTAT_COOLING_SETPOINT,
|
|
Command.SET_COOLING_SETPOINT,
|
|
MAIN,
|
|
argument=73.4,
|
|
),
|
|
],
|
|
),
|
|
(
|
|
"cool",
|
|
{ATTR_TEMPERATURE: 15},
|
|
[
|
|
call(
|
|
"2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
|
Capability.THERMOSTAT_COOLING_SETPOINT,
|
|
Command.SET_COOLING_SETPOINT,
|
|
MAIN,
|
|
argument=59.0,
|
|
)
|
|
],
|
|
),
|
|
(
|
|
"heat",
|
|
{ATTR_TEMPERATURE: 23},
|
|
[
|
|
call(
|
|
"2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
|
Capability.THERMOSTAT_HEATING_SETPOINT,
|
|
Command.SET_HEATING_SETPOINT,
|
|
MAIN,
|
|
argument=73.4,
|
|
)
|
|
],
|
|
),
|
|
(
|
|
"heat",
|
|
{ATTR_TEMPERATURE: 23, ATTR_HVAC_MODE: HVACMode.COOL},
|
|
[
|
|
call(
|
|
"2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
|
Capability.THERMOSTAT_MODE,
|
|
Command.SET_THERMOSTAT_MODE,
|
|
MAIN,
|
|
argument="cool",
|
|
),
|
|
call(
|
|
"2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
|
Capability.THERMOSTAT_COOLING_SETPOINT,
|
|
Command.SET_COOLING_SETPOINT,
|
|
MAIN,
|
|
argument=73.4,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
)
|
|
async def test_thermostat_set_temperature(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
state: str,
|
|
data: dict[str, Any],
|
|
calls: list[call],
|
|
) -> None:
|
|
"""Test thermostat set temperature."""
|
|
set_attribute_value(
|
|
devices, Capability.THERMOSTAT_MODE, Attribute.THERMOSTAT_MODE, state
|
|
)
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
SERVICE_SET_TEMPERATURE,
|
|
{ATTR_ENTITY_ID: "climate.asd"} | data,
|
|
blocking=True,
|
|
)
|
|
assert devices.execute_device_command.mock_calls == calls
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["virtual_thermostat"])
|
|
async def test_humidity(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test humidity extra state attribute."""
|
|
devices.get_device_status.return_value[MAIN][
|
|
Capability.RELATIVE_HUMIDITY_MEASUREMENT
|
|
] = {Attribute.HUMIDITY: Status(50)}
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
state = hass.states.get("climate.asd")
|
|
assert state
|
|
assert state.attributes[ATTR_CURRENT_HUMIDITY] == 50
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["virtual_thermostat"])
|
|
async def test_updating_humidity(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test updating humidity extra state attribute."""
|
|
devices.get_device_status.return_value[MAIN][
|
|
Capability.RELATIVE_HUMIDITY_MEASUREMENT
|
|
] = {Attribute.HUMIDITY: Status(50)}
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
state = hass.states.get("climate.asd")
|
|
assert state
|
|
assert state.attributes[ATTR_CURRENT_HUMIDITY] == 50
|
|
|
|
await trigger_update(
|
|
hass,
|
|
devices,
|
|
"2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
|
Capability.RELATIVE_HUMIDITY_MEASUREMENT,
|
|
Attribute.HUMIDITY,
|
|
40,
|
|
)
|
|
|
|
assert hass.states.get("climate.asd").attributes[ATTR_CURRENT_HUMIDITY] == 40
|
|
|
|
|
|
@pytest.mark.parametrize("device_fixture", ["virtual_thermostat"])
|
|
@pytest.mark.parametrize(
|
|
(
|
|
"capability",
|
|
"attribute",
|
|
"value",
|
|
"state_attribute",
|
|
"original_value",
|
|
"expected_value",
|
|
),
|
|
[
|
|
(
|
|
Capability.TEMPERATURE_MEASUREMENT,
|
|
Attribute.TEMPERATURE,
|
|
20,
|
|
ATTR_CURRENT_TEMPERATURE,
|
|
4734.6,
|
|
-6.7,
|
|
),
|
|
(
|
|
Capability.THERMOSTAT_FAN_MODE,
|
|
Attribute.THERMOSTAT_FAN_MODE,
|
|
"auto",
|
|
ATTR_FAN_MODE,
|
|
"followschedule",
|
|
"auto",
|
|
),
|
|
(
|
|
Capability.THERMOSTAT_FAN_MODE,
|
|
Attribute.SUPPORTED_THERMOSTAT_FAN_MODES,
|
|
["auto", "circulate"],
|
|
ATTR_FAN_MODES,
|
|
["on"],
|
|
["auto", "circulate"],
|
|
),
|
|
(
|
|
Capability.THERMOSTAT_OPERATING_STATE,
|
|
Attribute.THERMOSTAT_OPERATING_STATE,
|
|
"fan only",
|
|
ATTR_HVAC_ACTION,
|
|
HVACAction.COOLING,
|
|
HVACAction.FAN,
|
|
),
|
|
(
|
|
Capability.THERMOSTAT_MODE,
|
|
Attribute.SUPPORTED_THERMOSTAT_MODES,
|
|
["coolClean", "dryClean"],
|
|
ATTR_HVAC_MODES,
|
|
[],
|
|
[HVACMode.COOL, HVACMode.DRY],
|
|
),
|
|
],
|
|
ids=[
|
|
ATTR_CURRENT_TEMPERATURE,
|
|
ATTR_FAN_MODE,
|
|
ATTR_FAN_MODES,
|
|
ATTR_HVAC_ACTION,
|
|
ATTR_HVAC_MODES,
|
|
],
|
|
)
|
|
async def test_thermostat_state_attributes_update(
|
|
hass: HomeAssistant,
|
|
devices: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
capability: Capability,
|
|
attribute: Attribute,
|
|
value: Any,
|
|
state_attribute: str,
|
|
original_value: Any,
|
|
expected_value: Any,
|
|
) -> None:
|
|
"""Test state attributes update."""
|
|
await setup_integration(hass, mock_config_entry)
|
|
|
|
assert hass.states.get("climate.asd").attributes[state_attribute] == original_value
|
|
|
|
await trigger_update(
|
|
hass,
|
|
devices,
|
|
"2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
|
capability,
|
|
attribute,
|
|
value,
|
|
)
|
|
|
|
assert hass.states.get("climate.asd").attributes[state_attribute] == expected_value
|