Beta not Best
  • Home
  • Categories
  • Tags
  • Archives

MQTT Camera Based Motion Tracking for Home Assistant

Contents

  • Update
  • Background
  • Camera Configuration
  • Motion Configuration
    • Camera Setup
    • Disable Picture and Video Capture
    • Event Length
  • MQTT Configuration
  • Run the Service
  • Home Assistant Configuration

This blog post will demonstrate the process I use to add motion tracking to any IP camera (and also perhaps directly connected ones) using the free and open source software Motion, and publish the motion detection over the MQTT message bus for use by Home Assistant, or indeed anything else that may want to use it.

Since I run my services with Docker, it utilises a Docker Image of my creation, but the configuration details still apply, regardless of how you run Motion.

Update

Since posting this blog entry, I've been made aware of the ffmpeg_motion component built in to Home Assistant. This pretty much handles everything you can do with Motion, except for perhaps some edge cases. It's worth checking that out first as it's simpler to set up. Read on if you'd like to see an alternative method!

Background

I have a handful of IP cameras connected to the network in my home. They are relatively cheap, low powered, sparsely featured devices which just about handle the capture and streaming of video using Motion JPEG.

Home Assistant has no problem viewing the video feed from the devices, but in order to use the video in my automations, I needed a way of detecting motion. Thankfully, there's a great, lightweight, free and open source project called Motion which handles the detection of motion in video streams.

The majority of the 'smart' devices in my home communicate over the MQTT message bus. This is very convenient and integrates very well with Home Assistant. I wanted to find a way to use Motion to detect motion on my IP cameras and publish the events on an MQTT topic.

Most of the services running on my home server are within Docker containers. I wanted Motion to be no different so I created a Docker Image for it, specifically including an MQTT publish client.

Camera Configuration

All of the cameras I use serve Motion JPEG streams over HTTP. This method is not limited to this configuration, and will support any camera which is supported by Motion. This includes network cameras and also directly connected ones, although you'll need to pass the device through to the docker container.

In order to receive a Motion JPEG stream from my cameras, I use the following URL:

http://10.0.0.10/videostream.cgi?loginuse=admin&loginpas=mypassword

You may be able to get the URL for your camera by viewing its web interface in your browser (Chrome in this case), right clicking on the video feed and choosing 'Copy image address'.

Note that in my case, simply browsing to the above URL doesn't seem to work. The same URL does work within Home Assistant and Motion, however.

Motion Configuration

Motion requires the use of a configuration file, so in order to get this, use the following Docker command:

docker run -ti --rm flyte/motion-mqtt config > motion.conf

If you're not using Docker, then you should be able to find this file in /etc/motion or /usr/local/etc/motion. It may be called motion.conf or motion-dist.conf.

Camera Setup

To set up Motion to connect to your IP camera, edit the motion.conf file and perform the following actions:

  • Comment out the videodevice /dev/video0 line
  • Uncomment the netcam_url line and set it to the URL of your video camera. For example:
netcam_url http://10.0.0.10/videostream.cgi?loginuse=admin&loginpas=mypassword

Note, for my cameras I use the mjpeg:// 'protocol', as described in the Motion guide:

netcam_url mjpeg://10.0.0.10/videostream.cgi?loginuse=admin&loginpas=mypassword

Disable Picture and Video Capture

Since we're only using Motion to detect motion and not to record the events, change the following two config values from 'on' to 'off':

output_pictures off
ffmpeg_output_movies off

Event Length

By default each event lasts for 60 seconds after the motion is no longer detected. This is too long for my liking, so adjust the amount of seconds with the event_gap configuration value:

event_gap 5

MQTT Configuration

Finally, in order to actually publish the events to an MQTT topic, you must set the on_event_start and on_event_end configuration values. For example:

on_event_start mosquitto_pub -h test.mosquitto.org -u yourusername -P yourpassword -t "cam/office/motion" -m "on"
on_event_end mosquitto_pub -h test.mosquitto.org -u yourusername -P yourpassword -t "cam/office/motion" -m "off"

If you're not using my Docker image, then you should be able to get the mosquitto_pub tool from the mosquitto-clients package. apt-get install mosquitto-clients if you're using Ubuntu/Debian/Raspbian.

Have a look at mosquitto_pub --help for more usage information.

Run the Service

For my Docker containers, I tend to create a docker directory, then organise the files for each of the containers within subdirectories. For example, my three cameras are organised as such:

motion-mqtt
├── office
│   ├── config
│   │   └── motion.conf
│   └── run.sh
├── server_room
│   ├── config
│   │   └── motion.conf
│   └── run.sh
└── workshop
    ├── config
    │   └── motion.conf
    └── run.sh

Each of the run.sh files contains the command I use to run each container:

docker run -d \
    --name motion-mqtt-office \
    -v /home/flyte/docker/motion-mqtt/office/config:/motion:ro \
    flyte/motion-mqtt

Note that the Motion configuration file is within a config directory which is shared within the Docker container as a volume at /motion. By default, the container will look for a configuration file at /motion/motion.conf.

Once you've created a directory structure and created a run.sh script, make the script runnable with chmod +x run.sh and then execute it with ./run.sh. This should now have created a new Docker container. You can check the logs with docker logs -f motion-mqtt-office.

If everything's gone well, you should now be able to wave at the camera and receive log entries along the line of the following:

[1:ml1] [NTC] [ALL] motion_init: Started motion-stream server on port 8081 (auth Disabled)
[1:ml1] [NTC] [EVT] event_new_video: Source FPS 2
[1:ml1] [NTC] [ALL] motion_detected: Motion detected - starting event 1
[1:ml1] [NTC] [ALL] mlp_actions: End of event 1
[1:ml1] [NTC] [EVT] event_new_video: Source FPS 2
[1:ml1] [NTC] [ALL] motion_detected: Motion detected - starting event 2
[1:ml1] [NTC] [ALL] mlp_actions: End of event 2
[1:ml1] [NTC] [EVT] event_new_video: Source FPS 2
[1:ml1] [NTC] [ALL] motion_detected: Motion detected - starting event 3
[1:ml1] [NTC] [ALL] mlp_actions: End of event 3

Use your favourite MQTT subscription tool (MQTT Lens or mosquitto_sub in my case) to check that you're publishing events to MQTT properly.

Home Assistant Configuration

To add the new motion sensor to Home Assistant, create a new Binary Sensor:

binary_sensor:
  - name: Office Motion
    platform: mqtt
    state_topic: home/office/motion
    payload_on: "on"
    payload_off: "off"

You may also want to set its device_class as motion so that the UI makes more sense:

homeassistant:
  customize:
    binary_sensor.office_motion:
      device_class: motion

This should now be enough to view the motion sensor state in Home Assistant. You may now want to set up automations using the input of the motion sensor, in which case I recommend you start with Automating Home Assistant.

What do you think? Did I get something wrong? Could this be done better? Let me know below.

Comments
comments powered by Disqus

Published

Aug 2, 2017

Category

Blog

Tags

  • camera 1
  • cctv 1
  • docker 1
  • home-assistant 1
  • home-automation 1
  • motion 1
  • mqtt 1

More of Me

  • Powered by Pelican. Theme: Elegant by Talha Mansoor