Tuesday, August 20, 2013

The Surveillance System

this year I planned to travel with my family to China for a few weeks, so we had to leave alone our house. While being on vacation, I wanted to check sometimes if everything was alright at home. So I decided to install two more cameras and connect them to the webserver of my home automation system. I had one camera attached already before and I wrote about it here. Both cameras I placed inside the house so I did not have to bother about rain. One was directed to our garden through a window, the other was directed to our living room. I could have done more thoughts about the camera placement, but I considered this more as an experiment. Also I was constrained with the cables. I wanted to use the raspberry connected to the cameras without wireless, so there was only one place left to put the cameras without drilling holes: close to my dsl modem.  

The webcams and the hub

I bought two webcam vx-800 mostly because they are cheap, and I had good experience with them with the my first camera. Unfortunately this type of camera has a fixed shutter, so it controls the light passed through with the shutter speed. The problem is that the pictures are very often overexposed. But for this time I did not want to spend more money on the them.
The usb ports of the raspberry pi can only deliver about 100mA, and with two cameras, it will be over the limit. So I also bought a 4 port hub from logilink. A power supply came with it, and it was able to provide more than 1 A. It never came up to my mind before, but when you have a power supply for the hub, you dont need an additional one for the raspberry. It draws its power from the hub via usb.

The motion detection

I think it is quite useless to have a pure webcam, which constantly delivers life pictures. It is better that the cameras detect motions and store the motions on the sd card as a video. For this I installed the application motion. I created a howto guide here, so I will only describe a few settings here.
In the motion config file motion.conf, I had to add (or take out the comments) the following two lines:
thread /etc/motion/thread1.conf
thread /etc/motion/thread2.conf

So since I had two cameras, there were two config files. In the files thread1.conf and thread2.conf I adjusted the parameters target_dir and webcam_port. It worked almost instantly (I had few problems, but honestly I forgot about them).
You can setup motion to generate shockwave files each time the number of pixels exceeds a threshold between two sequential pictures. I assume it is the parameter ffmpeg_video_codec.
And this is exactly what I want. If there is some movement, the raspberry pi is storing this movement as a short video. Now the webserver just needs to pick up the videos and integrates them into the webpage generation process.

The video retrieval

my webserver runs on a different raspiberry pi, than the one which runs the motion detection with the cameras. So I implemented a getter program which downloads the swf files from the camera raspberry. I pasted the code which is doing this below. The first step, it logs into the camera raspberry with ssh and it uses a public key to overcome the need for a password, see the -i option. Then it executes the find command to get all swf files which are not older than 3 hours. In the second step, it searches for all swf files in an directory of the webserver. In the foreach loop, the program checks if the swf files already have been loaded, if not, it loads them with a scp command. Note the -i option, which is needed to omit the password entry.

my @args1 = ("ssh", "-i /home/pi/cam23key", "pi\@ ", "\"find /data/webcam/cam2/ -mmin -180 -type f  | grep swf; \"");
my @args2 = ("find /var/www/cgi-bin/pics/cam3 -type f | grep swf");

my line;
my @lines1;
my @lines2;

open(IN1, "@args1 |") or die "Can't open pipe: !";
while(<IN1>) {
    line = _;
    push(@lines1, line);

open(IN2, "@args2 |") or die "Can't open pipe: !";
while(<IN2>) {
    line = _;
    push(@lines2, basename(line));

foreach(@lines1) {

    line = _;
    if (grep {_ eq basename(line)} @lines2) {
    print "Found line\n";
    } else {
    print "No line, copying ...\n";
    my ret = system("scp -q -i /home/pi/cam23key pi\@ /var/www/cgi-bin/pics/cam3");


I apologize for taking out the perl dollar characters. It seems blogger cannot handle them.

I added this program in the webservers crontab, and it executes it about every hour once.

Integration into the webserver

swf files can be integrated into html with the following html::template code:

<embed width=30% height=30% fullscreen=yes src="<!-- TMPL_VAR NAME=FIRSTPATH -->">  

Key is the embed tag, which makes inclusion of swf files possible. TMPL_VAR NAME is a perl html::template module parameter, which is one of the perl modules I make use of.  FIRSTPATH is a html::template variable which gets assigned in the perl program.  It is the path and file name of the swf file to be displayed. Below you can see an example of the webpage provided by my webserver:

I added in the template code a selection form, where the user can select a swf file from a list. The template code looks like this:

<select name="selected_picture">
   <option value="<!-- TMPL_VAR NAME=FIRSTPATH -->" selected="selected"><!-- TMPL_VAR_NAME=FIRSTPIC -->
   <option value="<!-- TMPL_VAR NAME="PATH" -->"><!-- TMPL_VAR NAME="PIC"--> 


<p><input type="submit" name="Submit" value="Submit" /></p>

FIRSTPATH is a html::template variable containing the selected swf video file, so the selection form is displaying the swf name which is actually running as a video.

 PICTURES is a html::template variable. The perl program assigns a list of swf files into it. The list is gathered from the perl program by reading the directory, where the swf files are located (this is where the getter perl program puts them, see above):

opendir(D, "path") || die "Can't opendir\n";
my @filearr = grep(/\.swf/,readdir(D));

I apologize for taking out the perl dollar characters. It seems blogger cannot handle them.

TMPL_LOOP is a html::template instruction, which is looping through PICTURES and adding its entries into the selection form.
 Below you can see how this all looks like when accessing the website. You can see how a swf video is selected from the list. After this the user needs to press a submit button and the new swf video is loaded.

Final words

I had the camera surveillance system running for more than two weeks while I was in China. It just worked fine. The swf video had been often overexposed, but this was expected due to the low quality of the cameras I use.
I thought that I would have troubles with accessing the webpage because of China's internet restriction policies. But I was completely wrong and I learned my lessons not to be too prejudiced.