I've been experimenting and found this detection method to work almost as I want it. I have made a few adjustments and need some help making some more.
Like many others I've got multiple wifi access points and thus detecting a phone on either the 2.4 or 5GHz interfaces doesn't work well, I'd have to run scripts on all 3 access points. My network however is the same over all access points (i.e. my devices are all in the same ip-range, getting an address from the same dhcp server while roaming the access points). To fix this issue I've replaced running wl against the wifi interfaces by looking up the mac address in the arp cache on bridge br0 in my main router. This way the mac address will be found when it is on either 2.4GHz, 5GHz or on the wired network (from another access point). In my RT-AC66U (merlin 380.68_4) arp entries time out after 2 minutes, which results in an acceptable delay for turning off my presence of 2 to 3 minutes. The switch will turn On at most a minute after my phone connects to wifi because of the 1 minute schedule, and Off within 2 to 3 minutes after my phone disconnects. I have no idea how this change affects "sleeping" iphone detection, but for me it works like a charm. I'll post my revised script below. Because arp returns the mac address somewhat differently formatted and I have little experience in scripting in these languages, you have to pass the MAC address formatted like AB:CD:EF:01:02, so using capitals and with : instead of - in between the hex pairs. My domoticz is accessible from my lan without user name and passw, so I don't have to specify this in the url's. If your domoticz is configured differently, adjust the script accordingly.
Code: Select all
#!/bin/sh
mac=$1
idx=$2
device_present=Off
domoticz_status=`curl -s "http://192.168.128.100:8080/json.htm?type=devices&rid=$idx" | grep Status | awk '{print $3}' | sed 's/[",]//g'`
# look in bridge (br0) network for device
for x in `arp -i br0 -na | awk '{print $4}'`; do
echo "x: $x, mac: $mac"
if [ $x = $mac ]; then
device_present=On
fi
done
echo "Domoticz: $domoticz_status, router: $device_present"
# tell domoticz the new device status
if [ $domoticz_status != $device_present ]; then
echo "New status $device_present"
curl -s "http://192.168.128.100:8080/json.htm?type=command¶m=switchlight&idx=$idx&switchcmd=$device_present" > /dev/null
fi
fi
This is how far I've gotten and what I wanted to share with you. Now the part that I need some assistance on to make it work even better
:
As I've got at least 6 devices I need to configure, plus the fact that the rate at which people change phones at my home is rather high, I would like to make the entire process a little bit more maintenance friendly by having to set up the script on the router only once and later on I only need to create more switches, remove switches or modify existing switches in Domoticz to change which devices are being monitored.
In order to do this I want to adjust the presence_detection script such that it first queries domoticz for all devices ( selects only those which name starts with 'Presence' and for each of these reads both the "idx" value plus the "Description" value for the devices' json returned by domoticz. "idx" of course holds the switches idx value, required to get and set the switches Status. "Description" I fill with the mac address of the device I need monitored. I did find a way to find and loop over the device names, but for retrieving the "idx" and "Description" values I realy need to parse the json structure returned by domoticz and I don't know how to do that using just shell commands. If anyone has a suggestion or maybe some example code on how to parse the both values from the json I'd be much obliged.
Code: Select all
#!/bin/sh
mac=$1
idx=$2
for device in `curl -s "http://192.168.128.100:8080/json.htm?type=devices" | grep '"Name".*"Presence' | awk -F'"' '{print $4}'`; do
echo "Presence device: $device"
# to do: read the idx and Description values, then query each switch and if needed set the switch accordingly.
done
And here's an example of a single device of which there are multiple returned by the "devices" query to domoticz. I need both the value for "idx" and "Description" for each of these:
Code: Select all
{
"AddjMulti" : 1.0,
"AddjMulti2" : 1.0,
"AddjValue" : 0.0,
"AddjValue2" : 0.0,
"BatteryLevel" : 255,
"CustomImage" : 0,
"Data" : "Off",
"Description" : "DC:0B:34:82:AF:1B",
"Favorite" : 0,
"HardwareID" : 9,
"HardwareName" : "Dummy",
"HardwareType" : "Dummy (Does nothing, use for virtual switches only)",
"HardwareTypeVal" : 15,
"HaveDimmer" : true,
"HaveGroupCmd" : true,
"HaveTimeout" : false,
"ID" : "000140A8",
"Image" : "Light",
"IsSubDevice" : false,
"LastUpdate" : "2017-11-17 12:40:01",
"Level" : 0,
"LevelInt" : 0,
"MaxDimLevel" : 100,
"Name" : "Presence Richard",
"Notifications" : "false",
"PlanID" : "0",
"PlanIDs" : [ 0 ],
"Protected" : false,
"ShowNotifications" : true,
"SignalLevel" : "-",
"Status" : "Off",
"StrParam1" : "",
"StrParam2" : "",
"SubType" : "Switch",
"SwitchType" : "On/Off",
"SwitchTypeVal" : 0,
"Timers" : "false",
"Type" : "Light/Switch",
"TypeImg" : "lightbulb",
"Unit" : 1,
"Used" : 1,
"UsedByCamera" : false,
"XOffset" : "0",
"YOffset" : "0",
"idx" : "88"
}
EDIT: Although this script turns the swithces on and off, after some time of usage I don't think it is doing exactly what I want it to do: My phones sometimes do not go into the internet for periods longer than 2 minutes, resulting in their arp entries being cleared from the router's arp cache. Every time this happens, my presence switch is turned off, even though I'm still at home. i.e. this method is not reliable enough for me. I'll be looking for another method still.