Adding Reolink API to the IpCamera Binding, Alpha and Beta testers needed

Hi All,

Today I started adding the Reolink API into the ipcamera binding and wish to find people that are capable/willing to test and provide TRACE level logs to show what is wrong since I do not own a camera of this brand. Feature requests are welcome so long as you look through the API documentation to see if it is possible first, and then if possible post some output from your camera when you use the url with curl, or the Google Advanced REST client. They need to be POST and have the http headers that the API outlines for it to work.

Reolink API V7 is found here:
Camera HTTP API User Guide_v7.pdf - Google Drive

To test you can use curl commands in your linux terminal like this:

curl -k -H 'Content-Type:application/json' -X POST -d '[{"cmd":"Login", "param":{ "User":{ "Version": "0", "userName":"youUserNameHere", "password":"yourPasswordHere"}}}]' http://CameraIPhere/api.cgi?cmd=Login&token=null

To use the alpha/beta version of the binding you need to do the following:

  • Uninstall the merged binding
  • drop the unzipped jar file into the addons folder
  • install the tellstick binding to provide the dependency libraries that this binding needs.
  • Pause or Delete your existing camera thing if it is already setup and try using the auto discovery to find the camera.
  • Add the camera as a “reolink” thing type if not auto found, and set the nvr channel config correctly.

If you opt to just pause your working camera, you may find it does not get auto found and you will be able to setup manually a new reolink thing. This way you can switch between the working ONVIF thing and the newer REOLINK thing just by pausing and unpausing the one you wish to use. If it works then there is little reason to go back to ONVIF.

Because it is alpha/beta, as new channels get added, you will need to delete and re-add the thing to be able to see and use the new channels, but this will only apply to reolink thing types, you can leave any other types alone.

Main source code file is found here:
openhab-addons/ReolinkHandler.java at camera · Skinah/openhab-addons (github.com)

Whats new and needs testing?

Please report back if you try a feature and it works so I can tick them off and get this ready to be merged with a PR.

  • Auto Discovery and gets found as a Reolink thing type. Needs testing.
  • No need to provide URLS and the NVR channel config allows it to work behind a NVR. Needs testing.
  • humanAlarm Human AI detection. Tested to work.
  • carAlarm Vehicle AI detection. Needs testing.
  • animalAlarm Dog and Cat AI detection. Needs testing.
  • faceDetected Face AI detection. Needs testing.
  • activateAlarmOutput triggers the Siren in the camera. Needs testing.
  • enableLED Controls the white LED of the camera. Needs testing.
  • autoLED Controls the IR LED to OFF or AUTO. Needs testing.
  • enableAudioAlarm controls the audio alarm ON/OFF/Threshold. Needs testing.
  • enableMotionAlarm should turn motion on and off but I need the json packet tested with curl first.
  • enableFTP controls the ftp uploading. Needs testing.
  • enableRecordings controls the cameras internal recordings. Needs testing.
3 Likes

First Alpha build can be found here:
Index of /openhab/IpCameraBinding/ (pcmus.com)

Some notes are:

If the NVR channel is 0 then it will use ONVIF for the motion events which is event based.
If the NVR channel is 1 and up it will use the polling API methods which is meant to work behind a NVR, where the onvif will/may not as the nvr blocks the traffic. Seems that ONVIF may be disabled by default on NVR units.

The snapshot and rtsp urls should be hard coded in and do not need to be supplied, if people can confirm they work as they are auto generated from the NVR channel config.

Shouting out to some users that have posted they have Reolink cameras in the past in case they are interested in getting involved.

@gerrit @DieterK @azureshammer @Baschtlwaschtl @Moxified @Mario1982

1 Like

I will for sure test and help.
First thing I see that could have an improvement, the auto discover only discovers I. The same network as OH is placed in.
I have, as a best practice, all my camera’s and BlueIris in a seperate network.
Could you add an option to auto discover in an other network? (eg have a field where I could enter 192.168.5.0/24 or 10.10.0.0/20)

So, I’ve installed the ipcamera-Reolink-20221218PM binding.
I see a lot of new options :slight_smile:
However, I can’t find a “Doorbell Presses” channel jet.
The OpenHab Events log doesn’t show any changes once I press the doorbell.
But, the “Last Event data” shows:

[ { "cmd" : "GetAiState", "code" : 0, "value" : { "channel" : 0, "dog_cat" : { "alarm_state" : 0, "support" : 0 }, "face" : { "alarm_state" : 0, "support" : 0 }, "people" : { "alarm_state" : 0, "support" : 1 }, "vehicle" : { "alarm_state" : 0, "support" : 0 } } } ] 

