Detect reached API rate limit in Tankerkoenig (#110432)
parent
2a12369e31
commit
f13052f9aa
|
@ -12,6 +12,7 @@ from aiotankerkoenig import (
|
|||
TankerkoenigConnectionError,
|
||||
TankerkoenigError,
|
||||
TankerkoenigInvalidKeyError,
|
||||
TankerkoenigRateLimitError,
|
||||
)
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
@ -19,7 +20,7 @@ from homeassistant.const import CONF_API_KEY, CONF_SHOW_ON_MAP
|
|||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .const import CONF_FUEL_TYPES, CONF_STATIONS
|
||||
|
||||
|
@ -78,13 +79,22 @@ class TankerkoenigDataUpdateCoordinator(DataUpdateCoordinator):
|
|||
station_ids = list(self.stations)
|
||||
|
||||
prices = {}
|
||||
|
||||
# The API seems to only return at most 10 results, so split the list in chunks of 10
|
||||
# and merge it together.
|
||||
for index in range(ceil(len(station_ids) / 10)):
|
||||
data = await self._tankerkoenig.prices(
|
||||
station_ids[index * 10 : (index + 1) * 10]
|
||||
)
|
||||
try:
|
||||
data = await self._tankerkoenig.prices(
|
||||
station_ids[index * 10 : (index + 1) * 10]
|
||||
)
|
||||
except TankerkoenigInvalidKeyError as err:
|
||||
raise ConfigEntryAuthFailed(err) from err
|
||||
except (TankerkoenigError, TankerkoenigConnectionError) as err:
|
||||
if isinstance(err, TankerkoenigRateLimitError):
|
||||
_LOGGER.warning(
|
||||
"API rate limit reached, consider to increase polling interval"
|
||||
)
|
||||
raise UpdateFailed(err) from err
|
||||
|
||||
prices.update(data)
|
||||
|
||||
return prices
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
"documentation": "https://www.home-assistant.io/integrations/tankerkoenig",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["aiotankerkoenig"],
|
||||
"requirements": ["aiotankerkoenig==0.3.0"]
|
||||
"requirements": ["aiotankerkoenig==0.4.0"]
|
||||
}
|
||||
|
|
|
@ -377,7 +377,7 @@ aioswitcher==3.4.1
|
|||
aiosyncthing==0.5.1
|
||||
|
||||
# homeassistant.components.tankerkoenig
|
||||
aiotankerkoenig==0.3.0
|
||||
aiotankerkoenig==0.4.0
|
||||
|
||||
# homeassistant.components.tractive
|
||||
aiotractive==0.5.6
|
||||
|
|
|
@ -350,7 +350,7 @@ aioswitcher==3.4.1
|
|||
aiosyncthing==0.5.1
|
||||
|
||||
# homeassistant.components.tankerkoenig
|
||||
aiotankerkoenig==0.3.0
|
||||
aiotankerkoenig==0.4.0
|
||||
|
||||
# homeassistant.components.tractive
|
||||
aiotractive==0.5.6
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
"""Tests for the Tankerkoening integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import timedelta
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from aiotankerkoenig.exceptions import TankerkoenigRateLimitError
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.tankerkoenig.const import DEFAULT_SCAN_INTERVAL
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import STATE_UNAVAILABLE
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("setup_integration")
|
||||
async def test_rate_limit(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
tankerkoenig: AsyncMock,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test detection of API rate limit."""
|
||||
assert config_entry.state == ConfigEntryState.LOADED
|
||||
state = hass.states.get("binary_sensor.station_somewhere_street_1_status")
|
||||
assert state
|
||||
assert state.state == "on"
|
||||
|
||||
tankerkoenig.prices.side_effect = TankerkoenigRateLimitError
|
||||
async_fire_time_changed(
|
||||
hass, dt_util.utcnow() + timedelta(minutes=DEFAULT_SCAN_INTERVAL)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
"API rate limit reached, consider to increase polling interval" in caplog.text
|
||||
)
|
||||
state = hass.states.get("binary_sensor.station_somewhere_street_1_status")
|
||||
assert state
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
tankerkoenig.prices.side_effect = None
|
||||
async_fire_time_changed(
|
||||
hass, dt_util.utcnow() + timedelta(minutes=DEFAULT_SCAN_INTERVAL * 2)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("binary_sensor.station_somewhere_street_1_status")
|
||||
assert state
|
||||
assert state.state == "on"
|
Loading…
Reference in New Issue