Page 1 of 3
[Bash/Lua] Presence Detection via MAC Address
Posted: Thursday 05 February 2015 15:50
by dadogiobbe
i wrote a script to detect presence of 1 or multiple devices in the home using MAC address of devices...
i obtain it using arp-scan
you have to create:
a virtual switch for every device to poll;
a variable (PRESENCE_LIST) in this format: MAC_Address1;IDX1|MAC2;IDX2 ....
if you have only 1 device it's like 11:22:33:44:55:66;100
i have a time script that launch a bash script to poll the device and send json command to domoticz to switch on or off the assigned virtual switch.
it's perfect and very quick (~2 seconds in my lan with 15 devices connected) and it's IP independent...
this is the
script_time_Presence.lua
Code: Select all
function splitString(str, delim, maxNb)
-- Eliminate bad cases...
if string.find(str, delim) == nil then
return { str }
end
if maxNb == nil or maxNb < 1 then
maxNb = 0 -- No limit
end
local result = {}
local pat = "(.-)" .. delim .. "()"
local nb = 0
local lastPos
for part, pos in string.gmatch(str, pat) do
nb = nb + 1
result[nb] = part
lastPos = pos
if nb == maxNb then break end
end
-- Handle the last field
if nb ~= maxNb then
result[nb + 1] = string.sub(str, lastPos)
end
return result
end
commandArray = {}
maclist= uservariables['PRESENCE_LIST']
Lines=splitString(maclist,"|")
for i,line in pairs(Lines) do
--print (i.." "..line)
macs=splitString(line,";")
print ("MAC Address to Poll: "..macs[1].." On IDX:"..macs[2])
execcommand="sudo /home/pi/domoticz/scripts/bash/Check_MAC.sh "..macs[1].." "..macs[2].." &"
os.execute(execcommand)
end
and this the
Check_MAC.sh bash script
Code: Select all
#!/bin/bash
MAC=$1
IDX=$2
sudo arp-scan --localnet | grep -e $MAC
if [ $? -eq 1 ]
then
echo "Device $MAC Not in LOCAL LAN"
curl "http://127.0.0.1:8080/json.htm?type=command¶m=switchlight&idx=$IDX&switchcmd=Off"
else
echo "Device $MAC in LOCAL LAN"
curl "http://127.0.0.1:8080/json.htm?type=command¶m=switchlight&idx=$IDX&switchcmd=On"
fi
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Thursday 05 February 2015 16:37
by jannl
I think this depends on how many switches you have in your network......
And this also depends on wifi being on.
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Thursday 05 February 2015 16:38
by dadogiobbe
i have 4 switches and 2 access points...
10 devices are on cable lan and 5 in wireless...
if you want you could filter hosts to check with arp-scan filters...like ip range, hostnames,....
in this way it's faster...
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Saturday 04 April 2015 20:51
by rijo78
Hi, I love this idea, but I don't seem to get this working.
Maybe I have the mac-dress in the wrong place?
I have placed this script in domoticz/scripts/lua folder. The bash script is placed in the bash folder.
Could you help me out?
function splitString(str, delim, maxNb)
-- Eliminate bad cases...
if string.find(str, delim) == nil then
return { str }
end
if maxNb == nil or maxNb < 1 then
maxNb = 0 -- No limit
end
local result = {}
local pat = "(.-)" .. delim .. "()"
local nb = 0
local lastPos
for part, pos in string.gmatch(str, pat) do
nb = nb + 1
result[nb] = part
lastPos = pos
if nb == maxNb then break end
end
-- Handle the last field
if nb ~= maxNb then
result[nb + 1] = string.sub(str, lastPos)
end
return result
end
commandArray = {}
maclist= uservariables '44:xx:eb:xx:xx:xx;77|xx:6c:xx:xx:94:xx;78'
Lines=splitString(maclist,"|")
for i,line in pairs(Lines) do
--print (i.." "..line)
macs=splitString(line,";")
print ("MAC Address to Poll: "..macs[1].." On IDX:"..macs[2])
execcommand="sudo /home/pi/domoticz/scripts/bash/Check_MAC.sh "..macs[1].." "..macs[2]..$
os.execute(execcommand)
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Saturday 04 April 2015 21:23
by Immo
Useless for iphones or any other phone that switches off the wifi in standby.
it will keep telling you you're home and left every other minute or so..
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Saturday 04 April 2015 22:26
by rijo78
I don't have that problem. My Android phone does not switch off wifi
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Sunday 05 April 2015 13:50
by rijo78
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Monday 06 April 2015 15:09
by ceedebee
Nice script, I took the liberty to change it a bit so you don't need to use the bash script anymore.
Why did you use this bash script anyway? It seems to me it's a bit nicer to have it all in one script.
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Monday 06 April 2015 21:25
by realwheel
Can you please post your version of the script which does not require the bash script anymore?
Thanks!
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Monday 06 April 2015 21:45
by ceedebee
I am just a beginner in lua coding, so maybe some improvements do apply (the script is not tested through and through):
Code: Select all
function splitString(str, delim, maxNb)
-- Eliminate bad cases...
if string.find(str, delim) == nil then
return { str }
end
if maxNb == nil or maxNb < 1 then
maxNb = 0 -- No limit
end
local result = {}
local pat = "(.-)" .. delim .. "()"
local nb = 0
local lastPos
for part, pos in string.gmatch(str, pat) do
nb = nb + 1
result[nb] = part
lastPos = pos
if nb == maxNb then break end
end
-- Handle the last field
if nb ~= maxNb then
result[nb + 1] = string.sub(str, lastPos)
end
return result
end
commandArray = {}
--Get the list of phones to check on
phoneslist= uservariables['Telefoonlijst']
--Do an arp-scan on the localnet
--and search for the mac adresses
if phoneslist ~= nil then
local newphonelist =""
local currenttime = os.time()
local outdoorsdelay = 5 * 60
--do the arp scan and store the result
local command = "sudo arp-scan --interface=eth0 192.168.xxx.1-192.168.xxx.yyy --retry=5 --ignoredups"
local handle = io.popen(command)
local result = handle:read("*all")
handle:close()
--Get a list of all phones
phones=splitString(phoneslist,"|")
--Search arp-scan result for presence of MAC for each phone
for i,line in pairs(phones) do
--Get the data for this phone
phone=splitString(line,";")
--and the switch state
switchstate = otherdevices[phone[2]]
--Fill a new list with phones
if i > 1 then newphonelist = newphonelist.."|" end
newphonelist = newphonelist..phone[1]..";"..phone[2]
-- If phone detected write current time and switch on
-- else switch off after the given delay time
if string.find(result, string.lower(phone[1])) ~= nil then
phone[3]= currenttime
if string.lower(switchstate) == 'off' then commandArray[phone[2]] = 'On' end
else
if tonumber(currenttime) > (tonumber(phone[3]) + outdoorsdelay) and string.lower(switchstate) == 'on' then
commandArray[phone[2]] = 'Off'
print(phone[2].."; now:"..os.date("%Y-%m-%d %H:%M:%S", currenttime).."; last seen: "..os.date("%Y-%m-%d %H:%M:%S",tonumber(phone[3])))
end
end
newphonelist = newphonelist..";"..phone[3]
end
--print(newphonelist)
commandArray['Variable:Telefoonlijst']= newphonelist
else
print("Uservariable 'Telefoonlijst' not found!")
end
p.s. change the xxx and yy in the ip addresses to your own range
I added an extra field in the user variable to store the latest time the phone has been seen. With a delay on this time the switch is switched off when the phone is out of reach. The second field in the user variable is changed to the name of the switch to switch on/off, one switch for every phone each.
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Tuesday 07 April 2015 5:42
by Cannon
Hi Ceedebee
Would you mind providing a step by step on how to set this up?
I'm happy if you just PM if no one else wants the info.
Cheers for your help
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Tuesday 07 April 2015 19:32
by ceedebee
At first: one bugfix, I programmed a print statement for logging the case a phone gets out of reach (somewhere around line 73). The function 'date()' is wrong, must be 'os.date()'. I fixed it in the code, like I said: not all was checked although the scripts works just fine. It detects the presence of phone correctly, with the remark of course that the wifi must always be switched on.
Then the setup: I added three switches in domoticz with the name of the phone owners, but this name can be anything. After that I added a uservariable with the name 'Telefoonlijst' wich means 'Phonelist'. In this variable, per phone, separated by ";" sign three variables: MAC, name of the switch, 0. Followed by "|" symbol before the next phone entry. For example 00:11:22:33:44:55;Phone1;0|66:77:88:88:AA:BB;Phone2;0
The last field is the 'last time seen' field. Initially set to 0 but filled with the current time if the phone is detected on the network. Each minute the network is checked via arp-scan for the presence of phones. I changed the original arp-scan command a bit because I know my router isn't assigning IP addresses above the "100" so scanning all the range to 256 is not necessary . I also added the retry parameter and the ignore dups parameter.
The advantage of the script is that it only does one arp-scan each minute and not one for each phone listed like the original. So I could add some retries.
p.s. don't forget to install the arp-scan program via: sudo apt-get install arp-scan
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Saturday 11 April 2015 17:47
by zmaster
Your script works like a charm ceedebee! I just installed it. Phones going into standby is a bit tricky but I think the timeout in the script could minimize the flapping noise it might cause.
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Saturday 11 April 2015 18:01
by ceedebee
Nice to hear. I don't know if there is a better alternative to detect if the users are indoors. I considered use a geofence app but this is using wifi and gps so more battery drain. I hope the topic starter appreciates my changes to the original script.
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Saturday 25 April 2015 18:07
by rijo78
Hi ceedebee, I like the script. It seems pretty straight forward. Where exactly do I have to place the mac-address, switchname and 0? Do I have to replace something?
Thanks
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Saturday 25 April 2015 20:27
by ceedebee
Just make a uservariable named 'Telefoonlijst' (Dutch for telephone list) or name it like you wish. And fill it with your phones MAC and switch names as follows:
MAC1;switchname1;0|MAC2;switchname2;0
ps if you change your variable name you have to change the line "phoneslist= uservariables['Telefoonlijst']" accordantly
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Saturday 25 April 2015 22:51
by rijo78
Aah! I finally got it working.
two things I did wrong. 1st setting user variables, 2nd name of the script. When I got both correct, it was working like a charm. Great work ceedebee! Really great script (once you know how it is working).
For those who are struggling with this as well:
1st: The user variables have to be set in Domoticz (Setup>More Options)
2nd: The name of the script has to start with 'script_time_' (don't think the rest is that important for the functionality of the script)
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Saturday 25 April 2015 22:54
by ceedebee
Well, credits are for the topic starter. I only changed it a bit.
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Sunday 26 April 2015 12:07
by rijo78
You are right.
Dadogiobbe Thanks for sharing your work! Greatly appreciated
Re: [Bash/Lua] Presence Detection via MAC Address
Posted: Tuesday 05 May 2015 21:56
by BigDog
great script btw
thanks i am using it now
but how do i change the time that the script is scanning the mac adreses?
thanks in advance!
BigDog