Setting up NVR-based Reolink cameras

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