Setting up NVR-based Reolink cameras

Hi there, I’m using a Reolink E1 outdoor (no NVR) and I would be happy to provide a debug log. Unfortunaly I’m currently stuck with OH 3.0.2 as I need to fix a backup issue. Let me know if this (OH 3.0.2) isn’t an issue.

I tried the debug log.
I reinitializied the Thing and walked in Front of the cam…

2022-07-08 19:10:42.086 [DEBUG] [amera.internal.onvif.OnvifConnection] - Cameras  UTC dateTime is:2022-7-8T17:10:43
2022-07-08 19:10:42.087 [DEBUG] [amera.internal.onvif.OnvifConnection] - Openhabs UTC dateTime is:2022-07-08T17:10:42.086Z
2022-07-08 19:10:42.185 [DEBUG] [amera.internal.onvif.OnvifConnection] - deviceXAddr:http://192.168.0.178:8000/onvif/device_service
2022-07-08 19:10:42.186 [DEBUG] [amera.internal.onvif.OnvifConnection] - eventsXAddr:http://192.168.0.178:8000/onvif/event_service
2022-07-08 19:10:42.186 [DEBUG] [amera.internal.onvif.OnvifConnection] - mediaXAddr:http://192.168.0.178:8000/onvif/media_service
2022-07-08 19:10:42.186 [DEBUG] [amera.internal.onvif.OnvifConnection] - ptzXAddr:http://192.168.0.178:8000/onvif/ptz_service
2022-07-08 19:10:42.345 [DEBUG] [amera.internal.onvif.OnvifConnection] - GetStreamUri:rtsp://192.168.0.178:554/
2022-07-08 19:10:42.555 [DEBUG] [amera.internal.onvif.OnvifConnection] - GetSnapshotUri:/cgi-bin/api.cgi?cmd=onvifSnapPic&channel=0
2022-07-08 19:10:42.608 [DEBUG] [amera.internal.onvif.OnvifConnection] - ptzNodeToken=000
2022-07-08 19:10:42.678 [DEBUG] [amera.internal.onvif.OnvifConnection] - subscriptionXAddr=http://192.168.0.178:8000/onvif/PullSubManager?Idx=00_1
2022-07-08 19:10:42.700 [DEBUG] [amera.internal.onvif.OnvifConnection] - Processing new PTZ location now
2022-07-08 19:10:42.700 [WARN ] [amera.internal.onvif.OnvifConnection] - Binding could not determin the cameras current PTZ location. Not all cameras respond to GetStatus requests.
2022-07-08 19:10:42.753 [DEBUG] [amera.internal.onvif.OnvifConnection] - ptzConfigToken=000
2022-07-08 19:10:43.985 [DEBUG] [amera.internal.servlet.CameraServlet] - Now there are 0 autofps.mjpeg streams open.
2022-07-08 19:10:43.985 [DEBUG] [amera.internal.servlet.CameraServlet] - All autofps.mjpeg streams have stopped.
2022-07-08 19:10:56.436 [DEBUG] [amera.internal.onvif.OnvifConnection] - Onvif Event Topic:RuleEngine/CellMotionDetector/Motion, Data:IsMotion, Value:true
2022-07-08 19:10:56.512 [DEBUG] [amera.internal.onvif.OnvifConnection] - Onvif Event Topic:RuleEngine/CellMotionDetector/Motion, Data:IsMotion, Value:true
2022-07-08 19:10:56.591 [DEBUG] [amera.internal.onvif.OnvifConnection] - Onvif Event Topic:RuleEngine/CellMotionDetector/Motion, Data:IsMotion, Value:true
2022-07-08 19:10:56.661 [DEBUG] [amera.internal.onvif.OnvifConnection] - Onvif Event Topic:RuleEngine/CellMotionDetector/Motion, Data:IsMotion, Value:true
2022-07-08 19:10:56.741 [DEBUG] [amera.internal.onvif.OnvifConnection] - Onvif Event Topic:RuleEngine/CellMotionDetector/Motion, Data:IsMotion, Value:true
2022-07-08 19:10:56.791 [DEBUG] [amera.internal.onvif.OnvifConnection] - Onvif Event Topic:RuleEngine/CellMotionDetector/Motion, Data:IsMotion, Value:true
2022-07-08 19:10:56.841 [DEBUG] [amera.internal.onvif.OnvifConnection] - Onvif Event Topic:RuleEngine/CellMotionDetector/Motion, Data:IsMotion, Value:true
etc
. 
. 
. 

