1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-02 16:36:08 +01:00
Files
core/tests/components/homee/test_climate.py
2026-03-05 11:15:50 +01:00

363 lines
10 KiB
Python

"""Test Homee climate entities."""
from collections.abc import AsyncGenerator
from unittest.mock import MagicMock, patch
from pyHomee.const import AttributeType
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.climate import (
ATTR_HVAC_ACTION,
ATTR_HVAC_MODE,
ATTR_HVAC_MODES,
ATTR_PRESET_MODE,
ATTR_PRESET_MODES,
ATTR_TEMPERATURE,
DOMAIN as CLIMATE_DOMAIN,
PRESET_BOOST,
PRESET_ECO,
PRESET_NONE,
SERVICE_SET_HVAC_MODE,
SERVICE_SET_PRESET_MODE,
SERVICE_SET_TEMPERATURE,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
ClimateEntityFeature,
HVACAction,
HVACMode,
)
from homeassistant.components.homee.const import PRESET_MANUAL
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import build_mock_node, setup_integration
from tests.common import MockConfigEntry, snapshot_platform
@pytest.fixture(autouse=True)
async def platforms() -> AsyncGenerator[None]:
"""Return the platforms to be loaded for this test."""
with patch("homeassistant.components.homee.PLATFORMS", [Platform.CLIMATE]):
yield
async def setup_mock_climate(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_homee: MagicMock,
file: str,
) -> None:
"""Setups a climate node for the tests."""
mock_homee.nodes = [build_mock_node(file)]
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
await setup_integration(hass, mock_config_entry)
@pytest.mark.parametrize(
("file", "entity_id", "features", "hvac_modes"),
[
(
"thermostat_only_targettemp.json",
"climate.test_thermostat_1",
ClimateEntityFeature.TARGET_TEMPERATURE,
[HVACMode.HEAT],
),
(
"thermostat_with_currenttemp.json",
"climate.test_thermostat_2",
ClimateEntityFeature.TARGET_TEMPERATURE,
[HVACMode.HEAT],
),
(
"thermostat_with_heating_mode.json",
"climate.test_thermostat_3",
ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.TURN_ON
| ClimateEntityFeature.TURN_OFF,
[HVACMode.HEAT, HVACMode.OFF],
),
(
"thermostat_with_preset.json",
"climate.test_thermostat_4",
ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.TURN_ON
| ClimateEntityFeature.TURN_OFF
| ClimateEntityFeature.PRESET_MODE,
[HVACMode.HEAT, HVACMode.OFF],
),
],
)
async def test_climate_features(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_homee: MagicMock,
file: str,
entity_id: str,
features: ClimateEntityFeature,
hvac_modes: list[HVACMode],
) -> None:
"""Test available features of climate entities."""
await setup_mock_climate(hass, mock_config_entry, mock_homee, file)
attributes = hass.states.get(entity_id).attributes
assert attributes["supported_features"] == features
assert attributes[ATTR_HVAC_MODES] == hvac_modes
async def test_climate_preset_modes(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_homee: MagicMock,
) -> None:
"""Test available preset modes of climate entities."""
await setup_mock_climate(
hass, mock_config_entry, mock_homee, "thermostat_with_preset.json"
)
attributes = hass.states.get("climate.test_thermostat_4").attributes
assert attributes[ATTR_PRESET_MODES] == [
PRESET_NONE,
PRESET_ECO,
PRESET_BOOST,
PRESET_MANUAL,
]
@pytest.mark.parametrize(
("attribute_type", "value", "expected"),
[
(AttributeType.HEATING_MODE, 0.0, HVACAction.OFF),
(AttributeType.CURRENT_VALVE_POSITION, 0.0, HVACAction.IDLE),
(AttributeType.TEMPERATURE, 25.0, HVACAction.IDLE),
(AttributeType.TEMPERATURE, 18.0, HVACAction.HEATING),
],
)
async def test_hvac_action(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_homee: MagicMock,
attribute_type: AttributeType,
value: float,
expected: HVACAction,
) -> None:
"""Test hvac action of climate entities."""
mock_homee.nodes = [build_mock_node("thermostat_with_heating_mode.json")]
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
node = mock_homee.nodes[0]
# set target temperature to 24.0
node.attributes[0].current_value = 24.0
attribute = node.get_attribute_by_type(attribute_type)
attribute.current_value = value
await setup_integration(hass, mock_config_entry)
attributes = hass.states.get("climate.test_thermostat_3").attributes
assert attributes[ATTR_HVAC_ACTION] == expected
@pytest.mark.parametrize(
("preset_mode_int", "expected"),
[
(0, PRESET_NONE),
(1, PRESET_NONE),
(2, PRESET_ECO),
(3, PRESET_BOOST),
(4, PRESET_MANUAL),
],
)
async def test_current_preset_mode(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_homee: MagicMock,
preset_mode_int: int,
expected: str,
) -> None:
"""Test current preset mode of climate entities."""
mock_homee.nodes = [build_mock_node("thermostat_with_preset.json")]
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
node = mock_homee.nodes[0]
node.attributes[2].current_value = preset_mode_int
await setup_integration(hass, mock_config_entry)
attributes = hass.states.get("climate.test_thermostat_4").attributes
assert attributes[ATTR_PRESET_MODE] == expected
@pytest.mark.parametrize(
("preset_mode_int", "expected"),
[
(10, PRESET_NONE),
(11, PRESET_NONE),
(12, PRESET_ECO),
],
)
async def test_current_preset_mode_alternate(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_homee: MagicMock,
preset_mode_int: int,
expected: str,
) -> None:
"""Test current preset mode of climate entities."""
mock_homee.nodes = [build_mock_node("thermostat_with_alternate_preset.json")]
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
node = mock_homee.nodes[0]
node.attributes[2].current_value = preset_mode_int
await setup_integration(hass, mock_config_entry)
attributes = hass.states.get("climate.test_thermostat_5").attributes
assert attributes[ATTR_PRESET_MODE] == expected
@pytest.mark.parametrize(
("service", "service_data", "expected"),
[
(
SERVICE_TURN_ON,
{},
(4, 3, 1),
),
(
SERVICE_TURN_OFF,
{},
(4, 3, 0),
),
(
SERVICE_SET_HVAC_MODE,
{ATTR_HVAC_MODE: HVACMode.HEAT},
(4, 3, 1),
),
(
SERVICE_SET_HVAC_MODE,
{ATTR_HVAC_MODE: HVACMode.OFF},
(4, 3, 0),
),
(
SERVICE_SET_TEMPERATURE,
{ATTR_TEMPERATURE: 20},
(4, 1, 20),
),
(
SERVICE_SET_PRESET_MODE,
{ATTR_PRESET_MODE: PRESET_NONE},
(4, 3, 1),
),
(
SERVICE_SET_PRESET_MODE,
{ATTR_PRESET_MODE: PRESET_ECO},
(4, 3, 2),
),
(
SERVICE_SET_PRESET_MODE,
{ATTR_PRESET_MODE: PRESET_BOOST},
(4, 3, 3),
),
(
SERVICE_SET_PRESET_MODE,
{ATTR_PRESET_MODE: PRESET_MANUAL},
(4, 3, 4),
),
],
)
async def test_climate_services(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_homee: MagicMock,
service: str,
service_data: dict,
expected: tuple[int, int, int],
) -> None:
"""Test available services of climate entities."""
await setup_mock_climate(
hass, mock_config_entry, mock_homee, "thermostat_with_preset.json"
)
await hass.services.async_call(
CLIMATE_DOMAIN,
service,
{ATTR_ENTITY_ID: "climate.test_thermostat_4", **service_data},
blocking=True,
)
mock_homee.set_value.assert_called_once_with(*expected)
@pytest.mark.parametrize(
("service", "service_data", "expected"),
[
(
SERVICE_TURN_ON,
{},
(5, 3, 11),
),
(
SERVICE_TURN_OFF,
{},
(5, 3, 10),
),
(
SERVICE_SET_HVAC_MODE,
{ATTR_HVAC_MODE: HVACMode.HEAT},
(5, 3, 11),
),
(
SERVICE_SET_HVAC_MODE,
{ATTR_HVAC_MODE: HVACMode.OFF},
(5, 3, 10),
),
(
SERVICE_SET_PRESET_MODE,
{ATTR_PRESET_MODE: PRESET_NONE},
(5, 3, 11),
),
(
SERVICE_SET_PRESET_MODE,
{ATTR_PRESET_MODE: PRESET_ECO},
(5, 3, 12),
),
],
)
async def test_climate_services_alternate(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_homee: MagicMock,
service: str,
service_data: dict,
expected: tuple[int, int, int],
) -> None:
"""Test available services of climate entities."""
await setup_mock_climate(
hass, mock_config_entry, mock_homee, "thermostat_with_alternate_preset.json"
)
await hass.services.async_call(
CLIMATE_DOMAIN,
service,
{ATTR_ENTITY_ID: "climate.test_thermostat_5", **service_data},
blocking=True,
)
mock_homee.set_value.assert_called_once_with(*expected)
async def test_climate_snapshot(
hass: HomeAssistant,
mock_homee: MagicMock,
mock_config_entry: MockConfigEntry,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
) -> None:
"""Test snapshot of climates."""
mock_homee.nodes = [
build_mock_node("thermostat_only_targettemp.json"),
build_mock_node("thermostat_with_currenttemp.json"),
build_mock_node("thermostat_with_heating_mode.json"),
build_mock_node("thermostat_with_preset.json"),
build_mock_node("thermostat_with_alternate_preset.json"),
]
await setup_integration(hass, mock_config_entry)
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)