ONVIF Notifications
Having defined a motion detector rule I now want to receive notifications from my ONVIF ip camera.
ONVIF uses the WS-Notification standard for event distribution. This standard defines a publish-subscribe model that uses SOAP web service messages.
Using the same techniques described in earlier posts I created proxy modules from the WS-Notification WSDL files. Eventually I will upload all this code to my ZoneMinder branch on github.
Perl HTTP daemon
Up to now I have only queried my camera and then got a response immediately. For notifications to work we need a more complex setup:
- Set up a local HTTP daemon to receive the notifications.
- Register the daemon with the camera.
- Wait for messages.
Since the ZoneMinder scripts use the Perl programming language I used the SOAP::Transport::HTTP::Daemon module to implement the daemon.
The daemon listens on a local port of my linux box.
Subscription
The camera now needs to know that we are listing. Therefore we send a Subscribe
message specifying our local ip and local port to the camera’s ONVIF Event service. The message also contains the events we are interested in and the validity time of our subscription.
When we subscribe to events from the camera we get a response like this:
<wsnt:SubscribeResponse> <wsnt:SubscriptionReference> <wsa:Address>http://192.168.0.21/onvif/Events/SubManager_2014-09-08T16:19:23Z_0</wsa:Address> </wsnt:SubscriptionReference> <wsnt:CurrentTime>2014-09-08T16:19:23Z</wsnt:CurrentTime> <wsnt:TerminationTime>2014-09-08T16:20:23Z</wsnt:TerminationTime> </wsnt:SubscribeResponse>
Comparing the CurentTime
and TerminationTime
tags we can see that the subscription is valid for only one minute in this example.
Renewal
Now what happens when the TerminationTime
is reached? The camera then simply forgets about us and sends no more events our way.
Using a Renewal
request we can extend the subscription time. Observe that we must send the Renewal
request (and any other requests referring to the subsciption) to the subscription manager’s URL not to the ONVIF Event service. We got the subscription manager’s URL in answer to our Subscribe
request above:
http://192.168.0.21/onvif/Events/SubManager_2014-09-08T16:19:23Z_0
Notifications
Now we are set up. If we wave a hand in front of the camera we should get a Notify
message. Below I pasted an example from my camera:
<env:Body> <wsnt:Notify> <wsnt:NotificationMessage> <wsnt:Topic Dialect="http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet">tns1:RuleEngine/CellMotionDetector/Motion</wsnt:Topic> <wsnt:Message> <tt:Message UtcTime="2014-09-09T12:43:39Z" PropertyOperation="Changed"> <tt:Source> <tt:SimpleItem Name="VideoSourceConfigurationToken" Value="VideoSourceToken"/> <tt:SimpleItem Name="VideoAnalyticsConfigurationToken" Value="VideoAnalyticsToken"/> <tt:SimpleItem Name="Rule" Value="MyMotionDetectorRule"/> </tt:Source> <tt:Data><tt:SimpleItem Name="IsMotion" Value="true"/></tt:Data> </tt:Message> </wsnt:Message> </wsnt:NotificationMessage> </wsnt:Notify> </env:Body>
In the message we also see a reference to the motion detector Rule
I described in another post.
Actually I get more messages. The one I pasted has IsMotion=true
. And when the motion stops I get another with IsMotion=false
. If the time intervals defined in the trigger Rule
are too small I even get several events per second when waving my hand.
In upcoming posts I will concentrate on passing these events to ZoneMinder.
Nice and clear description for Onvif notifications.
By any chance, could you post how the perl deamon was set up to receive the notifications.
That part was really difficult. Mostly trial and error. When I find the time I will blog on it. For now please just have a look at the source code at https://github.com/altaroca/ZoneMinder/blob/onvif/onvif/scripts/zmonvif-trigger.pl , especially methods daemon_main() and start_daemon()
Thank you for posting this! I would LOVE to use your ONVIF motion notifications code for my home system using ZM 1.29 or 1.30. Aside from running your perl script, are code changes and a re-compile of ZM required to make this work? I’m technical, but new to ZM.
It’d be easiest to clone the complete repo from https://github.com/altaroca/ZoneMinder/ and then build from source. You can find build instructions on http://zoneminder.com . Though to tell you the truth it’s been almost two years since I built this myself. So you might run into problems.
Thanks so much for the reply! I see that the latest 1.3 version has ONVIF enabled in the build. Do you think your script might work with a standard build of 1.3, or did you have to add some hooks that are probably not in the public builds?
Thank you again!
The script would not work with a standard zm 1.3 package. You would need to merge the standard package with contents from my repo.
OK, thank you very much!
Could please let me know how to create daemon in Java and post xml file for Subscribe
I have Perl code that does exactly this in my zoneminder clone on github. You can migrate that to Java. I’d like to hear it when you get it to work.
Could you please advise me on how I could trigger my NVR to start recording using ONVIF. On motion the cameras normally triggers the NVR to start recording. There are times when I would like to manually trigger the NVR to start recording for home automation purposes. I am using Home Assistant for my home automation.