Using a Raspberry Pi as a surveillance camera in Home Assistant

Background

For the last few months I’ve been slowly building out my home automation system, based on Home Assistant. I have a couple of basic requirements for anything I add to it: It shouldn’t break the bank, and I don’t want any cloud features. For one thing, I don’t want my devices to suddenly stop working because of service disruptions, bankruptcy or outright planned obsolescence, but more importantly: I want to control my personal data.

I have a couple of other guiding principles as well: devices and systems based on open source is preferred, and whenever that is impractical, the stuff I buy should at least be based on industry standards. No walled gardens, please!

For instance I ended up with IKEA Trådfri for my lights, partly because of this short review by Matthew Garrett. I’ve successfully mixed and matched light bulbs from IKEA and Philips. I’ve also invested in a USB stick for Z-Wave integration.

So when I started looking for ways to add some cameras to the system, I quickly realized that «reasonably priced» and «no cloud» don’t mix. There are some awesome networked cameras out there, especially the Xiaomi Xiaofang/Wyzecam devices have impressive specs and are surprisingly affordable. Too bad that they also come with those pesky clouds (though there are ways to turn that stuff off). I could have gone with more traditional surveillance cameras from companies like Axis or Planet, but they are much pricier, and would generally require a wired connection. 

So I gave up looking for my dream camera, partly because I finally had an excuse to start messing around with Raspberry Pi and its Camera Module V2!

Setting up the camera

All you need for this little project is the Raspberry Pi 3 Model B+, the Camera Module V2, a micro SD card for storage, a decent power supply, a nice case and some way to mount and articulate the camera, something like this.

After assembling the Pi and installing the latest version of Raspbian, (don’t forget to change the default password!) and connecting it to the network, you need to activate the camera module:

$ sudo raspi-config

Use the cursor keys to navigate to Interfacing Options → Camera, and activate it.

We also need to load the Video4Linux2 kernel module, which will expose the camera at /dev/video0. Add this line to /etc/modules-load.d/modules.conf:

bcm2835-v4l2

Now we should reboot the Pi to make the changes take effect.

Next we need some packages installed:

$ sudo apt-get install gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad

This pulls in a hell of a lot of dependencies, but at the end we will have the necessary GStreamer modules to set up a pretty robust and versatile video stream. Next, we create a Systemd service by creating this file: /etc/systemd/system/raspicam.service:

[Unit]
Description=Raspberry Pi Camera Stream Service
After=network.target
[Service]
Type=simple
User=pi ExecStartPre=/usr/bin/v4l2-ctl -c video_bitrate=4000000 ExecStart=/usr/bin/gst-launch-1.0 v4l2src ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse config-interval=1 ! matroskamux streamable=true ! tcpserversink host=::0 port=9000 sync=false sync-method=2
[Install] WantedBy=multi-user.target

Note the line ExecStartPre, this is where we can change the video bitrate. The default is 10 Mbit/s, which is a bit high. Note also the end of the ExecStart line, where we specify the port for the video stream. After we’re done editing the service file, we can notify Systemd about the change, enable the service and start it:

$ sudo systemctl daemon-reload
$ sudo systemctl enable raspicam.service
$ sudo systemctl start raspicam.service

Now we can test that the stream is up by opening it up in i.e. VLC on our computer: File → Open Network Stream → tcp://<your-raspberry-ip>:9000

You should be seeing a beautiful and crisp video stream in 1280×720 at 30 frames per second. If you want higher resolution, just change the width and height in the service file (though this will give you a more narrow view from the camera lens).

Adding it to Home Assistant

Once we have the stream up and running, we can add it to Home Assistant. For this, we need ffmpeg installed on the machine/device/VM/container running Home Assistant. How you go about doing this will vary, and is outside the scope of this howto, but a good starting point can be found here.

Adding the camera is pretty trivial, all you need are these lines in your configuration:

camera:
  - platform: ffmpeg
    name: Raspicam
    input: tcp://<your-raspberry-ip>:9000

At this point you can easily add more automation, for instance record a minute of video if motion is detected while you’re away:

shell_command:
  - record_raspicam_minute: ffmpeg -i tcp://<your-raspberry-ip>:9000 -an -c:v copy -t 00:01:00 /var/tmp/raspicam-{{ now().strftime("%Y-%m-%d_%H-%M-%S") }}.mkv

automation:
- id: record_camera_on_motion
alias: Record some video if motion is detected while away
trigger:
- platform: template
value_template: "{{ is_state('binary.some_detector', 'on') }}"
condition: - condition: template
value_template: "{{ not is_state('device_tracker.you', 'home') }}"
action:
- service: shell_command.record_raspicam_minute

Locking it down (a bit)

It’s probably a good idea to restrict access to the video stream, so that only the Home Assistant server can access it. I use UFW for this. Don’t forget to allow SSH!

$ sudo apt-get install ufw
$ sudo ufw allow ssh
$ sudo ufw allow from <your-home-assistant-host> to any port 9000 proto tcp
$ sudo ufw enable

4 kommentarer til «Using a Raspberry Pi as a surveillance camera in Home Assistant»

  1. Hi,
    Many thanks for publishing this potentially very useful idea.
    Unfortunately I could not make it work despite my good experience of Raspberries, a fresh OS and nothing else installed…
    It run ok on the raspberry side but on the VLC side, no video is showing although the stream is rightly there and being received…
    I am using a raspberry zero…
    Any idea about what is wrong?
    Marc

    1. I apologize for not seeing this comment earlier. I haven’t tested this approach on a Raspberry Zero, so I don’t know if it would work on that board. I hope you found a solution that works for you.

  2. Hello,
    First of all thank you for this tutorial, it allowed me to recycle an unused Raspberry and make it a surveillance camera.
    I managed to install everything and everything works in Home Assistant. But now I ask myself the following question: how to view the videos recorded by the camera?
    Would you please explain your solution?
    In advance, thank you for your collaboration.

    1. Glad it’s useful!

      I wrote this blog post before the stream: integration came along, so I ended up writing a custom script that I called, which would record and then upload the video to a web server.

      #!/bin/bash
      Now=$(date +%Y-%m-%d_%H-%M-%S)
      Filename=raspicam-${Now}
      ffmpeg -i tcp://your-raspberry-ip:9000 -an -c:v copy -t 00:02:00 -movflags faststart /var/tmp/${Filename}.mp4
      sftp user@remoteserver:/path/to/webdir/ <<< $"put /var/tmp/${Filename}.mp4"

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *

Dette nettstedet bruker Akismet for å redusere spam. Lær om hvordan dine kommentar-data prosesseres.