Merge pull request #214 from fronzbot/bugfix-motion
Fix motion detection getting stuck 'on'
This commit is contained in:
+3
-3
@@ -1,5 +1,5 @@
|
||||
[run]
|
||||
omit =
|
||||
helpers/*
|
||||
parallel = true
|
||||
omit =
|
||||
tests/*
|
||||
setup.py
|
||||
setup.py
|
||||
|
||||
@@ -4,4 +4,8 @@ python:
|
||||
ignored_directories:
|
||||
- docs
|
||||
|
||||
flake8:
|
||||
enabled: true
|
||||
config_file: .flake8
|
||||
|
||||
fail_on_violations: true
|
||||
|
||||
+7
-2
@@ -2,8 +2,9 @@ sudo: required
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- python: "3.5.3"
|
||||
- python: "3.7"
|
||||
env: TOXENV=lint
|
||||
dist: xenial
|
||||
- python: "3.5.3"
|
||||
env: TOXENV=py35
|
||||
- python: "3.6"
|
||||
@@ -13,11 +14,15 @@ matrix:
|
||||
- python: "3.7"
|
||||
env: TOXENV=py37
|
||||
dist: xenial
|
||||
- python: "3.8"
|
||||
env: TOXENV=py38
|
||||
- python: "3.8-dev"
|
||||
env: TOXENV=py38
|
||||
dist: xenial
|
||||
|
||||
install: pip install -U tox coveralls
|
||||
install:
|
||||
- pip install -U tox coveralls
|
||||
- pip install coverage==4.5.4
|
||||
language: python
|
||||
script: tox
|
||||
after_success: coveralls
|
||||
|
||||
@@ -60,7 +60,7 @@ ONLINE = {'online': True, 'offline': False}
|
||||
'''
|
||||
OTHER
|
||||
'''
|
||||
TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S%Z'
|
||||
TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S%z'
|
||||
|
||||
DEFAULT_MOTION_INTERVAL = 1
|
||||
DEFAULT_REFRESH = 30
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
import logging
|
||||
import time
|
||||
from calendar import timegm
|
||||
from functools import partial, wraps
|
||||
from requests import Request, Session, exceptions
|
||||
import dateutil.parser
|
||||
from blinkpy.helpers.constants import BLINK_URL, TIMESTAMP_FORMAT
|
||||
import blinkpy.helpers.errors as ERROR
|
||||
|
||||
@@ -11,6 +13,17 @@ import blinkpy.helpers.errors as ERROR
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def time_to_seconds(timestamp):
|
||||
"""Convert TIMESTAMP_FORMAT time to seconds."""
|
||||
try:
|
||||
dtime = dateutil.parser.isoparse(timestamp)
|
||||
except ValueError:
|
||||
_LOGGER.error("Incorrect timestamp format for conversion: %s.",
|
||||
timestamp)
|
||||
return False
|
||||
return timegm(dtime.timetuple())
|
||||
|
||||
|
||||
def get_time(time_to_convert=None):
|
||||
"""Create blink-compatible timestamp."""
|
||||
if time_to_convert is None:
|
||||
|
||||
@@ -5,6 +5,7 @@ import logging
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
from blinkpy import api
|
||||
from blinkpy.camera import BlinkCamera
|
||||
from blinkpy.helpers.util import time_to_seconds
|
||||
from blinkpy.helpers.constants import ONLINE
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@@ -163,7 +164,7 @@ class BlinkSyncModule():
|
||||
def check_new_videos(self):
|
||||
"""Check if new videos since last refresh."""
|
||||
try:
|
||||
interval = self.blink.last_refresh - self.motion_interval*60
|
||||
interval = self.blink.last_refresh - self.motion_interval * 60
|
||||
except TypeError:
|
||||
# This is the first start, so refresh hasn't happened yet.
|
||||
# No need to check for motion.
|
||||
@@ -187,9 +188,13 @@ class BlinkSyncModule():
|
||||
name = entry['device_name']
|
||||
clip = entry['media']
|
||||
timestamp = entry['created_at']
|
||||
self.motion[name] = True
|
||||
self.motion[name] = self.check_new_video_time(timestamp)
|
||||
self.last_record[name] = {'clip': clip, 'time': timestamp}
|
||||
except KeyError:
|
||||
_LOGGER.debug("No new videos since last refresh.")
|
||||
|
||||
return True
|
||||
|
||||
def check_new_video_time(self, timestamp):
|
||||
"""Check if video has timestamp since last refresh."""
|
||||
return time_to_seconds(timestamp) > self.blink.last_refresh
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
flake8==3.5.0
|
||||
flake8-docstrings==1.3.0
|
||||
pylint==2.3.0
|
||||
pydocstyle==2.1.1
|
||||
pytest==3.7.1
|
||||
pytest-cov>=2.3.1
|
||||
pytest-sugar>=0.9.0
|
||||
pytest-timeout>=1.0.0
|
||||
coverage==4.5.4
|
||||
flake8==3.7.9
|
||||
flake8-docstrings==1.5.0
|
||||
pylint==2.4.4
|
||||
pydocstyle==5.0.2
|
||||
pytest==5.3.5
|
||||
pytest-cov==2.8.1
|
||||
pytest-sugar>=0.9.2
|
||||
pytest-timeout>=1.3.3
|
||||
restructuredtext-lint>=1.0.1
|
||||
pygments>=2.2.0
|
||||
|
||||
@@ -73,23 +73,41 @@ class TestBlinkSyncModule(unittest.TestCase):
|
||||
'media': [{
|
||||
'device_name': 'foo',
|
||||
'media': '/foo/bar.mp4',
|
||||
'created_at': '1970-01-01T00:00:00+0:00'
|
||||
'created_at': '1990-01-01T00:00:00+00:00'
|
||||
}]
|
||||
}
|
||||
|
||||
sync_module = self.blink.sync['test']
|
||||
sync_module.cameras = {'foo': None}
|
||||
sync_module.blink.last_refresh = 0
|
||||
self.assertEqual(sync_module.motion, {})
|
||||
self.assertTrue(sync_module.check_new_videos())
|
||||
self.assertEqual(sync_module.last_record['foo'],
|
||||
{'clip': '/foo/bar.mp4',
|
||||
'time': '1970-01-01T00:00:00+0:00'})
|
||||
'time': '1990-01-01T00:00:00+00:00'})
|
||||
self.assertEqual(sync_module.motion, {'foo': True})
|
||||
mock_resp.return_value = {'media': []}
|
||||
self.assertTrue(sync_module.check_new_videos())
|
||||
self.assertEqual(sync_module.motion, {'foo': False})
|
||||
self.assertEqual(sync_module.last_record['foo'],
|
||||
{'clip': '/foo/bar.mp4',
|
||||
'time': '1970-01-01T00:00:00+0:00'})
|
||||
'time': '1990-01-01T00:00:00+00:00'})
|
||||
|
||||
def test_check_new_videos_old_date(self, mock_resp):
|
||||
"""Test videos return response with old date."""
|
||||
mock_resp.return_value = {
|
||||
'media': [{
|
||||
'device_name': 'foo',
|
||||
'media': '/foo/bar.mp4',
|
||||
'created_at': '1970-01-01T00:00:00+00:00'
|
||||
}]
|
||||
}
|
||||
|
||||
sync_module = self.blink.sync['test']
|
||||
sync_module.cameras = {'foo': None}
|
||||
sync_module.blink.last_refresh = 1000
|
||||
self.assertTrue(sync_module.check_new_videos())
|
||||
self.assertEqual(sync_module.motion, {'foo': False})
|
||||
|
||||
def test_check_new_videos_failed(self, mock_resp):
|
||||
"""Test method when response is unexpected."""
|
||||
|
||||
+8
-1
@@ -3,7 +3,7 @@
|
||||
import unittest
|
||||
from unittest import mock
|
||||
import time
|
||||
from blinkpy.helpers.util import Throttle, BlinkURLHandler
|
||||
from blinkpy.helpers.util import Throttle, BlinkURLHandler, time_to_seconds
|
||||
|
||||
|
||||
class TestUtil(unittest.TestCase):
|
||||
@@ -105,3 +105,10 @@ class TestUtil(unittest.TestCase):
|
||||
self.assertEqual(urls.subdomain, 'rest-test')
|
||||
urls = BlinkURLHandler('test', legacy=True)
|
||||
self.assertEqual(urls.subdomain, 'rest.test')
|
||||
|
||||
def test_time_to_seconds(self):
|
||||
"""Test time to seconds conversion."""
|
||||
correct_time = '1970-01-01T00:00:05+00:00'
|
||||
wrong_time = '1/1/1970 00:00:03'
|
||||
self.assertEqual(time_to_seconds(correct_time), 5)
|
||||
self.assertFalse(time_to_seconds(wrong_time))
|
||||
|
||||
@@ -8,11 +8,11 @@ setenv =
|
||||
LANG=en_US.UTF-8
|
||||
PYTHONPATH = {toxinidir}
|
||||
commands =
|
||||
py.test --timeout=30 --duration=10 --cov=blinkpy --cov-report term-missing {posargs}
|
||||
pytest --timeout=9 --durations=10 --cov=blinkpy --cov-report term-missing {posargs}
|
||||
deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/requirements_test.txt
|
||||
|
||||
|
||||
[testenv:lint]
|
||||
deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
|
||||
Reference in New Issue
Block a user