This post may contain affiliate links. Please read my disclaimer for more info.

So you’ve got your Home Surveillance system setup, but how do you get notified when activity occurs? A text message or push notification would be great, but then you need to log into your camera system to actually view the camera to see what’s happening. In today’s article, I explain how I used the UniFi Video software, ffmpeg, MQTT and Home Assistant to send a GIF of the motion detected right to my smartphone (or anything else running Telegram).

The last few weeks have been all about stepping up my home video surveillance game. I recently got a UVC-G3-DOME setup at my house along with the UniFi video software for recording (check out that article here). Last week, I turned a Raspberry Pi into an always-on Video Surveillance monitor. Finally, I needed a way to get alerts to my phone when I’m away from the house when my cameras detect motion. With a little bit of Python, I created an application that watched for new motion videos and interfaced with an MQTT broker to notify any clients. Enjoy!

Architecture

Let’s step back for a second and look at how the systems work together.

First, motion happens on one of your cameras. UniFi writes video files to the disk and a JSON file describing the motion event. The unifi-video-gif-mqtt software watches the disk for new JSON files. When it finds one it reads in the metadata. After reading the metadata for the motion event, it uses ffmpeg to convert the video files on the disk to a gif. Next, an MQTT message is sent to a topic for the camera with the name of the gif file that just got created. Home Assistant subscribes to the MQTT topic, and fires an automation to send the gif over a Telegram message when it receives it from the MQTT message. Finally, you get a 15 second GIF video message on your phone or anywhere you have the Telegram app installed to view the footage

In my testing, this whole process takes about 30 seconds after the video is done being recorded. But it may vary on your system and your motion recording settings. The great thing about this setup is it all runs locally and stays on your network.

Setup

UniFi Video

First, you’ll need a UniFi Video instance running with some UniFi cameras. If you are interested in UniFi cameras and want to check out the NVR installation process check out my article on Adding Home Video Surveillance with UniFi Video. That will walk you through getting a camera installed and the UniFi Video software setup.

Once your camera is properly connected to UniFi Video, click the camera’s name on the “Cameras” screen and enable motion recording.

You’ll need to experiment a bit with your motion recording settings to make sure you’re capturing when there is movement you care about, and that you don’t miss any events. Experiment with the “Zones” feature of UniFi Video. This allows you to mark a zone of the room that should only be used for motion detection.

Once you’re happy with how your motion detection settings are working you can move on to the next section.

unifi-video-gif-mqtt

Now you need to install my new software. The full source code is available on GitHub. You can either download and install it from source or use the Docker image I built and published.

Before running the software, you need to create a simple configuration file. A sample can be seen below:

{ "mqtt_server": "192.168.1.2", "mqtt_port": 1883, "mqtt_base_topic": "cameras/gifs", "gif_output_dir": "/gifs", "unifi_video_watch_dir": "/unifi-video" } 1 2 3 4 5 6 7 { "mqtt_server" : "192.168.1.2" , "mqtt_port" : 1883 , "mqtt_base_topic" : "cameras/gifs" , "gif_output_dir" : "/gifs" , "unifi_video_watch_dir" : "/unifi-video" }

mqtt_server / mqtt_port just define where your MQTT broker is running.

/ just define where your MQTT broker is running. mqtt_base_topic is the beginning of an MQTT topic to use for publishing the gifs. The camera name will be appended to the end of the topic so subscribers can choose the camera they are interested in. For example, if you use my above configuration file and have a camera named “Backyard” the full topic will be cameras/gifs/Backyard

is the beginning of an MQTT topic to use for publishing the gifs. The camera name will be appended to the end of the topic so subscribers can choose the camera they are interested in. For example, if you use my above configuration file and have a camera named “Backyard” the full topic will be gif_output_dir is the directory to place the created gifs in

is the directory to place the created gifs in unifi_video_watch_dir is the path where UniFi Video stores new video recordings

The application watches the unifi_video_watch_dir for new recordings and then puts the gifs in gif_output_dir and sends an MQTT message using the mqtt_server , mqtt_port , and mqtt_base_topic .

Installation from Source

If installing from source, you’ll need to install Python 3 and ffmpeg on your operating system. Then you can download the code and install the remaining python dependencies.

wget https://github.com/selfhostedhome/unifi-video-gif-mqtt/archive/master.zip unzip master.zip cd unifi-video-gif-mqtt-master pip3 install -r requirements.txt 1 2 3 4 wget https : // github .com / selfhostedhome / unifi - video - gif - mqtt / archive / master .zip unzip master .zip cd unifi - video - gif - mqtt - master pip3 install - r requirements .txt

To run the software, pass in the configuration file as an arugment (for example: python3 unifi_video_giff_mqtt.py path/to/config.json ).

Installation using Docker

Or, if you’d prefer to just use a prebuilt docker image. It’s sitting on Docker Hub.

If running from the docker image, you need to mount your config file into /config/config.json . You’ll also need to mount the UniFi video directory and wherever you want to store the GIFs. My docker compose file looks like:

services: unifi-video-gif-mqtt: image: zlalanne/unifi-video-gif-mqtt:latest volumes: - ./config/unifi-video-gif-mqtt:/config - /srv/storage/Videos/Surveillance:/unifi-video - /tmp/gifs:/gifs restart: unless-stopped 1 2 3 4 5 6 7 8 services : unifi-video-gif-mqtt : image : zlalanne/unifi-video-gif-mqtt :latest volumes : - . /config/unifi-video-gif-mqtt :/config - /srv/storage/Videos/Surveillance :/unifi-video - /tmp/gifs :/gifs restart : unless-stopped