There is an Alarm state support = 1.
Could this be the doorbell button?

Also, Why doesn’t the /var/log/openhab/events.log update with events for the linked channels?

EDIT:
Small update, the LED control doesn’t work.
And the Alarm state support stays at 1

EDIT2:
Once I enabled the smart detection on the Reolink, The "people" : { "alarm_state" : 0, "support" : 1 } changed to "people" : { "alarm_state" : 1, "support" : 1 } once I put my face in front of the camera.

The data shows that you should link up the humanAlarm which reolink calls it the people alarm. This channel will then turn ON when you stand in front of the camera.

If it does not change states then you will need to give TRACE log output. Careful to remove any passwords if posting it in the forum. A PM is fine to give log output if your not sure.

I have not seen any indication that it is possible with the API to do that. Ask Reolink if they can add the ability. You can use the FTP Upload binding to achieve this most likely, but since I dont have a camera I do not know the exact details of what is possible.

The toggle didn’t change, but the last event data did.
This is what the log said.

2022-12-18 13:10:17.207 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ReolinkCamerawithAPI_LastEventData' changed from [
   {
      "cmd" : "GetAiState",
      "code" : 0,
      "value" : {
         "channel" : 0,
         "dog_cat" : {
            "alarm_state" : 0,
            "support" : 0
         },
         "face" : {
            "alarm_state" : 0,
            "support" : 0
         },
         "people" : {
            "alarm_state" : 0,
            "support" : 1
         },
         "vehicle" : {
            "alarm_state" : 0,
            "support" : 0
         }
      }
   }
]
 to [
   {
      "cmd" : "GetAiState",
      "code" : 0,
      "value" : {
         "channel" : 0,
         "dog_cat" : {
            "alarm_state" : 0,
            "support" : 0
         },
         "face" : {
            "alarm_state" : 0,
            "support" : 0
         },
         "people" : {
            "alarm_state" : 1,
            "support" : 1
         },
         "vehicle" : {
            "alarm_state" : 0,
            "support" : 0
         }
      }
   }
]

New build made to try to see if the AI alarms now toggle. Now using GSON library to parse the json which should fix it and it works with some emulated tests here.

EDIT: I should have mentioned that the token (only used for moving the controls not for the polling of alarms) will expire one hour after the binding connects, and I will need some log output that shows a response from the camera when the token has expired. I can then add the code to renew the token. To reset and get a new working token, just pause and un-paused the camera and it will then work for another hour to do some testing with these Alpha builds. Hopefully someone who has a camera and can read the source code can help speed it up by doing some tests with curl to confirm what Post contents will work.

Probably a good one to try is the activateAlarmOutput channel as this one should make your cameras built in siren go off. Useful if you want to scare intruders away by making all your cameras make noise.

This new binding is only for people with a Reolink NVR, correct? I have a Reolink E1 Pro camera which I have working (although a bit flaky) via onvif, but it doesn’t seem to have the cgi-endpoints, instead it has a proprietary protocol running on port 9000. I guess this is not what’s supported in the updated binding?

No you do not need a nvr, you just need a camera that has the api implemented in it which the first post has a link to the documentation for the api. The battery powered cameras do not have the api and a few other models do not either. The cameras that have no webui builtin proba ly do not work. I do not know which ones will work, it is worth trying and seeing what the trace logs show are coming back from the camera.

Also update the firmware as some only have it after an update.

1 Like

Installed the latest version.
The toggle ‘Human Alarm’ now turns on once it detects a human and turns off a few seconds later.

Now we still need a same kind of toggle/alarm for the button press (most important part of a doorbell :wink: )

About the token, what/how can I monitor that for you?
OpenHab is running on Debian 11.
Notebook is runnin on Windows 11 Enterprise and I have Advanced REST Client installed.

EDIT:
There is a new error in the openhab log:

==> /var/log/openhab/openhab.log <==
2022-12-19 09:00:47.605 [INFO ] [era.internal.handler.IpCameraHandler] - Please report this URL:/cgi-bin/api.cgi?cmd=Snap&channel=0&rs=openHAB is not handled correctly

And also:

2022-12-19 09:04:57.506 [INFO ] [era.internal.handler.IpCameraHandler] - Please report that your Reolink camera gave a login token:, in response:[
   {
      "cmd" : "Login",
      "code" : 1,
      "error" : {
         "detail" : "login failed",
         "rspCode" : -7
      }
   }
]

I am a 100% certain that the login is correct. (And I only used lowercase and numbers, because with special characters it goes wrong (also before this error))

