The script checks the ARP table (Address Resolution Protocol) of the Raspberry Pi for the presence of a phone. If the phone is in the same network as the Raspberry Pi, it shows up in the ARP table if there is traffic from the Pi to the phone. Other scripts I found use ping, but that does not work very well for iPhone because an iPhone does not respond to ping when it is inactive. I have tested the ARP method, and I have found it to be more reliable when combined with ping. I think this is because when the Pi pings the phone, it requests the MAC address of the phone on the network and stores it when it is replied in the ARP-table.
The script sets the dummy device to "On" if the phone has been seen on any moment in a given timeframe, and switches of the device if the device has not been seen during the give timeframe.
The setup consists of the following:
1. A dummy switch device in domoticz;
2. The script itself;
3. An entry in crontab that runs the script every minute.
First step is to create the dummy device in Domoticz via Setup > Hardware > Add device.
Check in devices what is the Idx number of the device, you will need this later on.
Second step is to create the scriptfile.
Login to the raspberry Pi via SSH and go to the domoticz/scripts directory. Usually the full path is /home/pi/domoticz/scripts, but that depends on your local setup. Please make sure that the directory you use is in the variable dir in the script in the Variables section. In the variable section you must also add username and password for Domoticz and if you have set it, the passcode for the dummy device.
create the script file, give the script file execution rights and open the nano-editor so you can paste the script:
Code: Select all
touch arpdetect.sh
chmod +x arpdetect.sh
nano arpdetect.sh
Code: Select all
#!/bin/bash
# experiment for presence detection: update dummy switch in Domoticz based on ARP result.
# will run every minute if setup in crontab
# Date: 2016-12-01
# parameters for calling script:
# 1: name of device
# 2: numeric ID of switchdevice in Domoticz
# 3: number of minutes after which away is detected (on is always set directly)
# example: ./arpdetect phone 72 10
# Variables
dir="/home/pi/domoticz/scripts"
username=""
password=""
passcode="pinokkio"
# do not change below line
#-----------------------------------
# check correct number of arguments
if [ "$#" -ne 3 ] ; then
echo "Usage: $0 devicename #domoticzdevice #minutes" >&2
exit 1
fi
period=$(expr $3 \* 60)
now=$(date +%s)
limit=$(expr $now - $period)
result=$(/usr/sbin/arp -a $1)
readdate=$(date)
# first do ping to make sure ARP is updated
/bin/ping -q -c 1 $1
# check if devicename exists in ARP table
if [[ ! "$result" =~ "$1" ]] ; then
echo "devicename $1 does not exist" >&2
exit 1
fi
# determine last detection:
# if devicename is in ARP table then last detection is now,
# otherwise read from file
if [[ $result =~ "ether" ]] ; then
lastdetect=$now
echo $now $result $readdate > $dir/lastdetect_$1.log
else
lastdetect=$(/usr/bin/awk '{print $1}' $dir/lastdetect_$1.log)
fi
# read current switch status
/usr/bin/curl -s "http://127.0.0.1:8080/json.htm?type=devices&username=“$username”&password=“$password"&rid="$2"" | /bin/grep '"Status" : Off",'
switchon=$?
# if device has not been present in the requested timeframe and switch is on then switch it off.
if [[ $limit -ge $lastdetect && $switchon -eq 1 ]] ; then
/usr/bin/curl "http://127.0.0.1:8080/json.htm?type=command&username="$username"&password="$password"¶m=switchlight&idx="$2"&switchcmd=Off&passcode="$passcode"";
fi
# if lastdetect in the requested timeframe and switch is off then switch it on.
if [[ $lastdetect -gt $limit && $switchon -eq 0 ]] ; then
/usr/bin/curl "http://127.0.0.1:8080/json.htm?type=command&username="$username"&password="$password"¶m=switchlight&idx="$2"&switchcmd=On&passcode="$passcode"";
fi
Some remarks on the script:
- It is assumed the there is no username/password necessary for Domoticz. If you have setup Domoticz with password protection, you should add these to the variables to the script.
- If you want to prevent the dummy devices from being set via the Domoticz website, you can use passcode protection. In that case you must add the passcode to the variables.
You call the script from the commandline with three parameters:
1. The name or IP-address of the phone you want to use for presence detection. If you want to find out your name, just type arp on the command line, you might recognize your phone . On my system the arp result looks like this:
Code: Select all
Address HWtype HWaddress Flags Mask Iface
iPad ether 4c:32:75:4f:78:a2 C eth0
10.0.0.69 ether 00:21:9b:e0:56:0e C eth0
10.0.0.102 (incomplete) eth0
10.0.0.137 ether d8:50:e6:33:1e:2f C eth0
DiskStation ether 00:11:32:37:ab:76 C eth0
iMac ether 00:23:df:99:59:5e C eth0
10.0.0.73 ether 00:21:9b:e0:56:0e C eth0
iPhone ether 00:6d:52:78:39:b4 C eth0
android-b0150a3c1e62016 ether 10:a5:d0:23:0d:d1 C eth0
router.asus.com ether 08:60:6e:ba:17:58 C eth0
2. the idx of the created dummy device.
3. the period between the latest time your phone is detected and the moment you want the switch the dummy device off in minutes.
You can test the script by calling it from the command line by typing ./arpdetect.sh <name of device on network> <idx> <#minutes>.
Example: ./arpdetect.sh iPhone 72 10
This searches for the iPhone and will switch off device 72 after 10 minutes.
You will see that after running the script a file is created in the directory with the name lastdetect_<device>.log. This contains the last time the device is detected, both in Epoch format and human readable format.
If the script works, you must setup the crontab to run the script every minute.
type
Code: Select all
crontab -e
Code: Select all
* * * * * /home/pi/domoticz/scripts/arpdetect.sh iphone 72 10
Check if the script runs every minute by looking at the logfile.
Hope this is useful for someone.