Can you make a Raspberry Pi Security Camera?

This weekend’s geeky challenge: Making a Raspberry Pi Security Camera.

TL;DR – Here’s a basic, practically-ready-to-deploy, open-source Raspberry Pi security camera.

Brief

Mostly because I’m cheap (but partly to reduce the scope and therefore increase chance of success) I added a few constraints:

  • Periodic still image capture is OK (streaming video will be tackled in a future iteration)
  • Securely store images in the cloud (so I can check them when I’m away from home)
  • Be configurable
  • Support the cheap official Raspberry Pi camera modules, particularly the “NoIR” variants which come without the Infrared filter for night-time captures when complemented with an IR light pack

Let’s get started.

Design

After a quick napkin sketch it becomes clear we need to build 4 key parts:

  • A .NET Core console application.
    • This is our entrypoint, and using .NET Core lets us compile to the “linux-arm” runtime target, i.e. Raspbian.
  • A timer
    • To periodically take the photos. I have some ideas for other conditions or events that could trigger the camera to take a snapshot (such as a PIR sensor detecting heat) so I’ve implemented the timer as a “TimerTrigger“, which implements an ITrigger interface. That way it’s nice and extendable.
  • Some code that speaks to the Raspberry Pi camera module
    • Again I’ve written a “CameraImageSource“, which implements the IImageSource interface.
    • I also wrote a TestImageSource which loads an image from the current working directory for testing.
  • A client for the cloud storage API
    • I’ve chosen Google Drive because it offers 15GB free storage, a decent SDK that supports .NET Standard (1.3) and has good documentation.
    • As with the other components, this is written as an implementation of the “IDataStore” interface, so it’s easy to expand to other cloud storage providers in the future.

And this is how they all communicate:

Implementation

The code is here:

https://github.com/richstokoe/pispy

Once you’ve cloned that repository, there are some things we need to do before we can run the code.

Cloud Storage Credentials

To use the Google Drive API, you need an OAuth2 client ID and client secret. Follow these instructions to get a client ID and client secret, then hit the Download button in the “Credentials” area of the API console and save the file as “client_secrets.json” in the src/PiSpy/ folder of the repository you just cloned.

This file will be copied to the output directory when the project is built, per MSBuild instructions in the PiSpy.csproj project file.

Configure the Raspberry Pi Security Camera

If you want to change the default options, open up the appSettings.json file in the project.

Timer interval

You can change the interval between camera shots by modifying the Triggers:TimerTrigger:Interval setting. This is in milliseconds (seconds / 1000 so 60 seconds = 60000).

The default is 180 seconds (3 minutes).

Camera output directory

You can change the output directory by modifying the CameraModule:OutputPath setting.

The default assumes you will copy the console app to /home/pi/pispy, if you want to copy it somewhere else, change the path accordingly, otherwise you’ll see an error from the “mmal” process.

Raspbian with a Desktop

For now, we need an operating system on the Pi with an interactive desktop to complete the Google OAuth2 authorization flow.

Follow the steps in my last blog to set up a Pi with Raspbian and the .NET core runtime – but with one minor difference: grab Raspbian Stretch, NOT Raspbian Stretch Lite. This gives you a Desktop – that’s important for when the Google authorization flow pops open a browser window to enter your Google account details.

(In a future iteration we’ll add a Kestrel HTTP endpoint to the service to negate the need for the non-Lite version of Raspbian with a desktop).

You can either plug in a HDMI-capable screen and keyboard, or you can enable VNC by running:

sudo raspi-config

at the command line (or via SSH) and enabling ‘VNC’ under the ‘Interfacing options’ menu.

I also found I had to set Chromium as my default browser for the authorization flow to work properly – to do that navigate to chrome://settings, choose “Set Chromium as my default browser” and then restart the pi by running:

sudo reboot

Deploy and run

As in my last blog, build the project targeting the linux-arm runtime:

dotnet publish -r linux-arm

and copy the the bin/Debug/netcoreapp2.0/linux-arm/publish folder via FTP to the pi. I copied it to /home/pi/pispy.

We’re going to need access to Raspbian’s PIXEL desktop in a moment, so connect to the Pi’s VNC server by following the instructions here. Once you’re in, open a Terminal and navigate to the folder you copied the /publish folder to. Create a new folder within it called stills, which is where the CameraImageSource code will write the pictures to before handing us a Stream.

cd /home/pi/pispy
mkdir stills

(I’m cheating a bit by simply running the “raspistill” executable that comes with Raspbian to take the pictures. More info here.)

Next, start the service by running:

dotnet /home/pi/pispy/PiSpy.dll

After the time specified in the Triggers:TimerTrigger:Interval appSetting elapses, a photo will be taken and then the GoogleDriveDataStore will trigger the authorization flow (this only needs to happen once). Once you’ve logged in future photos will stream up to the Google Drive.

Next steps

Pull requests are not only welcome, they are encouraged.

A good place to start: I haven’t had much time this holiday season to debug (same excuse for shoddy blogging 🙂 ), but there appears to be an async bug in the TimerTrigger whereby the subscribed actions are invoked on a separate thread and the Timer is restarted even though the CameraImageSource still hasn’t finished taking its picture.

And don’t forget to turn off your LEDs:

I hope you’ve enjoyed this slightly rushed guide to building a Raspberry Pi security camera!

A Vision of Future Tech

Slough, in 2022. Probably.

Nobody really knows what the world of future technology will bring. 10 years ago the word “Facebook” didn’t mean anything, Nokia was the largest mobile phone maker in the world, Apple’s very first iPod was only 6 months old, Bill Gates was still in charge of Microsoft having just settled the lawsuit filed by the DoJ, and Google hadn’t even gone public yet. In 10 years time we can expect more crazy changes as technology advancement is accelerating at unprecedented pace. Here is a story which encapsulates some of my predictions about Earth, 2022.

 

Commuting

@614, Sometime in August, 2022, New York City, New York

Chen slammed the door shut behind her, leapt down the steps three at-a-time and hit the pavement running. She absolutely could not be late for this interview!

“Time,” she demanded.

“Six fifteen, precisely,” said the tiny earpiece. It was probably right. It was as accurate as any atomic clock on Earth. “You have nine beats to arrive for your interview.” Her music resumed, at the perfect volume for the ambient noise on the streets.

“Thanks.” She accelerated through the New York City pedestrians clogging the streets. To be fair, it wasn’t gridlock. Most business was done from the home these days so there was easily enough room to sprint without slamming into anybody (too hard). Ultra high-speed broadband connections (MassivBand®) meant you could hold MassivDef® video conferences with tens or hundreds or even thousands of people at once (Bono had broadcast to the entire world at Band Aid 2020 in aid of 3rd-world, poverty-stricken Great Britain). Where great corporate skyscrapers once stood, now enormous, futuristic looking glass towers with the sole purpose of housing telecommuters stretched into the clouds.

No time to enjoy the scenery. Chen’s suit was graphene-polycarbonate, its fibres moved and ebbed to force cool air through to her skin, keeping her cool. Even while running. Sweat is not welcome at job interviews… Continue Reading “A Vision of Future Tech”