Just only the CellMotion Event.
In the http binding I saw person alarm…
Do I need to link an item? Or are all onvif Events logged? I have linked only cellmotion alarm to an item.
Maybe trace log?

NO, the logs will show any event that the camera sends exactly as you have shown. This means the camera has to recognize a person to send the event and for it to show up in the logs. Some cameras are slow and not reliable at detecting a person so give it some more time standing in front of the camera without wearing a cap/hat.

Great but that will be using the API method and not using ONVIF method. The ONVIF method is better as it is using the PUSH method, whereas the API is using the POLLING method. If you camera can only send it via the API (perhaps that is the case or you have an older firmware) then that is another reason to implement the API into the IP Camera binding which is very easy to do and sounds like we have a few users that are keen to look at it.

That would be great if you can contribute those soon as I will hold off making any changes until yours are made so that we can prevent any merge conflicts that may happen.

Hi Skinah,

unfortunately i’m struggling getting access to the repo, something seems to be wrong with the token.

To make it short, attached below the changes i made compared to the 3.2 release version.

Sorry for inconvinience!

Best regards,

Dieter

diff --git a/bundles/org.openhab.binding.ipcamera/pom.xml b/bundles/org.openhab.binding.ipcamera/pom.xml
index 432be60edb…606031fa4c 100644
— a/bundles/org.openhab.binding.ipcamera/pom.xml
+++ b/bundles/org.openhab.binding.ipcamera/pom.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>

hi, me again.
I wanted to try the Onvif Events with “Onvif Device Manager”.
I was not able to get a subscription for the Onvif Events , “400 Bad Request”.
After a reboot of the Cam I got a connection with Onvif Device Manger.
But there are also no Person Alarms… Just CellMotionAlarm… damn
I tried Trace Log from the Ipcambinding and found the following:

