mirror of
https://github.com/home-assistant/core.git
synced 2026-08-31 18:24:50 -05:00
Improve iaqualink 429 handling (#170231)
This commit is contained in:
@@ -8,6 +8,7 @@ from typing import Any
|
||||
import httpx
|
||||
from iaqualink.exception import (
|
||||
AqualinkServiceException,
|
||||
AqualinkServiceThrottledException,
|
||||
AqualinkServiceUnauthorizedException,
|
||||
)
|
||||
|
||||
@@ -46,6 +47,12 @@ class AqualinkDataUpdateCoordinator(DataUpdateCoordinator[None]):
|
||||
await self.system.update()
|
||||
except AqualinkServiceUnauthorizedException as err:
|
||||
raise ConfigEntryAuthFailed("Invalid credentials for iAquaLink") from err
|
||||
except AqualinkServiceThrottledException:
|
||||
_LOGGER.warning(
|
||||
"Rate limited by iAquaLink system %s, will retry later",
|
||||
self.system.serial,
|
||||
)
|
||||
return
|
||||
except (AqualinkServiceException, httpx.HTTPError) as err:
|
||||
raise UpdateFailed(
|
||||
f"Unable to update iAquaLink system {self.system.serial}: {err}"
|
||||
|
||||
@@ -6,6 +6,7 @@ from freezegun.api import FrozenDateTimeFactory
|
||||
from iaqualink.client import AqualinkClient
|
||||
from iaqualink.exception import (
|
||||
AqualinkServiceException,
|
||||
AqualinkServiceThrottledException,
|
||||
AqualinkServiceUnauthorizedException,
|
||||
)
|
||||
from iaqualink.systems.iaqua.device import (
|
||||
@@ -16,6 +17,7 @@ from iaqualink.systems.iaqua.device import (
|
||||
IaquaThermostat,
|
||||
)
|
||||
from iaqualink.systems.iaqua.system import IaquaSystem
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
|
||||
from homeassistant.components.climate import DOMAIN as CLIMATE_DOMAIN
|
||||
@@ -46,7 +48,9 @@ async def _advance_coordinator_time(
|
||||
hass: HomeAssistant, freezer: FrozenDateTimeFactory
|
||||
) -> None:
|
||||
"""Advance time to trigger coordinator update interval."""
|
||||
freezer.tick(delta=UPDATE_INTERVAL_BY_SYSTEM_TYPE["iaqua"])
|
||||
update_interval = UPDATE_INTERVAL_BY_SYSTEM_TYPE["iaqua"]
|
||||
|
||||
freezer.tick(delta=update_interval)
|
||||
async_fire_time_changed(hass, dt_util.utcnow())
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
@@ -104,6 +108,57 @@ async def test_system_refresh_failure_marks_entities_unavailable(
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_system_rate_limited_keeps_entities_available(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
client: AqualinkClient,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test a rate-limited update keeps entities at their last known state."""
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
system = get_aqualink_system(client, cls=IaquaSystem)
|
||||
system.online = True
|
||||
system.update = AsyncMock()
|
||||
systems = {system.serial: system}
|
||||
light = get_aqualink_device(
|
||||
system, name="aux_1", cls=IaquaLightSwitch, data={"state": "1"}
|
||||
)
|
||||
devices = {light.name: light}
|
||||
system.get_devices = AsyncMock(return_value=devices)
|
||||
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.iaqualink.AqualinkClient.login",
|
||||
return_value=None,
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.iaqualink.AqualinkClient.get_systems",
|
||||
return_value=systems,
|
||||
),
|
||||
):
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entity_ids = hass.states.async_entity_ids(LIGHT_DOMAIN)
|
||||
assert len(entity_ids) == 1
|
||||
entity_id = entity_ids[0]
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state is not None
|
||||
assert state.state == STATE_ON
|
||||
|
||||
system.update = AsyncMock(side_effect=AqualinkServiceThrottledException)
|
||||
|
||||
await _advance_coordinator_time(hass, freezer)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state is not None
|
||||
assert state.state == STATE_ON
|
||||
assert "Rate limited by iAquaLink" in caplog.text
|
||||
|
||||
|
||||
async def test_light_service_calls_update_entity_state(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
|
||||
Reference in New Issue
Block a user