Fix touchline_sl zone availability when alarm state is set (#163338)

This commit is contained in:
Thomas Sejr Madsen
2026-02-20 19:38:55 +00:00
committed by Franck Nijhof
parent ec56f183da
commit d0678e0641
3 changed files with 94 additions and 2 deletions
@@ -35,4 +35,8 @@ class TouchlineSLZoneEntity(CoordinatorEntity[TouchlineSLModuleCoordinator]):
@property
def available(self) -> bool:
"""Return if the device is available."""
return super().available and self.zone_id in self.coordinator.data.zones
return (
super().available
and self.zone_id in self.coordinator.data.zones
and self.zone.alarm is None
)
+34 -1
View File
@@ -2,7 +2,7 @@
from collections.abc import Generator
from typing import NamedTuple
from unittest.mock import AsyncMock, patch
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
@@ -19,6 +19,39 @@ class FakeModule(NamedTuple):
id: str
def make_mock_zone(
zone_id: int = 1, name: str = "Zone 1", alarm: str | None = None
) -> MagicMock:
"""Return a mock Zone with configurable alarm state."""
zone = MagicMock()
zone.id = zone_id
zone.name = name
zone.temperature = 21.5
zone.target_temperature = 22.0
zone.humidity = 45
zone.mode = "constantTemp"
zone.algorithm = "heating"
zone.relay_on = False
zone.alarm = alarm
zone.schedule = None
zone.enabled = True
zone.signal_strength = 100
zone.battery_level = None
return zone
def make_mock_module(zones: list) -> MagicMock:
"""Return a mock module with the given zones."""
module = MagicMock()
module.id = "deadbeef"
module.name = "Foobar"
module.type = "SL"
module.version = "1.0"
module.zones = AsyncMock(return_value=zones)
module.schedules = AsyncMock(return_value=[])
return module
@pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock]:
"""Override async_setup_entry."""
@@ -0,0 +1,55 @@
"""Tests for the Roth Touchline SL climate platform."""
from unittest.mock import AsyncMock, MagicMock
import pytest
from homeassistant.components.climate import HVACMode
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from .conftest import make_mock_module, make_mock_zone
from tests.common import MockConfigEntry
ENTITY_ID = "climate.zone_1"
async def test_climate_zone_available(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_touchlinesl_client: MagicMock,
) -> None:
"""Test that the climate entity is available when zone has no alarm."""
zone = make_mock_zone(alarm=None)
module = make_mock_module([zone])
mock_touchlinesl_client.modules = AsyncMock(return_value=[module])
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == HVACMode.HEAT
@pytest.mark.parametrize("alarm", ["no_communication", "sensor_damaged"])
async def test_climate_zone_unavailable_on_alarm(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_touchlinesl_client: MagicMock,
alarm: str,
) -> None:
"""Test that the climate entity is unavailable when zone reports an alarm state."""
zone = make_mock_zone(alarm=alarm)
module = make_mock_module([zone])
mock_touchlinesl_client.modules = AsyncMock(return_value=[module])
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == STATE_UNAVAILABLE