Skip to content

Commit

Permalink
fix: back off for 6 hours after rate limit error
Browse files Browse the repository at this point in the history
  • Loading branch information
firstof9 committed Dec 6, 2024
1 parent f3ee39b commit ca250c8
Showing 1 changed file with 60 additions and 53 deletions.
113 changes: 60 additions & 53 deletions custom_components/openei/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def __init__(self, hass: HomeAssistant, config: ConfigEntry) -> None:
self.hass = hass
self.interval = timedelta(seconds=30)
self._data = {}
self._rate_limit_count = 0

_LOGGER.debug("Data will be updated at the top of every hour.")

Expand All @@ -100,11 +101,8 @@ async def _async_update_data(self) -> dict:
async_call_later(self.hass, wait_seconds, self._async_refresh_data)
try:
self._data = await self.hass.async_add_executor_job(
get_sensors, self.hass, self._config
self.get_sensors, self.hass, self._config
)
except openeihttp.RateLimit:
_LOGGER.error("API Rate limit exceded, retrying later.")
self._data = {}
except Exception as exception:
raise UpdateFailed() from exception
return self._data
Expand All @@ -121,59 +119,68 @@ async def _async_refresh_data(self, data=None) -> None:
async_call_later(self.hass, wait_seconds, self._async_refresh_data)
try:
self._data = await self.hass.async_add_executor_job(
get_sensors, self.hass, self._config
self.get_sensors, self.hass, self._config
)
except openeihttp.RateLimit:
_LOGGER.error("API Rate limit exceded, retrying later.")
self._data = {}
except Exception as exception:
raise UpdateFailed() from exception


def get_sensors(hass, config) -> dict:
"""Update sensor data."""
api = config.data.get(CONF_API_KEY)
plan = config.data.get(CONF_PLAN)
meter = config.data.get(CONF_SENSOR)
reading = None

if config.data.get(CONF_MANUAL_PLAN):
plan = config.data.get(CONF_MANUAL_PLAN)

if meter:
_LOGGER.debug("Using meter data from sensor: %s", meter)
reading = hass.states.get(meter)
if not reading:
reading = None
_LOGGER.warning("Sensor: %s is not valid.", meter)
else:
reading = reading.state

rate = openeihttp.Rates(
api=api,
plan=plan,
reading=reading,
)
rate.update()
data = {}

for sensor in SENSOR_TYPES: # pylint: disable=consider-using-dict-items
_sensor = {}
value = getattr(rate, SENSOR_TYPES[sensor].key)
if isinstance(value, tuple):
_sensor[sensor] = value[0]
_sensor[f"{sensor}_uom"] = value[1]
else:
_sensor[sensor] = getattr(rate, SENSOR_TYPES[sensor].key)
data.update(_sensor)

for sensor in BINARY_SENSORS: # pylint: disable=consider-using-dict-items
_sensor = {}
_sensor[sensor] = getattr(rate, sensor)
data.update(_sensor)

_LOGGER.debug("DEBUG: %s", data)
return data
def get_sensors(self) -> dict:
"""Update sensor data."""
api = self._config.data.get(CONF_API_KEY)
plan = self._config.data.get(CONF_PLAN)
meter = self._config.data.get(CONF_SENSOR)
reading = None

if self._config.data.get(CONF_MANUAL_PLAN):
plan = self._config.data.get(CONF_MANUAL_PLAN)

if meter:
_LOGGER.debug("Using meter data from sensor: %s", meter)
reading = self.hass.states.get(meter)
if not reading:
reading = None
_LOGGER.warning("Sensor: %s is not valid.", meter)
else:
reading = reading.state

rate = openeihttp.Rates(
api=api,
plan=plan,
reading=reading,
)
if self._rate_limit_count == 0:
try:
rate.update()
except openeihttp.RateLimit:
_LOGGER.error("API Rate limit exceded, retrying later.")
if self._data == {}:
# 3 hour retry if we have no data
self._rate_limit_count = 3
else:
# 6 hour retry after rate limited
self._rate_limit_count = 6
elif self._rate_limit_count > 0:
self._rate_limit_count -= 1

data = {}

for sensor in SENSOR_TYPES: # pylint: disable=consider-using-dict-items
_sensor = {}
value = getattr(rate, SENSOR_TYPES[sensor].key)
if isinstance(value, tuple):
_sensor[sensor] = value[0]
_sensor[f"{sensor}_uom"] = value[1]
else:
_sensor[sensor] = getattr(rate, SENSOR_TYPES[sensor].key)
data.update(_sensor)

for sensor in BINARY_SENSORS: # pylint: disable=consider-using-dict-items
_sensor = {}
_sensor[sensor] = getattr(rate, sensor)
data.update(_sensor)

_LOGGER.debug("DEBUG: %s", data)
return data


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
Expand Down

0 comments on commit ca250c8

Please sign in to comment.