Remove dynamic rate limits from Tesla Fleet (#138576)

* remove

* TEsts
pull/138605/head
Brett Adams 2025-02-16 01:27:29 +10:00 committed by GitHub
parent 08f6e9cd12
commit c89d8edb3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 13 additions and 27 deletions

View File

@ -17,7 +17,6 @@ from tesla_fleet_api.exceptions import (
TeslaFleetError, TeslaFleetError,
VehicleOffline, VehicleOffline,
) )
from tesla_fleet_api.ratecalculator import RateCalculator
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.exceptions import ConfigEntryAuthFailed
@ -66,7 +65,6 @@ class TeslaFleetVehicleDataCoordinator(DataUpdateCoordinator[dict[str, Any]]):
updated_once: bool updated_once: bool
pre2021: bool pre2021: bool
last_active: datetime last_active: datetime
rate: RateCalculator
def __init__( def __init__(
self, self,
@ -87,44 +85,36 @@ class TeslaFleetVehicleDataCoordinator(DataUpdateCoordinator[dict[str, Any]]):
self.data = flatten(product) self.data = flatten(product)
self.updated_once = False self.updated_once = False
self.last_active = datetime.now() self.last_active = datetime.now()
self.rate = RateCalculator(100, 86400, VEHICLE_INTERVAL_SECONDS, 3600, 5)
async def _async_update_data(self) -> dict[str, Any]: async def _async_update_data(self) -> dict[str, Any]:
"""Update vehicle data using TeslaFleet API.""" """Update vehicle data using TeslaFleet API."""
try: try:
# Check if the vehicle is awake using a non-rate limited API call # Check if the vehicle is awake using a free API call
if self.data["state"] != TeslaFleetState.ONLINE: response = await self.api.vehicle()
response = await self.api.vehicle() self.data["state"] = response["response"]["state"]
self.data["state"] = response["response"]["state"]
if self.data["state"] != TeslaFleetState.ONLINE: if self.data["state"] != TeslaFleetState.ONLINE:
return self.data return self.data
# This is a rated limited API call
self.rate.consume()
response = await self.api.vehicle_data(endpoints=ENDPOINTS) response = await self.api.vehicle_data(endpoints=ENDPOINTS)
data = response["response"] data = response["response"]
except VehicleOffline: except VehicleOffline:
self.data["state"] = TeslaFleetState.ASLEEP self.data["state"] = TeslaFleetState.ASLEEP
return self.data return self.data
except RateLimited as e: except RateLimited:
LOGGER.warning( LOGGER.warning(
"%s rate limited, will retry in %s seconds", "%s rate limited, will skip refresh",
self.name, self.name,
e.data.get("after"),
) )
if "after" in e.data:
self.update_interval = timedelta(seconds=int(e.data["after"]))
return self.data return self.data
except (InvalidToken, OAuthExpired, LoginRequired) as e: except (InvalidToken, OAuthExpired, LoginRequired) as e:
raise ConfigEntryAuthFailed from e raise ConfigEntryAuthFailed from e
except TeslaFleetError as e: except TeslaFleetError as e:
raise UpdateFailed(e.message) from e raise UpdateFailed(e.message) from e
# Calculate ideal refresh interval self.update_interval = VEHICLE_INTERVAL
self.update_interval = timedelta(seconds=self.rate.calculate())
self.updated_once = True self.updated_once = True

View File

@ -156,14 +156,15 @@ async def test_vehicle_refresh_offline(
mock_vehicle_state.reset_mock() mock_vehicle_state.reset_mock()
mock_vehicle_data.reset_mock() mock_vehicle_data.reset_mock()
# Then the vehicle goes offline # Then the vehicle goes offline despite saying its online
mock_vehicle_data.side_effect = VehicleOffline mock_vehicle_data.side_effect = VehicleOffline
freezer.tick(VEHICLE_INTERVAL) freezer.tick(VEHICLE_INTERVAL)
async_fire_time_changed(hass) async_fire_time_changed(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
mock_vehicle_state.assert_not_called() mock_vehicle_state.assert_called_once()
mock_vehicle_data.assert_called_once() mock_vehicle_data.assert_called_once()
mock_vehicle_state.reset_mock()
mock_vehicle_data.reset_mock() mock_vehicle_data.reset_mock()
# And stays offline # And stays offline
@ -212,20 +213,15 @@ async def test_vehicle_refresh_ratelimited(
assert (state := hass.states.get("sensor.test_battery_level")) assert (state := hass.states.get("sensor.test_battery_level"))
assert state.state == "unknown" assert state.state == "unknown"
assert mock_vehicle_data.call_count == 1
mock_vehicle_data.reset_mock()
freezer.tick(VEHICLE_INTERVAL) freezer.tick(VEHICLE_INTERVAL)
async_fire_time_changed(hass) async_fire_time_changed(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
# Should not call for another 10 seconds assert (state := hass.states.get("sensor.test_battery_level"))
assert mock_vehicle_data.call_count == 1 assert state.state == "unknown"
freezer.tick(VEHICLE_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert mock_vehicle_data.call_count == 2
async def test_vehicle_sleep( async def test_vehicle_sleep(