Sending ONVIF request:Unsubscribe
2022-07-09 19:35:14.156 [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:wsa5="http://www.w3.org/2005/08/addressing" xmlns:xmime="http://tempuri.org/xmime.xsd" xmlns:xmime5="http://www.w3.org/2005/05/xmlmime" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:tt="http://www.onvif.org/ver10/schema" 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/ver10/actionengine/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:ns10="http://www.onvif.org/ver10/events/wsdl/PullPointBinding" xmlns:ns11="http://www.onvif.org/ver10/events/wsdl/CreatePullPointBinding" xmlns:ns12="http://www.onvif.org/ver10/events/wsdl/PausableSubscriptionManagerBinding" xmlns:ns13="http://www.onvif.org/ver10/network/wsdl/RemoteDiscoveryBinding" xmlns:ns14="http://www.onvif.org/ver10/network/wsdl/DiscoveryLookupBinding" xmlns:tdn="http://www.onvif.org/ver10/network/wsdl" xmlns:ns3="http://www.onvif.org/ver20/analytics/wsdl/RuleEngineBinding" xmlns:ns4="http://www.onvif.org/ver20/analytics/wsdl/AnalyticsEngineBinding" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:ns5="http://www.onvif.org/ver10/events/wsdl/PullPointSubscriptionBinding" xmlns:ns6="http://www.onvif.org/ver10/events/wsdl/EventBinding" xmlns:ns7="http://www.onvif.org/ver10/events/wsdl/SubscriptionManagerBinding" xmlns:ns8="http://www.onvif.org/ver10/events/wsdl/NotificationProducerBinding" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:ns9="http://www.onvif.org/ver10/events/wsdl/NotificationConsumerBinding" xmlns:tad="http://www.onvif.org/ver10/analyticsdevice/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tls="http://www.onvif.org/ver10/display/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:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><SOAP-ENV:Body><SOAP-ENV:Fault SOAP-ENV:encodingStyle="http://www.w3.org/2003/05/soap-encoding"><SOAP-ENV:Code>
<SOAP-ENV:Value>SOAP-ENV:Sender</SOAP-ENV:Value></SOAP-ENV:Code>
<SOAP-ENV:Reason><SOAP-ENV:Text xml:lang="en">Method 'Unsubscribe' not implemented: method name or namespace not recognized</SOAP-ENV:Text></SOAP-ENV:Reason></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

2022-07-09 19:35:16.185 [DEBUG] [amera.internal.onvif.OnvifConnection] - Eventloop is shutdown:true

is it possible that the "Method ‘Unsubscribe’ not implemented: " didnt let me subscribe to the Onvif Events with ‘Onvif Device Manager’? Was it locked by the ipcamerabinding?
I hope you know what I’m talking about :blush:

@matt1 I’m out of town right now, but will compile everything and test it out when I get back in a week or so.

@matt1 So, I’ve got the code setup, compiling, and creating the jar file.

1 Like

Hi Skinah,

have you been able to merge my changes into the code?

Sorry again for just sending the diffs, i’ve been traveling till now :frowning:

Kind regards,

Dieter

I tried it again. There are definitely no (onvif) people alarms to be found in the log.
Only the cellmotionalarm is displayed.
So no onvif with my Reolink E1 Outdoor cam.
Maybe with a firmware update in the future.
I stay with my http polling…
Greets.

1 Like

I do not see any detailed diff that contains anything useful, perhaps the forum cut the content short? The preferred way is via github in a PR.

Hi Skinah,

that’s bad news!

Haven’t you received my earlier email (9.7.) at all or was it cut off in the middle?

I’m aware that PR is the preferred option.
Since you mentioned you are in a hurry and i was offline for a week, to shorten it up, i send you the diifs (giving it another try, i.e. diffs attached below).

As mentioned, i’m facing access violation issues with the token.

Please let me know whether the diffs now made it.

In doubt i can give’m another try with the token at the weekend.

What i did: checkout, create branch, changed to the branch, added my changes on the branch, commited them and tried to check the branch in again.

With last step i got rejected, due to insuffiant access rights.

Any obvious mistake i made?

Thanks,

Dieter

diff --git a/bundles/org.openhab.binding.ipcamera/pom.xml b/bundles/org.openhab.binding.ipcamera/pom.xml
index 432be60edb…606031fa4c 100644
— a/bundles/org.openhab.binding.ipcamera/pom.xml
+++ b/bundles/org.openhab.binding.ipcamera/pom.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>

@matt1 I’ve started coding up a ReolinkHandler class, but have a few comments and questions:

  • It doesn’t look like the Reolink NVR allows for ONVIF functionality, only direct connection with a camera on the network (although I haven’t explicitly tried this). So, the NVR systems will have to only use polling. Not quite sure how to handle these two options.
  • I don’t understand how/when the readChannel method is called. Is it called after every HTTP request?
  • In the handleCommand method, what is the “refresh” portion of the code doing?

Thanks.

1 Like

That is pretty simple use cameraConfig.getNvrChannel() and what is setup in the config of the thing is returned. If 0 then it is a stand alone camera and this should be the default, then if it is above 0 it can then use the polling method. People will always have the ability of setting the camera up as a onvif thing instead of your newer reolink thing. Anyone that is currently setup as a onvif thing will not get effected and their will be no breaking change.

Just a heads up that when you change/add/remove channels and thing types to the binding, you will need to clean the cache and temp files before they work correctly.

Go to the IpCameraHandler.java file and look at line 522. Netty (the library that does the http work) has a bootstrap that setups up what it calls the pipeline and this is what happens to any in and out going packets it makes through http. Its not important to learn about Netty or that if you just do the following… You will need to ensure your handler gets used for your reolink thing at this point under line 522. Then when ever you make a public void sendHttpGET(String httpRequestURL) the http reply will go to the public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object msg) throws Exception in the handler you are creating. As suggested, it would make sense to base it on the AmcrestHandler.java file because it polls for the events, or the FoscamHandler.java also polls. This is what’s called Asynchronous http calls where you can make multiple http calls without waiting for the reply back from the camera and your code does not wait for the reply.

In openHAB 2.5 and older, all channels used to get a REFRESH command sent when you first started openHAB and this would make sure that any switches would match the real life position of any switches. In V3.x that command is not sent on startup, but you can choose when to send it. An example is if you have a schedule setup in the camera to turn the IR light on and off at set times, then it is possible that openHAB wont match what the cameras IR control actually is, so the REFRESH command can be sent to tell the binding to ask the camera and set the control to what the camera reports it is actually set to. The binding MUST have it implemented and not all channels in all bindings have any code written to handle that command.

You may be interested in what I found recently when reading up on Reolink. ONVIF is disabled by default on Reolink NVR’s and can only be enabled when you have a screen connected directly to the NVR. It is not possible to enable it via webb or any apps. Firmware upgrades can reset the ONVIF back to disabled requiring you to connect a screen to the NVR again.

Secondly Reolink does appear to be add to be adding support for call back URLS to notify openHAB when motion is detected, so it will be possible to do it without resorting to polling, when the new feature is added to their firmware.

I looks like they finally added in the ability (Firmware v3.3.0.226_23031609) to turn ONVIF on within the Reolink application and web browser interface.

1 Like

