Friday, January 11, 2013

The hacky way to motion detecion

Previously in our Project Homebrew Security System , we worked on trying motion detection and capture using a flood light hack after I had tried the Linux "motion" package, and also after I'd also tried "ZoneMinder", and had some ugly results with frame rates being bad.  I abandoned the motion flood light hack (yes, it works) because of two things - I didn't want to buy motion detection lights, and I didn't want to install new power lines to be able to run them.  I wanted them close to the cameras, and I didn't necessarily want the lights to turn on hiding the LED's that accompany a security camera.

Turns out, there are two absolute requirements for the motion implementation :
  1. Motion state changes (e.g. motion has been detected, or is all clear).  This one caused me to abandon the "motion" package, because of the lack of sensitivity and color-based detection algorythms.  The noisier something is without actual motion, the less likely you'll be to respond, so it had to be accurate, and not as noisy.
  2. Motion video capture for review.  Both ZoneMinder  and motion failed here, both coming in at a rate of three frames per second.  I needed a higher quality.

Some nice-to-haves :

  1. Automatic replication of videos to off-site location.
  2. Motion detection should be close by the camera.

State Changes

Luckily, the TrendNet TV-IP322P cameras have a setup section called "Event Server".  For notifications, we need the HTTP section.  It has chunks for notifying based on motion, and two GPIO pins through an HTTP web call.  I threw a quick CGI onto my security server that checks and makes sure the MAC address of the device is authorized to send the status change, and then the CGI can push that state change into Nagios to where I get real-time notifications via SMS, e-mail, etc, when motion is detected.  First requirement, check.

Then I realized that it never cleared.  That means the check went into a critical state, but never went back into an OK state.  Talking to TrendNet, it's not possible, nor are they willing to let me at their firmware to extend it.  Aside from that incapability, I have an idea to get a clearing, but need the next requirement to make it work : video capture to a network server.

Quality Capture

Rather than have the cgi trigger video capture (which I could simply grab via a wget to the URL's), it was easiest to actually configure a CIFS share (Windows world or Samba in Linux - they both work great here). Once the share is set up, in the TrendNet interface, click on "Event Server", then "Network Storage" :


In this interface, configure it to match your CIFS file server settings.

State Change - Getting an "All Clear"

Back to the state changes, now that we have video being copied up to the media server (quite nice, getting videos we can pull up quickly from one source on any device), we can finish the state changes.  There are two ways to do this : (1) Write a cron job that looks for modification times of the resulting uploaded files, and (2) add serious logging to Samba.  The first one is the simplest, but also more noisy when motion is being detected (because of the way Samba creates the files).  The second way will be more accurate, but also is more in-depth in it's configuration.

Watch the uploaded directory :

As I always hate being too complex, I tried the simplest way first.  Remember, I had to try this before I realized it was a little bit noisy.  We create a cron job that scans the video directory for the camera looking for recent videos and if a recent one has no more being written, send the "all clear" for that camera.  Basically, the job has to do the following :

  1. Get the most recent video file written by the camera.  In the TrendNet case, it was the CIFS share, followed by the date, followed by the hour, e.g. :

    /path/to/mount/garagecam/20130109/21/215208.mp4
    Would have been written on January 9th of 2013 at 9:52 P.M., and this is what we look for.
  2. If any of these files were written to within the last two minutes, check that they are still not being written to.  If they are, ignore the file as video is still being captured.
  3. If the files were written to in the last minute, but aren't written, make sure we don't have any new files, and if so, fire off the "all clear".
Suddenly, I have both the motion-is-happening events, and the okay-no-motion-anymore events being triggered.  Plus, I can get the motion-is-happening events to include a link to the currently happening video.  That's a nice feature for those with mobile phones that want to see what triggered the alert from a remote location!

Later, after getting multiple motion-detection events and all-clears for a single event (yes, The TrendNet does this), I decided to try the second option.

Add Serious Samba Logging and Watch the Log :

This was a bit more complex.  I was looking originally for a "hook" that would run after a file has been uploaded, but never did find one.  In the end, I added a few lines to the smb.conf file's "[global]" section that enabled a full audit :
    
    # AUDIT LOGGING
            vfs objects = full_audit
            full_audit:prefix = %u|%I|%m|%S
            full_audit:success = pwrite
            full_audit:failure = none
            full_audit:facility = local6
            full_audit:priority = NOTICE
    
Then, I added the log entry to /etc/rsyslog.conf :
    
    local6.*            /var/log/samba/audit.log
    
Restarting both Samba and rsyslog :
    
    /etc/init.d/smb restart
    /etc/init.d/rsyslog restart
    
And instantly, lots of messages in my /var/log/samba/audit.log file!  One thing to note here, is that the TrendNet IP camera kept firing off pwrite's, you get a continuous stream of messages in the audit file as it's writing to the video file.  I found a slightly better configuration for this same thing (no cron job, but named pipes) and you can do the same.  The link to the post is http://www.silverhawk.net/2013/10/catching-trendnet-end-of-motion-signals.html .

At that point, your cron job simply looks for any files and also checks to see if samba is still writing to the file via /var/log/samba/audit.log .  It's a bit more complex, but it is less noisy.


Offsite Automatic Backups

If you need offsite, automatic backups, I'd suggest using Samba under Linux as your CIFS software, and a while-loop shell script using inotifywait pointing to the directory where things will be dropped.  The inotifywait binary should come in the inotify-tools RPM package, so make sure that's installed.  The script should immediately start to copy the video file to a remote server when it starts to be written.

Next up, we visit setting up a portal .

No comments:

Post a Comment