coderTong / IpCamera

A binding for Openhab 2 that allows you to use IP Cameras without the need to disable authentication.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IP Camera Binding

This binding allows you to use most IP cameras in openHAB and has many features, so please take the time to read through this guide to learn the many hidden features and different ways to work with cameras that you may not know about. I recommend purchasing a brand of camera that has an open API, as many of the features use far less CPU when done with an API camera, and they usually have better picture quality compared to lower priced cameras.

To see what each brand has implemented from their API's, please see this post:

https://community.openhab.org/t/ipcamera-new-ip-camera-binding/42771

What to do if you have problems

  • Check this readme to see if there are any special setup steps that are needed for your brand, they are listed in the next section.
  • Always look at the log files, which includes looking at the logs with TRACE enabled. This readme has a section on logs to explain how to do this. To keep your log file clean, the binding holds back a lot of useful fault finding information out of the logs unless you turn on DEBUG or TRACE logging.
  • Search the forum using any error messages to help you find how others with the same problem have already solved it. Always read this file first as forum posts can be out dated where this file should always be current.
  • Only after doing the above ask for help in the forum and create a new thread, then when it is fixed post how and mark the thread as solved to help others. This is how a community helps each other out and no one is paid as Openhab is an opensource project with all volunteers.

Special notes for different brands

Generic Cameras

The binding can create snapshots, motion and audio alarms for cameras that only have a RTSP url, it requires FFmpeg to be installed for these features to work and this must be done manually. Some features also may not work fully unless your camera has a snapshot URL, but most will work with the FFmpeg generated snapshots from a RTSP source. The Image channel will not update when using FFmpeg to create snapshots, so you will need to use one of the other much better methods like ipcamera.jpg that is explained in this readme. Using FFmpeg to create snapshots requires much more CPU, and you can turn this CPU load on and off via the updateImageNow channel using a switch or rule. You can forget about using the switch if you setup the config IMAGE_UPDATE_EVENTS to be equal to 1 and then it runs all the time unless you move the switch to OFF. Snapshots generated by FFmpeg use the key frames (iFrames) only to lower the CPU load, and since some cameras only produce a key frame every 2 second with thier default settings, this will effect how often a snapshot is produced. Some cameras allow the keyframe (iFrame) to be created every second or a different amount by the user, refer to your cameras manual and support.

ESP32 Cameras

These cameras do not have the ability to create H264 streams and hence can not be used with HLS to cast to Chromecasts and Home Hubs. They will work with snapshots and mjpeg features. See the examples in the sections below on how to setup these cameras. Due to many custom firmwares available you may need to ask the firmware developer what the urls are for snapshots and mjpeg streams if they have changed from the defaults that the Arduino IDE sample code uses.

Amcrest

It is better to always setup your AMCREST camera as a DAHUA thing type. The old alarm polling method is used in AMCREST and the newer better event based method is used in DAHUA that is stream based. This means less CPU load on your server and far better response to alarms if you setup as Dahua. Please read the special notes for Dahua as they will apply.

Dahua

  • For mjpeg to work you need to set the first substream to be in mjpeg format for the default settings to work, otherwise you can override the default with STREAM_URL_OVERRIDE with a valid url for mjpeg streams.

Hikvision

  • For mjpeg to work you need to set the first substream to be in mjpeg format for the default settings to work, otherwise you can override the default with STREAM_URL_OVERRIDE with a valid url for mjpeg streams.

  • Each alarm you wish to use must have "Notify Surveillance Center" enabled under each alarms settings in the control panel of the camera itself.

  • The CGI/API and also ONVIF are disabled by default on these cameras, so enable and create user details for ONVIF that are the same user/pass as what you have given the binding. If your camera does not have PTZ then you can leave ONVIF disabled and just enable the CGI/API.

If you need a channel or control updated in case you have made a change with the cameras app, you can call a refresh on it by using a cron rule.

import org.eclipse.smarthome.core.types.RefreshType

rule "refresh"
when
    Time cron "0 */15 * * * ? *"
then
    //your ITEMS to refresh every 15 minutes here
    Item.sendCommand(RefreshType.REFRESH)
end

HikVision NVR's

In case your HikVision NVR does not communicate with the binding, make sure that:

  • ISAPI is enabled in the NVR settings
  • ONVIF is enabled and a user/pass created that match the bindings.
  • RTSP is enabled
  • Some NVR's allow each camera to be exposed on a set port to give direct access to each camera, some users report this works the best and needs to be enabled.

Some older versions of these NVRs require setting a different snapshot URL (SNAPSHOT_URL_OVERRIDE), as well as FFMPEG_INPUT. The older ones use the same URL's just with 'ISAPI' removed.

Thing ipcamera:HIKVISION:West "West Camera"
[
    IPADDRESS="192.168.0.XX",
    USERNAME="username",
    PASSWORD="password",
    ONVIF_PORT=8000, //normally 80 check what it needs
    PORT=80,
    NVR_CHANNEL=4,
    SERVER_PORT=54324,
    FFMPEG_OUTPUT="/etc/openhab2/html/cameras/camera-west/",
    FFMPEG_INPUT="rtsp://192.168.0.XX:554/ISAPI/Streaming/channels/401"
]

Foscam

  • If the user/pass is wrong the camera can lockout and refuse to answer the binding requiring a reset of the camera, so be sure the details are correct.

  • To use MJPEG streaming you need to enable one of the streams to use this format. This can be done by entering this into any browser:http://ip:88/cgi-bin/CGIProxy.fcgi?cmd=setSubStreamFormat&format=1&usr=admin&pwd=password

  • If your camera does not support mjpeg as some Foscams no longer do, then you can set STREAM_URL_OVERRIDE="ffmpeg" to use your CPU to generate a mjpeg stream.

  • Some FOSCAM cameras need to have a detection area listed in the URL when you enable the motion alarm. As each model has a different resolution and two different URLs, this makes it difficult to make this automatic so an override feature was added to create your own enable the alarm url. This setting is called MOTION_URL_OVERRIDE and the steps to using it are:

  1. Enable the motion alarm in the web interface of your camera and setup any areas you wish movement to be ignored in ie. Tree branches moving in the wind.
  2. Use any web browser to fetch this URL https://x.x.x.x/cgi-bin/CGIProxy.fcgi?cmd=getMotionDetectConfig1&usr=xxxxx&pwd=xxxxx
  3. Use the information returned by the above url to create the override settings.

An example for a Foscam C2 is...

/cgi-bin/CGIProxy.fcgi?cmd=setMotionDetectConfig1&isEnable=1&snapInterval=1&schedule0=281474976710655&schedule1=281474976710655&schedule2=281474976710655&schedule3=281474976710655&schedule4=281474976710655&schedule5=281474976710655&schedule6=281474976710655&x1=0&y1=0&width1=10000&height1=10000&sensitivity1=1&valid1=1&linkage=6&usr=xxxxx&pwd=xxxxx

Another example is:

/cgi-bin/CGIProxy.fcgi?cmd=setMotionDetectConfig&isEnable=1&linkage=0001&sensitivity=1&triggerInterval=15&schedule0=281474976710655&schedule1=281474976710655&schedule2=281474976710655&schedule3=281474976710655&schedule4=281474976710655&schedule5=281474976710655&schedule6=281474976710655&area0=1023&area1=1023&area2=1023&area3=1023&area4=1023&area5=1023&area6=1023&area7=1023&area7=1023&area8=1023&area9=1023&usr=username&pwd=password

Instar

  • For mjpeg to work you need to set the first substream to be in mjpeg format for the default settings to work, otherwise you can override the default with STREAM_URL_OVERRIDE with a valid url for mjpeg streams.
  • These cameras have the ability to call the openHAB REST API directly when an alarm occurs, can use MQTT, or you can use the built in Alarm Server that the binding auto sets up for you. The latter option is the easiest.
  • Be sure to update to the latest firmware for your camera as Instar have made a lot of improvements recently.

Installing the binding and Discovery

Installing the binding is as simple as first stopping Openhab from running (very important to stop it first) and then drop all the JAR files from inside the ZIP, into the addons folder. Ignore any errors until multiple restarts to Openhab are made, this is to allow the cache to be created.

You do not use PaperUI to install this binding as it is not yet merged.

Auto discovery can be used, however I would recommend using textual configuration which is covered below in more detail. Textual config should be preferred whilst the binding is under going a lot of changes as the channels and config items appear to be stored in a database and are not checked to be correct by the Openhab framework. If you use auto discovery or manually add a camera with PaperUI, it may/will be required to delete the camera and re-add it for the DB to be refreshed with the correct data each time you change the version of the binding. Only a THING file is needed to make changing versions far easier, the rest can be done via paperUI if you wish instead of ITEM files.

