Use Python to Build a Raspberry Pi-Powered Home Security Camera

Motion detection, video capture, and the power to send an email alert plus video attachment with Gmail included!

Andy Orr
Andy Orr
Jun 7, 2017 · 8 min read

// Update March 23, 2018: This story continues to get a lot of traffic! This is a somewhat dated project and in re-examining the code, I am the first one to admit it needs some clean-up, refactoring, exception handling, etc, and I believe there are a couple of imports that aren’t technically needed to make it work properly. Given everything I’ve learned about Python since writing it a year ago, I now see there are ways to make this project more Pythonic. This was merely a simple mvp, and if I can make the time, I would love to write a version 2. Thanks for reading :)

For those not in the know, a Raspberry Pi is an ultra low-cost, credit card-sized Linux computer. It was originally conceived as an educational tool to teach programming and hardware basics, and has since been enthusiastically adopted by makers the world over.

For me, Raspberry Pi has provided a user-friendly introduction to basic hardware. It also presents a fun way to learn one of the world’s most popular programming languages, Python. Additionally, raspberrypi.org provides a ridiculous amount of free content to help new users of all ages and backgrounds get started.

For around $35, the Raspberry Pi 3 offers built-in Bluetooth and WiFi, 4 USB ports, 40 GPIO pints, full HDMI port and more! Image from raspberrypi.org.

Inspiration for this build

The idea for this particular build started with a spate of package thefts in my neighborhood. I researched various WiFi enabled home security cameras, the average cost of which usually floated in the $100 to $200 range. Since I had a basic knowledge of Python and a Raspberry Pi already on hand, I decided to try building my own.

I learned so much in the process and had so much fun along the way, I decided to write this post for others who might be interested in making their own home security camera. The pride and sense of craftsmanship that goes along with making something, as opposed to buying a ready-made product off the shelf, cannot be underestimated. Save money, too!

Required materials

  • A Raspberry Pi 3 ($35) and power supply
  • A Raspberry Pi 2 works great too, you’ll just need a WiFi dongle
  • 5 megapixel or 8 megapixel Pi-compatible camera board ($15 to $30)
  • PIR motion sensor module ($2)
  • 8 or 16 GB micro SD card ($10)
  • That’s it!

Getting started tutorials

This raspberrypi.org tutorial helped me get the camera board up and running in just a few minutes, and this tutorial explained how to connect a cheap passive infrared (PIR) motion sensor to my Pi. (If your Pi is brand new out of the box, follow this basic tutorial to install Raspbian, the Raspberry Pi Foundation’s official supported operating system.)

Once all of my components were connected and working, I opened IDLE and started writing a Python script to actually perform the magic of detecting motion, recording video, then emailing that video as an attachment with a corresponding alert.

All in all, it took me several weeks to get the Python script to work correctly. I also spent a lot of time consulting sites like Stack Overflow and pouring over the official Python and PiCamera docs. And of course there was a bunch of testing throughout. The heavy-lifting is done; copy and paste at will!

Behold, the Python script

For those who don’t want commentary, here’s the full script, a total of 61 lines. For those interested in walking through the script line by line, keep scrolling.

This didn’t materialize fully-formed, like Athena from the mind of Zeus. For more experienced programmers probably, but not for me. I had to break the complex problem of detecting motion, capturing video, then emailing that video as an attachment into smaller, more bite-sized pieces, then focus on getting those individual pieces to work. Tackling a problem incrementally is definitely the way to go. Don’t let the big picture overwhelm you!

A line-by-line stroll through the script reveals the following:

Lines 1 to 3 include basic comments about the need to allow less secure apps in Gmail, which allows your Pi sufficient access to email an attachment from your Gmail address. These lines also include links to relevant getting-started tutorials on hooking up a camera board and a PIR sensor to your Pi. Using comments to talk about what your script does is good practice!

Lines 5 to 17 cover required imports to make the script work. I think I could eliminate some lines by using a single import and commas between multiple modules, though I’d want to test this first. Perhaps in a future revision. Salute to those who created all of this wonderful pre-defined code!