and also:

2022-12-19 09:23:54.289 [INFO ] [era.internal.handler.IpCameraHandler] - Please report this URL:/api.cgi?cmd=SetIrLights&token= is not handled correctly

I uploaded a newer version with some changes in it after your feedback, thank you for the help.

I think the best way is to use CURL in a linux terminal with the following to see what happens. If this works then you can test any of the API commands to see what json packet works.

curl -k -H 'Content-Type:application/json' -X POST -d '[{"cmd":"Login", "param":{ "User":{ "Version": "0", "userName":"youUserNameHere", "password":"yourPasswordHere"}}}]' http://CameraIPhere/api.cgi?cmd=Login&token=null

A user posted here on the forum and they were using a different URL (&token=null) and also their packet has action instead of version in it. Would be worth playing with what they had in case the API has a typo or omissions in it.

POST to external API from a rule - Setup, Configuration and Use / Beginners - openHAB Community

Also you will be able to provide a lot more helpful information if you turn on TRACE logging by entering this into the openHAB console.

log:set TRACE org.openhab.binding.ipcamera

Great thanks for confirming and helping with this, I have edited the first post of this thread to keep track of what is tested and what is not yet tested but is worth trying out.

Does not make a difference how many times you ask, the answer is still the same.
I have not seen it in the API and I would be surprised if it is possible, most brands do not publish this as an event/alarm so you have to use their app. My doorbell probably has only 30% of the visitors actually push the button, so I find that using a human alarm, PIR sensor of something else is actually far more reliable at picking up visitors. People seem to prefer to knock and not press a button maybe covid is a factor. There are ways around this if you search the forum, as I have posted solutions that get you a button push in the forum before by using a door contact sensor to send the alert.

It may be possible to support special characters as I have done it for FOSCAM already, but first I want to see if the token method can be used as it will be better in case people post logs into a forum as the token is useless after an hour goes by. If the token does not prove to be useful, then I can fall back to using the short term user/pass in every URL.

I’ve installed the newer version.
However, still the same login failed error.

The CURL command responds with this:

[1] 738963
root@openHAB:/usr/share/openhab/addons# [
   {
      "cmd" : "Login",
      "code" : 0,
      "value" : {
         "Token" : {
            "leaseTime" : 3600,
            "name" : "20978b87260e019"
         }
      }
   }
]

About the button press, Reolink calls it ‘Visitor’.
HACS has it working (GitHub - JimStar/reolink_cctv: Home Assistant Reolink NVR/cameras addon) So it should be doable.

FYI, I’ve read that Reolink uses the ONVIF Profile T

I enabled the trace logging.
Here is a part of it.

2022-12-20 08:44:48.833 [TRACE] [amera.internal.onvif.OnvifConnection] - Sending ONVIF request:Renew
2022-12-20 08:44:48.908 [TRACE] [amera.internal.onvif.OnvifConnection] - Onvif reply is:<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsdd="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:chan="http://schemas.microsoft.com/ws/2005/02/duplex" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml1="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:wsc="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:wsrfr="http://docs.oasis-open.org/wsrf/r-2" xmlns:ns1="http://www.onvif.org/ver20/media/wsdl" xmlns:tdn="http://www.onvif.org/ver10/network/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:trc="http://www.onvif.org/ver10/recording/wsdl" xmlns:trp="http://www.onvif.org/ver10/replay/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:trv="http://www.onvif.org/ver10/receiver/wsdl" xmlns:tse="http://www.onvif.org/ver10/search/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:tad="http://www.onvif.org/ver20/analytics/wsdl"><SOAP-ENV:Header><wsa5:To SOAP-ENV:mustUnderstand="1">http://192.168.2.9:8000/onvif/PullSubManager?Idx=46209591</wsa5:To><wsse:Security><wsse:UsernameToken><wsse:Username>****</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">****</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">****</wsse:Nonce><wsu:Created>2022-12-20T07:44:48.833Z</wsu:Created></wsse:UsernameToken></wsse:Security></SOAP-ENV:Header><SOAP-ENV:Body><wsnt:RenewResponse><wsnt:TerminationTime>2022-12-20T07:45:54Z</wsnt:TerminationTime><wsnt:CurrentTime>2022-12-20T07:44:54Z</wsnt:CurrentTime></wsnt:RenewResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

and