Supported Things

If using openHAB's textual configuration or when needing to setup HABPANEL/sitemaps, you are going to need to know what your camera is as a "thing type". These are listed in CAPS below. Example: The thing type for a generic onvif camera is "ONVIF".

Thing Type ID Description
AMCREST Use for all Amcrest Cameras that do not work as a Dahua thing. This uses an older polling method for alarm detection which is not as efficient as the newer method used in Dahua. Amcrest are made by Dahua and hence their cameras can be setup as a Dahua thing.
DAHUA Use for all current Dahua and Amcrest cameras as they support an API as well as ONVIF.
DOORBIRD Use for all current DOORBIRD cameras as they support an API as well as ONVIF.
FOSCAM Use for all current FOSCAM HD Cameras as they support an API as well as ONVIF.
HIKVISION Use for all current HIKVISION Cameras as they support an API as well as ONVIF.
HTTPONLY For any camera that is not ONVIF compatible yet still has the ability to fetch a snapshot or stream with a url.
INSTAR Use for all current INSTAR Cameras as they support an API as well as ONVIF.
ONVIF Use for all ONVIF Cameras from any brand that does not have an API.
GROUPDISPLAY Used to display or cast multiple cameras like they are a single camera. This is an advanced feature that may require some tweaking of the cameras settings to fully work.

Binding Configuration

The binding can be configured with PaperUI by clicking on the pencil icon of any of the cameras that you have manually added via the PaperUI inbox. To add a camera just press on the PLUS (+) icon in the INBOX of PaperUI.

Cameras can also be manually configured with text files by doing the following. DO NOT try and change a setting using PaperUI after using textual configuration as the two will conflict as the text file locks the settings preventing them from changing. If using PaperUI, each time I add a new channel you will need to remove and re-add the camera which then gives it a new UID number (Unique ID number), which in turn can break your sitemap and HABPanel setups. Textual configuration has its advantages and locks the camera to use a simple UID which can be a plain text name like "DrivewayCamera".

The configuration parameters that can be used in textual configuration are in CAPS, descriptions can be seen in PaperUI to help guide you on what each one does:

Parameter Description
IPADDRESS Local address of your camera or NVR
PORT This port will be used for HTTP calls for fetching the snapshot and alarm states.
ONVIF_PORT The port your camera uses for ONVIF connections. This is needed for PTZ movement and the auto discovery of RTSP and snapshot URLs.
SERVER_PORT The port that will serve the video streams and snapshots back to openHAB without authentication. You can choose any number, but it must be unique and unused for each camera that you setup. Setting the port to -1 (default), will turn all file serving off and some features will fail to work. Also learn about the Ip Whitelist feature if you enable this.
USERNAME User name used to connect to your camera. Leave blank if your camera does not use login details.
PASSWORD Leave blank if your camera does not use login details.
ONVIF_MEDIA_PROFILE 0 is your cameras Mainstream and the numbers above 0 are the substreams if your camera has any. Any auto discovered URLs will use the stream this indicates.
POLL_CAMERA_MS Time in milliseconds between fetching a JPG. Note that most features will not poll and are done on demand to keep network traffic at a minimum.
IMAGE_UPDATE_EVENTS The Image channel can be set to update in a number of ways to help reduce network traffic.
0 - Default, the Image channel never updates.
1 - Update the Image channel when the updateImageNow channel is turned on.
2 - Start of Motion Alarms will cause the Image channel to update next poll.
3 - Start Audio Alarm will cause the Image channel to update next poll.
23 - Start of Motion and Audio Alarms will the Image channel to update next poll.
4 - During Motion Alarm the Image channel will update every poll until Alarm stops.
5 - During Audio Alarm the Image channel will update every poll until Alarm stops.
45 - During Motion and Audio Alarms the Image channel will update every poll until both alarms stop.
UPDATE_IMAGE The default state of the channel updateImageNow when Openhab starts. When switched OFF the image channel will NOT update unless you override this with the updateImageNow channel.
NVR_CHANNEL Set this to 1 if it is a standalone camera, or to the input channel number of your NVR that the camera is connected to.
SNAPSHOT_URL_OVERRIDE Leave this empty to auto detect the snapshot URL if the camera has ONVIF. Enter a HTTP address if you wish to override with a different address, this can also make the camera connect quicker. Setting this to ffmpeg forces the camera to use ffmpeg to create the snapshots from the RTSP stream.
MOTION_URL_OVERRIDE Foscam only, for custom enable motion alarm use. More info found in Foscam setup below.
AUDIO_URL_OVERRIDE Foscam only, for custom enable audio alarm use. More info found in foscam setup below.
STREAM_URL_OVERRIDE A HTTP URL for MJPEG format streams only, it can not be a RTSP url however if you enter 'ffmpeg' the mjpeg stream can be generated from the RTSP url if you have ffmpeg installed.
FFMPEG_INPUT Best if this stream is in H264 format and can be RTSP or HTTP urls. Leave this blank to use the auto detected RTSP address, or enter a URL for any type of stream that ffmpeg can use as an input.
FFMPEG_LOCATION The full path including the filename for where you have installed ffmpeg. For windows use e.g. this format: c:\ffmpeg\bin\ffmpeg.exe
FFMPEG_OUTPUT The full path where ffmpeg has the ability to write files to ending with a slash. For windows use e.g. this format: c:\openhabconf\html\ipcamera\
If you would like to expose the GIF files to your static server, you can set FFMPEG_OUTPUT="/etc/openhab2/html/cameras/camera-name/"
FFMPEG_HLS_OUT_ARGUMENTS This gives you direct access to specify your own ffmpeg options to be used. Default: -strict -2 -f lavfi -i aevalsrc=0 -acodec aac -vcodec copy -hls_flags delete_segments -hls_time 2 -hls_list_size 4
FFMPEG_GIF_OUT_ARGUMENTS This gives you direct access to specify your own ffmpeg options to be used for animated GIF files. Default: -r 2 -filter_complex scale=-2:360:flags=lanczos,setpts=0.5*PTS,split[o1][o2];[o1]palettegen[p];[o2]fifo[o3];[o3][p]paletteuse
FFMPEG_MJPEG_ARGUMENTS Allows you to change the settings for creating a mjpeg stream from rtsp using FFmpeg. Possible reasons to change this would be to rotate or rescale the picture from the camera, change the jpeg compression for better quality or the FPS rate from 6 to another value. Default: -qscale:v 5 -r 6 -update 1
FFMPEG_MOTION_ARGUMENTS This gives access to the FFmpeg parameters for detecting motion alarms from a RTSP stream. One possible use for this is to use the CROP feature to ignore any trees that move in the wind or a timecode stamp. Crop will not remove the trees from your picture, it only ignores the movement of the tree. Default is an empty string.
GIF_PREROLL Store this many snapshots from BEFORE you trigger a GIF creation. Default: 0 will not use snapshots and will instead use a realtime stream from the FFMPEG_INPUT url
GIF_POSTROLL How long in seconds to create a GIF from a stream. Alternatively if GIF_PREROLL is set to value greater than 0, this is how many snapshots to use AFTER you trigger a GIF creation as snapshots occur at the poll rate.
IP_WHITELIST Enter any IPs inside brackets that you wish to allow to access the video stream. DISABLE the default value will turn this feature off. Example: IP_WHITELIST="(127.0.0.1)(192.168.0.99)"
PTZ_CONTINUOUS If set to false (default) the camera will move using Relative commands, If set to true the camera will instead use continuous movements and will require an OFF command to stop the movement.

Create a file called ipcamera.things and save it to your things folder. Inside this file enter this in plain text and modify it to your needs. Leaving a config out of this file will simply leave it at the default value which should work for most people.

// Uses Onvif to fetch the urls, hence why they are not defined here.
Thing ipcamera:DAHUA:BabyCamera "Baby Monitor" @ "Cameras"
[
    IPADDRESS="192.168.1.5",
    USERNAME="admin",
    PASSWORD="suitcase123456",
    POLL_CAMERA_MS=1000,
    SERVER_PORT=50001,
    ONVIF_PORT=80,
    PORT=80,
    GIF_PREROLL=0,
    GIF_POSTROLL=6,
    FFMPEG_OUTPUT="/tmpfs/babymonitor/"
]

