Add climate tests for Comelit

This commit is contained in:
Simone Chemelli
2025-03-12 17:04:39 +00:00
parent 33d7e1d485
commit 6d76d312a0
8 changed files with 292 additions and 3 deletions

View File

@@ -101,6 +101,7 @@ class ComelitClimateEntity(CoordinatorEntity[ComelitSerialBridge], ClimateEntity
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_has_entity_name = True
_attr_name = None
_attr_hvac_mode: HVACMode | None = None
def __init__(
self,

View File

@@ -9,3 +9,5 @@ _LOGGER = logging.getLogger(__package__)
DOMAIN = "comelit"
DEFAULT_PORT = 80
DEVICE_TYPE_LIST = [BRIDGE, VEDO]
SCAN_INTERVAL = 5

View File

@@ -22,7 +22,7 @@ from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import _LOGGER, DOMAIN
from .const import _LOGGER, DOMAIN, SCAN_INTERVAL
type ComelitConfigEntry = ConfigEntry[ComelitBaseCoordinator]
@@ -53,7 +53,7 @@ class ComelitBaseCoordinator(DataUpdateCoordinator[T]):
logger=_LOGGER,
config_entry=entry,
name=f"{DOMAIN}-{host}-coordinator",
update_interval=timedelta(seconds=5),
update_interval=timedelta(seconds=SCAN_INTERVAL),
)
device_registry = dr.async_get(self.hass)
device_registry.async_get_or_create(

View File

@@ -97,6 +97,7 @@ class ComelitHumidifierEntity(CoordinatorEntity[ComelitSerialBridge], Humidifier
_attr_min_humidity = 10
_attr_max_humidity = 90
_attr_has_entity_name = True
_attr_mode: str | None = None
def __init__(
self,

View File

@@ -29,7 +29,24 @@ VEDO_PIN = 5678
FAKE_PIN = 0000
BRIDGE_DEVICE_QUERY = {
CLIMATE: {},
CLIMATE: {
0: ComelitSerialBridgeObject(
index=0,
name="Climate0",
status=0,
human_status="off",
type="climate",
val=[
[221, 0, "U", "M", 50, 0, 0, "U"],
[650, 0, "O", "M", 500, 0, 0, "N"],
[0, 0],
],
protected=0,
zone="Living room",
power=0.0,
power_unit=WATT,
),
},
COVER: {
0: ComelitSerialBridgeObject(
index=0,

View File

@@ -0,0 +1,69 @@
# serializer version: 1
# name: test_all_entities[climate.climate0-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'hvac_modes': list([
<HVACMode.AUTO: 'auto'>,
<HVACMode.COOL: 'cool'>,
<HVACMode.HEAT: 'heat'>,
<HVACMode.OFF: 'off'>,
]),
'max_temp': 30,
'min_temp': 5,
'target_temp_step': 0.1,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'climate',
'entity_category': None,
'entity_id': 'climate.climate0',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': None,
'platform': 'comelit',
'previous_unique_id': None,
'supported_features': <ClimateEntityFeature: 385>,
'translation_key': None,
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[climate.climate0-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'current_temperature': None,
'friendly_name': 'Climate0',
'hvac_modes': list([
<HVACMode.AUTO: 'auto'>,
<HVACMode.COOL: 'cool'>,
<HVACMode.HEAT: 'heat'>,
<HVACMode.OFF: 'off'>,
]),
'max_temp': 30,
'min_temp': 5,
'supported_features': <ClimateEntityFeature: 385>,
'target_temp_step': 0.1,
'temperature': None,
}),
'context': <ANY>,
'entity_id': 'climate.climate0',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---

View File

@@ -5,6 +5,43 @@
'devices': list([
dict({
'clima': list([
dict({
'0': dict({
'human_status': 'off',
'name': 'Climate0',
'power': 0.0,
'power_unit': 'W',
'protected': 0,
'status': 0,
'val': list([
list([
221,
0,
'U',
'M',
50,
0,
0,
'U',
]),
list([
650,
0,
'O',
'M',
500,
0,
0,
'N',
]),
list([
0,
0,
]),
]),
'zone': 'Living room',
}),
}),
]),
}),
dict({

View File

@@ -0,0 +1,162 @@
"""Tests for Comelit SimpleHome climate platform."""
from typing import Any
from unittest.mock import AsyncMock, patch
from aiocomelit.api import ComelitSerialBridgeObject
from aiocomelit.const import CLIMATE, WATT
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy import SnapshotAssertion
from syrupy.filters import props
from homeassistant.components.climate import (
ATTR_HVAC_MODE,
DOMAIN as CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE,
SERVICE_SET_TEMPERATURE,
HVACAction,
HVACMode,
)
from homeassistant.components.comelit.const import SCAN_INTERVAL
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TEMPERATURE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import setup_integration
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
ENTITY_ID = "climate.climate0"
async def test_all_entities(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
mock_serial_bridge: AsyncMock,
mock_serial_bridge_config_entry: MockConfigEntry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test all entities."""
with patch("homeassistant.components.comelit.BRIDGE_PLATFORMS", [Platform.CLIMATE]):
await setup_integration(hass, mock_serial_bridge_config_entry)
await snapshot_platform(
hass,
entity_registry,
snapshot(exclude=props("unique_id")),
mock_serial_bridge_config_entry.entry_id,
)
@pytest.mark.parametrize(
"val",
[
[
[270, 0, "U", "M", 50, 0, 0, "U"],
[650, 0, "O", "M", 500, 0, 0, "N"],
[0, 0],
],
[
[270, 1, "O", "A", 50, 1, 0, "O"],
[650, 1, "O", "A", 500, 1, 0, "N"],
[0, 0],
],
],
)
async def test_climate_data_update(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
mock_serial_bridge: AsyncMock,
mock_serial_bridge_config_entry: MockConfigEntry,
val: list[Any, Any],
) -> None:
"""Test climate data update."""
await setup_integration(hass, mock_serial_bridge_config_entry)
entity = hass.states.get(ENTITY_ID)
assert entity
assert entity.state == HVACAction.HEATING
assert entity.attributes[ATTR_TEMPERATURE] == 21.1
mock_serial_bridge.get_all_devices.return_value[CLIMATE] = {
0: ComelitSerialBridgeObject(
index=0,
name="Climate0",
status=0,
human_status="off",
type="climate",
val=val,
protected=0,
zone="Living room",
power=0.0,
power_unit=WATT,
),
}
freezer.tick(SCAN_INTERVAL + 1)
async_fire_time_changed(hass)
await hass.async_block_till_done(wait_background_tasks=True)
entity = hass.states.get(ENTITY_ID)
assert entity
assert entity.state == HVACAction.HEATING
assert entity.attributes[ATTR_TEMPERATURE] == 27
async def test_climate_set_temperature(
hass: HomeAssistant,
mock_serial_bridge: AsyncMock,
mock_serial_bridge_config_entry: MockConfigEntry,
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Test climate set temperature service."""
await setup_integration(hass, mock_serial_bridge_config_entry)
entity = hass.states.get(ENTITY_ID)
assert entity
assert entity.state == HVACMode.HEAT
assert entity.attributes[ATTR_TEMPERATURE] == 21.1
# Test set temperature
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_TEMPERATURE,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_TEMPERATURE: 23},
blocking=True,
)
mock_serial_bridge.set_clima_status.assert_called()
entity = hass.states.get(ENTITY_ID)
assert entity
assert entity.state == HVACMode.HEAT
assert entity.attributes[ATTR_TEMPERATURE] == 23
async def test_climate_hvac_mode(
hass: HomeAssistant,
mock_serial_bridge: AsyncMock,
mock_serial_bridge_config_entry: MockConfigEntry,
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Test climate hvac mode service."""
await setup_integration(hass, mock_serial_bridge_config_entry)
entity = hass.states.get(ENTITY_ID)
assert entity
assert entity.state == HVACMode.HEAT
assert entity.attributes[ATTR_TEMPERATURE] == 21.1
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_HVAC_MODE: HVACMode.OFF},
blocking=True,
)
mock_serial_bridge.set_clima_status.assert_called()
entity = hass.states.get(ENTITY_ID)
assert entity
assert entity.state == HVACMode.OFF