Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 62 additions & 24 deletions ring_doorbell/doorbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,32 +154,70 @@ def existing_doorbell_type_duration(self, value):
return True
return None

def history(self, limit=30, timezone=None, kind=None):
"""Return history with datetime objects."""
# allow modify the items to return
params = {'limit': str(limit)}

url = API_URI + URL_DOORBELL_HISTORY.format(self.account_id)
response = self._ring.query(url, extra_params=params)

# convert for specific timezone
utc = pytz.utc
if timezone:
mytz = pytz.timezone(timezone)

for entry in response:
dt_at = datetime.strptime(entry['created_at'],
'%Y-%m-%dT%H:%M:%S.000Z')
utc_dt = datetime(dt_at.year, dt_at.month, dt_at.day, dt_at.hour,
dt_at.minute, dt_at.second, tzinfo=utc)
def history(self, limit=30, timezone=None, kind=None,
enforce_limit=False, retry=8):
"""
Return history with datetime objects.

:param limit: specify number of objects to be returned
:param timezone: determine which timezone to convert data objects
:param kind: filter by kind (ding, motion, on_demand)
:param enforce_limit: when True, this will enforce the limit and kind
:param retry: determine the max number of attempts to archive the limit
"""
queries = 0
original_limit = limit

# set cap for max queries
if retry > 10:
retry = 10

while True:
params = {'limit': str(limit)}

url = API_URI + URL_DOORBELL_HISTORY.format(self.account_id)
response = self._ring.query(url, extra_params=params)

# cherrypick only the selected kind events
if kind:
response = list(filter(
lambda array: array['kind'] == kind, response))

# convert for specific timezone
utc = pytz.utc
if timezone:
tz_dt = utc_dt.astimezone(mytz)
entry['created_at'] = tz_dt
else:
entry['created_at'] = utc_dt
mytz = pytz.timezone(timezone)

for entry in response:
dt_at = datetime.strptime(entry['created_at'],
'%Y-%m-%dT%H:%M:%S.000Z')
utc_dt = datetime(dt_at.year, dt_at.month, dt_at.day,
dt_at.hour, dt_at.minute, dt_at.second,
tzinfo=utc)
if timezone:
tz_dt = utc_dt.astimezone(mytz)
entry['created_at'] = tz_dt
else:
entry['created_at'] = utc_dt

if enforce_limit:
# return because already matched the number
# of events by kind
if len(response) >= original_limit:
return response[:original_limit]

if kind:
return list(filter(lambda array: array['kind'] == kind, response))
# ensure the loop will exit after max queries
queries += 1
if queries == retry:
_LOGGER.warning("Could not find total of %s of kind %s",
original_limit, kind)
break

# ensure the kind objects returned to match limit
limit = limit * 2

else:
break

return response

Expand Down
4 changes: 4 additions & 0 deletions tests/test_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ def test_doorbell_attributes(self, mock):
self.assertIsInstance(dev.history(limit=1, kind='motion'),
list)
self.assertEqual(0, len(dev.history(limit=1, kind='ding')))
self.assertEqual(0, len(dev.history(limit=1,
kind='ding',
enforce_limit=True,
retry=50)))

self.assertEqual('Mechanical', dev.existing_doorbell_type)
self.assertTrue(data._persist_token)
Expand Down