How to use your external camera's motion detection with ZM

From ZoneMinder Wiki
Jump to navigationJump to search

<Home

Background

Zone minder has an awesome 'trigger' architecture which allows any external event to trigger a recording on ZoneMinder. This section explains the basic architecture and then goes on to describe how you can use your own camera's HW motion detection to trigger a recording on ZM. You can replace this 'trigger' with any other event - such as, for example, triggering your ZM recording when say your Nest thermostat goes to Away mode. The options are limitless

Core Trigger Architecture

                      +-----------------+                                                                
                      |  zmtrigger.pl   |  record on/off                                                 
                      |listening on port|  directives over TCP (and other IPC mechanisms)                                          
                      |      6802       |<------+                                                        
                      |                 |       |                          polling or notification   x   
                      +-+---------------+       |                          - depends on device      / \  
                        |                       |                          capabilities            /   \ 
                        |                       |                                 +--------------->     |
                        |                       |                                 |                \   / 
                        |                       |                                 |                 \ /  
+----------------+      | record                |       +---------+               |                      
|                |      |                       |       | my own  |               |                device
|  Rest of Zone  |      |                       +-------| script  |<--------------+                      
|     Minder     <------+                               +---------+                                      
|                |                                                                                       
+----------------+                                                                                       

If you enable OPT_TRIGGERS in Options->System, then ZoneMinder starts a process called "zmtrigger.pl" (/usr/bin/zmtrigger.pl). This is a perl script that basically offers an easy to use interface for anyone to send it commands to its default TCP port (6802) to initiate/stop recordings. Note that zmtrigger also offers other means of IPC - I just found the TCP channel easy and reliable.

zmtrigger does not care what caused the event. All it is waiting for is a simple text instruction from anyone capable of sending a command to port 6802. So what that means is I can write any program that monitors anything, and when my program thinks something happened which warrants a recording, all I need to tell zmtrigger is "please record monitor 3" (and optionally specify more parameters)

Requirements for Triggering

  • OPT_TRIGGERS need to be enabled
  • After changing the OPT_TRIGGERS setting you need to either restart zoneminder so that it starts the zmtrigger.pl daemon
  • Prior to ZoneMinder v1.30.2, the monitor mode MUST be set to Nodect (ZM won't initiate recordings if in any other mode).
  • In 1.37 there is no Nodect setting, instead on the Storage tab, set Recording = OnMotion instead of None.

(To combine both ZM normal recording, and say external triggers, with ZoneMinder prior to v1.30.2 you can always add two monitors pointing to the same camera - one in say modect and the other in nodect and use the latter one for external triggers)

Quick test

Lets assume you have a monitor id of 1. As a quick test, just try this telnet zm_ip 6802 And when connected via telnet simply type in

1|on+20|1|External Motion|External Motion

You should see ZM create a new recording for Monitor ID=1 for 20 seconds with a name and cause of "External Motion"

Implementation Strategy

  • Foscam's CGI document shows that if the camera's motion detection is enabled, then when it detects motion, you can use the getDevState command - if the value of XML tag <motionDetectAlarm> is 2 then motion is detected. It resets back to 1 if there is no motion detect
  • Unfortunately, Foscam does not support posting events/callbacks when motion is detected. Note that there are cameras that support web hooks for motion notifications, like Axis cameras.
  • so I need to poll it once every few seconds and check this value
  • If this value == 2, send a record request to zmtrigger (and thanks to ZM's ring buffer, I won't miss the image that caused the alarm)

Source code

Here is the code to do just that (and some other checks for optimization) It loops through all my cameras and sends triggers when motion is detected

https://github.com/pliablepixels/ZoneMinderFoscamHDTrigger/blob/master/arc_zm_foscamHDmotion.pl uh-oh, looks like I deleted that repo by mistake. I don't have a copy. But looks like someone else took that code and improved it - see his repo here https://github.com/jshank/ZoneMinderHikvisionTrigger

Notes

  • Your imagination is the limit here - you can create triggers for any thing you want - ZM doesn't care what the trigger is. As long as your script tells zmtrigger to start/stop recording and for which monitor, that is all ZM needs
  • I initially used my camera's HW motion detection for a few weeks, after getting frustrated trying to configure ZM's own zone system, but when I understood how to use ZM's own zone detection, it was better
  • If you are worried if this constant pinging of the foscam may slow it down, it does not. I used it for weeks without any problem

References I found useful

http://www.sparxeng.com/blog/software/zoneminder-network-triggering