From 97996317974770a54751f1f025be76bc7633ca46 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Thu, 19 Jan 2017 18:53:08 +0100 Subject: [PATCH] [camera/mjpeg] Support still image for thumbmail (#5440) --- homeassistant/components/camera/mjpeg.py | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/homeassistant/components/camera/mjpeg.py b/homeassistant/components/camera/mjpeg.py index dd030099a45..b29cfcf8949 100644 --- a/homeassistant/components/camera/mjpeg.py +++ b/homeassistant/components/camera/mjpeg.py @@ -26,12 +26,14 @@ from homeassistant.helpers import config_validation as cv _LOGGER = logging.getLogger(__name__) CONF_MJPEG_URL = 'mjpeg_url' +CONF_STILL_IMAGE_URL = 'still_image_url' CONTENT_TYPE_HEADER = 'Content-Type' DEFAULT_NAME = 'Mjpeg Camera' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_MJPEG_URL): cv.url, + vol.Optional(CONF_STILL_IMAGE_URL): cv.url, vol.Optional(CONF_AUTHENTICATION, default=HTTP_BASIC_AUTHENTICATION): vol.In([HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION]), vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, @@ -70,6 +72,7 @@ class MjpegCamera(Camera): self._username = device_info.get(CONF_USERNAME) self._password = device_info.get(CONF_PASSWORD) self._mjpeg_url = device_info[CONF_MJPEG_URL] + self._still_image_url = device_info[CONF_STILL_IMAGE_URL] self._auth = None if self._username and self._password: @@ -78,6 +81,37 @@ class MjpegCamera(Camera): self._username, password=self._password ) + @asyncio.coroutine + def async_camera_image(self): + """Return a still image response from the camera.""" + # DigestAuth is not supported + if self._authentication == HTTP_DIGEST_AUTHENTICATION or \ + self._still_image_url is None: + image = yield from self.hass.loop.run_in_executor( + None, self.camera_image) + return image + + websession = async_get_clientsession(self.hass) + response = None + try: + with async_timeout.timeout(10, loop=self.hass.loop): + response = websession.get( + self._still_image_url, auth=self._auth) + + image = yield from response.read() + return image + + except asyncio.TimeoutError: + _LOGGER.error('Timeout getting camera image') + + except (aiohttp.errors.ClientError, + aiohttp.errors.ClientDisconnectedError) as err: + _LOGGER.error('Error getting new camera image: %s', err) + + finally: + if response is not None: + yield from response.release() + def camera_image(self): """Return a still image response from the camera.""" if self._username and self._password: