How to run webcam software only when I am not home (phone is not on the LAN)?

Running a script on your computer is much easier and definitely more clean than setting up a webserver that will wait for a phone to talk to it. Therefore I'm going to go with your first idea.

Assumptions:

  • You have root access.
  • /etc/init.d/motion is used to start and stop motion.
    • systemctl start|stop motion.service for systemd
  • You connect to the same network as your phone using eth0.
  • Your cron implementation uses the crontab command.

Getting the MAC address:

Get arp-scan and run arp-scan -I eth0 -l -r 10 as root. (I found -r 10 to be important for always detecting my Android phone)

This will return a list of devices in your network. The third column should make it easy to identify your phone. Let's say we get 01:01:01:01:01:01.

Script it:

Run arp-scan -I eth0 -l -r 10 | grep -q '01:01:01:01:01:01' as root. This will return 0 only if the phone is connected.

Run crontab -e as root and append this line to check if your phone is connected to the network every minute:

* * * * * arp-scan -I eth0 -l -r 10 | grep -q '01:01:01:01:01:01' && /etc/init.d/motion stop || /etc/init.d/motion start

Save the file and quit the editor.

Keep in mind that we do not need to check if motion is running ourselves. The service script does this internally.


zmode's answer is helpful, but didn't work for me. After a lot of reading, I came up with this solution:

#!/bin/sh
if arp-scan -I eth0 -r 10 android | grep -q '12:34:56:78:90:ab'
then
    echo "Phone present, killing motion"
    killall motion
    echo "Done killing motion"
else
    echo "Phone absent, starting motion"
    if ! ps -A | grep -q motion
        then
            echo "Motion is not running - starting it"
            su -c 'motion' - username
            echo "Motion started"
        else
            echo "Motion already running"
    fi
    echo "Done starting motion"
fi
exit

(The MAC address, hostname, and username need to be replaced.) It checks if the phone is on the network, using the phone's hostname android to avoid scanning unrelated addresses. It checks if motion is already running, so it doesn't start multiple instances or kill it repeatedly while it's working.

Then run sudo crontab -e to edit the root user's cron, and add a line like this:

*/5 * * * * /home/username/phone_webcam/phone_webcam.sh >> /var/log/cron.log 2>&1

This will run the script every 5 minutes, logging the output so you can debug it. Run the command tail -f /var/log/cron.log to make sure it's working. After confirming that it works, remove the logging line from crontab:

*/5 * * * * /home/username/phone_webcam/phone_webcam.sh

Taking the above response as a base you can tweak it to make it work slightly better.

#!/bin/sh
if arp-scan -I wlan0 -r 10 android-11111111111111111111 | grep -qi '11:11:11:11:11:11'
then
    echo "Phone present, killing motion"
    killall motion
    echo "Done killing motion"
else
    echo "Phone absent, starting motion"
    if ! ps -A | grep -q motion
        then
            echo "Motion is not running - starting it"
            su -c 'motion'
            echo "Motion started"
        else
            echo "Motion already running"
    fi
    echo "Done starting motion"
fi
exit

Typically, for wifi the interface is known as wlan0. The name of the android device is typically android- followed by a serial number. By adding -i to the grep command you can run the search with case insensitivity (took a while to figure this one out). On my machine starting motion properly requires root access. This can be accomplished by removing the username from the su command.

With those modifications and following everything in the above answer you can get Motion to start up no problem as soon as you leave (with your phone) your house. Flawless!