Ever since our garage doors got broken by burglars (they also broken others, stolen things, etc.), I wanted to get a security camera. However, it looks like there’s only two choices: a full sized CCTV system, costing many hundreds of pounds, with a lot of equipment and complicated setup, or cheap stupid WiFi cameras that not only require cloud access (to a cloud I don’t trust), but also opens up access to Mirai.
In 2016, the malware was already wide spread across the Internet and caused a huge Internet blackout, delivering hundreds of GB/s bandwidth in multiple DDoS attacks, also crippling many first grade websites like PayPal, Twitter and Spotify. Here’s some good coverage (as usual) by Ars and Engadget.
After the storm, I really though the IoT industry would shake up, grow up and a year or so later, we’d have better devices. Alas, mid-2017 still had vulnerable cameras in massive botnets. None of the big manufacturers issues recalls (only one small company did, AFAIK), and the cameras you find on Amazon today are the same you would find at the time of Mirai.
So, I had two choices: either pay premium for a full CCTV kit and spend weeks installing it all around my house (and getting the ire of the local community for a massive spy-shop), or build my own camera. Of course, I opted for the latter…
I’m not a very creative person when it comes to names (our kids have all standard names, as we do), so “CameraApp“ sounds like a name as good as any. What it is, basically, is a Python script that pools a PIR sensor for movement, and when it sees it, the camera takes a snapshot (optionally flashing an LED). That simple. The main loop is about 10 lines of Python on a RaspberryPi. The snapshots go into a directory that has a simple PHP script, which generates thumbnails of new pictures and print a simple gallery of the images in a very crude HTML.
If you setup a web server on the board, you have yourself a gallery. If you mount that directory into a NAS, and have a web server on another machine, you have a remote server and backup. All of the security is managed by two simple concepts:
- System security: No root passwords, clamped down Linux, only access via SSH keys, only open necessary ports, etc. Left as an exercise to the sysadmin.
- Isolation: No access to the Internet needed, in or out, so if you want to get to the images from outside you’ll need to either VPN in or DMZ an external server out. If you DMZ your camera, you get what you deserve.
While I could have used any small gadget board, I decided to go with the RaspberryPi. Not only I had 4 of them lying around the house, but it’s the easiest one to find proper Linux distributions, compatible hardware on Amazon and instructions on the Internet.
We also happen to have a 3D printer, and while it’s fun, it’s not easy to find uses for it to pay its own cost. Honestly, anything useful I can print on it, is cheaper on Amazon. So, if I get the chance to design something out of nothing, that’s a good use case for the printer.
On Thingverse, I looked for RaspberryPi cases, and you can find a huge list, so I just picked the simplest looking one (so I could mod). Then, using TinkerCAD, I designed from scratch a case for every component (PIR, LED, Camera) and joined them together into a face that would snap into the base. The project is here. That part took a lot of iterative print-try-mod cycles and the final design went back to Thingverse here.
Putting it all together
The software was developed in the Pi itself, by connecting it to the TV (via HDMI) and using wireless keyboard/mouse and the Python IDE that comes with Raspbian. This setup makes it a lot easier to develop than Arduino or mbed, as everything I do can be live tested directly on the board, instead of having compiler-flash-no-output problems all the time.
After the development period was over, I could remove everything from the Pi but the power cable (remember, 2A at least), and use the on-board WiFi module for connectivity. This makes it extremely simple to put the camera in random hard-to-reach places. You could, in theory, use a battery (if it is able to provide 2A), but that means a big 20Ah would only provide a day or two and it would crash when the juice runs out (damaging the filesystem).
While this is great for indoor snooping and holiday reassurance, it needs more than what’s in the package to be actually useful (like most other cameras). The only use that actually comes for free as is, is the cookie jar example, but you don’t want to teach your kids to only do the right thing because someone is watching, so scratch that.
For this use case, you’d just connect the camera and place it facing a door or the whole room. But if you keep the pictures in the camera’s filesystem, well, the burglar will take it too, and you’re back to square one. If you keep the pictures in a server, the burglar can also take the server, and your backups, so you need external backup. Luckily, Linux has good support for cloud storage, including safe (and encrypted) options, so you don’t need to trust the manufacturer.
You can either mount the Images directory directly on the cloud disk, or setup an rsync to push it once in a while in a cron job. In that case, you can easily look at the pictures while still on holidays, contact the police, send them the pictures and get it started even before you come back home.
Another problem that this could solve is package monitoring (ex. taking pictures of a door to see if a package has arrived), but this Python script won’t work because PIR sensors only detect movement of things that emit IR and boxes usually don’t. Extending to this usage would probably mean writing a slightly different script to take pictures every minute and compare with the previous. If similar enough, replace, try again.
You should replace the picture to make sure light and shadows only play a small enough role between two pictures, not the entire day. Also, comparing images will need additional software (like imagemagick), unless that’s your cup of tea and you want to do it all from scratch.
If the package you want to monitor is actually your pet, then the camera will work out of the box, providing you put the sensor on maximum, to capture the low heat that pets emit, compared to humans.
This is the use case I had in mind, but unfortunately, PIR sensors don’t work well through windows. That’s because glass is a good IR insulator, so this camera would pick up a mob with pitchforks and torches, but not much else. Unless you’re an orc afraid of your life, you’ll need to place the camera outside, and well, that comes with a lot of problems on its own.
First, the case will need to be waterproof (or at least resistant), and that’s a challenge on its own. The Pi is a computer, and as such, needs cooling, which is usually done by air passing on top of the CPU (or its heat sink). Heat it too much and the Pi dies, bricking the camera. Moreover, you will need to give some maintenance on the board some time later, so packing it as a one-off won’t do any good.
Second, taking power outside is usually done with proper extensions, not many of them with USB options, and not many USB adaptors are waterproof. So, the best option is to put the device inside a shed, providing the shed has power, of course. At least, taking power to a shed is a lot simpler (the endpoints are inside the house/shed) and then regular adaptors and bluetac would work for fixing the camera somewhere.
If your shed has solar power and a battery, giving the low consumption of the camera, it could last the whole summer at the very least.
The one thing I’ll have to add later is a way to configure the camera via a text file. As is, it doesn’t support night vision (even if your camera does), as this is a PiCamera option, along many others that one could easily add to the camera setup phase in the script. That’s my next step, which will go into GitHub as soon as I’m done.
A bit of bluetac would work to put that case as is on your dashboard and the car’s power socket usually has more than enough power to support a 5V 2A adaptor. But again, you would have to write a new Python script to take videos instead of snapshots. I’d also add a big button to start/stop recording and a large USB dongle to store the videos (they’ll get big).
Getting a camera was the idea, but the most important take out was to show the kids how easy it is to do something functional. By using the right tools, things essentially build themselves.
A few of the takeaways:
- By using the RaspberryPi instead of an Arduino, I could develop the app on the board itself and test it as I went, which really have shorten the development cycle.
- It also allowed me to download Raspbian, which comes with absolutely everything I needed (OS, GUI, IDE, Python, PiCamera, GPIO, browser for searching).
- It also allowed me to purchase the right devices on Amazon (especially the camera!) and everything worked out of the box.
- By doing it in the living room (on the only TV), I forced my kids to watch and sometimes help. Seeing only the final product makes it look like magic.
- The 3D printer was really helpful, as initially I have lost a lot of time looking for software bugs when actually the pins got disconnected by touching it.
- And it turned out to be half of the fun, printing, fitting, trying again.
- I hate to say this, but, by doing it in Python and PHP, I could really leverage the APIs and modules. Writing it in C++ would have been a nightmare and totally pointless.
- And I could also find a dozen other projects that did similar things, and even steal a bit of code from them, refactor, change completely.
In the end, building stuff is always half the fun, so you have to plan accordingly. If you need a camera today, go buy on Amazon, but if you have some time to spare on your holidays and are bored of looking at the cold rain outside, a project like this really shines.
If this project interests you in anyway, feel free to collaborate (on GitHub, TinkerCAD, Thingverse), and let me know (in the comments or as GitHub issues) of ideas you have and problems you find. Happy hacking!