core/tests/components/lcn/test_climate.py

290 lines
9.1 KiB
Python

"""Test for the LCN climate platform."""
from unittest.mock import patch
from pypck.inputs import ModStatusVar, Unknown
from pypck.lcn_addr import LcnAddr
from pypck.lcn_defs import Var, VarUnit, VarValue
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.climate import (
ATTR_CURRENT_TEMPERATURE,
ATTR_HVAC_MODE,
ATTR_TARGET_TEMP_HIGH,
ATTR_TARGET_TEMP_LOW,
DOMAIN as DOMAIN_CLIMATE,
SERVICE_SET_HVAC_MODE,
SERVICE_SET_TEMPERATURE,
HVACMode,
)
from homeassistant.components.lcn.helpers import get_device_connection
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_TEMPERATURE,
STATE_UNAVAILABLE,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers import entity_registry as er
from .conftest import MockConfigEntry, MockModuleConnection, init_integration
from tests.common import snapshot_platform
async def test_setup_lcn_climate(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the setup of climate."""
with patch("homeassistant.components.lcn.PLATFORMS", [Platform.CLIMATE]):
await init_integration(hass, entry)
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
async def test_set_hvac_mode_heat(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the hvac mode is set to heat."""
await init_integration(hass, entry)
with patch.object(MockModuleConnection, "lock_regulator") as lock_regulator:
state = hass.states.get("climate.climate1")
state.state = HVACMode.OFF
# command failed
lock_regulator.return_value = False
await hass.services.async_call(
DOMAIN_CLIMATE,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: "climate.climate1", ATTR_HVAC_MODE: HVACMode.HEAT},
blocking=True,
)
lock_regulator.assert_awaited_with(0, False)
state = hass.states.get("climate.climate1")
assert state is not None
assert state.state != HVACMode.HEAT
# command success
lock_regulator.reset_mock(return_value=True)
lock_regulator.return_value = True
await hass.services.async_call(
DOMAIN_CLIMATE,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: "climate.climate1", ATTR_HVAC_MODE: HVACMode.HEAT},
blocking=True,
)
lock_regulator.assert_awaited_with(0, False)
state = hass.states.get("climate.climate1")
assert state is not None
assert state.state == HVACMode.HEAT
async def test_set_hvac_mode_off(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the hvac mode is set off."""
await init_integration(hass, entry)
with patch.object(MockModuleConnection, "lock_regulator") as lock_regulator:
state = hass.states.get("climate.climate1")
state.state = HVACMode.HEAT
# command failed
lock_regulator.return_value = False
await hass.services.async_call(
DOMAIN_CLIMATE,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: "climate.climate1", ATTR_HVAC_MODE: HVACMode.OFF},
blocking=True,
)
lock_regulator.assert_awaited_with(0, True)
state = hass.states.get("climate.climate1")
assert state is not None
assert state.state != HVACMode.OFF
# command success
lock_regulator.reset_mock(return_value=True)
lock_regulator.return_value = True
await hass.services.async_call(
DOMAIN_CLIMATE,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: "climate.climate1", ATTR_HVAC_MODE: HVACMode.OFF},
blocking=True,
)
lock_regulator.assert_awaited_with(0, True)
state = hass.states.get("climate.climate1")
assert state is not None
assert state.state == HVACMode.OFF
async def test_set_temperature(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the temperature is set."""
await init_integration(hass, entry)
with patch.object(MockModuleConnection, "var_abs") as var_abs:
state = hass.states.get("climate.climate1")
state.state = HVACMode.HEAT
# wrong temperature set via service call with high/low attributes
var_abs.return_value = False
with pytest.raises(ServiceValidationError):
await hass.services.async_call(
DOMAIN_CLIMATE,
SERVICE_SET_TEMPERATURE,
{
ATTR_ENTITY_ID: "climate.climate1",
ATTR_TARGET_TEMP_LOW: 24.5,
ATTR_TARGET_TEMP_HIGH: 25.5,
},
blocking=True,
)
var_abs.assert_not_awaited()
# command failed
var_abs.reset_mock(return_value=True)
var_abs.return_value = False
await hass.services.async_call(
DOMAIN_CLIMATE,
SERVICE_SET_TEMPERATURE,
{ATTR_ENTITY_ID: "climate.climate1", ATTR_TEMPERATURE: 25.5},
blocking=True,
)
var_abs.assert_awaited_with(Var.R1VARSETPOINT, 25.5, VarUnit.CELSIUS)
state = hass.states.get("climate.climate1")
assert state is not None
assert state.attributes[ATTR_TEMPERATURE] != 25.5
# command success
var_abs.reset_mock(return_value=True)
var_abs.return_value = True
await hass.services.async_call(
DOMAIN_CLIMATE,
SERVICE_SET_TEMPERATURE,
{ATTR_ENTITY_ID: "climate.climate1", ATTR_TEMPERATURE: 25.5},
blocking=True,
)
var_abs.assert_awaited_with(Var.R1VARSETPOINT, 25.5, VarUnit.CELSIUS)
state = hass.states.get("climate.climate1")
assert state is not None
assert state.attributes[ATTR_TEMPERATURE] == 25.5
async def test_pushed_current_temperature_status_change(
hass: HomeAssistant,
entry: MockConfigEntry,
) -> None:
"""Test the climate changes its current temperature on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
temperature = VarValue.from_celsius(25.5)
inp = ModStatusVar(address, Var.VAR1, temperature)
await device_connection.async_process_input(inp)
await hass.async_block_till_done()
state = hass.states.get("climate.climate1")
assert state is not None
assert state.state == HVACMode.HEAT
assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 25.5
assert state.attributes[ATTR_TEMPERATURE] is None
async def test_pushed_setpoint_status_change(
hass: HomeAssistant,
entry: MockConfigEntry,
) -> None:
"""Test the climate changes its setpoint on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
temperature = VarValue.from_celsius(25.5)
inp = ModStatusVar(address, Var.R1VARSETPOINT, temperature)
await device_connection.async_process_input(inp)
await hass.async_block_till_done()
state = hass.states.get("climate.climate1")
assert state is not None
assert state.state == HVACMode.HEAT
assert state.attributes[ATTR_CURRENT_TEMPERATURE] is None
assert state.attributes[ATTR_TEMPERATURE] == 25.5
async def test_pushed_lock_status_change(
hass: HomeAssistant,
entry: MockConfigEntry,
) -> None:
"""Test the climate changes its setpoint on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
temperature = VarValue(0x8000)
inp = ModStatusVar(address, Var.R1VARSETPOINT, temperature)
await device_connection.async_process_input(inp)
await hass.async_block_till_done()
state = hass.states.get("climate.climate1")
assert state is not None
assert state.state == HVACMode.OFF
assert state.attributes[ATTR_CURRENT_TEMPERATURE] is None
assert state.attributes[ATTR_TEMPERATURE] is None
async def test_pushed_wrong_input(
hass: HomeAssistant,
entry: MockConfigEntry,
) -> None:
"""Test the climate handles wrong input correctly."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
await device_connection.async_process_input(Unknown("input"))
await hass.async_block_till_done()
state = hass.states.get("climate.climate1")
assert state.attributes[ATTR_CURRENT_TEMPERATURE] is None
assert state.attributes[ATTR_TEMPERATURE] is None
async def test_unload_config_entry(
hass: HomeAssistant,
entry: MockConfigEntry,
) -> None:
"""Test the climate is removed when the config entry is unloaded."""
await init_integration(hass, entry)
await hass.config_entries.async_unload(entry.entry_id)
state = hass.states.get("climate.climate1")
assert state.state == STATE_UNAVAILABLE