mirror of https://github.com/home-assistant/core
236 lines
7.6 KiB
Python
236 lines
7.6 KiB
Python
"""Tests of the climate entity of the balboa integration."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from pybalboa import SpaControl
|
|
from pybalboa.enums import HeatMode, OffLowMediumHighState
|
|
import pytest
|
|
from syrupy import SnapshotAssertion
|
|
|
|
from homeassistant.components.climate import (
|
|
ATTR_FAN_MODE,
|
|
ATTR_FAN_MODES,
|
|
ATTR_HVAC_ACTION,
|
|
ATTR_HVAC_MODES,
|
|
ATTR_MAX_TEMP,
|
|
ATTR_MIN_TEMP,
|
|
ATTR_PRESET_MODE,
|
|
ATTR_PRESET_MODES,
|
|
FAN_HIGH,
|
|
FAN_LOW,
|
|
FAN_MEDIUM,
|
|
FAN_OFF,
|
|
ClimateEntityFeature,
|
|
HVACAction,
|
|
HVACMode,
|
|
)
|
|
from homeassistant.const import ATTR_TEMPERATURE, Platform, UnitOfTemperature
|
|
from homeassistant.core import HomeAssistant, State
|
|
from homeassistant.exceptions import ServiceValidationError
|
|
from homeassistant.helpers import entity_registry as er
|
|
|
|
from . import client_update, init_integration
|
|
|
|
from tests.common import MockConfigEntry, snapshot_platform
|
|
from tests.components.climate import common
|
|
|
|
HVAC_SETTINGS = [
|
|
HVACMode.HEAT,
|
|
HVACMode.OFF,
|
|
HVACMode.AUTO,
|
|
]
|
|
|
|
ENTITY_CLIMATE = "climate.fakespa"
|
|
|
|
|
|
async def test_climate(
|
|
hass: HomeAssistant,
|
|
client: MagicMock,
|
|
entity_registry: er.EntityRegistry,
|
|
snapshot: SnapshotAssertion,
|
|
) -> None:
|
|
"""Test spa climate."""
|
|
with patch("homeassistant.components.balboa.PLATFORMS", [Platform.CLIMATE]):
|
|
entry = await init_integration(hass)
|
|
|
|
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
|
|
|
|
|
|
async def test_spa_defaults_fake_tscale(
|
|
hass: HomeAssistant, client: MagicMock, integration: MockConfigEntry
|
|
) -> None:
|
|
"""Test supported features flags."""
|
|
client.temperature_unit = 1
|
|
|
|
state = hass.states.get(ENTITY_CLIMATE)
|
|
|
|
assert state
|
|
assert (
|
|
state.attributes["supported_features"]
|
|
== ClimateEntityFeature.TARGET_TEMPERATURE
|
|
| ClimateEntityFeature.PRESET_MODE
|
|
| ClimateEntityFeature.TURN_OFF
|
|
| ClimateEntityFeature.TURN_ON
|
|
)
|
|
assert state.state == HVACMode.HEAT
|
|
assert state.attributes[ATTR_MIN_TEMP] == 10.0
|
|
assert state.attributes[ATTR_MAX_TEMP] == 40.0
|
|
assert state.attributes[ATTR_PRESET_MODE] == "ready"
|
|
assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.IDLE
|
|
|
|
|
|
async def test_spa_temperature(
|
|
hass: HomeAssistant, client: MagicMock, integration: MockConfigEntry
|
|
) -> None:
|
|
"""Test spa temperature settings."""
|
|
client.temperature_minimum = 110
|
|
client.temperature_maximum = 250
|
|
# flip the spa into F
|
|
# set temp to a valid number
|
|
state = await _patch_spa_settemp(hass, client, 0, 100)
|
|
assert state.attributes.get(ATTR_TEMPERATURE) == 38.0
|
|
|
|
|
|
async def test_spa_temperature_unit(
|
|
hass: HomeAssistant, client: MagicMock, integration: MockConfigEntry
|
|
) -> None:
|
|
"""Test temperature unit conversions."""
|
|
with patch.object(
|
|
hass.config.units, "temperature_unit", UnitOfTemperature.FAHRENHEIT
|
|
):
|
|
state = await _patch_spa_settemp(hass, client, 0, 15.4)
|
|
assert state.attributes.get(ATTR_TEMPERATURE) == 15.0
|
|
|
|
|
|
async def test_spa_hvac_modes(
|
|
hass: HomeAssistant, client: MagicMock, integration: MockConfigEntry
|
|
) -> None:
|
|
"""Test hvac modes."""
|
|
# try out the different heat modes
|
|
for heat_mode in list(HeatMode)[:2]:
|
|
state = await _patch_spa_heatmode(hass, client, heat_mode)
|
|
modes = state.attributes.get(ATTR_HVAC_MODES)
|
|
assert modes == [HVACMode.HEAT, HVACMode.OFF]
|
|
assert state.state == HVAC_SETTINGS[heat_mode]
|
|
|
|
|
|
async def test_spa_hvac_action(
|
|
hass: HomeAssistant, client: MagicMock, integration: MockConfigEntry
|
|
) -> None:
|
|
"""Test setting of the HVAC action."""
|
|
# try out the different heat states
|
|
state = await _patch_spa_heatstate(hass, client, 0)
|
|
assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.OFF
|
|
|
|
state = await _patch_spa_heatstate(hass, client, 1)
|
|
assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.HEATING
|
|
|
|
state = await _patch_spa_heatstate(hass, client, 2)
|
|
assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.IDLE
|
|
|
|
|
|
async def test_spa_preset_modes(
|
|
hass: HomeAssistant, client: MagicMock, integration: MockConfigEntry
|
|
) -> None:
|
|
"""Test the various preset modes."""
|
|
state = hass.states.get(ENTITY_CLIMATE)
|
|
assert state
|
|
modes = state.attributes.get(ATTR_PRESET_MODES)
|
|
assert modes == ["ready", "rest"]
|
|
|
|
# Put it in Ready and Rest
|
|
modelist = ["ready", "rest"]
|
|
for mode in modelist:
|
|
client.heat_mode.state = HeatMode[mode.upper()]
|
|
await common.async_set_preset_mode(hass, mode, ENTITY_CLIMATE)
|
|
|
|
state = await client_update(hass, client, ENTITY_CLIMATE)
|
|
assert state
|
|
assert state.attributes[ATTR_PRESET_MODE] == mode
|
|
|
|
with pytest.raises(ServiceValidationError):
|
|
await common.async_set_preset_mode(hass, 2, ENTITY_CLIMATE)
|
|
|
|
# put it in RNR and test assertion
|
|
client.heat_mode.state = HeatMode.READY_IN_REST
|
|
state = await client_update(hass, client, ENTITY_CLIMATE)
|
|
assert state
|
|
assert state.attributes[ATTR_PRESET_MODE] == "ready_in_rest"
|
|
|
|
|
|
async def test_spa_with_blower(hass: HomeAssistant, client: MagicMock) -> None:
|
|
"""Test supported features flags."""
|
|
blower = MagicMock(SpaControl)
|
|
blower.state = OffLowMediumHighState.OFF
|
|
blower.options = list(OffLowMediumHighState)
|
|
client.blowers = [blower]
|
|
|
|
await init_integration(hass)
|
|
|
|
state = hass.states.get(ENTITY_CLIMATE)
|
|
|
|
assert state
|
|
assert (
|
|
state.attributes["supported_features"]
|
|
== ClimateEntityFeature.TARGET_TEMPERATURE
|
|
| ClimateEntityFeature.PRESET_MODE
|
|
| ClimateEntityFeature.FAN_MODE
|
|
| ClimateEntityFeature.TURN_OFF
|
|
| ClimateEntityFeature.TURN_ON
|
|
)
|
|
assert state.state == HVACMode.HEAT
|
|
assert state.attributes[ATTR_MIN_TEMP] == 10.0
|
|
assert state.attributes[ATTR_MAX_TEMP] == 40.0
|
|
assert state.attributes[ATTR_PRESET_MODE] == "ready"
|
|
assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.IDLE
|
|
assert state.attributes[ATTR_FAN_MODES] == ["off", "low", "medium", "high"]
|
|
assert state.attributes[ATTR_FAN_MODE] == FAN_OFF
|
|
|
|
for fan_mode in (FAN_LOW, FAN_MEDIUM, FAN_HIGH):
|
|
client.blowers[0].set_state.reset_mock()
|
|
state = await _patch_blower(hass, client, fan_mode)
|
|
assert state.attributes[ATTR_FAN_MODE] == fan_mode
|
|
client.blowers[0].set_state.assert_called_once()
|
|
|
|
|
|
# Helpers
|
|
|
|
|
|
async def _patch_blower(hass: HomeAssistant, client: MagicMock, fan_mode: str) -> State:
|
|
"""Patch the blower state."""
|
|
client.blowers[0].state = OffLowMediumHighState[fan_mode.upper()]
|
|
await common.async_set_fan_mode(hass, fan_mode)
|
|
return await client_update(hass, client, ENTITY_CLIMATE)
|
|
|
|
|
|
async def _patch_spa_settemp(
|
|
hass: HomeAssistant, client: MagicMock, tscale: int, settemp: float
|
|
) -> State:
|
|
"""Patch the settemp."""
|
|
client.temperature_unit = tscale
|
|
client.target_temperature = settemp
|
|
await common.async_set_temperature(
|
|
hass, temperature=settemp, entity_id=ENTITY_CLIMATE
|
|
)
|
|
return await client_update(hass, client, ENTITY_CLIMATE)
|
|
|
|
|
|
async def _patch_spa_heatmode(
|
|
hass: HomeAssistant, client: MagicMock, heat_mode: int
|
|
) -> State:
|
|
"""Patch the heatmode."""
|
|
client.heat_mode.state = heat_mode
|
|
await common.async_set_hvac_mode(hass, HVAC_SETTINGS[heat_mode], ENTITY_CLIMATE)
|
|
return await client_update(hass, client, ENTITY_CLIMATE)
|
|
|
|
|
|
async def _patch_spa_heatstate(
|
|
hass: HomeAssistant, client: MagicMock, heat_state: int
|
|
) -> State:
|
|
"""Patch the heatmode."""
|
|
client.heat_state = heat_state
|
|
await common.async_set_hvac_mode(hass, HVAC_SETTINGS[heat_state], ENTITY_CLIMATE)
|
|
return await client_update(hass, client, ENTITY_CLIMATE)
|