Serialize amcrest snapshot commands and bump PyPI package to 1.2.4 (#21664)

* Serialize snapshot commands and bump amcrest package to 1.2.4

Attempting to send a snapshot command when a previous one hasn't finished will result in warnings and/or errors. This can happen when the camera picture is clicked on in the frontend, resulting in the thread that updates the thumbnail in the background every 10 seconds to sometimes collide with the thread that updates the large picture in the foreground quickly. An automation that calls the camera.snapshot service in yet another thread can make the situation worse. Fix by adding a thread lock to serialize snapshot commands. Also bump the amcrest package to 1.2.4 which fixes error handling in the command method and improves performance by reusing requests sessions.

* Update amcrest package to 1.2.4
This commit is contained in:
Phil Bruckner 2019-03-05 10:03:19 -06:00 committed by Anders Melchiorsen
parent 3ffff887d8
commit 16d79b52c3
3 changed files with 15 additions and 5 deletions

View File

@ -13,7 +13,7 @@ from homeassistant.const import (
from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['amcrest==1.2.3']
REQUIREMENTS = ['amcrest==1.2.4']
DEPENDENCIES = ['ffmpeg']
_LOGGER = logging.getLogger(__name__)

View File

@ -1,5 +1,9 @@
"""Support for Amcrest IP cameras."""
import logging
import threading
from requests import RequestException
from urllib3.exceptions import ReadTimeoutError
from homeassistant.components.amcrest import (
DATA_AMCREST, STREAM_SOURCE_LIST, TIMEOUT)
@ -43,12 +47,18 @@ class AmcrestCam(Camera):
self._stream_source = amcrest.stream_source
self._resolution = amcrest.resolution
self._token = self._auth = amcrest.authentication
self._snapshot_lock = threading.Lock()
def camera_image(self):
"""Return a still image response from the camera."""
# Send the request to snap a picture and return raw jpg data
response = self._camera.snapshot(channel=self._resolution)
return response.data
with self._snapshot_lock:
try:
# Send the request to snap a picture and return raw jpg data
return self._camera.snapshot(channel=self._resolution).data
except (RequestException, ReadTimeoutError, ValueError) as error:
_LOGGER.error(
'Could not get camera image due to error %s', error)
return None
async def handle_async_mjpeg_stream(self, request):
"""Return an MJPEG stream."""

View File

@ -152,7 +152,7 @@ alarmdecoder==1.13.2
alpha_vantage==2.1.0
# homeassistant.components.amcrest
amcrest==1.2.3
amcrest==1.2.4
# homeassistant.components.switch.anel_pwrctrl
anel_pwrctrl-homeassistant==0.0.1.dev2