Resolve August integration makes too many requests and hits rate limits (#31558)

This commit is contained in:
J. Nick Koston 2020-02-08 13:22:48 -06:00 committed by GitHub
parent ca1319e1ef
commit 0dd151c1c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 46 additions and 40 deletions

View file

@ -36,8 +36,15 @@ AUGUST_CONFIG_FILE = ".august.conf"
DATA_AUGUST = "august" DATA_AUGUST = "august"
DOMAIN = "august" DOMAIN = "august"
DEFAULT_ENTITY_NAMESPACE = "august" DEFAULT_ENTITY_NAMESPACE = "august"
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=5)
DEFAULT_SCAN_INTERVAL = timedelta(seconds=5) # Limit battery and hardware updates to 1800 seconds
# in order to reduce the number of api requests and
# avoid hitting rate limits
MIN_TIME_BETWEEN_LOCK_DETAIL_UPDATES = timedelta(seconds=1800)
DEFAULT_SCAN_INTERVAL = timedelta(seconds=10)
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=10)
LOGIN_METHODS = ["phone", "email"] LOGIN_METHODS = ["phone", "email"]
CONFIG_SCHEMA = vol.Schema( CONFIG_SCHEMA = vol.Schema(
@ -180,7 +187,9 @@ class AugustData:
self._access_token = access_token self._access_token = access_token
self._doorbells = self._api.get_doorbells(self._access_token) or [] self._doorbells = self._api.get_doorbells(self._access_token) or []
self._locks = self._api.get_operable_locks(self._access_token) or [] self._locks = self._api.get_operable_locks(self._access_token) or []
self._house_ids = [d.house_id for d in self._doorbells + self._locks] self._house_ids = set()
for device in self._doorbells + self._locks:
self._house_ids.add(device.house_id)
self._doorbell_detail_by_id = {} self._doorbell_detail_by_id = {}
self._lock_status_by_id = {} self._lock_status_by_id = {}
@ -284,58 +293,51 @@ class AugustData:
This is the status from the door sensor. This is the status from the door sensor.
""" """
self._update_doors() self._update_locks_status()
return self._door_state_by_id.get(lock_id) return self._door_state_by_id.get(lock_id)
def _update_locks(self):
self._update_locks_status()
self._update_locks_detail()
@Throttle(MIN_TIME_BETWEEN_UPDATES) @Throttle(MIN_TIME_BETWEEN_UPDATES)
def _update_doors(self): def _update_locks_status(self):
status_by_id = {}
state_by_id = {} state_by_id = {}
_LOGGER.debug("Start retrieving door status") _LOGGER.debug("Start retrieving lock and door status")
for lock in self._locks: for lock in self._locks:
_LOGGER.debug("Updating door status for %s", lock.device_name) _LOGGER.debug("Updating lock and door status for %s", lock.device_name)
try: try:
state_by_id[lock.device_id] = self._api.get_lock_door_status( (
self._access_token, lock.device_id status_by_id[lock.device_id],
state_by_id[lock.device_id],
) = self._api.get_lock_status(
self._access_token, lock.device_id, door_status=True
) )
except RequestException as ex: except RequestException as ex:
_LOGGER.error( _LOGGER.error(
"Request error trying to retrieve door status for %s. %s", "Request error trying to retrieve lock and door status for %s. %s",
lock.device_name, lock.device_name,
ex, ex,
) )
status_by_id[lock.device_id] = None
state_by_id[lock.device_id] = None state_by_id[lock.device_id] = None
except Exception: except Exception:
status_by_id[lock.device_id] = None
state_by_id[lock.device_id] = None state_by_id[lock.device_id] = None
raise raise
_LOGGER.debug("Completed retrieving door status") _LOGGER.debug("Completed retrieving lock and door status")
self._lock_status_by_id = status_by_id
self._door_state_by_id = state_by_id self._door_state_by_id = state_by_id
@Throttle(MIN_TIME_BETWEEN_UPDATES) @Throttle(MIN_TIME_BETWEEN_LOCK_DETAIL_UPDATES)
def _update_locks(self): def _update_locks_detail(self):
status_by_id = {}
detail_by_id = {} detail_by_id = {}
_LOGGER.debug("Start retrieving locks status") _LOGGER.debug("Start retrieving locks detail")
for lock in self._locks: for lock in self._locks:
_LOGGER.debug("Updating lock status for %s", lock.device_name)
try:
status_by_id[lock.device_id] = self._api.get_lock_status(
self._access_token, lock.device_id
)
except RequestException as ex:
_LOGGER.error(
"Request error trying to retrieve door status for %s. %s",
lock.device_name,
ex,
)
status_by_id[lock.device_id] = None
except Exception:
status_by_id[lock.device_id] = None
raise
try: try:
detail_by_id[lock.device_id] = self._api.get_lock_detail( detail_by_id[lock.device_id] = self._api.get_lock_detail(
self._access_token, lock.device_id self._access_token, lock.device_id
@ -351,8 +353,7 @@ class AugustData:
detail_by_id[lock.device_id] = None detail_by_id[lock.device_id] = None
raise raise
_LOGGER.debug("Completed retrieving locks status") _LOGGER.debug("Completed retrieving locks detail")
self._lock_status_by_id = status_by_id
self._lock_detail_by_id = detail_by_id self._lock_detail_by_id = detail_by_id
def lock(self, device_id): def lock(self, device_id):

View file

@ -11,7 +11,7 @@ from . import DATA_AUGUST
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=5) SCAN_INTERVAL = timedelta(seconds=10)
def _retrieve_door_state(data, lock): def _retrieve_door_state(data, lock):

View file

@ -7,7 +7,7 @@ from homeassistant.components.camera import Camera
from . import DATA_AUGUST, DEFAULT_TIMEOUT from . import DATA_AUGUST, DEFAULT_TIMEOUT
SCAN_INTERVAL = timedelta(seconds=5) SCAN_INTERVAL = timedelta(seconds=10)
def setup_platform(hass, config, add_entities, discovery_info=None): def setup_platform(hass, config, add_entities, discovery_info=None):

View file

@ -12,7 +12,7 @@ from . import DATA_AUGUST
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=5) SCAN_INTERVAL = timedelta(seconds=10)
def setup_platform(hass, config, add_entities, discovery_info=None): def setup_platform(hass, config, add_entities, discovery_info=None):
@ -88,7 +88,12 @@ class AugustLock(LockDevice):
if self._lock_detail is None: if self._lock_detail is None:
return None return None
return {ATTR_BATTERY_LEVEL: self._lock_detail.battery_level} attributes = {ATTR_BATTERY_LEVEL: self._lock_detail.battery_level}
if self._lock_detail.keypad is not None:
attributes["keypad_battery_level"] = self._lock_detail.keypad.battery_level
return attributes
@property @property
def unique_id(self) -> str: def unique_id(self) -> str:

View file

@ -2,7 +2,7 @@
"domain": "august", "domain": "august",
"name": "August", "name": "August",
"documentation": "https://www.home-assistant.io/integrations/august", "documentation": "https://www.home-assistant.io/integrations/august",
"requirements": ["py-august==0.7.0"], "requirements": ["py-august==0.8.1"],
"dependencies": ["configurator"], "dependencies": ["configurator"],
"codeowners": [] "codeowners": []
} }

View file

@ -1068,7 +1068,7 @@ pushetta==1.0.15
pwmled==1.4.1 pwmled==1.4.1
# homeassistant.components.august # homeassistant.components.august
py-august==0.7.0 py-august==0.8.1
# homeassistant.components.canary # homeassistant.components.canary
py-canary==0.5.0 py-canary==0.5.0