// Use 3rd stream of camera to feed openHAB with 720p so it can be Chromecasted as the mainstream is 4K.
Thing ipcamera:HIKVISION:DrivewayCam "DrivewayCam" @ "Cameras"
[
    IPADDRESS="192.168.1.6",
    PASSWORD="suitcase123456",
    USERNAME="admin",
    POLL_CAMERA_MS=1000,
    SERVER_PORT=50002,
    FFMPEG_OUTPUT="/tmpfs/DrivewayCam/",
    FFMPEG_INPUT="rtsp://192.168.1.6:554/Streaming/Channels/103?transportmode=unicast&profile=Profile_1"
]

// Example for using the IP_WHITELIST.
Thing ipcamera:ONVIF:003
[
    IPADDRESS="192.168.1.21",
    PASSWORD="suitcase123456",
    USERNAME="admin",
    ONVIF_PORT=80,    
    SERVER_PORT=50003,
    FFMPEG_OUTPUT="/tmpfs/camera3/",
    IP_WHITELIST="(192.168.2.8)(192.168.2.83)(192.168.2.99)"
]

// ESP32 Cameras have the stream on port 81 and snapshots on port 80, this can be setup easily.
// Use JPG files as the source for animated Gifs (preroll of 1 or higher) as the camera can only handle 1 stream at a time.
Thing ipcamera:HTTPONLY:TTGoCamera "TTGo Camera" @ "Cameras"
[
    IPADDRESS="192.168.1.181",
    POLL_CAMERA_MS=1000,
    SERVER_PORT=54321,
    PORT=80,
    GIF_PREROLL=1,
    GIF_POSTROLL=6,
    SNAPSHOT_URL_OVERRIDE="http://192.168.1.181/capture",
    STREAM_URL_OVERRIDE="http://192.168.1.181:81/stream",
    FFMPEG_OUTPUT="/tmpfs/TTGoCamera/",
    FFMPEG_INPUT="http://192.168.1.181:81/stream"
]

In the examples above you see the format is: bindingID:THINGTYPE:UID [param1="string",param2=x,param3=x]

BindingID: is always ipcamera.

THINGTYPE: is found listed above under the heading "supported things"

UID: Can be made up but it must be UNIQUE, hence why it is called UniqueID. If you use PaperUI you will notice the UID will be something like "0A78687F" which is not very nice when using it in sitemaps and rules. PaperUI will choose a new random ID each time you remove and add the camera causing you to edit your rules, items and sitemaps to make them match. You can use text to name it something useful like "DrivewayCamera" if you wish.

Channels

Use PaperUI to see a full list of channels and the descriptions, most are easy to understand however any channels which need further explanation will be added here. Each camera brand will have different channels depending on how much of the support for an API has been added. The channels are kept consistent as much as possible from brand to brand to make upgrading to a different branded camera easier and to help when sharing rules with other users in the forum.

externalMotion

This channel is intended to allow any external sensor the ability to inform the binding that there is motion in the cameras field of view. Note: It will not be passed onto your camera and will not trigger any recordings, it is purely for the bindings own set of features. An example of how this is useful is if your camera either has no motion alarm features, or you have bugs tripping the built in sensors, you can use this channel with a ZWave PIR sensor to inform the camera of motion. This becomes more important when you start to use Camera groups that dynamically change the display order of the cameras based on if there is movement or not. It can also be handy to use this when doing testing as it allows motion to be simulated with the press of a button.

updateImageNow

This control can be used to manually start and stop updating the Image channel with a picture, or it will start and stop FFmpeg from creating snapshots from a RTSP source depending on how the bindings config parameters are set. The UPDATE_IMAGE config sets the state this control is set to on startup/reboot of Openhab. When ON the image channel will update at the POLL_CAMERA_MS rate. Note that cameras that create snapshots from RTSP using FFmpeg will not update the image channel at all and the better methods like ipcamera.jpg covered in this readme are the recommended way to achieve a picture. When OFF the Image channel will NOT update, but the other methods of achieving a picture or stream will still work. If you need to update the image channel more often then every 5 seconds, please see the snapshot and stream sections of this readme to learn how to get a picture without using the Image channel.

ffmpegMotionControl

This control allows FFmpeg to detect movement from a RTSP or HTTP source and inform Openhab. It is best described in the first few posts of this thread. https://community.openhab.org/t/how-to-turn-a-cameras-rtsp-stream-into-motion-detection/89906 You can link a Switch and a Slider to this channel at the same time to have ON/OFF control as well as a slider to change the threshold.

thresholdAudioAlarm

Most of the API cameras have a separate ON/OFF channel, but for non API cameras that use ffmpeg to create an Audio Alarm from a RTSP source, this channel can be linked to a Switch and a Slider. Linking both controls to this channel at the same time gives ON/OFF control as well as a slider to change the threshold. The value of the slider is the value in dB that is detected as no noise/alarm. Higher values are more sensitive and will trigger the Alarm with quieter / less noise.

updateGif

When this control is turned ON it will trigger an animated Gif to be created by FFmpeg. You will need to install FFmpeg on your server manually. Once the file is created the control will auto turn itself back to OFF which can be used to trigger a rule to email/Pushover/Telegram the file to you. When GIF_PREROLL is set to a value higher than 0, the binding will create and use snapshots (jpg) instead of using the RTSP feed from the camera, which is the default behavior when the GIF_PREROLL is set to 0 or not defined. IMAGE_UPDATE_EVENTS must be set to always update the image and POLL_CAMERA_MS sets how often the snapshot is added to the FIFO buffer that creates the animated GIF. The snapshot files are not deleted but are overwritten each time a gif is created. These files 'snapshotxx.jpg' can also be used by yourself to create and email Jpeg files also giving you a number to choose from in case your camera has delayed footage. The files are placed into the folder specified by the config FFMPEG_OUTPUT.

lastMotionType

Cameras with multiple alarm types will update this with which alarm detected motion.ie a lineCrossing, faceDetection or item stolen alarm. You can use this to create a timestamp of when the last motion was detected by creating a rule when this channel is updated.

items:

String BabyCamLastMotionType "Last Motion Type" { channel="ipcamera:DAHUA:BabyCamera:lastMotionType" }
DateTime BabyCamLastMotionTime "Last Update [%1$ta %1$tR]"

rules:

rule "Create timestamp of last movement"
    when
    Item BabyCamLastMotionType received update
    then
    BabyCamLastMotionTime.postUpdate( new DateTimeType() )
end

apiAccess

A special String channel has been added that allows you to send any GET request to Dahua cameras only. This is due to the HTTP binding currently not supporting the DIGEST method that these cameras must use in the latest firmwares. For other brands you can use the HTTP binding should a feature not have direct support in this binding. It is far better to add or request a feature so that it gets added to the binding so that all future users benefit. One goal of this binding is to save all users from needing to learn an API, instead they can use that time saved to automate with openHAB.

The reply from the camera is not captured nor returned, so this is only a 1 way GET request. To use this feature you can simply use this command inside any rule at any time and with as many url Strings as you wish. User/pass and the IP are handled automagically.

item:

String CamAPIAccess "Access the API" { channel="ipcamera:DAHUA:001:apiAccess" }

Command to use in rules:

CamAPIAccess.sendCommand('/cgi-bin/configManager.cgi?action=setConfig&Lighting[0][0].Mode=Off')

The URL must be in this format without the IP:Port info and the binding will handle the user and password for you making it far simpler to change a password on a camera without the need to update countless lines in your openHAB files.

Full Example

Use the following examples to base your setup on to save some time. In the example below I believe older versions of OpenHAB needed a fake address in the "Image url=" line, however Openhab 2.4 and newer do not need this to work but for backwards compatibility reasons it was left in the examples. The item= overrides the url.

NOTE: If you used PaperUI to create the camera thing instead of textual config, you will need to ensure the 001 is replaced with the cameras UID which may look like "0A78687F". Also replace AMCREST or HIKVISION with the name of the supported thing you are using from the list above.

*.things

Thing ipcamera:GROUPDISPLAY:OutsideCameras
[
    POLL_CAMERA_MS=2000, SERVER_PORT=54320, 
    FFMPEG_OUTPUT="/tmpfs/OutsideGroup/",
    FIRST_CAM="001",
    SECOND_CAM="002",
    THIRD_CAM="TestCam",
    FORTH_CAM="",
    MOTION_CHANGES_ORDER=true
]

Thing ipcamera:DAHUA:001
[ 
    IPADDRESS="192.168.0.5", PASSWORD="suitcase123456",
    USERNAME="admin",
    POLL_CAMERA_MS=2000,
    SERVER_PORT=54321,
    FFMPEG_OUTPUT="/tmpfs/camera1/"
]

