core/homeassistant/components/camera/generic.py

99 lines
3.3 KiB
Python
Raw Normal View History

2015-06-05 12:51:29 +00:00
"""
Support for IP Cameras.
2015-10-13 19:00:28 +00:00
For more details about this platform, please refer to the documentation at
2015-11-09 12:12:18 +00:00
https://home-assistant.io/components/camera.generic/
2015-06-05 12:51:29 +00:00
"""
import logging
2015-11-29 21:49:05 +00:00
import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
import voluptuous as vol
from homeassistant.const import (
CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_AUTHENTICATION,
HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION)
from homeassistant.exceptions import TemplateError
from homeassistant.components.camera import (PLATFORM_SCHEMA, Camera)
from homeassistant.helpers import config_validation as cv
2015-11-29 21:49:05 +00:00
2015-06-05 12:51:29 +00:00
_LOGGER = logging.getLogger(__name__)
CONF_LIMIT_REFETCH_TO_URL_CHANGE = 'limit_refetch_to_url_change'
CONF_STILL_IMAGE_URL = 'still_image_url'
DEFAULT_NAME = 'Generic Camera'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_STILL_IMAGE_URL): cv.template,
vol.Optional(CONF_AUTHENTICATION, default=HTTP_BASIC_AUTHENTICATION):
vol.In([HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION]),
vol.Optional(CONF_LIMIT_REFETCH_TO_URL_CHANGE, default=False): cv.boolean,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PASSWORD): cv.string,
vol.Optional(CONF_USERNAME): cv.string,
})
2015-06-05 12:51:29 +00:00
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
2016-03-07 16:45:06 +00:00
"""Setup a generic IP Camera."""
add_devices([GenericCamera(hass, config)])
2015-06-05 12:51:29 +00:00
# pylint: disable=too-many-instance-attributes
class GenericCamera(Camera):
2016-03-07 19:29:54 +00:00
"""A generic implementation of an IP camera."""
def __init__(self, hass, device_info):
2016-03-07 19:29:54 +00:00
"""Initialize a generic camera."""
2015-07-11 06:17:12 +00:00
super().__init__()
self.hass = hass
self._name = device_info.get(CONF_NAME)
self._still_image_url = device_info[CONF_STILL_IMAGE_URL]
self._still_image_url.hass = hass
self._limit_refetch = device_info[CONF_LIMIT_REFETCH_TO_URL_CHANGE]
2015-07-11 06:17:12 +00:00
username = device_info.get(CONF_USERNAME)
password = device_info.get(CONF_PASSWORD)
if username and password:
if device_info[CONF_AUTHENTICATION] == HTTP_DIGEST_AUTHENTICATION:
self._auth = HTTPDigestAuth(username, password)
else:
self._auth = HTTPBasicAuth(username, password)
2015-07-10 08:03:46 +00:00
else:
self._auth = None
self._last_url = None
self._last_image = None
def camera_image(self):
"""Return a still image response from the camera."""
try:
url = self._still_image_url.render()
except TemplateError as err:
_LOGGER.error('Error parsing template %s: %s',
self._still_image_url, err)
return self._last_image
if url == self._last_url and self._limit_refetch:
return self._last_image
kwargs = {'timeout': 10, 'auth': self._auth}
try:
response = requests.get(url, **kwargs)
except requests.exceptions.RequestException as error:
_LOGGER.error('Error getting camera image: %s', error)
return None
2015-06-05 12:51:29 +00:00
self._last_url = url
self._last_image = response.content
return self._last_image
2015-06-05 12:51:29 +00:00
@property
def name(self):
2016-03-07 16:45:06 +00:00
"""Return the name of this device."""
2015-07-11 06:17:12 +00:00
return self._name