diff --git a/README.md b/README.md index d74b28d..5d8fb81 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,8 @@ loop.close() - `set_streaming_mode` now accepts a boolean instead of string. - Removed `model_type` property, replaced with `mount` and `model_generation` properties. - Added `battery_saving` property and `set_battery_saving_mode` method +- 0.1.7 + - Implemented rudimentary throttling on `update()` requests ## Meta diff --git a/logi_circle/camera.py b/logi_circle/camera.py index 8c6a44a..eeabba8 100644 --- a/logi_circle/camera.py +++ b/logi_circle/camera.py @@ -3,7 +3,7 @@ # vim:sw=4:ts=4:et: import logging import os -from datetime import datetime +from datetime import datetime, timedelta from subprocess import CalledProcessError from tempfile import NamedTemporaryFile import pytz @@ -11,7 +11,8 @@ from .const import ( PROTOCOL, ACCESSORIES_ENDPOINT, ACTIVITIES_ENDPOINT, IMAGES_ENDPOINT, JPEG_CONTENT_TYPE, FEATURES, MODEL_GEN_1, MODEL_GEN_2, MODEL_GEN_1_NAME, MODEL_GEN_2_NAME, MODEL_GEN_UNKNOWN_NAME, - MODEL_GEN_1_MOUNT, MODEL_GEN_2_MOUNT_WIRED, MODEL_GEN_2_MOUNT_WIRELESS) + MODEL_GEN_1_MOUNT, MODEL_GEN_2_MOUNT_WIRED, MODEL_GEN_2_MOUNT_WIRELESS, + UPDATE_REQUEST_THROTTLE) from .activity import Activity from .live_stream import LiveStream from .utils import (_stream_to_file, _write_to_file, _delete_quietly, _get_file_duration, @@ -28,6 +29,8 @@ def __init__(self, logi, camera): """Initialise Logi Camera object.""" self._logi = logi self._attrs = {} + # Internal prop to determine when the next update is allowed. + self._next_update_time = datetime.utcnow() self._set_attributes(camera) @@ -80,15 +83,21 @@ def _set_attributes(self, camera): self._local_tz = pytz.timezone(self._attrs['timezone']) - async def update(self): + async def update(self, force=False): """Poll API for changes to camera properties.""" _LOGGER.debug('Updating properties for camera %s', self.name) - url = '%s/%s' % (ACCESSORIES_ENDPOINT, self.id) - camera = await self._logi._fetch( - url=url, method='GET') + if force is True or datetime.utcnow() >= self._next_update_time: + url = '%s/%s' % (ACCESSORIES_ENDPOINT, self.id) + camera = await self._logi._fetch( + url=url, method='GET') - self._set_attributes(camera) + self._set_attributes(camera) + self._next_update_time = datetime.utcnow( + ) + timedelta(seconds=UPDATE_REQUEST_THROTTLE) + else: + _LOGGER.debug('Request to update ignored, requested too soon after previous update. Throttle interval is %s.', + UPDATE_REQUEST_THROTTLE) def supported_features(self): """Returns an array of supported sensors for this camera.""" diff --git a/logi_circle/const.py b/logi_circle/const.py index a25e09d..921c248 100644 --- a/logi_circle/const.py +++ b/logi_circle/const.py @@ -20,6 +20,7 @@ except (AttributeError, TypeError): CACHE_FILE = os.path.join('.', '.logi_circle-session.cache') COOKIE_NAME = 'prod_session' +UPDATE_REQUEST_THROTTLE = 5 # seconds # Date formats # Yes, we're hard-coding the timezone. "%z" is a py37 only feature, diff --git a/logi_circle/live_stream.py b/logi_circle/live_stream.py index ab89ea2..ce9e652 100644 --- a/logi_circle/live_stream.py +++ b/logi_circle/live_stream.py @@ -46,7 +46,7 @@ async def _get_mpd(self): """Gets the MPD XML and extracts the data required to download segments""" # Force an update to get the latest node ID - await self._camera.update() + await self._camera.update(force=True) # Get MPD XML and save to raw_xml var url = self._get_mpd_url() diff --git a/setup.py b/setup.py index 7793c54..e58131f 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def readme(): setup( name='logi_circle', packages=['logi_circle'], - version='0.1.6', + version='0.1.7', description='A Python library to communicate with Logi Circle cameras', long_description=readme(), long_description_content_type='text/markdown',