Try to avoid rate limiting in honeywell (#55304)

* Limit parallel update and sleep loop

* Use asyncio sleep instead

* Extract sleep to const for testing

* Make loop sleep 0 in test
pull/55969/head
RDFurman 2021-09-07 08:32:26 -06:00 committed by Paulus Schoutsen
parent 823c3735ce
commit 7f3adce675
3 changed files with 17 additions and 8 deletions

View File

@ -1,4 +1,5 @@
"""Support for Honeywell (US) Total Connect Comfort climate systems."""
import asyncio
from datetime import timedelta
import somecomfort
@ -9,7 +10,8 @@ from homeassistant.util import Throttle
from .const import _LOGGER, CONF_DEV_ID, CONF_LOC_ID, DOMAIN
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180)
UPDATE_LOOP_SLEEP_TIME = 5
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=300)
PLATFORMS = ["climate"]
@ -42,7 +44,7 @@ async def async_setup_entry(hass, config):
return False
data = HoneywellData(hass, client, username, password, devices)
await data.update()
await data.async_update()
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][config.entry_id] = data
hass.config_entries.async_setup_platforms(config, PLATFORMS)
@ -102,18 +104,19 @@ class HoneywellData:
self.devices = devices
return True
def _refresh_devices(self):
async def _refresh_devices(self):
"""Refresh each enabled device."""
for device in self.devices:
device.refresh()
await self._hass.async_add_executor_job(device.refresh)
await asyncio.sleep(UPDATE_LOOP_SLEEP_TIME)
@Throttle(MIN_TIME_BETWEEN_UPDATES)
async def update(self) -> None:
async def async_update(self) -> None:
"""Update the state."""
retries = 3
while retries > 0:
try:
await self._hass.async_add_executor_job(self._refresh_devices)
await self._refresh_devices()
break
except (
somecomfort.client.APIRateLimited,
@ -124,7 +127,7 @@ class HoneywellData:
if retries == 0:
raise exp
result = await self._hass.async_add_executor_job(self._retry())
result = await self._retry()
if not result:
raise exp

View File

@ -107,6 +107,8 @@ HW_FAN_MODE_TO_HA = {
"follow schedule": FAN_AUTO,
}
PARALLEL_UPDATES = 1
async def async_setup_entry(hass, config, async_add_entities, discovery_info=None):
"""Set up the Honeywell thermostat."""
@ -384,4 +386,4 @@ class HoneywellUSThermostat(ClimateEntity):
async def async_update(self):
"""Get the latest state from the service."""
await self._data.update()
await self._data.async_update()

View File

@ -1,11 +1,14 @@
"""Test honeywell setup process."""
from unittest.mock import patch
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
@patch("homeassistant.components.honeywell.UPDATE_LOOP_SLEEP_TIME", 0)
async def test_setup_entry(hass: HomeAssistant, config_entry: MockConfigEntry):
"""Initialize the config entry."""
config_entry.add_to_hass(hass)
@ -15,6 +18,7 @@ async def test_setup_entry(hass: HomeAssistant, config_entry: MockConfigEntry):
assert hass.states.async_entity_ids_count() == 1
@patch("homeassistant.components.honeywell.UPDATE_LOOP_SLEEP_TIME", 0)
async def test_setup_multiple_thermostats(
hass: HomeAssistant, config_entry: MockConfigEntry, location, another_device
) -> None: