mirror of
https://github.com/home-assistant/core.git
synced 2025-05-19 13:29:17 +00:00
330 lines
10 KiB
Python
330 lines
10 KiB
Python
"""Test the Whirlpool Sixth Sense climate domain."""
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
from syrupy import SnapshotAssertion
|
|
import whirlpool
|
|
|
|
from homeassistant.components.climate import (
|
|
ATTR_CURRENT_HUMIDITY,
|
|
ATTR_CURRENT_TEMPERATURE,
|
|
ATTR_FAN_MODE,
|
|
ATTR_HVAC_MODE,
|
|
ATTR_SWING_MODE,
|
|
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,
|
|
HVACMode,
|
|
)
|
|
from homeassistant.const import (
|
|
ATTR_ENTITY_ID,
|
|
ATTR_TEMPERATURE,
|
|
SERVICE_TURN_OFF,
|
|
SERVICE_TURN_ON,
|
|
STATE_UNAVAILABLE,
|
|
Platform,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.exceptions import ServiceValidationError
|
|
from homeassistant.helpers import entity_registry as er
|
|
|
|
from . import init_integration, snapshot_whirlpool_entities, trigger_attr_callback
|
|
|
|
|
|
@pytest.fixture(
|
|
params=[
|
|
("climate.aircon_said1", "mock_aircon1_api"),
|
|
("climate.aircon_said2", "mock_aircon2_api"),
|
|
]
|
|
)
|
|
def multiple_climate_entities(request: pytest.FixtureRequest) -> tuple[str, str]:
|
|
"""Fixture for multiple climate entities."""
|
|
entity_id, mock_fixture = request.param
|
|
return entity_id, mock_fixture
|
|
|
|
|
|
async def update_ac_state(
|
|
hass: HomeAssistant,
|
|
entity_id: str,
|
|
mock_aircon_api_instance: MagicMock,
|
|
):
|
|
"""Simulate an update trigger from the API."""
|
|
await trigger_attr_callback(hass, mock_aircon_api_instance)
|
|
return hass.states.get(entity_id)
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
|
async def test_all_entities(
|
|
hass: HomeAssistant,
|
|
snapshot: SnapshotAssertion,
|
|
entity_registry: er.EntityRegistry,
|
|
) -> None:
|
|
"""Test all entities."""
|
|
await init_integration(hass)
|
|
snapshot_whirlpool_entities(hass, entity_registry, snapshot, Platform.CLIMATE)
|
|
|
|
|
|
async def test_dynamic_attributes(
|
|
hass: HomeAssistant,
|
|
multiple_climate_entities: tuple[str, str],
|
|
request: pytest.FixtureRequest,
|
|
) -> None:
|
|
"""Test dynamic attributes."""
|
|
entity_id, mock_fixture = multiple_climate_entities
|
|
mock_instance = request.getfixturevalue(mock_fixture)
|
|
await init_integration(hass)
|
|
|
|
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_instance)
|
|
assert state.state == HVACMode.OFF
|
|
|
|
mock_instance.get_online.return_value = False
|
|
state = await update_ac_state(hass, entity_id, mock_instance)
|
|
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_instance)
|
|
assert state.state == HVACMode.COOL
|
|
|
|
mock_instance.get_mode.return_value = whirlpool.aircon.Mode.Heat
|
|
state = await update_ac_state(hass, entity_id, mock_instance)
|
|
assert state.state == HVACMode.HEAT
|
|
|
|
mock_instance.get_mode.return_value = whirlpool.aircon.Mode.Fan
|
|
state = await update_ac_state(hass, entity_id, mock_instance)
|
|
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_instance)
|
|
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_instance)
|
|
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_instance)
|
|
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_instance)
|
|
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_instance)
|
|
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_instance)).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_instance)).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
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("service", "service_data", "expected_call", "expected_args"),
|
|
[
|
|
(SERVICE_TURN_OFF, {}, "set_power_on", [False]),
|
|
(SERVICE_TURN_ON, {}, "set_power_on", [True]),
|
|
(
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_HVAC_MODE: HVACMode.COOL},
|
|
"set_mode",
|
|
[whirlpool.aircon.Mode.Cool],
|
|
),
|
|
(
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_HVAC_MODE: HVACMode.HEAT},
|
|
"set_mode",
|
|
[whirlpool.aircon.Mode.Heat],
|
|
),
|
|
(
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_HVAC_MODE: HVACMode.FAN_ONLY},
|
|
"set_mode",
|
|
[whirlpool.aircon.Mode.Fan],
|
|
),
|
|
(
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_HVAC_MODE: HVACMode.OFF},
|
|
"set_power_on",
|
|
[False],
|
|
),
|
|
(SERVICE_SET_TEMPERATURE, {ATTR_TEMPERATURE: 20}, "set_temp", [20]),
|
|
(
|
|
SERVICE_SET_FAN_MODE,
|
|
{ATTR_FAN_MODE: FAN_AUTO},
|
|
"set_fanspeed",
|
|
[whirlpool.aircon.FanSpeed.Auto],
|
|
),
|
|
(
|
|
SERVICE_SET_FAN_MODE,
|
|
{ATTR_FAN_MODE: FAN_LOW},
|
|
"set_fanspeed",
|
|
[whirlpool.aircon.FanSpeed.Low],
|
|
),
|
|
(
|
|
SERVICE_SET_FAN_MODE,
|
|
{ATTR_FAN_MODE: FAN_MEDIUM},
|
|
"set_fanspeed",
|
|
[whirlpool.aircon.FanSpeed.Medium],
|
|
),
|
|
(
|
|
SERVICE_SET_FAN_MODE,
|
|
{ATTR_FAN_MODE: FAN_HIGH},
|
|
"set_fanspeed",
|
|
[whirlpool.aircon.FanSpeed.High],
|
|
),
|
|
(
|
|
SERVICE_SET_SWING_MODE,
|
|
{ATTR_SWING_MODE: SWING_HORIZONTAL},
|
|
"set_h_louver_swing",
|
|
[True],
|
|
),
|
|
(
|
|
SERVICE_SET_SWING_MODE,
|
|
{ATTR_SWING_MODE: SWING_OFF},
|
|
"set_h_louver_swing",
|
|
[False],
|
|
),
|
|
],
|
|
)
|
|
async def test_service_calls(
|
|
hass: HomeAssistant,
|
|
service: str,
|
|
service_data: dict,
|
|
expected_call: str,
|
|
expected_args: list,
|
|
multiple_climate_entities: tuple[str, str],
|
|
request: pytest.FixtureRequest,
|
|
) -> None:
|
|
"""Test controlling the entity through service calls."""
|
|
await init_integration(hass)
|
|
entity_id, mock_fixture = multiple_climate_entities
|
|
mock_instance = request.getfixturevalue(mock_fixture)
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
service,
|
|
{ATTR_ENTITY_ID: entity_id, **service_data},
|
|
blocking=True,
|
|
)
|
|
assert getattr(mock_instance, expected_call).call_count == 1
|
|
getattr(mock_instance, expected_call).assert_called_once_with(*expected_args)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("service", "service_data"),
|
|
[
|
|
(
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_HVAC_MODE: HVACMode.COOL},
|
|
),
|
|
(
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_HVAC_MODE: HVACMode.HEAT},
|
|
),
|
|
(
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_HVAC_MODE: HVACMode.FAN_ONLY},
|
|
),
|
|
],
|
|
)
|
|
async def test_service_hvac_mode_turn_on(
|
|
hass: HomeAssistant,
|
|
service: str,
|
|
service_data: dict,
|
|
multiple_climate_entities: tuple[str, str],
|
|
request: pytest.FixtureRequest,
|
|
) -> None:
|
|
"""Test that the HVAC mode service call turns on the entity, if it is off."""
|
|
await init_integration(hass)
|
|
entity_id, mock_fixture = multiple_climate_entities
|
|
mock_instance = request.getfixturevalue(mock_fixture)
|
|
|
|
mock_instance.get_power_on.return_value = False
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
service,
|
|
{ATTR_ENTITY_ID: entity_id, **service_data},
|
|
blocking=True,
|
|
)
|
|
mock_instance.set_power_on.assert_called_once_with(True)
|
|
|
|
# Test that set_power_on is not called if the device is already on
|
|
mock_instance.set_power_on.reset_mock()
|
|
mock_instance.get_power_on.return_value = True
|
|
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
service,
|
|
{ATTR_ENTITY_ID: entity_id, **service_data},
|
|
blocking=True,
|
|
)
|
|
mock_instance.set_power_on.assert_not_called()
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("service", "service_data", "exception"),
|
|
[
|
|
(
|
|
SERVICE_SET_HVAC_MODE,
|
|
{ATTR_HVAC_MODE: HVACMode.DRY},
|
|
ValueError,
|
|
),
|
|
(
|
|
SERVICE_SET_FAN_MODE,
|
|
{ATTR_FAN_MODE: FAN_MIDDLE},
|
|
ServiceValidationError,
|
|
),
|
|
],
|
|
)
|
|
async def test_service_unsupported(
|
|
hass: HomeAssistant,
|
|
service: str,
|
|
service_data: dict,
|
|
exception: type[Exception],
|
|
multiple_climate_entities: tuple[str, str],
|
|
) -> None:
|
|
"""Test that unsupported service calls are handled properly."""
|
|
await init_integration(hass)
|
|
entity_id, _ = multiple_climate_entities
|
|
|
|
with pytest.raises(exception):
|
|
await hass.services.async_call(
|
|
CLIMATE_DOMAIN,
|
|
service,
|
|
{ATTR_ENTITY_ID: entity_id, **service_data},
|
|
blocking=True,
|
|
)
|