Architecture of a Raspberry Pi Security System
After our apartment was burgled, I decided to build a kickass security system.
I needed a camera that would be
- cheap,
- remote controlled via internet,
- able to detect movement and inform me immediately, and
- able to stream images to offsite storage in case someone takes the camera.
Eventually, after a few iterations I came up with the following high level design.

This design has three main components:
- Raspberry Pi with camera module ($40 + $35 = $75)
- Remote storage (Dropbox is free)
- A VPS on Digital Ocean ($5/mo.)
What the RasPi does
The limitation of Raspberry Pi in this case is that its ARM processor isn't really up to performing CPU intensive image processing at a decent speed. In order to more accurately detect movement, it needs to capture images at fairly high interval. So, the Pi’s only task in this system is to
- capture an image,
- timestamp it by way of filename,
- upload it to remote storage, and
- queue it in a Redis instance, hosted on my VPS.
And repeat, until I tell it to stop. No image processing is done on site. This process not only allows captures to happen as quickly as possible, but also immediately get the images to a remote location where they're safe.
Image Difference Processing
At this point, the VPS is now able to continuously pop the redis queue, each entry being the next capture to download. Using ImageMagick’s handy compare tool, each image is compared to the one before it, and a normalized measure of the difference is produced.
This part of the system is entirely written in Go, as it’s a language primarily aimed at concurrency. I was able to isolate network I/O and IM operations into their own goroutines. This way, the image processing will not be blocked by the network, nor vice versa.
As an aside, here’s an amazing Go package for Imagemagick bindings.
Analysis & Alert Dispatch
Now the system is at a point where I have access to a constant stream of image deltas. The final module needed is one that can monitor this stream, and send me a notification if appropriate.
Once again, this part is written in Go, and technically part of the previous module. Thanks to Go’s fantastic channels, this part is really as simple as
for diff := range DifferenceChan {
if diff > THRESHOLD {
EmailMe()
}
}
I now have total vision of my front door, regardless of where I am in the world.
Email me when Arsham publishes or recommends stories