Generic camera with motion detection and MQTT

I have several web-cameras around the house, both inside and outside (some d-link and some tp-link), and all of them have motion detection with some kind of trigger. It has been bugging me for a long time that I have all those motion detection devices that I don’t use for motion detection in HA. Now I have found a solution that works, and it’s not that hard to set up.

What you will need

  • MQTT server
  • FTP server
  • Camera that supports uploading image (or something) on motion detection to FTP

How it works

When a camera detects motion, it will upload an image (or text document depending on the type of camera) to the FTP-server. On the FTP-server I have a script running that checks for new files in a specific directory. When a file appears, the script will publish a specific topic to the MQTT server depending on the filename. HA has subscribed to these topics and will immediately know that motion is detected.

check_images.sh

Example bash script for detecting new images (and other files) in one specific folder. Repeat with more if-tests to check several filenames from different cameras. (Updated with inotifywait - thanks to jpontius)

#!/bin/bash

USER="username"
PASS="password"
DIR="/home/camera/images/"
WAIT=10       # Number of seconds before turning off sensor

# Tell syslog that we have started
logger "File monitor started!"

inotifywait -m -r -e create --format '%f' "${DIR}" | while read NEWFILE
do
    # Porch. Will detect new files that includes the name "porch"
    if [[ $NEWFILE == *"porch"* ]]; then
        TOPIC="homeassistant/porch/motion_sensor"
        # Publish MQTT message ON
        mosquitto_pub -P "$PASS" -u "$USER" -t "$TOPIC" -m "on"
        # Log action to syslog
        logger "Motion detected: Porch."
        # Delete file
        rm ${DIR}${NEWFILE}
        # Wait $WAIT seconds and publish MQTT message OFF
        sleep $WAIT && mosquitto_pub -P "$PASS" -u "$USER" -t "$TOPIC" -m "off" &
    # Kitchen
    elif [[ $NEWFILE == *"kitchen"* ]]; then
        TOPIC="homeassistant/kitchen/motion_sensor"
        mosquitto_pub -P "$PASS" -u "$USER" -t "$TOPIC" -m "on"
        logger "Motion detected: Kitchen."
        rm ${DIR}${NEWFILE}
        sleep $WAIT && mosquitto_pub -P "$PASS" -u "$USER" -t "$TOPIC" -m "off" &
    # Unknown file
    else
        echo "Filename $NEWFILE not recognized."
    fi
done

configuration.yaml

Add the MQTT sensors:

sensor:
  - platform: mqtt
    state_topic: "homeassistant/porch/motion_sensor"
    name: "Motion Porch"
  - platform: mqtt
    state_topic: "homeassistant/kitchen/motion_sensor"
    name: "Motion Kitchen"

groups.yaml

If you want, you can add a specific group for all motion detectors

motion:
  name: Motion Detection
  control: hidden
  entities:
    - sensor.motion_porch
    - sensor.motion_kitchen

I think that’s just about it. All comments for improving this are very welcome. If you have any questions about this, I will gladly answer and/or help.

By the way - I have changed my crontab to start the bash-script in the background at boot, and I also have another bash script that checks the process now and then just to be safe. I can post all this also if somebody is interested.

5 Likes

Instead of watching for new files every 10 seconds, check out inotifywait https://linux.die.net/man/1/inotifywait

It can fire off an event as soon as a file is written or modified. I think it needs to be on a local file system though, no NFS or samba mounts. Other than that, pretty cool!

1 Like

Or do it with python.

2 Likes

I will definitely check this out. I am actually watching for new files every second, but still this will prevent any delays. Thanks a lot!

I wish. I am just a beginner programmer, and my Python skills are really bad. I do some (very little though) bash-scripting in my job, and that’s my go-to language. Anyway this would be a nice and simple Python project, so I will bookmark this. Thanks!

Bash-script is updated after good advice from jpontius :slightly_smiling_face:

2 Likes

Thank you very much!! You’ve just saved me 2 motion detectors, I will used my 2 old Dlink cameras.

For the FTP server have you tried the Hassio add on below? I expect this whole project could be done using Hassio and native HA, which is something I would like to implement.

For motion:

Thank you for setting this up. It is just what I was looking for.

Would you please share how you went about setting up your crontab to start the bash script in the background at boot and the second bash script to check the process.

Hi. Here is what you need. I have placed my scripts in the /root/bin directory.

process_control.sh:

#!/bin/bash

# Check if script is running. Start it if not.