Thing ipcamera:HIKVISION:002
[
    IPADDRESS="192.168.0.6", PASSWORD="suitcase123456",
    USERNAME="admin",
    POLL_CAMERA_MS=2000,
    SERVER_PORT=54322,
    FFMPEG_OUTPUT="/tmpfs/camera2/"
]

Thing ipcamera:HTTPONLY:TestCam
[
    IPADDRESS="192.168.0.7", PASSWORD="pass123", USERNAME="admin", POLL_CAMERA_MS=1000, SERVER_PORT=54323,
    SNAPSHOT_URL_OVERRIDE="http://192.168.1.65/tmpfs/snap.jpg", //remove this line if your camera has none
    STREAM_URL_OVERRIDE="ffmpeg",
    FFMPEG_OUTPUT="/tmpfs/HttpTest/", 
    FFMPEG_INPUT="rtsp://192.168.1.65:554/11" //no need to add user or pass as binding handles this for you.
]

*.items

Switch BabyCamCreateGif "Create animated GIF" { channel="ipcamera:DAHUA:001:updateGif" }
Number BabyCamDirection "Camera Direction"
Dimmer BabyCamPan "Pan [%d] left/right" { channel="ipcamera:DAHUA:001:pan" }
Dimmer BabyCamTilt "Tilt [%d] up/down" { channel="ipcamera:DAHUA:001:tilt" }
Dimmer BabyCamZoom "Zoom [%d] in/out" { channel="ipcamera:DAHUA:001:zoom" }
Switch BabyCamEnableMotion "MotionAlarm on/off" { channel="ipcamera:DAHUA:001:enableMotionAlarm" }
Switch BabyCamMotionAlarm "Motion detected" { channel="ipcamera:DAHUA:001:motionAlarm" }
Switch BabyCamEnableAudioAlarm "AudioAlarm on/off" { channel="ipcamera:DAHUA:001:enableAudioAlarm" }
Switch BabyCamAudioAlarm "Audio detected" { channel="ipcamera:DAHUA:001:audioAlarm" }
Dimmer BabyCamAudioThreshold "Audio Threshold [%d]" { channel="ipcamera:DAHUA:001:thresholdAudioAlarm" }
Dimmer BabyCamLED "IR LED [%d]" { channel="ipcamera:DAHUA:001:enableLED" }
Switch BabyCamAutoLED "Auto IR LED" { channel="ipcamera:DAHUA:001:autoLED" }
String BabyCamTextOverlay "Text to overlay" { channel="ipcamera:DAHUA:001:textOverlay" }
String BabyCamAPIAccess "Access the API" { channel="ipcamera:DAHUA:001:apiAccess" }
String BabyCamStreamUrl "Mjpeg Stream" { channel="ipcamera:DAHUA:BabyCamera:streamUrl" }
String BabyCamHlsStreamUrl "HLS Stream" { channel="ipcamera:DAHUA:BabyCamera:hlsUrl" }
String BabyCamRTSPStreamUrl "RTSP Stream" { channel="ipcamera:DAHUA:BabyCamera:rtspUrl" }
DateTime BabyCamLastMotionTime "Time motion was last detected [%1$ta %1$tR]"
String BabyCamLastMotionType "Last Motion Type" { channel="ipcamera:DAHUA:BabyCamera:lastMotionType" }
Switch BabyCamStartHLS { channel="ipcamera:DAHUA:BabyCamera:startStream" }

Switch CamEnableMotionAlarm "MotionAlarm on/off" { channel="ipcamera:HIKVISION:002:enableMotionAlarm" }
Switch CamMotionAlarm "Motion detected" { channel="ipcamera:HIKVISION:002:motionAlarm" }
Switch CamEnableLineAlarm "LineAlarm on/off" { channel="ipcamera:HIKVISION:002:enableLineCrossingAlarm" }
Switch CamLineAlarm "Line Alarm detected" { channel="ipcamera:HIKVISION:002:lineCrossingAlarm" }

Dimmer HttpOnlyMotionControl "Motion Threshold [%d]" { channel="ipcamera:HTTPONLY:TestCam:ffmpegMotionControl" }
Switch HttpOnlyMotionAlarm "Motion detected" { channel="ipcamera:HTTPONLY:TestCam:motionAlarm" }
Dimmer HttpOnlyAudioThreshold "Audio Threshold [%d]" { channel="ipcamera:HTTPONLY:TestCam:thresholdAudioAlarm" }
Switch HttpOnlyAudioAlarm "Audio detected" { channel="ipcamera:HTTPONLY:TestCam:audioAlarm" }
Switch HttpOnlyCreateGif "Create animated GIF" { channel="ipcamera:HTTPONLY:TestCam:updateGif" }
String HttpOnlyMjpegStreamUrl "Mjpeg Stream" { channel="ipcamera:HTTPONLY:TestCam:streamUrl" }
String HttpOnlyRTSPStreamUrl "RTSP Stream" { channel="ipcamera:HTTPONLY:TestCam:rtspUrl" }
String HttpOnlyHlsStreamUrl "HLS Stream" { channel="ipcamera:HTTPONLY:TestCam:hlsUrl" }
String HttpOnlyImageUrl "Image Url" { channel="ipcamera:HTTPONLY:TestCam:imageUrl" }

String OutsideCameraGroupHlsStreamUrl "Outside Cameras" { channel="ipcamera:GROUPDISPLAY:OutsideCameras:hlsUrl", ga="Camera" [ protocols="hls" ] }
Switch OutsideCameraGroupStartHLS "Start outside HLS" { channel="ipcamera:GROUPDISPLAY:OutsideCameras:startStream" }
String OutsideCameraGroupMjpegUrl "Mjpeg Stream" { channel="ipcamera:GROUPDISPLAY:OutsideCameras:streamUrl" }
String OutsideCameraGroupImageUrl "Image Url" { channel="ipcamera:GROUPDISPLAY:OutsideCameras:imageUrl" }

*.sitemap

Text label="Outside Camera Group" icon="camera"{Image url="http://192.168.0.2:54320/ipcamera.jpg" refresh=1000} 

    Text label="BabyMonitor" icon="camera"{
        Switch item=BabyCamDirection icon=movecontrol label="Camera Direction" mappings=[0="Room", 1="Cot", 2="Door"]
        Default item=BabyCamMotionAlarm icon=siren
        Default item=BabyCamAudioAlarm icon=siren
        Text label="Advanced Controls" icon="settings"{
            Switch item=BabyCamEnableMotion
            Default item=BabyCamEnableAudioAlarm
            Default item=BabyCamAudioThreshold icon=recorder
            Slider item=BabyCamLED
            Default item=BabyCamAutoLED
            Slider item=BabyCamPan icon=movecontrol
            Slider item=BabyCamTilt icon=movecontrol
            Slider item=BabyCamZoom icon=zoom
        }
        Text label="Last Movement" icon="motion"{
                    Webview url="http://192.168.0.2:54321/ipcamera.gif" height=9
                    Switch item=BabyCamCreateGif
                    Default item=BabyCamMotionAlarm icon=siren
                    Default item=BabyCamLastMotionTime
                    Default item=BabyCamLastMotionType
        }
            Text label="Cameras Mjpeg Stream" icon="camera"{Video url="http://192.168.0.2:54321/ipcamera.mjpeg" encoding="mjpeg"}
            Text label="Snapshot 1FPS Stream" icon="camera"{Video url="http://192.168.0.2:54321/snapshots.mjpeg" encoding="mjpeg"}
            Text label="autofps Stream" icon="camera"{Video url="http://192.168.0.2:54321/autofps.mjpeg" encoding="mjpeg"}
            Text label="HLS Video Stream" icon="camera"{Video url="http://192.168.0.2:54321/ipcamera.m3u8" encoding="hls"}
            Text label="HLS Webview Stream" icon="camera"{Webview url="http://192.168.0.2:54321/ipcamera.m3u8" height=15}
            Text label="Image using jpg method" icon="camera"{Image url="http://192.168.0.2:54321/ipcamera.jpg" refresh=2000}        
    }
    
    Text label="Httponly Camera" icon="camera"{
            Switch item=HttpOnlyCreateGif
            Switch item=HttpOnlyMotionControl
            Slider item=HttpOnlyMotionControl
            Default item=HttpOnlyMotionAlarm
            Switch item=HttpOnlyAudioThreshold
            Slider item=HttpOnlyAudioThreshold          
            Default item=HttpOnlyAudioAlarm
            Text label="Mjpeg Stream" icon="camera"{Video url="http://192.168.0.2:54323/ipcamera.mjpeg" encoding="mjpeg"}
            Text label="snapshots 1FPS Stream" icon="camera"{Video url="http://192.168.0.2:54323/snapshots.mjpeg" encoding="mjpeg"}
            Text label="autofps Stream" icon="camera"{Video url="http://192.168.0.2:54323/autofps.mjpeg" encoding="mjpeg"}
            Text label="HLS Video Stream" icon="camera"{Video url="http://192.168.0.2:54323/ipcamera.m3u8" encoding="hls"}
            Text label="HLS Stream" icon="camera"{Webview url="http://192.168.0.2:54323/ipcamera.m3u8" height=15}
            Text label="Image jpg method" icon="camera"{Image url="http://192.168.0.2:54323/ipcamera.jpg" refresh=1000}                
        }

