From 9c6609cb796afc71c72bec5c3674026a420e4560 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Wed, 30 Nov 2016 16:07:17 -0500 Subject: [PATCH] Added support to Amcrest camera (#4573) * Introduced support to Amcrest IP Cameras * Fixed lint issues * Fixed requirements test * * Implemented test to verify crendentials during camera setup * Added persistent_notification in case of error when during Amcrest setup --- .coveragerc | 1 + homeassistant/components/camera/amcrest.py | 79 ++++++++++++++++++++++ requirements_all.txt | 3 + 3 files changed, 83 insertions(+) create mode 100644 homeassistant/components/camera/amcrest.py diff --git a/.coveragerc b/.coveragerc index c7d1e4237f5..8e01d88154f 100644 --- a/.coveragerc +++ b/.coveragerc @@ -124,6 +124,7 @@ omit = homeassistant/components/binary_sensor/concord232.py homeassistant/components/binary_sensor/rest.py homeassistant/components/browser.py + homeassistant/components/camera/amcrest.py homeassistant/components/camera/bloomsky.py homeassistant/components/camera/foscam.py homeassistant/components/camera/mjpeg.py diff --git a/homeassistant/components/camera/amcrest.py b/homeassistant/components/camera/amcrest.py new file mode 100644 index 00000000000..ff862f2db11 --- /dev/null +++ b/homeassistant/components/camera/amcrest.py @@ -0,0 +1,79 @@ +""" +This component provides basic support for Amcrest IP cameras. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/camera.amcrest/ +""" +import logging +import voluptuous as vol + +from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA) +from homeassistant.const import ( + CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_PORT) +from homeassistant.helpers import config_validation as cv +import homeassistant.loader as loader + +REQUIREMENTS = ['amcrest==1.0.0'] + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_PORT = 80 +DEFAULT_NAME = 'Amcrest Camera' + +NOTIFICATION_ID = 'amcrest_notification' +NOTIFICATION_TITLE = 'Amcrest Camera Setup' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_USERNAME): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup an Amcrest IP Camera.""" + from amcrest import AmcrestCamera + data = AmcrestCamera(config.get(CONF_HOST), + config.get(CONF_PORT), + config.get(CONF_USERNAME), + config.get(CONF_PASSWORD)) + + persistent_notification = loader.get_component('persistent_notification') + try: + data.camera.current_time + # pylint: disable=broad-except + except Exception as ex: + _LOGGER.error('Unable to connect to Amcrest camera: %s', str(ex)) + persistent_notification.create( + hass, 'Error: {}
' + 'You will need to restart hass after fixing.' + ''.format(ex), + title=NOTIFICATION_TITLE, + notification_id=NOTIFICATION_ID) + return False + + add_devices([AmcrestCam(config, data)]) + return True + + +class AmcrestCam(Camera): + """An implementation of an Amcrest IP camera.""" + + def __init__(self, device_info, data): + """Initialize an Amcrest camera.""" + super(AmcrestCam, self).__init__() + self._name = device_info.get(CONF_NAME) + self._data = data + + def camera_image(self): + """Return a still image reponse from the camera.""" + # Send the request to snap a picture and return raw jpg data + response = self._data.camera.snapshot() + return response.data + + @property + def name(self): + """Return the name of this camera.""" + return self._name diff --git a/requirements_all.txt b/requirements_all.txt index 88cab503659..ad1a41b457b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -33,6 +33,9 @@ TwitterAPI==2.4.2 # homeassistant.components.http aiohttp_cors==0.5.0 +# homeassistant.components.camera.amcrest +amcrest==1.0.0 + # homeassistant.components.apcupsd apcaccess==0.0.4