Skip to content

Instantly share code, notes, and snippets.

@matt2005
Last active February 9, 2018 13:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matt2005/057b85ca3f39af5e24b3c817dd9599b7 to your computer and use it in GitHub Desktop.
Save matt2005/057b85ca3f39af5e24b3c817dd9599b7 to your computer and use it in GitHub Desktop.
onvif v3
"""
Support for ONVIF Cameras with FFmpeg as decoder.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.onvif/
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.const import (
CONF_NAME, CONF_HOST, CONF_USERNAME, CONF_PASSWORD, CONF_PORT)
from homeassistant.components.camera import Camera, PLATFORM_SCHEMA
from homeassistant.components.ffmpeg import (
DATA_FFMPEG)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.aiohttp_client import (
async_aiohttp_proxy_stream)
_LOGGER = logging.getLogger(__name__)
REQUIREMENTS = ['onvif-py3==0.1.3',
'suds-py3==1.3.3.0',
'http://github.com/tgaugry/suds-passworddigest-py3'
'/archive/86fc50e39b4d2b8997481967d6a7fe1c57118999.zip'
'#suds-passworddigest-py3==0.1.2a']
DEPENDENCIES = ['ffmpeg']
DEFAULT_NAME = 'ONVIF Camera'
DEFAULT_PORT = 5000
DEFAULT_USERNAME = 'admin'
DEFAULT_PASSWORD = '888888'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PASSWORD, default=DEFAULT_PASSWORD): cv.string,
vol.Optional(CONF_USERNAME, default=DEFAULT_USERNAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
})
@asyncio.coroutine
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([ONVIFCameraHASS(hass, config)])
class ONVIFCameraHASS(Camera):
"""An implementation of an ONVIF camera."""
def __init__(self, hass, config):
"""Initialize a ONVIF camera."""
from onvif import ONVIFCamera
super().__init__()
self._name = config.get(CONF_NAME)
self._ffmpeg_arguments = '-q:v 2'
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):
"""Return a still image response from the camera."""
from haffmpeg import ImageFrame, IMAGE_JPEG
ffmpeg = ImageFrame(
self.hass.data[DATA_FFMPEG].binary, loop=self.hass.loop)
image = yield from asyncio.shield(ffmpeg.get_image(
self._input, output_format=IMAGE_JPEG,
extra_cmd=self._ffmpeg_arguments), loop=self.hass.loop)
return image
@asyncio.coroutine
def handle_async_mjpeg_stream(self, request):
"""Generate an HTTP MJPEG stream from the camera."""
from haffmpeg import CameraMjpeg
stream = CameraMjpeg(self.hass.data[DATA_FFMPEG].binary,
loop=self.hass.loop)
yield from stream.open_camera(
self._input, extra_cmd=self._ffmpeg_arguments)
yield from async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
yield from stream.close()
@property
def name(self):
"""Return the name of this camera."""
return self._name
@matt2005
Copy link
Author

matt2005 commented Nov 26, 2017

Add custom_components folder to config folder
under the custom_components folder create a camera folder
under the camera folder you need to save the onvif.py file

Remember to add debug logging for custom_components.camera.onvif

logger:
  logs:
    custom_components.camera.onvif: debug

@matt2005
Copy link
Author

Tested on Sricam port 5000, Android IP CAM port 8080

@karlkar
Copy link

karlkar commented Jan 13, 2018

Hi!
Great job! Have you tried to create a PR to HA github?

Copy link

ghost commented Feb 9, 2018

Hi!
Am a bit new to both Home Assistant and Linux, so I do not really understand what you mean by config folder. Are you referring to /home/homeassistant/.homeassistant?
I have taken the assumption that it was it. I have created /custom_component/camera, copied onvif.py in this folder, added the logger: into configuration.yaml. Check config says config is valid. Restart service but still I cannot get the picture of my camera with ONVIF platform.

Any help?
Thanks

Copy link

ghost commented Feb 9, 2018

My camera configuration is like this:
onvif 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment