core/tests/components/nibe_heatpump/test_climate.py

318 lines
9.0 KiB
Python
Raw Normal View History

"""Test the Nibe Heat Pump config flow."""
from typing import Any
from unittest.mock import call, patch
from nibe.coil import CoilData
from nibe.coil_groups import (
CLIMATE_COILGROUPS,
UNIT_COILGROUPS,
ClimateCoilGroup,
UnitCoilGroup,
)
from nibe.heatpump import Model
import pytest
from syrupy import SnapshotAssertion
from homeassistant.components.climate import (
ATTR_HVAC_MODE,
ATTR_TARGET_TEMP_HIGH,
ATTR_TARGET_TEMP_LOW,
ATTR_TEMPERATURE,
DOMAIN as PLATFORM_DOMAIN,
SERVICE_SET_HVAC_MODE,
SERVICE_SET_TEMPERATURE,
HVACMode,
)
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from . import MockConnection, async_add_model
@pytest.fixture(autouse=True)
async def fixture_single_platform():
"""Only allow this platform to load."""
with patch("homeassistant.components.nibe_heatpump.PLATFORMS", [Platform.CLIMATE]):
yield
def _setup_climate_group(
coils: dict[int, Any], model: Model, climate_id: str
) -> tuple[ClimateCoilGroup, UnitCoilGroup]:
"""Initialize coils for a climate group, with some default values."""
climate = CLIMATE_COILGROUPS[model.series][climate_id]
unit = UNIT_COILGROUPS[model.series]["main"]
if climate.active_accessory is not None:
coils[climate.active_accessory] = "ON"
coils[climate.current] = 20.5
coils[climate.setpoint_heat] = 21.0
coils[climate.setpoint_cool] = 30.0
coils[climate.mixing_valve_state] = 20
coils[climate.use_room_sensor] = "ON"
coils[unit.prio] = "OFF"
coils[unit.cooling_with_room_sensor] = "ON"
return climate, unit
@pytest.mark.parametrize(
("model", "climate_id", "entity_id"),
[
(Model.S320, "s1", "climate.climate_system_s1"),
(Model.F1155, "s2", "climate.climate_system_s2"),
],
)
async def test_basic(
hass: HomeAssistant,
mock_connection: MockConnection,
model: Model,
climate_id: str,
entity_id: str,
coils: dict[int, Any],
entity_registry_enabled_by_default: None,
snapshot: SnapshotAssertion,
) -> None:
"""Test setting of value."""
climate, unit = _setup_climate_group(coils, model, climate_id)
await async_add_model(hass, model)
assert hass.states.get(entity_id) == snapshot(name="initial")
mock_connection.mock_coil_update(unit.prio, "COOLING")
assert hass.states.get(entity_id) == snapshot(name="cooling")
mock_connection.mock_coil_update(unit.prio, "HEAT")
assert hass.states.get(entity_id) == snapshot(name="heating")
mock_connection.mock_coil_update(climate.mixing_valve_state, 30)
assert hass.states.get(entity_id) == snapshot(name="idle (mixing valve)")
mock_connection.mock_coil_update(climate.mixing_valve_state, 20)
mock_connection.mock_coil_update(unit.cooling_with_room_sensor, "OFF")
assert hass.states.get(entity_id) == snapshot(name="heating (only)")
mock_connection.mock_coil_update(climate.use_room_sensor, "OFF")
assert hass.states.get(entity_id) == snapshot(name="heating (auto)")
mock_connection.mock_coil_update(unit.prio, None)
assert hass.states.get(entity_id) == snapshot(name="off (auto)")
coils.clear()
assert hass.states.get(entity_id) == snapshot(name="unavailable")
@pytest.mark.parametrize(
("model", "climate_id", "entity_id"),
[
(Model.F1155, "s2", "climate.climate_system_s2"),
(Model.F1155, "s3", "climate.climate_system_s3"),
],
)
async def test_active_accessory(
hass: HomeAssistant,
mock_connection: MockConnection,
model: Model,
climate_id: str,
entity_id: str,
coils: dict[int, Any],
entity_registry_enabled_by_default: None,
snapshot: SnapshotAssertion,
) -> None:
"""Test climate groups that can be deactivated by configuration."""
climate, unit = _setup_climate_group(coils, model, climate_id)
await async_add_model(hass, model)
assert hass.states.get(entity_id) == snapshot(name="initial")
mock_connection.mock_coil_update(climate.active_accessory, "OFF")
assert hass.states.get(entity_id) == snapshot(name="unavailable (not supported)")
@pytest.mark.parametrize(
("model", "climate_id", "entity_id"),
[
(Model.S320, "s1", "climate.climate_system_s1"),
(Model.F1155, "s2", "climate.climate_system_s2"),
],
)
async def test_set_temperature(
hass: HomeAssistant,
mock_connection: MockConnection,
model: Model,
climate_id: str,
entity_id: str,
coils: dict[int, Any],
entity_registry_enabled_by_default: None,
snapshot: SnapshotAssertion,
) -> None:
"""Test setting temperature."""
climate, _ = _setup_climate_group(coils, model, climate_id)
await async_add_model(hass, model)
coil_setpoint_heat = mock_connection.heatpump.get_coil_by_address(
climate.setpoint_heat
)
coil_setpoint_cool = mock_connection.heatpump.get_coil_by_address(
climate.setpoint_cool
)
await hass.services.async_call(
PLATFORM_DOMAIN,
SERVICE_SET_TEMPERATURE,
{
ATTR_ENTITY_ID: entity_id,
ATTR_TEMPERATURE: 22,
ATTR_HVAC_MODE: HVACMode.HEAT,
},
blocking=True,
)
await hass.async_block_till_done()
assert mock_connection.write_coil.mock_calls == [
call(CoilData(coil_setpoint_heat, 22))
]
mock_connection.write_coil.reset_mock()
await hass.services.async_call(
PLATFORM_DOMAIN,
SERVICE_SET_TEMPERATURE,
{
ATTR_ENTITY_ID: entity_id,
ATTR_TEMPERATURE: 22,
ATTR_HVAC_MODE: HVACMode.COOL,
},
blocking=True,
)
await hass.async_block_till_done()
assert mock_connection.write_coil.mock_calls == [
call(CoilData(coil_setpoint_cool, 22))
]
mock_connection.write_coil.reset_mock()
with pytest.raises(ValueError):
await hass.services.async_call(
PLATFORM_DOMAIN,
SERVICE_SET_TEMPERATURE,
{
ATTR_ENTITY_ID: entity_id,
ATTR_TEMPERATURE: 22,
},
blocking=True,
)
await hass.services.async_call(
PLATFORM_DOMAIN,
SERVICE_SET_TEMPERATURE,
{
ATTR_ENTITY_ID: entity_id,
ATTR_TARGET_TEMP_HIGH: 30,
ATTR_TARGET_TEMP_LOW: 22,
},
blocking=True,
)
await hass.async_block_till_done()
assert mock_connection.write_coil.mock_calls == [
call(CoilData(coil_setpoint_heat, 22)),
call(CoilData(coil_setpoint_cool, 30)),
]
mock_connection.write_coil.reset_mock()
@pytest.mark.parametrize(
("hvac_mode", "cooling_with_room_sensor", "use_room_sensor"),
[
(HVACMode.HEAT_COOL, "ON", "ON"),
(HVACMode.HEAT, "OFF", "ON"),
(HVACMode.AUTO, "OFF", "OFF"),
],
)
@pytest.mark.parametrize(
("model", "climate_id", "entity_id"),
[
(Model.S320, "s1", "climate.climate_system_s1"),
(Model.F1155, "s2", "climate.climate_system_s2"),
],
)
async def test_set_hvac_mode(
hass: HomeAssistant,
mock_connection: MockConnection,
model: Model,
climate_id: str,
entity_id: str,
cooling_with_room_sensor: str,
use_room_sensor: str,
hvac_mode: HVACMode,
coils: dict[int, Any],
entity_registry_enabled_by_default: None,
) -> None:
"""Test setting a hvac mode."""
climate, unit = _setup_climate_group(coils, model, climate_id)
await async_add_model(hass, model)
coil_use_room_sensor = mock_connection.heatpump.get_coil_by_address(
climate.use_room_sensor
)
coil_cooling_with_room_sensor = mock_connection.heatpump.get_coil_by_address(
unit.cooling_with_room_sensor
)
await hass.services.async_call(
PLATFORM_DOMAIN,
SERVICE_SET_HVAC_MODE,
{
ATTR_ENTITY_ID: entity_id,
ATTR_HVAC_MODE: hvac_mode,
},
blocking=True,
)
await hass.async_block_till_done()
assert mock_connection.write_coil.mock_calls == [
call(CoilData(coil_cooling_with_room_sensor, cooling_with_room_sensor)),
call(CoilData(coil_use_room_sensor, use_room_sensor)),
]
@pytest.mark.parametrize(
("model", "climate_id", "entity_id"),
[
(Model.S320, "s1", "climate.climate_system_s1"),
(Model.F1155, "s2", "climate.climate_system_s2"),
],
)
async def test_set_invalid_hvac_mode(
hass: HomeAssistant,
mock_connection: MockConnection,
model: Model,
climate_id: str,
entity_id: str,
coils: dict[int, Any],
entity_registry_enabled_by_default: None,
) -> None:
"""Test setting an invalid hvac mode."""
_setup_climate_group(coils, model, climate_id)
await async_add_model(hass, model)
with pytest.raises(ValueError):
await hass.services.async_call(
PLATFORM_DOMAIN,
SERVICE_SET_HVAC_MODE,
{
ATTR_ENTITY_ID: entity_id,
ATTR_HVAC_MODE: HVACMode.DRY,
},
blocking=True,
)
await hass.async_block_till_done()
assert mock_connection.write_coil.mock_calls == []