mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Add coordinator to suez_water (#129242)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
d75dda0c05
commit
274c928ec0
@ -2,15 +2,12 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pysuez import SuezClient
|
||||
from pysuez.client import PySuezError
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryError, ConfigEntryNotReady
|
||||
|
||||
from .const import CONF_COUNTER_ID, DOMAIN
|
||||
from .const import DOMAIN
|
||||
from .coordinator import SuezWaterCoordinator
|
||||
|
||||
PLATFORMS: list[Platform] = [Platform.SENSOR]
|
||||
|
||||
@ -18,23 +15,10 @@ PLATFORMS: list[Platform] = [Platform.SENSOR]
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up Suez Water from a config entry."""
|
||||
|
||||
def get_client() -> SuezClient:
|
||||
try:
|
||||
client = SuezClient(
|
||||
entry.data[CONF_USERNAME],
|
||||
entry.data[CONF_PASSWORD],
|
||||
entry.data[CONF_COUNTER_ID],
|
||||
provider=None,
|
||||
)
|
||||
if not client.check_credentials():
|
||||
raise ConfigEntryError
|
||||
except PySuezError as ex:
|
||||
raise ConfigEntryNotReady from ex
|
||||
return client
|
||||
coordinator = SuezWaterCoordinator(hass, entry)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})[
|
||||
entry.entry_id
|
||||
] = await hass.async_add_executor_job(get_client)
|
||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
"""Constants for the Suez Water integration."""
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
DOMAIN = "suez_water"
|
||||
|
||||
CONF_COUNTER_ID = "counter_id"
|
||||
|
||||
DATA_REFRESH_INTERVAL = timedelta(hours=12)
|
||||
|
108
homeassistant/components/suez_water/coordinator.py
Normal file
108
homeassistant/components/suez_water/coordinator.py
Normal file
@ -0,0 +1,108 @@
|
||||
"""Suez water update coordinator."""
|
||||
|
||||
import asyncio
|
||||
from dataclasses import dataclass
|
||||
from datetime import date
|
||||
|
||||
from pysuez import SuezClient
|
||||
from pysuez.client import PySuezError
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import _LOGGER, HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryError, ConfigEntryNotReady
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .const import CONF_COUNTER_ID, DATA_REFRESH_INTERVAL, DOMAIN
|
||||
|
||||
|
||||
@dataclass
|
||||
class AggregatedSensorData:
|
||||
"""Hold suez water aggregated sensor data."""
|
||||
|
||||
value: float
|
||||
current_month: dict[date, float]
|
||||
previous_month: dict[date, float]
|
||||
previous_year: dict[str, float]
|
||||
current_year: dict[str, float]
|
||||
history: dict[date, float]
|
||||
highest_monthly_consumption: float
|
||||
attribution: str
|
||||
|
||||
|
||||
class SuezWaterCoordinator(DataUpdateCoordinator[AggregatedSensorData]):
|
||||
"""Suez water coordinator."""
|
||||
|
||||
_sync_client: SuezClient
|
||||
config_entry: ConfigEntry
|
||||
|
||||
def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
||||
"""Initialize suez water coordinator."""
|
||||
super().__init__(
|
||||
hass,
|
||||
_LOGGER,
|
||||
name=DOMAIN,
|
||||
update_interval=DATA_REFRESH_INTERVAL,
|
||||
always_update=True,
|
||||
config_entry=config_entry,
|
||||
)
|
||||
|
||||
async def _async_setup(self) -> None:
|
||||
self._sync_client = await self.hass.async_add_executor_job(self._get_client)
|
||||
|
||||
async def _async_update_data(self) -> AggregatedSensorData:
|
||||
"""Fetch data from API endpoint."""
|
||||
async with asyncio.timeout(30):
|
||||
return await self.hass.async_add_executor_job(self._fetch_data)
|
||||
|
||||
def _fetch_data(self) -> AggregatedSensorData:
|
||||
"""Fetch latest data from Suez."""
|
||||
try:
|
||||
self._sync_client.update()
|
||||
except PySuezError as err:
|
||||
raise UpdateFailed(
|
||||
f"Suez coordinator error communicating with API: {err}"
|
||||
) from err
|
||||
current_month = {}
|
||||
for item in self._sync_client.attributes["thisMonthConsumption"]:
|
||||
current_month[item] = self._sync_client.attributes["thisMonthConsumption"][
|
||||
item
|
||||
]
|
||||
previous_month = {}
|
||||
for item in self._sync_client.attributes["previousMonthConsumption"]:
|
||||
previous_month[item] = self._sync_client.attributes[
|
||||
"previousMonthConsumption"
|
||||
][item]
|
||||
highest_monthly_consumption = self._sync_client.attributes[
|
||||
"highestMonthlyConsumption"
|
||||
]
|
||||
previous_year = self._sync_client.attributes["lastYearOverAll"]
|
||||
current_year = self._sync_client.attributes["thisYearOverAll"]
|
||||
history = {}
|
||||
for item in self._sync_client.attributes["history"]:
|
||||
history[item] = self._sync_client.attributes["history"][item]
|
||||
_LOGGER.debug("Retrieved consumption: " + str(self._sync_client.state))
|
||||
return AggregatedSensorData(
|
||||
self._sync_client.state,
|
||||
current_month,
|
||||
previous_month,
|
||||
previous_year,
|
||||
current_year,
|
||||
history,
|
||||
highest_monthly_consumption,
|
||||
self._sync_client.attributes["attribution"],
|
||||
)
|
||||
|
||||
def _get_client(self) -> SuezClient:
|
||||
try:
|
||||
client = SuezClient(
|
||||
username=self.config_entry.data[CONF_USERNAME],
|
||||
password=self.config_entry.data[CONF_PASSWORD],
|
||||
counter_id=self.config_entry.data[CONF_COUNTER_ID],
|
||||
provider=None,
|
||||
)
|
||||
if not client.check_credentials():
|
||||
raise ConfigEntryError
|
||||
except PySuezError as ex:
|
||||
raise ConfigEntryNotReady from ex
|
||||
return client
|
@ -2,11 +2,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from pysuez import SuezClient
|
||||
from pysuez.client import PySuezError
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
@ -14,12 +11,10 @@ from homeassistant.const import UnitOfVolume
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import CONF_COUNTER_ID, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SCAN_INTERVAL = timedelta(hours=12)
|
||||
from .coordinator import SuezWaterCoordinator
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -28,11 +23,11 @@ async def async_setup_entry(
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Suez Water sensor from a config entry."""
|
||||
client = hass.data[DOMAIN][entry.entry_id]
|
||||
async_add_entities([SuezSensor(client, entry.data[CONF_COUNTER_ID])], True)
|
||||
coordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
async_add_entities([SuezAggregatedSensor(coordinator, entry.data[CONF_COUNTER_ID])])
|
||||
|
||||
|
||||
class SuezSensor(SensorEntity):
|
||||
class SuezAggregatedSensor(CoordinatorEntity[SuezWaterCoordinator], SensorEntity):
|
||||
"""Representation of a Sensor."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
@ -40,9 +35,9 @@ class SuezSensor(SensorEntity):
|
||||
_attr_native_unit_of_measurement = UnitOfVolume.LITERS
|
||||
_attr_device_class = SensorDeviceClass.WATER
|
||||
|
||||
def __init__(self, client: SuezClient, counter_id: int) -> None:
|
||||
def __init__(self, coordinator: SuezWaterCoordinator, counter_id: int) -> None:
|
||||
"""Initialize the data object."""
|
||||
self.client = client
|
||||
super().__init__(coordinator)
|
||||
self._attr_extra_state_attributes = {}
|
||||
self._attr_unique_id = f"{counter_id}_water_usage_yesterday"
|
||||
self._attr_device_info = DeviceInfo(
|
||||
@ -51,45 +46,24 @@ class SuezSensor(SensorEntity):
|
||||
manufacturer="Suez",
|
||||
)
|
||||
|
||||
def _fetch_data(self) -> None:
|
||||
"""Fetch latest data from Suez."""
|
||||
try:
|
||||
self.client.update()
|
||||
# _state holds the volume of consumed water during previous day
|
||||
self._attr_native_value = self.client.state
|
||||
self._attr_available = True
|
||||
self._attr_attribution = self.client.attributes["attribution"]
|
||||
@property
|
||||
def native_value(self) -> float:
|
||||
"""Return the current daily usage."""
|
||||
return self.coordinator.data.value
|
||||
|
||||
self._attr_extra_state_attributes["this_month_consumption"] = {}
|
||||
for item in self.client.attributes["thisMonthConsumption"]:
|
||||
self._attr_extra_state_attributes["this_month_consumption"][item] = (
|
||||
self.client.attributes["thisMonthConsumption"][item]
|
||||
)
|
||||
self._attr_extra_state_attributes["previous_month_consumption"] = {}
|
||||
for item in self.client.attributes["previousMonthConsumption"]:
|
||||
self._attr_extra_state_attributes["previous_month_consumption"][
|
||||
item
|
||||
] = self.client.attributes["previousMonthConsumption"][item]
|
||||
self._attr_extra_state_attributes["highest_monthly_consumption"] = (
|
||||
self.client.attributes["highestMonthlyConsumption"]
|
||||
)
|
||||
self._attr_extra_state_attributes["last_year_overall"] = (
|
||||
self.client.attributes["lastYearOverAll"]
|
||||
)
|
||||
self._attr_extra_state_attributes["this_year_overall"] = (
|
||||
self.client.attributes["thisYearOverAll"]
|
||||
)
|
||||
self._attr_extra_state_attributes["history"] = {}
|
||||
for item in self.client.attributes["history"]:
|
||||
self._attr_extra_state_attributes["history"][item] = (
|
||||
self.client.attributes["history"][item]
|
||||
)
|
||||
@property
|
||||
def attribution(self) -> str:
|
||||
"""Return data attribution message."""
|
||||
return self.coordinator.data.attribution
|
||||
|
||||
except PySuezError:
|
||||
self._attr_available = False
|
||||
_LOGGER.warning("Unable to fetch data")
|
||||
|
||||
def update(self) -> None:
|
||||
"""Return the latest collected data from Suez."""
|
||||
self._fetch_data()
|
||||
_LOGGER.debug("Suez data state is: %s", self.native_value)
|
||||
@property
|
||||
def extra_state_attributes(self) -> Mapping[str, Any]:
|
||||
"""Return aggregated data."""
|
||||
return {
|
||||
"this_month_consumption": self.coordinator.data.current_month,
|
||||
"previous_month_consumption": self.coordinator.data.previous_month,
|
||||
"highest_monthly_consumption": self.coordinator.data.highest_monthly_consumption,
|
||||
"last_year_overall": self.coordinator.data.previous_year,
|
||||
"this_year_overall": self.coordinator.data.current_year,
|
||||
"history": self.coordinator.data.history,
|
||||
}
|
||||
|
@ -1 +1,15 @@
|
||||
"""Tests for the Suez Water integration."""
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def setup_integration(
|
||||
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
"""Init suez water integration."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -1,10 +1,31 @@
|
||||
"""Common fixtures for the Suez Water tests."""
|
||||
|
||||
from collections.abc import Generator
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.suez_water.const import DOMAIN
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
MOCK_DATA = {
|
||||
"username": "test-username",
|
||||
"password": "test-password",
|
||||
"counter_id": "test-counter",
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config_entry() -> MockConfigEntry:
|
||||
"""Create mock config_entry needed by suez_water integration."""
|
||||
return MockConfigEntry(
|
||||
unique_id=MOCK_DATA["username"],
|
||||
domain=DOMAIN,
|
||||
title="Suez mock device",
|
||||
data=MOCK_DATA,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_setup_entry() -> Generator[AsyncMock]:
|
||||
@ -13,3 +34,42 @@ def mock_setup_entry() -> Generator[AsyncMock]:
|
||||
"homeassistant.components.suez_water.async_setup_entry", return_value=True
|
||||
) as mock_setup_entry:
|
||||
yield mock_setup_entry
|
||||
|
||||
|
||||
@pytest.fixture(name="suez_client")
|
||||
def mock_suez_client() -> Generator[MagicMock]:
|
||||
"""Create mock for suez_water external api."""
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.suez_water.coordinator.SuezClient", autospec=True
|
||||
) as mock_client,
|
||||
patch(
|
||||
"homeassistant.components.suez_water.config_flow.SuezClient",
|
||||
new=mock_client,
|
||||
),
|
||||
):
|
||||
client = mock_client.return_value
|
||||
client.check_credentials.return_value = True
|
||||
client.update.return_value = None
|
||||
client.state = 160
|
||||
client.attributes = {
|
||||
"thisMonthConsumption": {
|
||||
"2024-01-01": 130,
|
||||
"2024-01-02": 145,
|
||||
},
|
||||
"previousMonthConsumption": {
|
||||
"2024-12-01": 154,
|
||||
"2024-12-02": 166,
|
||||
},
|
||||
"highestMonthlyConsumption": 2558,
|
||||
"lastYearOverAll": 1000,
|
||||
"thisYearOverAll": 1500,
|
||||
"history": {
|
||||
"2024-01-01": 130,
|
||||
"2024-01-02": 145,
|
||||
"2024-12-01": 154,
|
||||
"2024-12-02": 166,
|
||||
},
|
||||
"attribution": "suez water mock test",
|
||||
}
|
||||
yield client
|
||||
|
67
tests/components/suez_water/snapshots/test_sensor.ambr
Normal file
67
tests/components/suez_water/snapshots/test_sensor.ambr
Normal file
@ -0,0 +1,67 @@
|
||||
# serializer version: 1
|
||||
# name: test_sensors_valid_state[sensor.suez_mock_device_water_usage_yesterday-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.suez_mock_device_water_usage_yesterday',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.WATER: 'water'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Water usage yesterday',
|
||||
'platform': 'suez_water',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'water_usage_yesterday',
|
||||
'unique_id': 'test-counter_water_usage_yesterday',
|
||||
'unit_of_measurement': <UnitOfVolume.LITERS: 'L'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors_valid_state[sensor.suez_mock_device_water_usage_yesterday-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'attribution': 'suez water mock test',
|
||||
'device_class': 'water',
|
||||
'friendly_name': 'Suez mock device Water usage yesterday',
|
||||
'highest_monthly_consumption': 2558,
|
||||
'history': dict({
|
||||
'2024-01-01': 130,
|
||||
'2024-01-02': 145,
|
||||
'2024-12-01': 154,
|
||||
'2024-12-02': 166,
|
||||
}),
|
||||
'last_year_overall': 1000,
|
||||
'previous_month_consumption': dict({
|
||||
'2024-12-01': 154,
|
||||
'2024-12-02': 166,
|
||||
}),
|
||||
'this_month_consumption': dict({
|
||||
'2024-01-01': 130,
|
||||
'2024-01-02': 145,
|
||||
}),
|
||||
'this_year_overall': 1500,
|
||||
'unit_of_measurement': <UnitOfVolume.LITERS: 'L'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.suez_mock_device_water_usage_yesterday',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '160',
|
||||
})
|
||||
# ---
|
@ -10,13 +10,9 @@ from homeassistant.components.suez_water.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from .conftest import MOCK_DATA
|
||||
|
||||
MOCK_DATA = {
|
||||
"username": "test-username",
|
||||
"password": "test-password",
|
||||
"counter_id": "test-counter",
|
||||
}
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_form(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
||||
|
35
tests/components/suez_water/test_init.py
Normal file
35
tests/components/suez_water/test_init.py
Normal file
@ -0,0 +1,35 @@
|
||||
"""Test Suez_water integration initialization."""
|
||||
|
||||
from homeassistant.components.suez_water.coordinator import PySuezError
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import setup_integration
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_initialization_invalid_credentials(
|
||||
hass: HomeAssistant,
|
||||
suez_client,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test that suez_water can't be loaded with invalid credentials."""
|
||||
|
||||
suez_client.check_credentials.return_value = False
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR
|
||||
|
||||
|
||||
async def test_initialization_setup_api_error(
|
||||
hass: HomeAssistant,
|
||||
suez_client,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test that suez_water needs to retry loading if api failed to connect."""
|
||||
|
||||
suez_client.check_credentials.side_effect = PySuezError("Test failure")
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
62
tests/components/suez_water/test_sensor.py
Normal file
62
tests/components/suez_water/test_sensor.py
Normal file
@ -0,0 +1,62 @@
|
||||
"""Test Suez_water sensor platform."""
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.suez_water.const import DATA_REFRESH_INTERVAL
|
||||
from homeassistant.components.suez_water.coordinator import PySuezError
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import STATE_UNAVAILABLE, 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
|
||||
|
||||
|
||||
async def test_sensors_valid_state(
|
||||
hass: HomeAssistant,
|
||||
snapshot: SnapshotAssertion,
|
||||
suez_client: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test that suez_water sensor is loaded and in a valid state."""
|
||||
with patch("homeassistant.components.suez_water.PLATFORMS", [Platform.SENSOR]):
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
|
||||
async def test_sensors_failed_update(
|
||||
hass: HomeAssistant,
|
||||
suez_client,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test that suez_water sensor reflect failure when api fails."""
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
entity_ids = await hass.async_add_executor_job(hass.states.entity_ids)
|
||||
assert len(entity_ids) == 1
|
||||
|
||||
state = hass.states.get(entity_ids[0])
|
||||
assert entity_ids[0]
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
|
||||
suez_client.update.side_effect = PySuezError("Should fail to update")
|
||||
|
||||
freezer.tick(DATA_REFRESH_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done(True)
|
||||
|
||||
state = hass.states.get(entity_ids[0])
|
||||
assert state
|
||||
assert state.state == STATE_UNAVAILABLE
|
Loading…
x
Reference in New Issue
Block a user