Lines 19 to 23 establish important variables needed to make the camera and PIR sensor work properly, as well as variables we’ll need later on in the script to convert video files from h264 to mp4. Didn’t know the first thing about h264 and mp4 going into this, by the way. Learning!

Line 25 introduces some basic logic by creating a while loop. This tells our Python script to run so long as a condition is true. Since True is always true, our script will run in a continuous loop until the end of time, or at least until my three year-old unplugs the Pi.

Lines 27 to 35 represent the sensor detecting motion. Once motion is detected, the camera will begin recording video. Once the sensor registers the absence of motion, the camera will stop recording, leaving us with an h264 video file that is conveniently named with a month-day-year-hour-minute-second format. From there, the script invokes some basic Linux commands and uses string concatenation to re-save the h264 as an mp4, then deletes the original h264. It was only after some deep Googling that I serendipitously discovered this tutorial which described an install that makes the h264 to mp4 conversion possible. Thank you Stuart Green, wherever and whoever you are!

Lines 37 to 44 are preparing the email we’re about to send. “Subject” is content for the subject line. I used another timestamp for easy reference. “From” is obviously the Gmail account you are sending from. “To” is the recipient and “text” is body text in the email. The end’s in sight!

Lines 46 to 51 attach the mp4 video. As an mp4, I can view the video on my iPhone. Like the h264 to mp4 conversion, getting this particular segment of the script working required deep Googling and serendipitous discovery of online conversations that pointed me in the right direction.

Lines 53 to 58 describe how to access a Gmail account and email everything. As already mentioned, it is critical that you allow less secure apps in Gmail first. I also created a dedicated Gmail account for this project so that mp4s aren’t being sent and received by my personal Gmail account.

We made it! Line 61 describes a simple Linux commands that deletes the mp4 (we already deleted the original h264 in line 34). This way, your script can run continuously in true while loop fashion without fear of a bunch of mp4s eating up valuable storage space on your Pi. Even if you’ve never written a line of code, you can read this entire script and probably get a sense of what’s going on. I love Python!

Lessons learned

  1. Break a complex problem down into its constituent parts. Focus, in other words, on solving micro challenges, then begin stringing those achievements together to assemble the whole. This project, for example, included a bunch of sub-tasks in service of the larger goal: getting a sensor to work, getting a camera to work, sending an email, sending an attachment, converting video files from one format to another, invoking basic Linux commands, the list goes on. Incremental problem-solving was key.
  2. Along those lines, before writing a line of Python, comment your script out using the # symbol to describe in simple English what it is you want your script to do. Outline first, code second.
  3. Test frequently, as you go.
  4. Don’t just write your Python script. Listen to it, too. This general notion comes from “What Technology Wants” by Kevin Kelly. As an inanimate collection of human inventions, one could say that a given technology wants to go in a certain direction, and in this, it takes on a desire, a spirit even, of its own. In similar fashion, once I started writing my Python script, the script began taking on a life of its own, suggesting turns, next steps, and features unstated in my original outline. Your script is an extension of your being. Don’t be afraid to listen to it.
  5. Python is a great first language to learn. My sense is, you can accomplish a lot of work with just a few lines of code. Efficient and meaningful — Python is the Ernest Hemingway of programming languages.
  6. People in online Python communities are happy to share their knowledge and expertise.
  7. The Raspberry Pi is so flipping cool and is an amazing resource for the masses. Thank you Raspberry Pi Foundation for creating such a marvelous piece of engineering that is affordable and accessible. Keep up the great work!

Extra credit

Here’s a short Python script for using SMS gateways to send a simple text message. How could you graft this functionality into motion_video_alert.py above so that you also receive a text message alert when motion is detected?

I’m not a programmer by trade, but I sure enjoy Python. A few months ago, I set a goal for myself to devote 20 minutes a day to learning Python, and this post is one product of that endeavor. Thanks for reading!

Andy Orr

Written by

Andy Orr

Program Manager | Content Developer | Python Guy | Dev Meetup Co-Founder

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade