Today I programmed another part of the system I envision for my new house. It’s a bash shell script which checks if either my phone or that of my girlfriend is in range and depending on if it is or not it changes a switch in Domoticz. That way I can automate all the lights turning off when we are not home, and coming back on when we are!
Detecting the presence of the phones
I looked at several ways of doing this, from a simple ping script to a arp-scan, etc.
NMAP
I searched a bit online and found that nmap has a “no port scan” presence detection ability and tried it out. With all of my Android devices and in my routed setup it has worked great. Even when a device does not respond to ping anymore it does still respond to this request and for the last few hours I have been testing with it, it has worked flawlessly.
Ping example:
root@domoticz:/home/quindor# ping -w 10s 10.24.1.10
PING 10.24.1.10 (10.24.1.10) 56(84) bytes of data.
--- 10.24.1.10 ping statistics ---
10 packets transmitted, 0 received, 100% packet loss, time 9072ms
root@domoticz:/home/quindor#
Nmap example:
root@domoticz:/home/quindor# nmap -sn 10.24.1.10
Starting Nmap 6.40 ( http://nmap.org ) at 2015-02-01 01:50 CET
Nmap scan report for 10.24.1.10
Host is up (0.43s latency).
Nmap done: 1 IP address (1 host up) scanned in 1.46 seconds
root@domoticz:/home/quindor#
As you can see, the ping response hangs (set maximum wait time to ~10s) but the nmap responds that same host is up. If I try to namp the same address but turn WiFi off on my phone it correctly mentions that the host is not up. There is no delay in this such as decaying arp records, etc.
So this seems to work for all my Android devices, I can’t say if Apple or anything else will work, but it’s worth a shot I would say!
The need for static IP addresses
Script for using with Domoticz
Virtual Sensor |
Bash Script
–update 2015-02-03
I’ve made the whole script run from variable which can be stated in the beginning of the script. Only the URL is not a variable because 90% of the people will be running the script from the same machine as where Domoticz is running.
I have also implemented a check to see if the switch is already ON or OFF so that it doesn’t keep switching the Domoticz switch causing all kinds of weird things to happen. 😉 That also means that if you change something, those changes will not get overwritten except by the OFF or ON command when it occurs.
I also did a little bit of cleanup work and re-wrote some stuff.
The script I’m currently using is the following:
loop=1
sleep=10
switch=40
while [ "$loop" -eq "1" ]
do
echo ""
echo ""
echo ""
echo ""
echo Phone on = 0, Phone off = 1
nmap -sn 10.24.1.10 | grep -q latency
phone1=$?
echo Phone Name1 = $phone1
nmap -sn 10.24.1.11 | grep -q latency
phone2=$?
echo Phone Name2 = $phone2
total=$(($phone1 + $phone2))
echo Phones Total command = $total
if [ "$total" -gt "1" ];
then
echo Detected 0 phones, Checking status switch $switch;
curl -s "http://127.0.0.1:8080/json.htm?type=devices&rid="$switch"" | grep '"Status" : "Off",'
switchon=$?
if [ "$switchon" -eq "0" ];
then
echo Switch $switch is already OFF, skipping sending command to Domoticz;
else
echo Switch $switch was ON, turning switch OFF; curl "http://127.0.0.1:8080/json.htm?type=command¶m=switchlight&idx="$switch"&switchcmd=Off";
fi
else
echo Detected 1 or more phones, Checking status switch $switch;
curl -s "http://127.0.0.1:8080/json.htm?type=devices&rid="$switch"" | grep '"Status" : "On",'
switchon=$?
if [ "$switchon" -eq "0" ];
then
echo Switch $switch is already ON, skipping sending command to Domoticz;
else
echo Switch $switch was OFF, turning switch ON; curl "http://127.0.0.1:8080/json.htm?type=command¶m=switchlight&idx="$switch"&switchcmd=On";
fi
fi
echo ""
echo ""
echo ""
echo ""
echo Execution done, sleeping for $sleep seconds
sleep $sleep
done
What the script does is create a loop (sleep time at the end). This loop runs the NMAP command with a grep. If it’s succesful (grep finds the word “latency”) it returns with exit code 0. I check for this exit code and copy it to an environment variable. I do this also with the second phone.
After this I have two environment variable which are either 0 or 1 (or higher). I add these up to form another variable. Then I use a statement, if this variable is higher then 1, turn off the switch (no one is home). If it is 1 or lower, the switch needs to be on.
Be sure to change the IP address to where you are hosting Domoticz (probably localhost like mine) and to lookup your switch Device Index number and change it in the code. It’s the “idx=40″ part.
This will need to be changed reflecting the amount of devices you are checking.
Currently the sleep is 10 seconds. This is quite short, but I have not yet noticed any negative effects because of it. Domoticz checks it’s blocky scripts every 30 seconds, so the maximum time it can take to have an effect is ~39 seconds!
After this you just need to use a way of running the script. For now I’m starting it using a screen session after my machine boots. But you can also start it automatically during startup, or start it periodically using a cron job (remove the sleep line).
You can use this Switch in a LUA script or in a Blocky script inside of Domoticz. This post will not go into that right now, I might do another post about how to create that another time!
And that’s it! The switch should now get automatically updated in Domoticz.
Any questions or remarks, please let me know. If you are using it, drop me a line, always nice to know!