core/tests/components/whirlpool/test_climate.py

401 lines
13 KiB
Python
Raw Normal View History

"""Test the Whirlpool Sixth Sense climate domain."""
from unittest.mock import MagicMock
from attr import dataclass
import pytest
import whirlpool
from homeassistant.components.climate import (
ATTR_CURRENT_HUMIDITY,
ATTR_CURRENT_TEMPERATURE,
ATTR_FAN_MODE,
ATTR_FAN_MODES,
ATTR_HVAC_MODE,
ATTR_HVAC_MODES,
ATTR_MAX_TEMP,
ATTR_MIN_TEMP,
ATTR_SWING_MODE,
ATTR_SWING_MODES,
ATTR_TARGET_TEMP_STEP,
DOMAIN as CLIMATE_DOMAIN,
FAN_AUTO,
FAN_HIGH,
FAN_LOW,
FAN_MEDIUM,
FAN_MIDDLE,
FAN_OFF,
SERVICE_SET_FAN_MODE,
SERVICE_SET_HVAC_MODE,
SERVICE_SET_SWING_MODE,
SERVICE_SET_TEMPERATURE,
SWING_HORIZONTAL,
SWING_OFF,
ClimateEntityFeature,
HVACMode,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_FRIENDLY_NAME,
ATTR_SUPPORTED_FEATURES,
ATTR_TEMPERATURE,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_UNAVAILABLE,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import init_integration
async def update_ac_state(
hass: HomeAssistant,
entity_id: str,
mock_aircon_api_instances: MagicMock,
mock_instance_idx: int,
):
"""Simulate an update trigger from the API."""
update_ha_state_cb = mock_aircon_api_instances.call_args_list[
mock_instance_idx
].args[3]
update_ha_state_cb()
await hass.async_block_till_done()
return hass.states.get(entity_id)
async def test_no_appliances(
hass: HomeAssistant, mock_appliances_manager_api: MagicMock
):
"""Test the setup of the climate entities when there are no appliances available."""
mock_appliances_manager_api.return_value.aircons = []
await init_integration(hass)
assert len(hass.states.async_all()) == 0
async def test_static_attributes(hass: HomeAssistant, mock_aircon1_api: MagicMock):
"""Test static climate attributes."""
await init_integration(hass)
for entity_id in ("climate.said1", "climate.said2"):
entry = er.async_get(hass).async_get(entity_id)
assert entry
assert entry.unique_id == entity_id.split(".")[1]
state = hass.states.get(entity_id)
assert state is not None
assert state.state != STATE_UNAVAILABLE
assert state.state == HVACMode.COOL
attributes = state.attributes
assert attributes[ATTR_FRIENDLY_NAME] == "TestZone"
assert (
attributes[ATTR_SUPPORTED_FEATURES]
== ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.FAN_MODE
| ClimateEntityFeature.SWING_MODE
)
assert attributes[ATTR_HVAC_MODES] == [
HVACMode.COOL,
HVACMode.HEAT,
HVACMode.FAN_ONLY,
HVACMode.OFF,
]
assert attributes[ATTR_FAN_MODES] == [
FAN_AUTO,
FAN_HIGH,
FAN_MEDIUM,
FAN_LOW,
FAN_OFF,
]
assert attributes[ATTR_SWING_MODES] == [SWING_HORIZONTAL, SWING_OFF]
assert attributes[ATTR_TARGET_TEMP_STEP] == 1
assert attributes[ATTR_MIN_TEMP] == 16
assert attributes[ATTR_MAX_TEMP] == 30
async def test_dynamic_attributes(
hass: HomeAssistant,
mock_aircon_api_instances: MagicMock,
mock_aircon1_api: MagicMock,
mock_aircon2_api: MagicMock,
):
"""Test dynamic attributes."""
await init_integration(hass)
@dataclass
class ClimateTestInstance:
"""Helper class for multiple climate and mock instances."""
entity_id: str
mock_instance: MagicMock
mock_instance_idx: int
for clim_test_instance in (
ClimateTestInstance("climate.said1", mock_aircon1_api, 0),
ClimateTestInstance("climate.said2", mock_aircon2_api, 1),
):
entity_id = clim_test_instance.entity_id
mock_instance = clim_test_instance.mock_instance
mock_instance_idx = clim_test_instance.mock_instance_idx
state = hass.states.get(entity_id)
assert state is not None
assert state.state == HVACMode.COOL
mock_instance.get_power_on.return_value = False
state = await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
assert state.state == HVACMode.OFF
mock_instance.get_online.return_value = False
state = await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
assert state.state == STATE_UNAVAILABLE
mock_instance.get_power_on.return_value = True
mock_instance.get_online.return_value = True
state = await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
assert state.state == HVACMode.COOL
mock_instance.get_mode.return_value = whirlpool.aircon.Mode.Heat
state = await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
assert state.state == HVACMode.HEAT
mock_instance.get_mode.return_value = whirlpool.aircon.Mode.Fan
state = await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
assert state.state == HVACMode.FAN_ONLY
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Auto
state = await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
assert state.attributes[ATTR_FAN_MODE] == HVACMode.AUTO
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Low
state = await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
assert state.attributes[ATTR_FAN_MODE] == FAN_LOW
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Medium
state = await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
assert state.attributes[ATTR_FAN_MODE] == FAN_MEDIUM
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.High
state = await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
assert state.attributes[ATTR_FAN_MODE] == FAN_HIGH
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Off
state = await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
assert state.attributes[ATTR_FAN_MODE] == FAN_OFF
mock_instance.get_current_temp.return_value = 15
mock_instance.get_temp.return_value = 20
mock_instance.get_current_humidity.return_value = 80
mock_instance.get_h_louver_swing.return_value = True
attributes = (
await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
).attributes
assert attributes[ATTR_CURRENT_TEMPERATURE] == 15
assert attributes[ATTR_TEMPERATURE] == 20
assert attributes[ATTR_CURRENT_HUMIDITY] == 80
assert attributes[ATTR_SWING_MODE] == SWING_HORIZONTAL
mock_instance.get_current_temp.return_value = 16
mock_instance.get_temp.return_value = 21
mock_instance.get_current_humidity.return_value = 70
mock_instance.get_h_louver_swing.return_value = False
attributes = (
await update_ac_state(
hass, entity_id, mock_aircon_api_instances, mock_instance_idx
)
).attributes
assert attributes[ATTR_CURRENT_TEMPERATURE] == 16
assert attributes[ATTR_TEMPERATURE] == 21
assert attributes[ATTR_CURRENT_HUMIDITY] == 70
assert attributes[ATTR_SWING_MODE] == SWING_OFF
async def test_service_calls(
hass: HomeAssistant, mock_aircon1_api: MagicMock, mock_aircon2_api: MagicMock
):
"""Test controlling the entity through service calls."""
await init_integration(hass)
@dataclass
class ClimateInstancesData:
"""Helper class for multiple climate and mock instances."""
entity_id: str
mock_instance: MagicMock
for clim_test_instance in (
ClimateInstancesData("climate.said1", mock_aircon1_api),
ClimateInstancesData("climate.said2", mock_aircon2_api),
):
mock_instance = clim_test_instance.mock_instance
entity_id = clim_test_instance.entity_id
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
mock_instance.set_power_on.assert_called_once_with(False)
mock_instance.set_power_on.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
mock_instance.set_power_on.assert_called_once_with(True)
mock_instance.set_power_on.reset_mock()
mock_instance.get_power_on.return_value = False
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.COOL},
blocking=True,
)
mock_instance.set_power_on.assert_called_once_with(True)
mock_instance.set_temp.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_TEMPERATURE,
{ATTR_ENTITY_ID: entity_id, ATTR_TEMPERATURE: 15},
blocking=True,
)
mock_instance.set_temp.assert_called_once_with(15)
mock_instance.set_mode.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.COOL},
blocking=True,
)
mock_instance.set_mode.assert_called_once_with(whirlpool.aircon.Mode.Cool)
mock_instance.set_mode.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.HEAT},
blocking=True,
)
mock_instance.set_mode.assert_called_once_with(whirlpool.aircon.Mode.Heat)
mock_instance.set_mode.reset_mock()
# HVACMode.DRY is not supported
with pytest.raises(ValueError):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.DRY},
blocking=True,
)
mock_instance.set_mode.assert_not_called()
mock_instance.set_mode.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.FAN_ONLY},
blocking=True,
)
mock_instance.set_mode.assert_called_once_with(whirlpool.aircon.Mode.Fan)
mock_instance.set_fanspeed.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_FAN_MODE: FAN_AUTO},
blocking=True,
)
mock_instance.set_fanspeed.assert_called_once_with(
whirlpool.aircon.FanSpeed.Auto
)
mock_instance.set_fanspeed.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_FAN_MODE: FAN_LOW},
blocking=True,
)
mock_instance.set_fanspeed.assert_called_once_with(
whirlpool.aircon.FanSpeed.Low
)
mock_instance.set_fanspeed.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_FAN_MODE: FAN_MEDIUM},
blocking=True,
)
mock_instance.set_fanspeed.assert_called_once_with(
whirlpool.aircon.FanSpeed.Medium
)
mock_instance.set_fanspeed.reset_mock()
# FAN_MIDDLE is not supported
with pytest.raises(ValueError):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_FAN_MODE: FAN_MIDDLE},
blocking=True,
)
mock_instance.set_fanspeed.assert_not_called()
mock_instance.set_fanspeed.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_FAN_MODE: FAN_HIGH},
blocking=True,
)
mock_instance.set_fanspeed.assert_called_once_with(
whirlpool.aircon.FanSpeed.High
)
mock_instance.set_h_louver_swing.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_SWING_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_SWING_MODE: SWING_HORIZONTAL},
blocking=True,
)
mock_instance.set_h_louver_swing.assert_called_with(True)
mock_instance.set_h_louver_swing.reset_mock()
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_SWING_MODE,
{ATTR_ENTITY_ID: entity_id, ATTR_SWING_MODE: SWING_OFF},
blocking=True,
)
mock_instance.set_h_louver_swing.assert_called_with(False)