From 0788946a0fb656052ac8eb0372234a3739089959 Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 13 Dec 2017 22:40:00 +0000 Subject: [PATCH 01/14] added Error handling and rtsp authentication. Bugfixes for several issues with hass.io and non-venv installations --- homeassistant/components/camera/onvif.py | 36 ++++++++++++++++-------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 8f30d9c8b8fdb9..b139e1c04051b6 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -46,30 +46,42 @@ 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([ONVIFCameraHASS(hass, config)]) -class ONVIFCamera(Camera): +class ONVIFCameraHASS(Camera): """An implementation of an ONVIF camera.""" def __init__(self, hass, config): """Initialize a ONVIF camera.""" - from onvif import ONVIFService + from onvif import ONVIFCamera import onvif super().__init__() self._name = config.get(CONF_NAME) self._ffmpeg_arguments = '-q:v 2' - 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._input = None + try: + _LOGGER.debug("Attempting to communicate 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() + profiles = media_service.GetProfiles() + stream_uri = media_service.GetStreamUri( + {'StreamSetup': { + 'Stream': 'RTP-Unicast', 'Transport': 'RTSP' + }, 'ProfileToken': profiles[0]._token} + ) + 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): From f239b7aba0588df0f8de0031545cc31764913d17 Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 13 Dec 2017 22:52:36 +0000 Subject: [PATCH 02/14] Fixed pep8 errors --- homeassistant/components/camera/onvif.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index b139e1c04051b6..1e6c23be72660b 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -62,7 +62,7 @@ def __init__(self, hass, config): self._ffmpeg_arguments = '-q:v 2' self._input = None try: - _LOGGER.debug("Attempting to communicate with ONVIF Camera: %s on port %s", + _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), @@ -75,10 +75,12 @@ def __init__(self, hass, config): }, 'ProfileToken': profiles[0]._token} ) 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) + '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 From 50f1b4af48899ead641fad04fc71a8172e0ea775 Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 13 Dec 2017 22:59:45 +0000 Subject: [PATCH 03/14] remove unnessary imports --- homeassistant/components/camera/onvif.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 1e6c23be72660b..327d9f7bc2f701 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 @@ -55,7 +54,6 @@ class ONVIFCameraHASS(Camera): def __init__(self, hass, config): """Initialize a ONVIF camera.""" from onvif import ONVIFCamera - import onvif super().__init__() self._name = config.get(CONF_NAME) From 04328e09a9762a440b738939ceee607ad090bf43 Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 13 Dec 2017 23:49:46 +0000 Subject: [PATCH 04/14] fixed accessing protected member --- homeassistant/components/camera/onvif.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 327d9f7bc2f701..1d5763d16d980a 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -66,11 +66,11 @@ def __init__(self, hass, config): config.get(CONF_HOST), config.get(CONF_PORT), config.get(CONF_USERNAME), config.get(CONF_PASSWORD) ).create_media_service() - profiles = media_service.GetProfiles() + profiletoken = (media_service.GetProfiles())[0]._token stream_uri = media_service.GetStreamUri( {'StreamSetup': { 'Stream': 'RTP-Unicast', 'Transport': 'RTSP' - }, 'ProfileToken': profiles[0]._token} + }, 'ProfileToken': profiletoken} ) self._input = stream_uri.Uri.replace( 'rtsp://', 'rtsp://{}:{}@'.format( From 793c0b413cd5b7ba50412312680d26af20c52a00 Mon Sep 17 00:00:00 2001 From: matt Date: Thu, 14 Dec 2017 21:26:12 +0000 Subject: [PATCH 05/14] removed unnecessary profile token --- homeassistant/components/camera/onvif.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 1d5763d16d980a..7a39d19429e3a3 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -66,11 +66,10 @@ def __init__(self, hass, config): config.get(CONF_HOST), config.get(CONF_PORT), config.get(CONF_USERNAME), config.get(CONF_PASSWORD) ).create_media_service() - profiletoken = (media_service.GetProfiles())[0]._token stream_uri = media_service.GetStreamUri( {'StreamSetup': { 'Stream': 'RTP-Unicast', 'Transport': 'RTSP' - }, 'ProfileToken': profiletoken} + }} ) self._input = stream_uri.Uri.replace( 'rtsp://', 'rtsp://{}:{}@'.format( From ffff1cb0adea2c8c3904a0f914858b74becf880a Mon Sep 17 00:00:00 2001 From: matt Date: Thu, 14 Dec 2017 21:44:57 +0000 Subject: [PATCH 06/14] tidied up StreamSetup --- homeassistant/components/camera/onvif.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 7a39d19429e3a3..fa70fbcb7f2b90 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -67,9 +67,7 @@ def __init__(self, hass, config): config.get(CONF_USERNAME), config.get(CONF_PASSWORD) ).create_media_service() stream_uri = media_service.GetStreamUri( - {'StreamSetup': { - 'Stream': 'RTP-Unicast', 'Transport': 'RTSP' - }} + {'StreamSetup': {'Stream': 'RTP-Unicast', 'Transport': 'RTSP'}} ) self._input = stream_uri.Uri.replace( 'rtsp://', 'rtsp://{}:{}@'.format( From 79d4b29a308f8209f29d37277a6b25d65a603c5d Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 13 Dec 2017 22:40:00 +0000 Subject: [PATCH 07/14] added Error handling and rtsp authentication. Bugfixes for several issues with hass.io and non-venv installations --- homeassistant/components/camera/onvif.py | 34 +++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 65f291bf41d889..327c84966188df 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -48,30 +48,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)]) -class ONVIFCamera(Camera): """An implementation of an ONVIF camera.""" def __init__(self, hass, config): """Initialize a ONVIF camera.""" - from onvif import ONVIFService + from onvif import ONVIFCamera import onvif 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._input = None + try: + _LOGGER.debug("Attempting to communicate 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() + profiles = media_service.GetProfiles() + stream_uri = media_service.GetStreamUri( + {'StreamSetup': { + 'Stream': 'RTP-Unicast', 'Transport': 'RTSP' + }, 'ProfileToken': profiles[0]._token} + ) + 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): From 5c736e39f2aeaba31b51ffc0d0383f9e1f0927c1 Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 13 Dec 2017 22:52:36 +0000 Subject: [PATCH 08/14] Fixed pep8 errors --- homeassistant/components/camera/onvif.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 327c84966188df..40f7735bf8fbed 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -62,7 +62,7 @@ def __init__(self, hass, config): self._ffmpeg_arguments = config.get(CONF_EXTRA_ARGUMENTS) self._input = None try: - _LOGGER.debug("Attempting to communicate with ONVIF Camera: %s on port %s", + _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), @@ -75,10 +75,12 @@ def __init__(self, hass, config): }, 'ProfileToken': profiles[0]._token} ) 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) + '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 From 44de4a0d6dcdc3793ac530d52e14300a99b39802 Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 13 Dec 2017 22:59:45 +0000 Subject: [PATCH 09/14] remove unnessary imports --- homeassistant/components/camera/onvif.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 40f7735bf8fbed..6b4778d3e3ccf0 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 @@ -55,7 +54,6 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): def __init__(self, hass, config): """Initialize a ONVIF camera.""" from onvif import ONVIFCamera - import onvif super().__init__() self._name = config.get(CONF_NAME) From 91dac8090c1e2267de2e7634319520948bfccf0c Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 13 Dec 2017 23:49:46 +0000 Subject: [PATCH 10/14] fixed accessing protected member --- homeassistant/components/camera/onvif.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 6b4778d3e3ccf0..6904bc9e153332 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -66,11 +66,11 @@ def __init__(self, hass, config): config.get(CONF_HOST), config.get(CONF_PORT), config.get(CONF_USERNAME), config.get(CONF_PASSWORD) ).create_media_service() - profiles = media_service.GetProfiles() + profiletoken = (media_service.GetProfiles())[0]._token stream_uri = media_service.GetStreamUri( {'StreamSetup': { 'Stream': 'RTP-Unicast', 'Transport': 'RTSP' - }, 'ProfileToken': profiles[0]._token} + }, 'ProfileToken': profiletoken} ) self._input = stream_uri.Uri.replace( 'rtsp://', 'rtsp://{}:{}@'.format( From 8e286068070ab9e6299d7422ce58ad6e2696a5f6 Mon Sep 17 00:00:00 2001 From: matt Date: Thu, 14 Dec 2017 21:26:12 +0000 Subject: [PATCH 11/14] removed unnecessary profile token --- homeassistant/components/camera/onvif.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 6904bc9e153332..6f0c14807b7aab 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -66,11 +66,10 @@ def __init__(self, hass, config): config.get(CONF_HOST), config.get(CONF_PORT), config.get(CONF_USERNAME), config.get(CONF_PASSWORD) ).create_media_service() - profiletoken = (media_service.GetProfiles())[0]._token stream_uri = media_service.GetStreamUri( {'StreamSetup': { 'Stream': 'RTP-Unicast', 'Transport': 'RTSP' - }, 'ProfileToken': profiletoken} + }} ) self._input = stream_uri.Uri.replace( 'rtsp://', 'rtsp://{}:{}@'.format( From 0ceae2b4db9b875951400e0f1a7abacd0a055098 Mon Sep 17 00:00:00 2001 From: matt Date: Thu, 14 Dec 2017 21:44:57 +0000 Subject: [PATCH 12/14] tidied up StreamSetup --- homeassistant/components/camera/onvif.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 6f0c14807b7aab..ebf94f626b7fd5 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -67,9 +67,7 @@ def __init__(self, hass, config): config.get(CONF_USERNAME), config.get(CONF_PASSWORD) ).create_media_service() stream_uri = media_service.GetStreamUri( - {'StreamSetup': { - 'Stream': 'RTP-Unicast', 'Transport': 'RTSP' - }} + {'StreamSetup': {'Stream': 'RTP-Unicast', 'Transport': 'RTSP'}} ) self._input = stream_uri.Uri.replace( 'rtsp://', 'rtsp://{}:{}@'.format( From b55ebd7b6fef30223c178480ba8db2d493d1fba4 Mon Sep 17 00:00:00 2001 From: matt2005 Date: Wed, 17 Jan 2018 12:52:13 +0000 Subject: [PATCH 13/14] Fixed merge error --- homeassistant/components/camera/onvif.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index ebf94f626b7fd5..8624615f7d4b52 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -47,8 +47,10 @@ 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)]) +class ONVIFCamera(Camera): """An implementation of an ONVIF camera.""" def __init__(self, hass, config): From 282de4ab5c39ed7828f267718287e12717ed8b3c Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 17 Jan 2018 22:10:24 +0000 Subject: [PATCH 14/14] renamed class as it clashed with the modules class --- homeassistant/components/camera/onvif.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/camera/onvif.py b/homeassistant/components/camera/onvif.py index 8624615f7d4b52..17108e730916eb 100644 --- a/homeassistant/components/camera/onvif.py +++ b/homeassistant/components/camera/onvif.py @@ -47,10 +47,10 @@ 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):