<- Jacob Vorreuter

Raspberry Pi Surveillance

I’m always looking for new ways to spy on my dog, Nika. I recently put together a simple Raspberry Pi surveillance system to keep tabs on her while I’m away from home.

My requirements were for a motion-based system that published data somewhere accessible outside of my home network. Here’s the architecture I ended up with:

UPDATE: The image browser web app has been simplified since this post was published. See s3-image-viewer for details

Hardware

Let’s start by discussing the physical components in the system.

It includes the following items:

The motion detector (PIR sensor) connects to the Raspberry Pi through the breadboard, so let’s hook that up first. You can place the PCB anywhere along the breadboard, as long as you place one row of pins on either side of the center divide. Next, wire up the PIR sensor to the breadboard as follows:

1
2
3
4
5
PIR     Breadboard
===     ==========
VCC <-> 5v0
OUT <-> #18
GND <-> GND

Connect the 26 pin ribbon cable from the PCB to your Raspberry Pi and connect the camera board to the Pi as well.

Software

UPDATE: The image browser web app has been simplified since this post was published. See s3-image-viewer for details

There are two software components in this system. The first, pi-surveillance, runs on the Raspberry Pi and is responsible for receiving input from the PIR sensor, capturing images and posting them to S3. Files posted to S3 will persist for 5 days before expiring. The second piece of software is a web application written in node.js, s3-image-viewer, that fetches images from S3 and serves them over a WebSocket connection to a web browser.

You will need an Amazon AWS account before you begin configuring the software components. I decided to generate separate, scoped AWS credentials for the two software applications. This can be done by creating two new users, pi-surveillance-reader and pi-surveillance-writer, under the IAM section of the AWS console. Save the Access Key ID and Secret Access Key for each user somewhere handy. You’ll need those values later.

In the S3 management console, create a new bucket. In the bucket properties, under the Permissions section, select Edit bucket policy and fill in the following policy definition, with YOURBUCKETNAME and AWS account ID (111111111111) replaced:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
{
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::111111111111:user/pi-surveillance-writer",
          "arn:aws:iam::111111111111:user/pi-surveillance-reader"
        ]
      },
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::YOURBUCKETNAME"]
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": ["arn:aws:iam::111111111111:user/pi-surveillance-writer"]
      },
      "Action": ["s3:PutLifecycleConfiguration"],
      "Resource": ["arn:aws:s3:::YOURBUCKETNAME"]
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": ["arn:aws:iam::111111111111:user/pi-surveillance-reader"]
      },
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::YOURBUCKETNAME/*"]
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": ["arn:aws:iam::111111111111:user/pi-surveillance-writer"]
      },
      "Action": ["s3:PutObject"],
      "Resource": ["arn:aws:s3:::YOURBUCKETNAME/*"]
    }
  ]
}

Now you have a bucket setup and scoped credentials for reading and writing. The next step is to configure the Raspberry Pi.

Setting up pi-surveillance on the Raspberry Pi requires first installing the following packages:

1
2
3
$ sudo apt-get install upstart
$ sudo apt-get install python-dev
$ sudo apt-get install python-rpi.gpio

Next, we need to export some config vars in ~/.profile. You’ll need the Access Key ID and Secret Access Key for the pi-surveillance-writer user that you just created and the S3 bucket name. Additionally, we’re setting the PI_SURVEILLANCE_DIR config var, which points to the application directory of the pi-surveillance application. This directory should not yet exist at this point. We’ll be cloning the application from GitHub in the next step.

1
2
3
4
5
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export S3_IMAGE_UPLOADER_BUCKET_NAME=
export S3_IMAGE_WIDTH=800
export PI_SURVEILLANCE_DIR=$HOME/dev/pi-surveillance

Clone the pi-surveillance repository from GitHub and manually start the daemon in foreground to test your configuration:

1
2
3
4
$ source ~/.profile
$ git clone git@github.com:JacobVorreuter/pi-surveillance.git $PI_SURVEILLANCE_DIR
$ cd $PI_SURVEILLANCE_DIR
$ sudo -E ./motion_detector.py

If everything is operational, you should see the motion_detector.py script enter a loop and capture and upload a photo when it detects motion. The script uses backoff logic to prevent it from snapping and uploading photos continuously. The maximum backoff is 5 minutes, so if there’s constant motion, an image will be captured every 5 minutes. After 10 minutes of inactivity the backoff is reset.

Running the script in the foreground isn’t ideal, so let’s configure upstart to manage the script as a daemon:

1
2
3
$ sudo cp motion-detector.conf /etc/init/
$ sudo start motion-detector
$ tail -f /tmp/motion-detector.log

That’s it. You’re up and running, snapping photos everytime your dog wakes up and yawns.

Image Viewer

The final piece of the puzzle is the web application, s3-image-viewer, used to view the images captured by the Raspberry Pi.

The s3-image-viewer app can be deployed to Heroku in a few simple steps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git clone git@github.com:JacobVorreuter/s3-image-viewer.git
$ cd s3-image-viewer
$ heroku create
$ heroku labs:enable websockets
$ heroku config:add \
  AWS_ACCESS_KEY_ID= \
  AWS_SECRET_ACCESS_KEY= \
  S3_BUCKET_NAME= \
  S3_IMAGE_PREFIX= \
  AUTH_USER= \
  AUTH_PASSWORD= \
  MOMENT_TZ="America/Los_Angeles"
$ git push heroku master
$ heroku open

When setting the application config vars, use the AWS credentials for the pi-surveillance-reader user. The web application uses HTTP basic authentication to control access. Choose a username and password and set the AUTH_USER and AUTH_PASSWORD values.

If you access you Heroku app via HTTPS then the WebSocket connection established by the javascript running in the browser will also be secure (WSS).

« Raspberry Pi Bittorrent Server Archiving with AWS Glacier »