From cab1100a51e64d1ede7fa3f4e192df2a7f31c9a1 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Sat, 6 Feb 2016 01:24:44 +0000 Subject: [PATCH] Add Ubiquiti Unifi Video Camera support This adds support for Ubiquiti's UniFi Video cameras via their NVR device (or service). By configuring just the address of the NVR and a valid API key, all cameras are discovered and enabled, including direct-to-camera image snapshot-based video support. --- homeassistant/components/camera/uvc.py | 110 +++++++++++++++++++++++++ requirements_all.txt | 3 + 2 files changed, 113 insertions(+) create mode 100644 homeassistant/components/camera/uvc.py diff --git a/homeassistant/components/camera/uvc.py b/homeassistant/components/camera/uvc.py new file mode 100644 index 00000000000..5185b302c00 --- /dev/null +++ b/homeassistant/components/camera/uvc.py @@ -0,0 +1,110 @@ +""" +Ubiquiti Unifi Video Cameras +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Support for Ubiquiti's UVC cameras + +Configuration: + +camera: + platform: uvc + nvr: ADDRESS + port: PORT + key: APIKEY + +Variable: + +nvr +*Required +ADDRESS should be the IP or hostname of the NVR server + +port +*Optional +PORT is the port number to use for accessing the NVR + +key +*Required +APIKEY should be the API key available from the NVR web interface +""" +import logging +import socket + +import requests + +from homeassistant.helpers import validate_config +from homeassistant.components.camera import DOMAIN, Camera + +REQUIREMENTS = ['uvcclient==0.5'] + +_LOGGER = logging.getLogger(__name__) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """ Discover cameras on a Unifi NVR. """ + if not validate_config({DOMAIN: config}, {DOMAIN: ['nvr', 'key']}, + _LOGGER): + return None + + addr = config.get('nvr') + port = int(config.get('port', 7080)) + key = config.get('key') + + from uvcclient import nvr + nvrconn = nvr.UVCRemote(addr, port, key) + try: + cameras = nvrconn.index() + except nvr.NotAuthorized: + _LOGGER.error('Authorization failure while connecting to NVR') + return False + except nvr.NvrError: + _LOGGER.error('NVR refuses to talk to me') + return False + except requests.exceptions.ConnectionError as ex: + _LOGGER.error('Unable to connect to NVR: %s', str(ex)) + return False + + for camera in cameras: + add_devices([UnifiVideoCamera(nvrconn, + camera['uuid'], + camera['name'])]) + + +class UnifiVideoCamera(Camera): + """ A Ubiquiti Unifi Video Camera. """ + + def __init__(self, nvr, uuid, name): + super(UnifiVideoCamera, self).__init__() + self._nvr = nvr + self._uuid = uuid + self._name = name + self.is_streaming = False + + @property + def name(self): + return self._name + + @property + def is_recording(self): + caminfo = self._nvr.get_camera(self._uuid) + return caminfo['recordingSettings']['fullTimeRecordEnabled'] + + def camera_image(self): + from uvcclient import camera as uvc_camera + + caminfo = self._nvr.get_camera(self._uuid) + camera = None + for addr in [caminfo['host'], caminfo['internalHost']]: + try: + camera = uvc_camera.UVCCameraClient(addr, + caminfo['username'], + 'ubnt') + _LOGGER.debug('Logged into UVC camera %(name)s via %(addr)s', + dict(name=self._name, addr=addr)) + except socket.error: + pass + + if not camera: + _LOGGER.error('Unable to login to camera') + return None + + camera.login() + return camera.get_snapshot() diff --git a/requirements_all.txt b/requirements_all.txt index 9e0e159a1d2..8697003b2c4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -228,6 +228,9 @@ tellive-py==0.5.2 # homeassistant.components.switch.transmission transmissionrpc==0.11 +# homeassistant.components.camera.uvc +uvcclient==0.5 + # homeassistant.components.verisure vsure==0.5.0