91 lines
2.9 KiB
Python
91 lines
2.9 KiB
Python
"""Support for viewing the camera feed from a DoorBird video doorbell."""
|
|
|
|
import asyncio
|
|
import datetime
|
|
import logging
|
|
import voluptuous as vol
|
|
|
|
import aiohttp
|
|
import async_timeout
|
|
|
|
from homeassistant.components.camera import PLATFORM_SCHEMA, Camera
|
|
from homeassistant.components.doorbird import DOMAIN as DOORBIRD_DOMAIN
|
|
from homeassistant.helpers import config_validation as cv
|
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
|
|
DEPENDENCIES = ['doorbird']
|
|
|
|
_CAMERA_LIVE = "DoorBird Live"
|
|
_CAMERA_LAST_VISITOR = "DoorBird Last Ring"
|
|
_LIVE_INTERVAL = datetime.timedelta(seconds=1)
|
|
_LAST_VISITOR_INTERVAL = datetime.timedelta(minutes=1)
|
|
_LOGGER = logging.getLogger(__name__)
|
|
_TIMEOUT = 10 # seconds
|
|
|
|
CONF_SHOW_LAST_VISITOR = 'last_visitor'
|
|
|
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|
vol.Optional(CONF_SHOW_LAST_VISITOR, default=False): cv.boolean
|
|
})
|
|
|
|
|
|
@asyncio.coroutine
|
|
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|
"""Set up the DoorBird camera platform."""
|
|
device = hass.data.get(DOORBIRD_DOMAIN)
|
|
|
|
_LOGGER.debug("Adding DoorBird camera %s", _CAMERA_LIVE)
|
|
entities = [DoorBirdCamera(device.live_image_url, _CAMERA_LIVE,
|
|
_LIVE_INTERVAL)]
|
|
|
|
if config.get(CONF_SHOW_LAST_VISITOR):
|
|
_LOGGER.debug("Adding DoorBird camera %s", _CAMERA_LAST_VISITOR)
|
|
entities.append(DoorBirdCamera(device.history_image_url(1),
|
|
_CAMERA_LAST_VISITOR,
|
|
_LAST_VISITOR_INTERVAL))
|
|
|
|
async_add_devices(entities)
|
|
_LOGGER.info("Added DoorBird camera(s)")
|
|
|
|
|
|
class DoorBirdCamera(Camera):
|
|
"""The camera on a DoorBird device."""
|
|
|
|
def __init__(self, url, name, interval=None):
|
|
"""Initialize the camera on a DoorBird device."""
|
|
self._url = url
|
|
self._name = name
|
|
self._last_image = None
|
|
self._interval = interval or datetime.timedelta
|
|
self._last_update = datetime.datetime.min
|
|
super().__init__()
|
|
|
|
@property
|
|
def name(self):
|
|
"""Get the name of the camera."""
|
|
return self._name
|
|
|
|
@asyncio.coroutine
|
|
def async_camera_image(self):
|
|
"""Pull a still image from the camera."""
|
|
now = datetime.datetime.now()
|
|
|
|
if self._last_image and now - self._last_update < self._interval:
|
|
return self._last_image
|
|
|
|
try:
|
|
websession = async_get_clientsession(self.hass)
|
|
|
|
with async_timeout.timeout(_TIMEOUT, loop=self.hass.loop):
|
|
response = yield from websession.get(self._url)
|
|
|
|
self._last_image = yield from response.read()
|
|
self._last_update = now
|
|
return self._last_image
|
|
except asyncio.TimeoutError:
|
|
_LOGGER.error("Camera image timed out")
|
|
return self._last_image
|
|
except aiohttp.ClientError as error:
|
|
_LOGGER.error("Error getting camera image: %s", error)
|
|
return self._last_image
|