*.rules

rule "Move cameras direction"
when
    Item BabyCamDirection changed
then
    switch (BabyCamDirection.state as DecimalType) {
        case 0 :{
        //Room
        BabyCamPan.sendCommand(22)
        BabyCamTilt.sendCommand(60)
        BabyCamZoom.sendCommand(0)
        }
        case 1 :{
        //Cot
        BabyCamPan.sendCommand(22)
        BabyCamTilt.sendCommand(0)
        BabyCamZoom.sendCommand(0)
        }
        case 2 : {
        //Door
        BabyCamPan.sendCommand(15)
        BabyCamTilt.sendCommand(75)
        BabyCamZoom.sendCommand(1)
        }
    }
end

rule "Camera detected crying"
when
    Item BabyCamAudioAlarm changed from OFF to ON
then
if(BabyMonitor.state==ON){

    if(MumAlerts.state==ON){
    sendNotification("mum@parentCo.com", "Mum, the baby is awake.")
    }

    if(DadAlerts.state==ON){
    sendNotification("dad@parentCo.com", "Dad, the baby is awake.")
    }

    if(TvAlerts.state==ON){
    myKodi_notification.sendCommand("Baby is crying.")
    }
}
end

rule "Create time of last movement"
    when
    Item BabyCamLastMotionType received update
    then
    BabyCamLastMotionTime.postUpdate( new DateTimeType() )
end

For the above notifications to work you will need to setup multiple users with the correct email address's at the openHAB cloud.

Moving PTZ capable cameras

To move a camera with this binding you need an ONVIF camera that supports one of the following:

  • Absolute movements
  • Relative movements
  • Continuous movements
  • Presets

To test your cameras compatibility out and also to create some preset locations, use a free program called onvif device manager (ODM for short). Not all Onvif cameras work with all of the methods, so testing first to confirm what works is a good idea and the presets can not be created with the binding, only loaded after they are already created. After creating new or changing existing presets, it may be necessary to restart the binding before they can be used. You can create names using the mappings feature of the selection element. See docs here https://www.openhab.org/docs/configuration/sitemaps.html#mappings

Moving the camera using Relative or Continuous (the config PTZ_CONTINUOUS must be true) movements can be done by sending the INCREASE and DECREASE commands to the Pan, Tilt and Zoom channels. When the config is set to false (the default if not specified) the binding will send Relative movements. There are some widgets created in the Habpanel widget gallery that you can download and use right away saving you time if your camera supports either presets, relative or continuous modes. For sitemaps the Setpoint buttons will send INCREASE and DECREASE commands and not the usual ON and OFF that a switch normally sends. The OFF command (can be sent to any of the PTZ channels) will stop the cameras movements in the case of continuous being selected in the things config setup.

item:

Number TestCamGotoPreset "Goto Preset" { channel="ipcamera:ONVIF:TestCam:gotoPreset" }
Dimmer TestCamPan "Pan [%d] left/right" { channel="ipcamera:ONVIF:TestCam:pan" }
Dimmer TestCamTilt "Tilt [%d] up/down" { channel="ipcamera:ONVIF:TestCam:tilt" }
Dimmer TestCamZoom "Zoom [%d] in/out" { channel="ipcamera:ONVIF:TestCam:zoom" }

sitemap:

Selection item=TestCamGotoPreset
Setpoint item=TestCamPan
Setpoint item=TestCamTilt 
Setpoint item=TestCamZoom
Slider item=TestCamPan
Slider item=TestCamTilt 
Slider item=TestCamZoom

Moving the camera to an EXACT repeatable location (Preset 1 saved location) with a rule:

TestCamGotoPreset.sendCommand(1)

Moving the camera to an EXACT repeatable location using Absolute movement with a rule:

TestCamPan.sendCommand(22)
TestCamTilt.sendCommand(60)
TestCamZoom.sendCommand(0)

Image / Snapshots

There are a number of ways to use snapshots with this binding. There are advantages to using these methods from the binding instead of directly from the camera.

Ways to use snapshots are:

  • Use the cameras URL and fetch it directly so it passes from the camera to your end device ie a tablet without passing any data through the openHAB server. For cameras like Dahua that refuse to allow DIGEST to be turned off, this is not an option. The binding has some advantages which are explained below so even if your camera can work directly, you may not wish to do so.
  • Request a snapshot with the url http://192.168.xxx.xxx:54321/ipcamera.jpg (with 54321 being the SERVER_PORT number that you specify in the bindings setup) this will return the current snapshot without needing to wait for the camera to create and send a snapshot. This file does not exist on disk and is served out of ram to keep disk writes to a minimum with this binding. This means the binding can serve a jpg file much faster than a camera can directly as a camera usually waits for a keyframe, then has to compresses the data, before it can then be sent. All of this takes time giving you a delay compared to serving the file from Ram and can make a sitemap or habpanel UI feel slow to respond if the pictures take time to appear. The ipcamera.jpg can be cast as most cameras can not cast their snapshots without using the binding.
  • Use the http://192.168.xxx.xxx:54321/snapshots.mjpeg to request a stream of snapshots to be delivered in mjpeg format. See the streaming section for more info but this only works if the Poll time is 8 seconds or lower. For poll times above 8 seconds use the Image channel.
  • Use the Create GIF feature and use a preroll value >0. This creates a number of snapshots in the ffmpeg output folder called snapshotXXX.jpg where XXX starts at 0 and increases each poll amount of time. This means you can get a snapshot from an exact amount of time before, on, or after triggering the GIF to be created. Handy for cameras which lag due to slow processors and buffering. These snapshots can be fetched either directly as they exist on disk, or via this url format. http://192.168.xxx.xxx:54321/snapshot0.jpg Where the IP is your Openhab server and the port is what is setup in the binding as the SERVER_PORT.
  • The Image channel can be used but is not recommended unless the poll time is above 8 seconds. The snapshots.mjpeg is a better way or if using 1 second updates the newer autofps.mjpeg which are discussed in the streaming section of this readme.
  • You can also read the raw image data directly from the image channel and use it in rules, there are some examples on the forum how to do this, however it is far easier to use the above methods.
  • Also worth a mention is that you can off load cameras to a software package running on a separate hardware server. These have their advantages, but can be overkill depending on what you plan to do with your cameras. Motion, Shinobi and Zoneminder are opensource projects worth checking out.

See this forum thread for examples of how to use snapshots and streams. https://community.openhab.org/t/ip-camera-how-to-clickable-thumbnail-overview-in-sitemaps-that-opens-up-to-a-larger-view/77990

How to get working video streams

IMPORTANT: The binding has its own file server that works by allowing access to the snapshot and video streams with no user/password for requests that come from an IP located in the white list. Requests from outside IP's or internal requests not on the white list will fail to get any answer. If you prefer to use your own firewall instead, you can also choose to make the ip whitelist equal "DISABLE" (now the default) to turn this feature off and then all internal IP's will have access.

There are now multiple ways to get a moving picture:

  • HLS (Http Live Streaming) which uses high resolution h264. This can be used to cast to Chromecast devices, or can display video in many browsers.
  • ipcamera.mjpeg whilst larger in size, it is more compatible for displaying in a wider range of UI's and browsers. It has less lag behind realtime when compared to HLS. Ffmpeg can be used to create this stream if your camera does not create one for you, but this uses more CPU. A lot of cameras limit the resolution in this format, so consider using HLS, autofps.mjpeg, or snapshots.mjpeg instead which will be in higher resolution.
  • snapshots.mjpeg is a special mjpeg stream created from the cameras snapshots that are taken at the polling rate. If the polling time is too long, this will not work so I suggest using it with 1000ms to 9000ms polling times.
  • autofps.mjpeg This requires the poll time to be 1000ms and the motion alarm to be turned on or it will not work as intended. This feature is designed to keep data traffic to your mobile devices as low as possible by automatically sending 1fps when motion is occurring, but only 1 picture every 8 seconds when the picture has no motion. The idea is to not send lots of pictures if the picture has not changed as doing so only eats up your data plan.
  • Animated GIF. This is small in size and very compatible and handy to use in push notifications, Pushover, Telegram, or emails.
  • MP4 recordings can be created by the binding and FFmpeg, more on this below.

