From 66dcb6c9471e677b7430f551d510947fed7a566a Mon Sep 17 00:00:00 2001 From: Matthew Hilton Date: Sat, 17 Feb 2018 13:57:05 +0000 Subject: [PATCH] ONVIF Camera added Error handling and rtsp authentication. (#11129) Bugfixes for several issues with hass.io and non-venv installations Added passing of credentials to RTSP stream Changed from ONVIFService to ONVIFCamera as ONVIFService didn't contain the same error handling. Changed method to get Stream URL from camera to a more compatible method Added extra Error handling --- homeassistant/components/camera/onvif.py | 39 +++++++++++++++--------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 65f291bf41d889..17108e730916eb 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -6,7 +6,6 @@ """ import asyncio import logging -import os import voluptuous as vol @@ -48,30 +47,40 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up a ONVIF camera.""" if not hass.data[DATA_FFMPEG].async_run_test(config.get(CONF_HOST)): return - async_add_devices([ONVIFCamera(hass, config)]) + async_add_devices([ONVIFHassCamera(hass, config)]) -class ONVIFCamera(Camera): +class ONVIFHassCamera(Camera): """An implementation of an ONVIF camera.""" def __init__(self, hass, config): """Initialize a ONVIF camera.""" - from onvif import ONVIFService - import onvif + from onvif import ONVIFCamera super().__init__() self._name = config.get(CONF_NAME) self._ffmpeg_arguments = config.get(CONF_EXTRA_ARGUMENTS) - media = ONVIFService( - 'http://{}:{}/onvif/device_service'.format( - config.get(CONF_HOST), config.get(CONF_PORT)), - config.get(CONF_USERNAME), - config.get(CONF_PASSWORD), - '{}/wsdl/media.wsdl'.format(os.path.dirname(onvif.__file__)) - ) - self._input = media.GetStreamUri().Uri - _LOGGER.debug("ONVIF Camera Using the following URL for %s: %s", - self._name, self._input) + self._input = None + try: + _LOGGER.debug("Connecting with ONVIF Camera: %s on port %s", + config.get(CONF_HOST), config.get(CONF_PORT)) + media_service = ONVIFCamera( + config.get(CONF_HOST), config.get(CONF_PORT), + config.get(CONF_USERNAME), config.get(CONF_PASSWORD) + ).create_media_service() + stream_uri = media_service.GetStreamUri( + {'StreamSetup': {'Stream': 'RTP-Unicast', 'Transport': 'RTSP'}} + ) + self._input = stream_uri.Uri.replace( + 'rtsp://', 'rtsp://{}:{}@'.format( + config.get(CONF_USERNAME), + config.get(CONF_PASSWORD)), 1) + _LOGGER.debug( + "ONVIF Camera Using the following URL for %s: %s", + self._name, self._input) + except Exception as err: + _LOGGER.error("Unable to communicate with ONVIF Camera: %s", err) + raise @asyncio.coroutine def async_camera_image(self):