@matt1 I has some time to test things out and was able to get ONVIF event handling to work for my NVR; however, the current Onvif event implementation triggers an event for all my cameras even though only one of them was triggered. Below is a portion of the XML return for a motion event. In addition to the Data return, there is also a Source return that contains reference to the zero indexed NVR channel. So, I made the below modification to the OnvifConnection “eventReceived” method to check to see if the event corresponds to the correct source before processing the response and everything works as expected now. I don’t have an easy way to check if all Onvif event returns contain this source information. Can you check if this small modification works for your Onvif cameras?

<SOAP-ENV:Body>
        <tev:PullMessagesResponse>
            <tev:CurrentTime>2023-04-16T02:19:45Z</tev:CurrentTime>
            <tev:TerminationTime>2023-04-16T02:20:38Z</tev:TerminationTime>
            <wsnt:NotificationMessage>
                <wsnt:Topic Dialect="http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet">tns1:RuleEngine/CellMotionDetector/Motion</wsnt:Topic>
                <wsnt:Message>
                    <tt:Message UtcTime="2023-04-16T02:19:48Z" PropertyOperation="Changed">
                        <tt:Source>
                            <tt:SimpleItem Name="VideoSourceConfigurationToken" Value="003" />
                        </tt:Source>
                        <tt:Data>
                            <tt:SimpleItem Name="IsMotion" Value="true" />
                        </tt:Data>
                    </tt:Message>
                </wsnt:Message>
            </wsnt:NotificationMessage>
        </tev:PullMessagesResponse>
    </SOAP-ENV:Body>
public void eventRecieved(String eventMessage) {
        String topic = Helper.fetchXML(eventMessage, "Topic", "tns1:");
        // String sourceName = Helper.fetchXML(eventMessage, "tt:Source", "Name=\"");
        String sourceValue = Helper.fetchXML(eventMessage, "tt:Source", "Value=\"");
        if (!topic.isEmpty() && Integer.parseInt(sourceValue) == this.ipCameraHandler.cameraConfig.getNvrChannel()) {
            String dataName = Helper.fetchXML(eventMessage, "tt:Data", "Name=\"");
            String dataValue = Helper.fetchXML(eventMessage, "tt:Data", "Value=\"");
            logger.debug("Onvif Event Topic:{}, Source:{}, Data:{}, Value:{}", topic, sourceValue, dataName, dataValue);
            switch (topic) {
                case "RuleEngine/CellMotionDetector/Motion":
                    if ("true".equals(dataValue)) {
                        ipCameraHandler.motionDetected(CHANNEL_CELL_MOTION_ALARM);
                    } else if ("false".equals(dataValue)) {
                        ipCameraHandler.noMotionDetected(CHANNEL_CELL_MOTION_ALARM);
                    }
                    break;

Thanks for looking at it, best to do one of these:

  1. Raise a PR with your changes.
  2. Raise an issue detailing it as you have in your post here.

I don’t have the time to deal with it right now and wont for at least a month.

It is helpful to have the changes highlighted as to what is removed/changed/moved to make a quick comment.

I would need to test them on the 3+ different branded cameras that I have laying around, AND also refer to the ONVIF specs to be sure, and that will need some time to do.

I do not have an NVR to test with so its highly likely that you are correct that such a change is needed when talking to NVR units, just a matter of making sure its backwards compatible with cameras connected directly to openHAB so it can handle both use cases.

I know this isn’t your current target and I hope you are able to help evolve the ONVIF towards Reolink NVR support, but in the meantime you could get motion events per camera using the ftpupload binding. I have something similar to the below and get images and triggers from my NVR-attached Reolink cameras as I want.

things/ftpupload.things:

Thing ftpupload:imagereceiver:reolink "Reolink NVR" [ userName="USER", password="PASSWORD" ] {
   Channels:
        Type image-channel : cam1 "Camera1" [ filename="Your NVR_01_[0-9]{14}.jpg" ]
        Type image-channel : cam2 "Camera2" [ filename="Your NVR_02_[0-9]{14}.jpg" ]
        Type image-channel : cam3 "Camera3" [ filename="Your NVR_03_[0-9]{14}.jpg" ]
        Type image-channel : cam4 "Camera4" [ filename="Your NVR_04_[0-9]{14}.jpg" ]
}

Matt, I’m happy to help test if you have the time to look at this.

Mike

This thread is now very old and some reolink support has been added to the binding. Best to create a new thread if you have a problem with the latest milestone build and provide logs and details as to what is happening. I do not own any reolink so it would be best tackled by someone that does.

1 Like