See this forum thread for examples of how to use snapshots and streams. https://community.openhab.org/t/ip-camera-how-to-clickable-thumbnail-overview-in-sitemaps-that-opens-up-to-a-larger-view/77990

To get some of the video formats working, you need to install the FFmpeg program. Visit their site here to learn how https://ffmpeg.org/

Under Linux, FFmpeg can be installed very easily with this command.

sudo apt update && sudo apt install ffmpeg

MP4 Recordings

The binding can now use FFmpeg to create a recording to a file. To do this:

  • Consider setting the String channel that is called mp4Filename to a date and time stamp in a format that you like, or leave the channel empty for the filename to default to ipcamera.mp4.
  • Change the Number channel called recordMp4 to a number of how many seconds that you wish to record for. The recording will then start.
  • Once the file is created the channel recordMp4 will change itself back to 0 which can be used to trigger a rule to send the file, or you could use this event to change a counter variable that is used in the filename to create visitor1.mp4 visitor2.mp4.

*.items

Switch BackyardCamExternalMotion "External Motion" { channel="ipcamera:HIKVISION:BackyardCam:externalMotion" }
String BackyardCamMp4Filename "Backyard Mp4 Filename" { channel="ipcamera:HIKVISION:BackyardCam:mp4Filename" }
Number BackyardCamRecordMp4 "Backyard seconds to Record" { channel="ipcamera:HIKVISION:BackyardCam:recordMp4" }

*.rules

rule "Record MP4 on External Zwave PIR"
    when
    Item BackyardCamExternalMotion changed to ON
    then
        BackyardCamMp4Filename.sendCommand( new DateTimeType().toString ) //create a file with the timestamp as the filename.
        BackyardCamRecordMp4.sendCommand(5) // record 5 seconds    
end

rule "Do something when recording finished"
    when
    Item BackyardCamRecordMp4 changed to 0
    then
    var TimeStamp = BackyardCamMp4Filename.state
    logInfo("camera.rules", "Mp4 recording "+ TimeStamp.toString +".mp4 is ready to be used.")
end

##MJPEG Streams##

Cameras that have built in MJPEG abilities can stream to openHAB with the MJPEG format with next to no CPU load and FFmpeg does not need to be installed. Cameras without this ability can still use this binding to convert their cameras h264 format to mjpeg (keep reading for more on this below) and this takes a lot of CPU power to handle the conversion. The alternative HLS format does not need the conversion, however due to HLS needing to buffer the files to disk, the HLS will result in lag (delay) behind real time. For video without a delay, you need mjpeg and without a camera that can create it, you will need to use a lot of CPU power.

An alternative way to keep the CPU load low is to use the snapshots.mjpeg feature of the binding to create a stream from the cameras snapshots instead of the RTSP stream. This is limited to 1 frame a second but often results in far greater picture quality, so be sure to try the different ways and choose what you prefer.

The main cameras that can do mjpeg with very low CPU load are Amcrest, Dahua, Hikvision, Foscam HD and Instar HD. To set this up, see the special setup steps in this readme. The binding can then distribute this stream to many devices around your home whilst the camera only sees a single open stream.

To request the mjpeg stream from the binding, all you need to do is use this link changing the IP to that of your Openhab server and the SERVER_PORT to match the settings in the bindings setup for that camera. ipcamera.mjpeg is not changed and stays the same for all of your cameras, it is the port that changes between multiple cameras, the rest stays the same.

http://OpenhabIP:ServerPort/ipcamera.mjpeg

For cameras without the ability to create mjpeg streams onboard, the binding is now able to create mjpeg from the cameras RTSP source if FFmpeg is installed and will use the Openhab CPU to create the stream. If you wish to do this for multiple cameras at the same time, then consider setting up a separate video server running a software package to remove this high CPU load off your Openhab server.

To use this feature, all you need to do is set STREAM_URL_OVERRIDE="ffmpeg" to use your CPU to generate the mjpeg stream. If you leave the option blank the binding will warn you in the logs and still use ffmpeg, so by adding this line it will remove the warning from your logs.

Ffmpeg may require you to lower the resolution and/or the FPS to lower the CPU load down enough to run, you may need to experiment. To change the settings used by this feature the binding exposes the config FFMPEG_MJPEG_ARGUMENTS which the default is currently -q:v 10 -r 3 -update 1 where 10 is the jpg quality/compression setting and -r 3 is how many frames per second to try and create. Always try to get the default settings working first before you begin to experiment.

snapshots.mjpeg and autofps.mjpeg a special kind of MJPEG Stream

These features allow you to request a mjpeg stream created by the binding with low CPU usage from the cameras snapshots. Snapshots are usually high resolution and look great, however they are limited to a max of 1 frame per second (1 FPS). The reason this is more useful than snapshots on their own, is some UI's will flash white or black when a snapshot is refreshing, this does not happen with snapshots.mjpeg and is the same bandwidth and CPU load as just using snapshots!

The autofps.mjpeg feature will display a snapshot that updates every 8 seconds to keep network traffic low, then when motion is detected it will automatically increase the frames to every second until the motion stops. This means lower traffic unless the picture is actually changing.

Request the stream to be sent to an item with this url. NOTE: The IP is Openhabs not your cameras IP and the 54321 is what you have set as the SERVER_PORT.

http://192.168.xxx.xxx:54321/snapshots.mjpeg

Use the following to display it in your sitemap or the habpanel equivalent.

With motion alarm turned on and poll at 1000ms. Video url="http://192.168.0.32:54321/autofps.mjpeg" encoding="mjpeg"

With a poll time below 9000ms Video url="http://192.168.0.32:54321/snapshots.mjpeg" encoding="mjpeg"

##HLS (HTTP Live Streaming)##

A channel called 'startStream' can now be used to have HLS run non stop to lower the startup delay that comes with using this type of stream. If the channel is OFF, the stream will start and stop automatically as required, but you will get a delay before the stream is fully running and this may cause you to need to ask twice for the stream. It can be helpful sometimes to use this line in a rule to start the stream before it is needed further on in the rule sendHttpGetRequest("http://192.168.0.2:54321/ipcamera.m3u8") as the stream will stay running for 60 seconds. This 60 second delay before the stream is stopped helps when you are moving back and forth in a UI, as the stream does not keep stopping and needing to start each time you move around the UI. Cameras with h264 format streams (most cameras except ESP32 Cams) can have this copied into the HLS format which can be used to stream to Chromecasts and also display in browsers that support this format using the webview or Habpanel items. Apple devices have excellent support for HLS due to the standard being invented by Apple. Some browsers like Chrome may require a plugin or an update to be installed before they are able to display the video.

Google metadata support now allows you to ask Google to 'Show the Front Door Camera'.

Example of how this is done in your items file.


String FrontDoorCamHlsUrl "Front Door" { channel="ipcamera:ONVIF:FrontDoor:hlsUrl", ga="Camera" [ protocols="hls" ] }

To use the HLS steaming features, you need to:

  1. Set a valid SERVER_PORT as the default value of -1 will turn the feature off.
  2. The audio format in the cameras settings must be AAC and not missing for Chromecast to work. The binding will default to creating a silent AAC audio track which should be used until you have a working setup.
  3. Ensure FFmpeg is installed.
  4. For cameras that do not auto detect the H264 stream which is done for ONVIF cameras, you will need to use the FFMPEG_INPUT and provide a http or rtsp link. This is used for HLS and many other features like the animated GIF.
  5. For Onvif cameras the ONVIF_MEDIA_PROFILE needs to match the stream number you have setup for h264. This is usually 0 and is the main-stream, the higher numbers are the sub-streams if your camera has any. For non Onvif cameras you just need to check the url in the last step works and is provided to the binding.
  6. If streaming to a Chromecast that is not 4k capable, you need to ensure the stream is in a standard resolution that your Chromecast is capable of, ie 1080p or 720p. Cameras with 3 streams are handy as you can have a 4k stream going to a NVR whilst a 720p stream can be cast to your TV whilst a 3rd can be for mjpeg format.
  7. Consider using a SSD, HDD or a tmpfs (ram drive) if using SD/flash cards as the HLS streams are written to the FFMPEG_OUTPUT folder. Only a small amount of storage is needed. I use micro SD cards and a ramdrive and have excellent performance.

