How to use your external camera's motion detection with ZM
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 | 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
- The monitor mode MUST be set to Nodect (ZM won't initiate recordings if in any other mode).
(To combine both ZM normal recording, and say external triggers, 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
- 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)