Presence Detection using wifi

I have tried a few different methods for presence detection but have not yet found a reliable method. I want to be able to detect the presence of mobile devices on my home network so I can trigger scenes when one, some, all or no devices are present.

I have implemented a solution which I have been running for a few days and has proved to be 100% reliable so far with no false positives. The approach I have taken is to run a script on my router to detect devices by MAC number and then use a http address to trigger a virtual switches on my VeraLite.

For this to work you need to be running a router with Merlin custom firmware to let you run scripts. I have an ASUS RT-AC88U router with ASUS Merlin custom firmware.

Here’s what I did:

  1. login to the router and enable JFFS custom scripts under Administration>system

  2. enable SSH login to the router

  3. Login to your router via SSH using Putty.

4, Browse to the folder /jffs/scripts

  1. create a file named CheckIfHome

  2. Place the following code into this new file.
    This code is monitoring 3 devices. You can delete or add as many as you like. You need to change Name1, Name2, Name3 throughout the code for your requirements. Also enter the MAC adddress for each device your are tracking by replacing the XX:XX:XX:XX:XX. You also need to add your router’s IP address (remove the < > symbols). Then in the CURL urls you need to add your specific device number and target status.


#!/bin/sh

if [ ! -d /tmp/CheckUser ]
 then
  mkdir /tmp/CheckUser
fi

Name1=Away
Name2=Away
Name3=Away

macadresser="`wl -i eth1 assoclist` `wl -i eth2 assoclist` `wl -i eth3 assoclist`"
antal=0
antal=`qcsapi_sockrpc get_count_assoc wifi0`

while [ $antal -gt 0 ]
do
  antal=`expr $antal - 1`
  macadresser="`qcsapi_sockrpc get_station_mac_addr wifi0 $antal`;$macadresser"
done

case "$macadresser" in
 *XX:XX:XX:XX:XX:XX*)
 Name1=Home
 ;;
esac

case "$macadresser" in
 *XX:XX:XX:XX:XX:XX*)
 Name2=Home
 ;;
esac

case "$macadresser" in
 *XX:XX:XX:XX:XX:XX*)
 Name3=Home
 ;;
esac

if [ "$Name1" = Home ]
then
 if [ ! -f /tmp/CheckUser/Name1Home ]
 then
  touch /tmp/CheckUser/Name1Home
  curl "http://<yourRouterIP>:3480/data_request?id=action&output_format=xml&DeviceNum=106&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1" -k
 fi
else
 if [ -f /tmp/CheckUser/Name1Home ]
 then
  rm -f /tmp/CheckUser/Name1Home
  curl "http://<yourRouterIP>:3480/data_request?id=action&output_format=xml&DeviceNum=106&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0" -k
  fi
fi

if [ "$Name2" = Home ]
then
 if [ ! -f /tmp/CheckUser/Name2Home ]
 then
  touch /tmp/CheckUser/Name2Home
  curl "http://<yourRouterIP>:3480/data_request?id=action&output_format=xml&DeviceNum=107&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1" -k
 fi
else
 if [ -f /tmp/CheckUser/Name2Home ]
 then
  rm -f /tmp/CheckUser/Name2Home
  curl "http://<yourRouterIP>:3480/data_request?id=action&output_format=xml&DeviceNum=107&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0" -k
  fi
fi

if [ "$Name3" = Home ]
then
 if [ ! -f /tmp/CheckUser/Name3Home ]
 then
  touch /tmp/CheckUser/Name3Home
  curl "http://<yourRouterIP>:3480/data_request?id=action&output_format=xml&DeviceNum=108&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1" -k
 fi
else
 if [ -f /tmp/CheckUser/Name3Home ]
 then
  rm -f /tmp/CheckUser/Name3Home
  curl "http://<yourRouterIP>:3480/data_request?id=action&output_format=xml&DeviceNum=108&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0" -k
  fi
fi

  1. give tg file r/w permission by entering at the command prompt in Putty: chmod 777 /jffs/scripts/CheckIfHome

  2. create the CheckUser Folder with the command prompt line: mkdir /jffs/scripts/CheckUser

  3. Next install the number of Virtual Switches you need in your Vera unit. In my case I installed three. Then make a note of their vera device ID and enter them into the relevant CURL URL in the above code.

  4. next setup a cron job to run the script at defined intervals. I used 15 seconds. to do this create a file called init-start and paste the code below into it.


#!/bin/sh
cru a CheckIfHome "* * * * * /jffs/scripts/CheckIfHome"
cru a CheckIfHome15 "* * * * * sleep 15; /jffs/scripts/CheckIfHome"
cru a CheckIfHome30 "* * * * * sleep 30; /jffs/scripts/CheckIfHome"
cru a CheckIfHome45 "* * * * * sleep 45; /jffs/scripts/CheckIfHome"

  1. then give this new file r/w permissions: chmod 777 /jffs/scripts/init-start

  2. reboot router

  3. via SSH using Putty enter: ./init-start

Thats it. Now every 15 seconds the script will check for the presence of these devices by MAC address This code works for 2.5 and 5ghz wifi.

Whe a devie connects or disconnects the virtual switch on your vera will be set to on or off. You can then use this switch to run a scene or send a notification etc.

The problem is often the power-saving/management on smartphones. Smartphones go quite far to save power, so a phone that just sits in your home doing nothing might be taken offline from the (W)LAN and the entry in your router will be flushed over time. You need to disable power-savings for sure on the phone to remain really well connected on the LAN.

You could also some “ping” (every 10-15sec) Vera plugin to determine some presence, but this will keep phones awake for sure reducing battery life.

This is such an important point, not just for presence detection using WiFi, but for Vera’s mobile apps and geofencing as well. In Android in particular, enabling “power saving” mode on the phone, or choosing default settings incorrectly, can all but disable reliable geofencing. This includes the settings the prevent background apps from using the network, restriction of mobile data, and putting background apps to sleep altogether. Many Android users are not even aware that these detailed settings exist.

For the moment, it’s hard to imagine getting reliable presence detection without multi-factor evaluation. Relying on one data point, especially when it’s a mobile phone, will be just OK most of the time, but won’t carry the day every day. And Murphy assures us it will go wrong when our spouses, partners and clients will be most annoyed by it.

I agree about Android Pwr settings. I have set my phone’s WiFi preference to be on even when sleeping. I haven’t noticed any difference battery drain and my presence detection has worked 100% with no false positives since implementation 2 days ago.

Yes, the effectiveness of this method is really good, but it can depend on individual clients. Here was the original discussion on using custom router firmware with some good info for other models. In particular, the broadcom and atheros models have different commands for listing wifi devices.:

I tried arping from my vera with limited success. I often got false positives. It wasn’t reliable enough to drive any scenes from it.

I’ve been running three devices on this router method for 3 days now and its been 100% so far. Fingers crossed it stays that way

@col8eral - I tried using your script and it does not seem to run on my Broadcom chip router (Asus RT-AC66U_B1 with Merlin )

I ssh into my router and running the lines separately to see where the issue is, and I have an issue at the beginning with the variable.

this snippet of code
macadresser=“wl -i eth1 assoclist wl -i eth2 assoclist wl -i eth3 assoclist

returns an error stating it can not find “wl adapter”