Ram drive setup

To create a tmpfs of 20mb at /tmpfs/ run this command to open the file for editing. Recommend using 20Mb per camera that uses this location although it could use less than half that amount if carefully streamlined for less ram. If using the ffmpeg -hls_wrap wrap option (causes issues for my Home Hub), you may even get away with 5Mb per camera.

nano /etc/fstab

Enter and save this at the bottom of the file using ctrl X when done.

tmpfs /tmpfs tmpfs defaults,nosuid,nodev,noatime,size=20m 0 0

FFmpeg HLS Special settings

Please get the default settings working first before playing with the advanced settings.

To get audio working you need to have the camera include audio in the stream and in a format that is supported by Chromecast or your browser, I suggest using AAC as MP3 is not supported by Google/Nest. Then you need to change the HLS settings to what you need, some are suggestions below.

Less delay behind realtime (no audio) if your cameras iFrames are 1 second apart:

-strict -2 -f lavfi -i aevalsrc=0 -acodec aac -vcodec copy -hls_flags delete_segments -hls_time 1 -hls_list_size 4

For cameras with no audio in the stream (default setting) and it must be a supported format like AAC.

-strict -2 -f lavfi -i aevalsrc=0 -acodec aac -vcodec copy -hls_flags delete_segments -hls_time 2 -hls_list_size 4

For cameras with audio in the stream. Note will break Chromecast if the camera does not send audio which is why this is not the default.

-strict -2 -acodec aac -vcodec copy -hls_flags delete_segments -hls_time 2 -hls_list_size 4

Some browsers require larger segment sizes to prevent choppy playback, this can be done with this setting to create 10 second segment files which increases the time before you can get playback working.

-strict -2 -f lavfi -i aevalsrc=0 -acodec aac -vcodec copy -hls_flags delete_segments -hls_time 10 -hls_list_size 4

HLS Sitemap examples

The webview version allows you to zoom in on the video when using the iOS app, the Video element version does not zoom, but it will pass through myopenhab.


Text label="HLS Video Stream" icon="camera"{Video url="http://192.168.1.9:54321/ipcamera.m3u8" encoding="hls"}

Text label="HLS Webview Stream" icon="camera"{Webview url="http://192.168.1.9:54321/ipcamera.m3u8" height=15}

Display multiple HLS streams side by side

In order to display camera hls streams side by side you can also create a webView item and link it to a HTML file in the conf/html directory as follows: The webView url is that of your openhab installation.

Webview url="http://192.168.6.4:8080/static/html/file.html" height=5

<!DOCTYPE html>
<html>
    <body>
        <div style="width: 50%; float: left;">
            <video playsinline autoplay muted controls style="width:100%; " src="http://192.168.6.4:50001/ipcamera.m3u8" />
        </div>
        <div style="width: 50%; float: left;">
            <video playsinline autoplay muted controls style="width: 100%; " src="http://192.168.6.4:50002/ipcamera.m3u8" />
        </div>
        <div style="width: 50%; float: left;">
            <video playsinline autoplay muted controls style="width:100%; " src="http://192.168.6.4:50003/ipcamera.m3u8" />
        </div>
        <div style="width: 50%; float: left;">
            <video playsinline autoplay muted controls style="width: 100%; " src="http://192.168.6.4:50004/ipcamera.m3u8" />
        </div>
    </body>
</html> 

##Habpanel##

This section is about how to get things working in Habpanel.

I highly recommend you check out the easy to use WIDGETS of which there are now 3 ready made ones that are discussed on the forum here. https://community.openhab.org/t/custom-widget-camera-clickable-thumbnails-that-open-a-stream/101275

The widgets in the link above are the easiest way to get an advanced stream working in Openhab and you are welcome to open them up, look at how they work and change them to something even better that suits your needs. If you don't like doing things the easy way with a ready made widget, below are how it can be done without a widget.

How to manually display Mjpeg based streams without using the above WIDGETS:

  • Add a FRAME widget
  • Set URL Source to be 'openHAB String Item'
  • Select the item that is bound to the streamUrl channel of your camera that is setup with this binding and ONLINE.
  • Alternatively you can set a static url like http://192.168.1.2:50001/snapshots.mjpeg to have the binding create a high resolution mjpeg stream out of your snapshots or the cameras url to fetch the stream directly.

How to manually display HLS without using the above WIDGETS:

  • Add a template widget with the following code using an Openhab item to link to your cameras hlsUrl channel.

<video width="100%" height="100%" autoplay src="{{itemValue('Camera_hlsUrl')}}"</video>

##Animated GIF feature##

This binding has a channel called updateGif and when this switch is turned 'ON' (either by a rule or manually) the binding will create an animated GIF called ipcamera.gif in the ffmpeg output folder. You can change the filename using the string channel that is called gifFilename and an example of how to use this in a rule can be seen under the MP4 recording section. Once the file is created the switch will turn 'OFF' and this can be used to trigger a rule to send the picture via email, pushover or telegram messages. This feature saves you from using sleep commands in your rules to ensure a file is created, as the control only turns off when the file is actually created. The switch can be turned on with a rule triggered by an external zwave PIR sensor or the cameras own motion alarm, the choice and the logic can be created by yourself. The feature has two options called preroll and postroll to be aware of. When preroll is 0 (the default) the binding will use the RTSP stream to fetch the amount of seconds specified in the postroll config to create the GIF from. By changing to a preroll value above 0 the binding will change to using snapshots as the source and this requires the jpeg to be updating. The time between the snapshots is the polling time of the camera (2 seconds by default) and can be raised or lowered to 1 second if you desire. The snapshots are saved to disk and can be used as a feature that is described in the snapshot section above in more detail.

You can request the gif by using this url, or by the path to where the file is stored:

http://OpenhabIP:ServerPort/ipcamera.gif

.items

Switch DoorCamCreateGif "Create animated GIF" { channel="ipcamera:DAHUA:DoorCam:updateGif" }

.rules

rule "Create front door camera GIF when front doorbell button pushed"
when
    Item FrontDoorbellButton changed to ON
then
    //Start creating the GIF
    DoorCamCreateGif.sendCommand(ON)
    //Cast a doorbell sound using the Chromecast binding.
    KitchenHomeHubPlayURI.sendCommand("http://192.168.1.8:8080/static/doorbell.mp3")
end

rule "Send doorbell GIF via Pushover"
when
    Item DoorCamCreateGif changed to OFF
then
    sendPushoverMessage(pushoverBuilder("Sending GIF from backyard").withApiKey("dsfhghj6546fghfg").withUser("qwerty54657").withDevice("Phone1").withAttachment("/tmpfs/DoorCam/ipcamera.gif"))
end

Group Displays

The full example section has an example of how to setup a group display. Some additional things to check to get it working are:

  • Currently the poll time of the group must be the same or less than the total time contained in each cameras m3u8 files. If you have 3 seconds worth of video segments in the cameras HLS stream, this is the max time you can set to the Poll time of the group to. If your not using HLS and are just using ipcamera.jpg to display the groups picture with, then the poll time can be set to a wider range.
  • All cameras should have the same HLS segment size setting. 1 and 2 second long segments have been tested to work.

This is still a very new feature and if you have any issues please send some TRACE level log output of when the problem occurs.

Batch motion detection rules

In case you have more than one camera to manage, you might want to create a general rule that would react on the events.

Let's say you have a multiple cameras with motion detection, intrusion detection or others. You can create a Group item called gCameraEvent that would combine all these events:

*.items:

Group gCameraEvent

Switch   East_Camera_MotionAlarm                     "Motion alarm"   (gCameraEvent)  {channel="ipcamera:HIKVISION:East:motionAlarm"}
Switch   East_Camera_FieldDetectionAlarm             "Intrusion alarm"   (gCameraEvent)  {channel="ipcamera:HIKVISION:East:fieldDetectionAlarm"}
Switch   East_Camera_UpdateGif                       "Create an animated gif"   (gCameraGif)    {channel="ipcamera:HIKVISION:East:updateGif"}
DateTime East_Camera_LastMotion                      "Last motion [%1$tH:%1$tM %1$tY-%1$tm-%1$td]"

Then we can make a rule that would launch GIF recorder for each camera that caught motion alert:

camera.rules:

import org.eclipse.smarthome.model.script.ScriptServiceUtil

rule "Update last motion"
when
    Member of gCameraEvent changed to ON
then
    val camera = triggeringItem.name.split("_Camera_").get(0)
    val time = ScriptServiceUtil.getItemRegistry.getItem(camera + "_Camera_LastMotion") as DateTimeItem
    val gif = ScriptServiceUtil.getItemRegistry.getItem(camera + "_Camera_UpdateGif") as SwitchItem
    postUpdate(time, new DateTimeType())
    sendCommand(gif, ON)
