diff --git a/custom_components/myskoda/coordinator.py b/custom_components/myskoda/coordinator.py index 68871c9..caa13fa 100644 --- a/custom_components/myskoda/coordinator.py +++ b/custom_components/myskoda/coordinator.py @@ -1,8 +1,11 @@ import logging +from collections.abc import Coroutine + from myskoda import MySkoda, Vehicle from myskoda.event import Event, EventAccess, EventAirConditioning, ServiceEventTopic from myskoda.models.user import User from homeassistant.helpers.update_coordinator import DataUpdateCoordinator +from homeassistant.helpers.debounce import Debouncer from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from datetime import timedelta @@ -10,10 +13,29 @@ from homeassistant.util.ssl import get_default_context from myskoda.mqtt import EventCharging, EventType from .const import DOMAIN +from typing import Any _LOGGER = logging.getLogger(__name__) +class MySkodaDebouncer(Debouncer[Coroutine[Any, Any, None]]): + """Class to rate limit calls to MySkoda REST APIs.""" + + def __init__(self, hass: HomeAssistant) -> None: + """Initialize debounce.""" + super.__init__(hass, _LOGGER, cooldown=60.0, immediate=False) + + async def async_call(self) -> None: + """Call the intended function.""" + # Restart timer when calling + self.async_cancel() + await super().async_call() + + def has_pending_call(self) -> bool: + """Is there a call pending already?""" + return self._execute_at_end_of_timer + + class State: vehicles: dict[str, Vehicle] user: User @@ -39,7 +61,11 @@ def __init__(self, hass: HomeAssistant, config: ConfigEntry) -> None: """Create a new coordinator.""" super().__init__( - hass, _LOGGER, name=DOMAIN, update_interval=timedelta(minutes=30) + hass, + _LOGGER, + name=DOMAIN, + update_interval=timedelta(minutes=30), + request_refresh_debouncer=MySkodaDebouncer(hass), ) self.myskoda = MySkoda(async_get_clientsession(hass)) self.config = config