if ! pgrep -f "/bin/bash /root/bin/image_monitor.sh" > /dev/null
then
    /usr/bin/nohup /root/bin/image_monitor.sh  > /dev/null 2>&1 &
    echo "Process image_monitor.sh not running. Starting up."
    logger "Process image_monitor was not running. Starting."
else
    echo "Process image_monitor.sh still running."
fi

/etc/crontab entry:

# Process control for scripts
*/5 * * * *     root    /root/bin/process_control.sh > /dev/null 2>&1

That’s all you need. Every 5 minutes the control script will run and start the process if it has stopped (or if it is not running after a reboot).

-Thomas

Thank you. It is truly appreciated.

I found this works even better if I send only the On event to MQTT and drop the sleep statements. Then add

expire_after: 15

to mqtt sensor to reset the sensor to “unknown” state and therefore the motion group to off.

this takes care of the situation when another motion is detected before the 15 sec timer expires…

1 Like

Friend,

Can I use this with the hassio ftp server installed on a raspberry pi4?

I would love to make it work

Yes, I did adapt the code a little bit to fit my needs.
My cameras upload to FTP server. Then, the code copies it to the www folder on homeassitant for the ios notification, then, it sends the ON command for the sensor topic.

#!/bin/bash

USER="username"
PASS="password"
DIR="/usr/share/hassio/share/cameras/motion"
WAIT=10       # Number of seconds before turning off sensor

# Tell syslog that we have started
logger "File monitor started!"

inotifywait -m -r -e create --format '%w%f' "${DIR}" | while read NEWFILE
do
    # Front Door. Will detect new files that includes the name "frontdoor"
    if [[ $NEWFILE == *"frontdoor"* ]]; then
        TOPIC="sensor/frontdoormotion"
		# Copy PIC to www hassio folder
		sleep 1
		sudo cp ${NEWFILE} /usr/share/hassio/homeassistant/www/frontdoor.jpg
        # Publish MQTT message ON
        mosquitto_pub -P "$PASS" -u "$USER" -t "$TOPIC" -m "on"
        # Log action to syslog
        logger "Motion detected: Front Door."
        sleep $WAIT && mosquitto_pub -P "$PASS" -u "$USER" -t "$TOPIC" -m "off" &
	# Garage
    elif [[ $NEWFILE == *"garage"* ]]; then
		echo ${NEWFILE}
        TOPIC="sensor/garagemotion"
		# Copy PIC to www hassio folder
		sleep 1
		sudo cp ${NEWFILE} /usr/share/hassio/homeassistant/www/garage.jpg
        mosquitto_pub -P "$PASS" -u "$USER" -t "$TOPIC" -m "on"
        logger "Motion detected: Garage."
        sleep $WAIT && mosquitto_pub -P "$PASS" -u "$USER" -t "$TOPIC" -m "off" &

    # Unknown file
    else
        echo "Filename $NEWFILE not recognized."
    fi
done

and on home assistant I use this automation:

- id: '15798453451765'
  alias: Motion - Garage
  description: ''
  trigger:
  - entity_id: sensor.motion_garage
    platform: state
    to: 'on'
  action:
  - data:
      data:
        attachment:
          content-type: jpeg
          url: https://**homeassitantaddress**:8123/local/garage.jpg
        push:
          sound: sms-received2.caf
      message: Motion Garage!
    service: notify.mobile_app_iphone

It works very good for me. Thanks so much for everyone who put effort in making this code for all to use.

1 Like

Appreciate your work.

Can you please provide what cameras support uploading image to FTP when motion is detected.

Hi Arafath,

There are a lot of cameras that support FTP uploading. I was using both Logitech and Vivotek cameras. I think also a lot of TP-Link cameras has this support.

On the other hand - this method of detecting motion is getting outdated. I would recommend checking if your cameras have their own component in HA (Integrations - Home Assistant). This way you might get a motion sensor right from the integration.

Another thing to check would be ONVIF (ONVIF - Home Assistant). A lot of cameras support this standard, and also here you will automatically get sensors for movement and a lot more.

A third option, the one that I currently use, is motionEye (motionEye - Home Assistant). This requires a separate installation, but it can handle almost any camera and you will get sensors for all of them in HA.

Hi,

this doesn’t seem to work anymore.

Any suggestion how to adapt the sensors would be greatly appreciated.

Thanks in advance and Happy New Year!

EDIT:
Solved it by putting all mqtt sensors into a separate mqtt.yaml! :slight_smile:

Is it possible to install inotify-tools on HA OS?
At least apt-get install is no option.