end

NOTE: This approach implies that you follow a specific naming convention for your items: [Room]_Camera_[Action] where Action is either MotionAlarm, UpdateGif or LastMotion

Auto renaming archived GIF files

You can also group together all "updateGif" actions by making a gCameraGif group and assigning all your cameras there:

Group gCameraGif
Switch   Backyard_Camera_UpdateGif                   "Create an animated gif"               (gCameraGif)    {channel="ipcamera:HIKVISION:Backyard:updateGif"}
Switch   East_Camera_UpdateGif                       "Create an animated gif"               (gCameraGif)    {channel="ipcamera:HIKVISION:East:updateGif"}
Switch   Front_Camera_UpdateGif                   "Create an animated gif"                  (gCameraGif)    {channel="ipcamera:HIKVISION:Front:updateGif"}
Switch   West_Camera_UpdateGif                    "Create an animated gif"                  (gCameraGif)    {channel="ipcamera:HIKVISION:West:updateGif"}
Switch   Garage_Camera_UpdateGif                  "Create an animated gif"                  (gCameraGif)    {channel="ipcamera:HTTPONLY:Garage:updateGif"}
Switch   Driveway_Camera_UpdateGif                   "Create an animated gif"               (gCameraGif)    {channel="ipcamera:HTTPONLY:Driveway:updateGif"}
Switch   LivingRoom_Camera_UpdateGif              "Create an animated gif"                  (gCameraGif)    {channel="ipcamera:HTTPONLY:LivingRoom:updateGif"}

By default all GIFs are saved with ipcamera.gif name. Now we can archive the old ones by renaming them with a timestamp:

camera.rules:

var Timer timer = null // top of the file, optionally after imports

rule "Rename GIF Anims when Saved"
    when
        Member of gCameraGif changed to ON
   then
        val String timeNow = String::format( "%1$tY%1$tm%1$td-%1$tT", new java.util.Date ).replace(":", "")
        val camera = triggeringItem.name.split("_Camera_").get(0).toLowerCase + "/"

        // Wait 12 secs for ffmpeg to complete
        if (timer === null) {
            timer = createTimer(now.plusSeconds(12), [ |

                // Same as FFMPEG_OUTPUT parameter in Thing definition
                var filePath = "/etc/openhab2/html/cameras/camera-" + camera
                var oldFileName = (filePath + "ipcamera.gif")

                // Separator between filename and timestamp, e.g. '_', '-', '.', or whatever you prefer
                var fileDateSeparator = "_"

                // Substitute "ipCam2" to your new filename preference
                var newFileName = (filePath + "ipcamera" + fileDateSeparator + timeNow + ".gif")

                // Options are "mv" to rename file or "cp" to copy file
                var methodUsed = "cp"

                executeCommandLine("/bin/" + methodUsed + " " + oldFileName + " "  + newFileName)
                logInfo(oldFileName, "Copied to " + newFileName)
            ])
        } else {
            if(timer !== null) {
                timer.cancel
                timer = null
            }
       }
end

Note that the example above also implies that you use the same naming convention ([Room]_Camera_[Action]) and the folders where your GIF files are stored are called /camera-[room]/ where [room] is simply [Room] but in lowercase.

Changing the log to show debug or trace and reducing log output

Any issues from FFmpeg will only get seen in DEBUG level or TRACE. The cameras reply is only shown in TRACE mode and often you will find the camera telling you the password is wrong, or the camera has locked you out due to previous passwords being wrong.

There are two log files discussed here, openHAB.log and events.log please take the time to consider both logs if a fast and stable setup is something you care about. On some systems with slow disk access like SD cards, the writing of a log file can greatly impact on performance. We can turn on/up logs to fault find issues, and then disable them to get the performance back when everything is working.

To watch the logs in realtime with Linux based setups, you can use this linux command which can be done via SSH with a program called putty from a pc or mac.


tail -f /var/log/openhab2/openhab.log -f /var/log/openhab2/events.log

CTRL+C will close the stream. You can also use SAMBA/network shares to open or copy the file directly, but my favorite way to view the logs is with "Frontail". Frontail is another UI that can be selected like paperUI, and can be installed using the openHABian config tool. This allows you to search and only show what you care about, ie a particular warning or error.

openHAB.log

This file displays the information from all bindings and can have the amount of information turned up or down on a per binding basis. The default level is INFO and is the middle level of 5 settings you can use. The OpenHAB documentation goes into this in more detail and is kept up to date. Using the KARAF console you can use these commands to turn the logging up and down to suit your needs. If you are having issues with the binding not working with your camera, then TRACE will give me everything in DEBUG with the additional reply packets from the camera for me to use for fault finding. Because the TRACE shows the cameras replies it often shows you in plain english what the camera is telling you is wrong greatly speeding up the diagnosis of any issues, so please use this to find what is wrong before asking for help.


log:set WARN org.openhab.binding.ipcamera

log:set INFO org.openhab.binding.ipcamera

log:set DEBUG org.openhab.binding.ipcamera

log:set TRACE org.openhab.binding.ipcamera

events.log

By default openHAB will log all image channel updates as an event into a file called events.log, this file can quickly grow if you have multiple cameras all updating the image channel every second.

I believe it is possible for enough high resolution cameras to flood and swamp the event bus with more incoming data then the system can process even if the logs are disabled, so I highly recommend to not use the Image channel and instead use another method outlined in the snapshot section of this readme file. If the data is coming in faster then it can be processed it will result in an Out Off Memory Error (OOME) that can halt your Openhab server so if your reading this to shut down the logging, reconsider the need to use the Image channel.

If you still wish to use the Image channel, the following is how to deal with the log output that is created as the raw picture data in text format is ugly and makes the log very hard to read.

  • You can switch to only updating the image channel on EVENTS like motion alarms.
  • Turn off (disable) all events from being logged.
  • Filter out only the events caused by the image changing before they reach the log file.

The openHAB event.log does not allow normal filtering at a binding level due to the log being a pure output from the event bus.

To disable the event.log use this command in Karaf.


log:set WARN smarthome.event

To re-enable just use the same command with INFO instead of WARN.

To filter out the events do the following:

sudo nano /var/lib/openhab2/etc/org.ops4j.pax.logging.cfg

Inside that file paste the following, save and then reboot.

############ CUSTOM FILTERS START HERE #################
# event log filter
log4j2.appender.event.filter.myfilter1.type = RegexFilter
log4j2.appender.event.filter.myfilter1.regex = .*changed from raw type.*
log4j2.appender.event.filter.myfilter1.onMatch = DENY
log4j2.appender.event.filter.myfilter1.onMisMatch = ACCEPT
################# END OF FILTERS ######################

You can specify the item name in the filter to remove just 1 camera, or you can use the above without the item name to remove all events from images updating which will be for other bindings as well.

Roadmap for further development

Currently the focus is on creating a stable framework that allows all brands to be used in a consistent way, new features that most users wont use are not held as highly as having a stable binding. Sharing rules with others will become easier if all brands are handled the same way and with channels that have the same name.

If you need a feature added that is in an API and you can not program, please raise an issue ticket at Github with a sample of what a browser shows when you enter in the URL, it is usually very quick to add features.

If you wish to contribute then please create an issue ticket first to discuss how things will work before doing any coding. This is for multiple reasons due to needing to keep things CONSISTENT between brands, lower the risk of breaking changes, and also keep the binding easy to maintain.

The following list is a great place to start helping with this binding if you wish to contribute. Any feedback, push requests and ideas are welcome, just please create a Github issue with your plans first.

Areas the binding could be improved are:

  • Taking care of any build errors to get the binding ready for merging into the main project.

  • Fixing any text that is confusing in log output or in the User Interfaces.

  • 1 and 2 way audio. Keen to add this at some point for talking with people at my front door and baby monitor uses. Most likely only a few select brands of camera that have an API for doing this will get the ability.

  • Any of the Onvif methods not implemented.

If you do wish to implement more Onvif features, I have found some example SOAP contents found here to be useful for most requests and responses. Often example SOAP traces are not in the Onvif documentation. https://git.linuxmce.org/garagevibes/linuxmce/tree/08c52739954c0bfce7443eddc1ad4f6936a70fbe/src/Advanced_IP_Camera/onvif

About

A binding for Openhab 2 that allows you to use IP Cameras without the need to disable authentication.

License:Eclipse Public License 2.0


Languages

Language:Java 100.0%