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
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.
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!
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!
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.
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).
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
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.