2022-12-20 08:44:48.908 [TRACE] [amera.internal.onvif.OnvifConnection] - Sending ONVIF request:PullMessages
2022-12-20 08:44:52.425 [TRACE] [era.internal.handler.IpCameraHandler] - Sending camera: GET: http://192.168.2.9:80/api.cgi?cmd=GetAiState&channel=0&user=*****&password=*****
2022-12-20 08:44:52.513 [DEBUG] [era.internal.handler.IpCameraHandler] - Reply is chunked.
2022-12-20 08:44:52.513 [TRACE] [era.internal.handler.IpCameraHandler] - HTTP Result from /api.cgi?cmd=GetAiState&channel=0&user=****&password=**** contains     :[
   {
      "cmd" : "GetAiState",
      "code" : 0,
      "value" : {
         "channel" : 0,
         "dog_cat" : {
            "alarm_state" : 0,
            "support" : 0
         },
         "face" : {
            "alarm_state" : 0,
            "support" : 0
         },
         "people" : {
            "alarm_state" : 0,
            "support" : 1
         },
         "vehicle" : {
            "alarm_state" : 0,
            "support" : 0
         }
      }
   }
]
:
2022-12-20 08:44:52.514 [TRACE] [era.internal.handler.IpCameraHandler] - HTTP Result from /api.cgi?cmd=GetAiState&channel=0&user=****&password=**** contains     :[
   {
      "cmd" : "GetAiState",
      "code" : 0,
      "value" : {
         "channel" : 0,
         "dog_cat" : {
            "alarm_state" : 0,
            "support" : 0
         },
         "face" : {
            "alarm_state" : 0,
            "support" : 0
         },
         "people" : {
            "alarm_state" : 0,
            "support" : 1
         },
         "vehicle" : {
            "alarm_state" : 0,
            "support" : 0
         }
      }
   }
]
:
2022-12-20 08:44:52.514 [DEBUG] [era.internal.handler.IpCameraHandler] - Reply is chunked.
2022-12-20 08:44:52.514 [TRACE] [era.internal.handler.IpCameraHandler] - HTTP Result from /api.cgi?cmd=GetAiState&channel=0&user=****&password=**** contains     :[
   {
      "cmd" : "GetAiState",
      "code" : 0,
      "value" : {
         "channel" : 0,
         "dog_cat" : {
            "alarm_state" : 0,
            "support" : 0
         },
         "face" : {
            "alarm_state" : 0,
            "support" : 0
         },
         "people" : {
            "alarm_state" : 0,
            "support" : 1
         },
         "vehicle" : {
            "alarm_state" : 0,
            "support" : 0
         }
      }
   }
]
:

Please try the newer build just uploaded, it has two changes.
1.Login for the token has changed to use Capitals On The Start of words in the http headers. Despite the http spec saying it does not matter, some cameras seem to have issues if the headers are in all lowercase. Seen it before so this may fix it.
2. The onvif events will log if there is an unknown event topic the binding does not know about. DEBUG or TRACE level is needed to see it, but debug would be best to reduce the traffic in the logs down whilst you go and press the doorbell button.

Great thanks for the info, I’ll see if we can add this as its just an ONVIF event. So the logs should pick it up.

The binding does not do profile T, only profile S. The main difference is that a camera MUST protect the traffic with http digest authentication on top of the onvif auth. I have been looking into doing this recently as I have a camera which is Profile T only. Cameras can support both profiles.
Your camera is talking just fine from the short part of log you gave.

Added the latest version.
Pasted the TRACE LOG at pastebin due to the size.
https://pastebin.com/rVCnewQU

FYI, changed the login and password of the camera to **** in the logs :wink:

I Guess the log did pick it up :slight_smile:

Please report this camera has an un-implemented Onvif Event Topic:RuleEngine/MyRuleDetector/Visitor

Done, new build uploaded that now should have Visitor and all the AI alarms implemented via ONVIF event based methods. Since a new channel was added called doorBell you should delete and readd the thing, taking care to use the same UID so the items all link back up when the new thing is created.

I also added the token=null but I doubt that will be it.

Thank you, I’ve updated to PM2.
Here is the log: https://pastebin.com/9jsay0bY

The log is not working it says its private or waiting for moderation… I found and fixed a bug that would have stopped the token url from working, uploaded to try.

I see it is still pending moderation indeed.
I’ve updated to the newest version.

Small update,
I can confirm that the doorbell button is pressed trigger works.
It stays on quite a while, but that is easy fixable to set it to off at the end of a script/rule.
So, many thanks for including this.
Now it already does what the Google nest doorbell did, and gives me a lot of extra options.

Don’t worry, of course I will stil test new updates for you.
Hope to see this binding go live with full reolink support so that others can enjoy this.

I will try and do this tomorrow! Cannot wait… been trying to get my Reolinks to work