Similarly, the equivalent docker run command would be:

docker run -v $(pwd)/config:/config \ -v /srv/storage/Videos/Surveillance:/unifi-video \ -v /tmp/gifs:gifs \ zlalanne/unifi-video-gif-mqtt:latest 1 2 3 4 docker run - v $ ( pwd ) / config : / config \ - v / srv / storage / Videos / Surveillance : / unifi - video \ - v / tmp / gifs : gifs \ zlalanne / unifi - video - gif - mqtt : latest

Once you start running the application go and trigger a motion event on the camera. You should see some output from the process invoking ffmpeg and a GIF appearing in the GIF directory. Open the GIF to ensure everything is working for your setup. The next section will detail how to get the gif to your notification platform.

Home Assistant

If you’ve never heard of Home Assistant, it’s a Home Automation platform that puts local control and privacy first. It’s popular among DIY enthusiasts and can be run on your own local server. Check out my articles on Setting up MQTT Broker and Home Assistant Notification Showdown for how to set up an MQTT broker and the different notification systems Home Assistant provides. Today, I’ll be using the Telegram notification component to send the GIFs to my phone. If you don’t use Home Assistant but your Home Automation has support for MQTT you should be able to create something similar.

First off, we need a new MQTT sensor to get the name of the GIF that was created. The unifi-video-gif-mqtt publishes to an MQTT topic when it creates the GIF, so this sensor will subscribe to the topic to receive this GIF name. A small amount of YAML is needed to add another MQTT sensor. Add the following to your sensors configuration.

- platform: mqtt name: "Backyard Camera Gif" state_topic: "cameras/gifs/Backyard" 1 2 3 - platform : mqtt name : "Backyard Camera Gif" state _ topic : "cameras/gifs/Backyard"

Creating the Automation

Now Home Assistant will be notified when the GIF is created. But how can Home Assistant access it? I mounted the GIF directory into my Home Assistant docker container. If you’re running Home Assistant on your bare server (not using Docker) your Home Assistant instance should already be able to see the GIF output directory. You can see the directory is mounted into the container at /camera_gifs .

services: homeassistant: image: homeassistant/home-assistant:0.84.6 volumes: - $PWD/configuration:/config - /etc/localtime:/etc/localtime:ro - /tmp/gifs:/camera_gifs network_mode: "host" 1 2 3 4 5 6 7 8 services : homeassistant : image : homeassistant/home-assistant :0.84.6 volumes : - $ PWD/configuration :/config - /etc/localtime :/etc/localtime :ro - /tmp/gifs :/camera_gifs network _ mode : "host"

Next, we need to “whitelist” this directory in Home Assistant. You can read more about the setting in the Home Assistant docs. Basically, you list the directory where any pictures you’ll be sending will live in your top-level homeassistant configuration. Following my example, I enable the /camera_gifs directory which is mounted in my container:

homeassistant: latitude: 32.87336 longitude: 117.22743 elevation: 430 unit_system: metric time_zone: America/Los_Angeles name: Home whitelist_external_dirs: - /camera_gifs 1 2 3 4 5 6 7 8 9 homeassistant : latitude : 32.87336 longitude : 117.22743 elevation : 430 unit _ system : metric time _ zone : America/Los_Angeles name : Home whitelist _ external _ dirs : - /camera _ gifs

Finally, we can add an automation that triggers whenever we receive a new GIF and sends out the GIF to your notification platform. If you have presence detection working, you can use that as a condition to only send messages when you’re not home.

--- - alias: Notify phone of new movement in backyard trigger: - platform: state entity_id: sensor.backyard_camera_gif condition: - condition: state entity_id: 'device_tracker.zack_phone' state: 'not_home' action: - service: notify.zack_telegram data: title: "Movement detected!" message: "Movement detected in the Backyard!" data: video: - file: /camera_gifs/{{ states.sensor.backyard_camera_gif.state }} caption: "Movement detected in the Backyard!" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 --- - alias : Notify phone of new movement in backyard trigger : - platform : state entity _ id : sensor.backyard_camera_gif condition : - condition : state entity _ id : 'device_tracker.zack_phone' state : 'not_home' action : - service : notify.zack_telegram data : title : "Movement detected!" message : "Movement detected in the Backyard!" data : video : - file : /camera_gifs/ { { states . sensor . backyard _ camera _ gif . state } } caption : "Movement detected in the Backyard!"

This automation works by:

Trigger when a new MQTT message appears which causes the sensor to change state.

Checks that I’m not home, so it only sends a message when I’m away.

Calls the notify service with the location of the video and some text. Notice that a GIF has to be sent using the video support for it to correctly render in the Telegram app, rather than as an image.

Reboot Home Assistant and go trigger some motion on one of your cameras. You should get a message in your Telegram app with a GIF of the movement that triggered the recording.

Next Steps

While this system should be flexible and work with an existing UniFi video system, there are a couple of things to keep in mind. First off, the software currently waits for the recording to be done before converting to a gif and sending it out. This was just done to keep the initial implementation simple though and in the future the GIF could be rendered before the motion capture event is done. Also, the GIF settings are hardcoded into the code, I’d like to make some of that configurable in the configuration file.

Hope you enjoyed the tutorial and consider adding it to your setup. Make sure to sign up for the mailing list and follow the blog on social media for continued updates. If you’ve got another system for receiving notifications from your home video surveillance system let me know in the comments!