Presence detection based on IP and Bluetooth
Moderator: leecollings
- havnegata
- Posts: 114
- Joined: Wednesday 10 September 2014 11:05
- Target OS: Raspberry Pi / ODroid
- Domoticz version: V4.10162
- Location: Norway
- Contact:
Re: Presence detection based on IP and Bluetooth
Have arrived at the spot where I'm to test the script:
pi@raspberrypi:~/domoticz/scripts $ lua presence.lua
lua: presence.lua:85: module 'socket.http' not found:
no field package.preload['socket.http']
no file './socket/http.lua'
no file '/usr/local/share/lua/5.1/socket/http.lua'
no file '/usr/local/share/lua/5.1/socket/http/init.lua'
no file '/usr/local/lib/lua/5.1/socket/http.lua'
no file '/usr/local/lib/lua/5.1/socket/http/init.lua'
no file '/usr/share/lua/5.1/socket/http.lua'
no file '/usr/share/lua/5.1/socket/http/init.lua'
no file './socket/http.so'
no file '/usr/local/lib/lua/5.1/socket/http.so'
no file '/usr/lib/arm-linux-gnueabihf/lua/5.1/socket/http.so'
no file '/usr/lib/lua/5.1/socket/http.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
no file './socket.so'
no file '/usr/local/lib/lua/5.1/socket.so'
no file '/usr/lib/arm-linux-gnueabihf/lua/5.1/socket.so'
no file '/usr/lib/lua/5.1/socket.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
I have made the two new directories and downloaded the two files from https://www.domoticz.com/wiki/Remote_Co ... _Libraries and and extracted them:
pi@raspberrypi:/usr/local/share/lua/5.2 $ ls -l
total 152
-rw-r--r-- 1 root staff 2184 Oct 25 2013 ansicolors.lua
-rw-r--r-- 1 root staff 34843 May 28 2015 JSON.lua
-rw-r--r-- 1 root staff 8331 Sep 25 2014 ltn12.lua
-rw-r--r-- 1 root staff 4812 Sep 25 2014 luacolors.lua
-rw-r--r-- 1 root staff 2487 Sep 25 2014 mime.lua
-rw-r--r-- 1 root staff 62698 Sep 7 2014 mobdebug.lua
drwxr-sr-x 2 root staff 4096 Sep 25 2014 socket
-rw-r--r-- 1 root staff 5011 Sep 7 2014 socket.lua
drwxr-xr-x 2 root staff 4096 Jul 5 2015 ssl
-rw-r--r-- 1 root staff 4663 Jul 5 2015 ssl.lua
pi@raspberrypi:/usr/local/lib/lua/5.2 $ ls -l
total 68
drwxr-sr-x 2 root staff 4096 Sep 25 2014 mime
drwxr-sr-x 2 root staff 4096 Sep 7 2014 socket
-rwxr-xr-x 1 root root 61293 Jul 5 2015 ssl.so
pi@raspberrypi:/usr/local/lib/lua/5.2 $
Why is LUA searching for the files in the /5.1 directory?
pi@raspberrypi:~/domoticz/scripts $ lua presence.lua
lua: presence.lua:85: module 'socket.http' not found:
no field package.preload['socket.http']
no file './socket/http.lua'
no file '/usr/local/share/lua/5.1/socket/http.lua'
no file '/usr/local/share/lua/5.1/socket/http/init.lua'
no file '/usr/local/lib/lua/5.1/socket/http.lua'
no file '/usr/local/lib/lua/5.1/socket/http/init.lua'
no file '/usr/share/lua/5.1/socket/http.lua'
no file '/usr/share/lua/5.1/socket/http/init.lua'
no file './socket/http.so'
no file '/usr/local/lib/lua/5.1/socket/http.so'
no file '/usr/lib/arm-linux-gnueabihf/lua/5.1/socket/http.so'
no file '/usr/lib/lua/5.1/socket/http.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
no file './socket.so'
no file '/usr/local/lib/lua/5.1/socket.so'
no file '/usr/lib/arm-linux-gnueabihf/lua/5.1/socket.so'
no file '/usr/lib/lua/5.1/socket.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
I have made the two new directories and downloaded the two files from https://www.domoticz.com/wiki/Remote_Co ... _Libraries and and extracted them:
pi@raspberrypi:/usr/local/share/lua/5.2 $ ls -l
total 152
-rw-r--r-- 1 root staff 2184 Oct 25 2013 ansicolors.lua
-rw-r--r-- 1 root staff 34843 May 28 2015 JSON.lua
-rw-r--r-- 1 root staff 8331 Sep 25 2014 ltn12.lua
-rw-r--r-- 1 root staff 4812 Sep 25 2014 luacolors.lua
-rw-r--r-- 1 root staff 2487 Sep 25 2014 mime.lua
-rw-r--r-- 1 root staff 62698 Sep 7 2014 mobdebug.lua
drwxr-sr-x 2 root staff 4096 Sep 25 2014 socket
-rw-r--r-- 1 root staff 5011 Sep 7 2014 socket.lua
drwxr-xr-x 2 root staff 4096 Jul 5 2015 ssl
-rw-r--r-- 1 root staff 4663 Jul 5 2015 ssl.lua
pi@raspberrypi:/usr/local/lib/lua/5.2 $ ls -l
total 68
drwxr-sr-x 2 root staff 4096 Sep 25 2014 mime
drwxr-sr-x 2 root staff 4096 Sep 7 2014 socket
-rwxr-xr-x 1 root root 61293 Jul 5 2015 ssl.so
pi@raspberrypi:/usr/local/lib/lua/5.2 $
Why is LUA searching for the files in the /5.1 directory?
- jvdz
- Posts: 2266
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
Guess you also still need to install LUA 5.2 as described a little above the libraries: https://www.domoticz.com/wiki/Remote_Co ... ll_Lua_5.2
Jos
Jos
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
- havnegata
- Posts: 114
- Joined: Wednesday 10 September 2014 11:05
- Target OS: Raspberry Pi / ODroid
- Domoticz version: V4.10162
- Location: Norway
- Contact:
Re: Presence detection based on IP and Bluetooth
OK, then I get:
pi@raspberrypi:~/domoticz/scripts $ lua presence.lua
lua: error loading module 'ssl.core' from file '/usr/local/lib/lua/5.2/ssl.so':
libssl.so.1.0.0: cannot open shared object file: No such file or directory
stack traceback:
[C]: in ?
[C]: in function 'require'
/usr/local/share/lua/5.2/ssl.lua:7: in main chunk
[C]: in function 'require'
/usr/local/share/lua/5.2/ssl/https.lua:10: in main chunk
[C]: in function 'require'
presence.lua:87: in main chunk
[C]: in ?
pi@raspberrypi:~/domoticz/scripts $
pi@raspberrypi:~/domoticz/scripts $ lua presence.lua
lua: error loading module 'ssl.core' from file '/usr/local/lib/lua/5.2/ssl.so':
libssl.so.1.0.0: cannot open shared object file: No such file or directory
stack traceback:
[C]: in ?
[C]: in function 'require'
/usr/local/share/lua/5.2/ssl.lua:7: in main chunk
[C]: in function 'require'
/usr/local/share/lua/5.2/ssl/https.lua:10: in main chunk
[C]: in function 'require'
presence.lua:87: in main chunk
[C]: in ?
pi@raspberrypi:~/domoticz/scripts $
- jvdz
- Posts: 2266
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
Did you download both files? Think you missed the second one.
Jos
Jos
usrlocalsharelua52.tar.gz
cd /usr/local/share/lua/5.2/
sudo tar -xvf ~/temp/usrlocalsharelua52.tar.gz
(128.81 KiB) Downloaded 1111 times
usrlocalliblua52.tar.gz
cd /usr/local/lib/lua/5.2/
sudo tar -xvf usrlocalliblua52.tar.gz
(142.82 KiB) Downloaded 888 times
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
- jvdz
- Posts: 2266
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
I have updated the install lines to:
Let me know in case this doesn't work.
Thanks for the feedback,
Jos
Code: Select all
--
-- Install LUA 5.2 when its not installed yet:
--> sudo apt-get install lua5.2
--
-- require some LUA libraries: SOCKET.HTTP/SOCKET/JSON/ssl.https
-- includes need to be located in: /usr/local/share/lua/5.2/ and /usr/local/lib/lua/5.2/
-- Download and install usrlocalsharelua52.tar.gz from: http://www.domoticz.com/forum/download/file.php?id=3677
--> wget -O /tmp/usrlocalsharelua52.tar.gz "http://www.domoticz.com/forum/download/file.php?id=3677"
--> cd /usr/local/share/lua/5.2/
--> sudo tar -xvf /tmp/usrlocalsharelua52.tar.gz
-- Download and install usrlocalliblua52.tar.gz from: http://www.domoticz.com/forum/download/file.php?id=3676
--> wget -O /tmp/usrlocalliblua52.tar.gz "http://www.domoticz.com/forum/download/file.php?id=3676"
--> cd /usr/local/lib/lua/5.2/
--> sudo tar -xvf /tmp/usrlocalliblua52.tar.gz
-- end - Prerequisites --------------------------------------------------------------------------
Thanks for the feedback,
Jos
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
- havnegata
- Posts: 114
- Joined: Wednesday 10 September 2014 11:05
- Target OS: Raspberry Pi / ODroid
- Domoticz version: V4.10162
- Location: Norway
- Contact:
Re: Presence detection based on IP and Bluetooth
Thank you very much for trying to help me, and the improved installguide is much easier, but following it again gives me exactly the same error. Should say that I'm on RPI3 with Stretch and V3.8661
- jvdz
- Posts: 2266
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
I am on a RPI2b with jessie so can't try what you are doing, but I would have expected when the files are in the correct path shown in the previous error, that things should work... Maybe this is related to the other errors I have seen around this ssl topic & Stretch?
http://www.domoticz.com/forum/viewtopic ... .0#p154713
Jos
http://www.domoticz.com/forum/viewtopic ... .0#p154713
Jos
Last edited by jvdz on Friday 03 November 2017 14:23, edited 1 time in total.
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
- havnegata
- Posts: 114
- Joined: Wednesday 10 September 2014 11:05
- Target OS: Raspberry Pi / ODroid
- Domoticz version: V4.10162
- Location: Norway
- Contact:
Re: Presence detection based on IP and Bluetooth
Yes, I was thinking the same too... The only thing different is that I have a working Domoticz.
Anyway, thanks for your efforts!
Anyway, thanks for your efforts!
- jvdz
- Posts: 2266
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
See here in case you have the below ssl warning: http://www.domoticz.com/forum/viewtopic ... 94#p158394
Joslua: error loading module 'ssl.core' from file '/usr/local/lib/lua/5.2/ssl.so':
libssl.so.1.0.0: cannot open shared object file: No such file or directory
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
-
- Posts: 8
- Joined: Friday 30 March 2018 22:51
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: Presence detection based on IP and Bluetooth
So I got this working on a raspberry pi 3 (many thanks by the way!!) but it seems to be crashing Domoticz randomly when it tries to update the switch status (but not always). The following error message appeared in the console whilst running the script:
JSON request <http://192.168.1.90:8080/json.htm?type=devices&rid=25>
lua: /usr/local/share/lua/5.2/JSON.lua:383: nil passed to JSON:decode()
stack traceback:
[C]: in function 'assert'
/usr/local/share/lua/5.2/JSON.lua:383: in function 'onDecodeOfNilError'
/usr/local/share/lua/5.2/JSON.lua:644: in function 'decode'
/home/pi/domoticz/scripts/presence.lua:133: in function 'retrieve_status'
/home/pi/domoticz/scripts/presence.lua:166: in function 'domo_status'
/home/pi/domoticz/scripts/presence.lua:228: in main chunk
[C]: in ?
Any advice please?
JSON request <http://192.168.1.90:8080/json.htm?type=devices&rid=25>
lua: /usr/local/share/lua/5.2/JSON.lua:383: nil passed to JSON:decode()
stack traceback:
[C]: in function 'assert'
/usr/local/share/lua/5.2/JSON.lua:383: in function 'onDecodeOfNilError'
/usr/local/share/lua/5.2/JSON.lua:644: in function 'decode'
/home/pi/domoticz/scripts/presence.lua:133: in function 'retrieve_status'
/home/pi/domoticz/scripts/presence.lua:166: in function 'domo_status'
/home/pi/domoticz/scripts/presence.lua:228: in main chunk
[C]: in ?
Any advice please?
- jvdz
- Posts: 2266
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
That error means that the JSON call to the server fails as no data is returned.
I will have a look and add some error checking in that function to Ensure it doesn't crash and post that here.
Jos
I will have a look and add some error checking in that function to Ensure it doesn't crash and post that here.
Jos
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
-
- Posts: 8
- Joined: Friday 30 March 2018 22:51
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: Presence detection based on IP and Bluetooth
That would be good, much appreciated. I think it might be that Domoticz occasionally doesn't respond to the JSON. I tried the URL in the browser and it returned data on the relevant virtual switch.
- jvdz
- Posts: 2266
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
Could you try this version to see if that now works for you with that error?
Will update first post when it works ok.
Thanks,
Jos
Code: Select all
-- ==============================================================================================
-- Presence detection script using both fixed IP and BlueTooth to ensure proper detection
-- ==============================================================================================
-- -Prerequisites -------------------------------------------------------------------------------
-- Install bluetooth support:
--> sudo apt-get update # Update package list
--> sudo apt-get upgrade # Upgrade system
--> sudo apt-get install bluetooth bluez-utils blueman
--
-- Perform a scan for BT devices: (make sure your device is visible on BT)
--> hcitool scan
--
-- Find the proper directory for your PI bt in /var/lib/bluetooth/??:??:??:??
-- For the found device add a pin code to pincodes file: # use existing MAC folder
--> echo "<MAC> 0000" > /var/lib/bluetooth/??:??:??:??/pincodes
-- Test device by doing: hcitool name <MAC>
--
-- optionally could need to first Pair device when previous doesn't work. Worked for me without this
--> rfcomm connect 0 <MAC> 10 #and fill pin 0000 on phone/device
-- The rfcomm command can fail, no problem.
--
-- Changed the timeout "Page timeout: 8192 slots (5120.00 ms)" to " Page timeout: 4096 slots (2560.00 ms)"
--> sudo hciconfig hci0 pageto 4096
--
-- Install LUA 5.2 when its not installed yet:
--> sudo apt-get install lua5.2
--
-- require some LUA libraries: SOCKET.HTTP/SOCKET/JSON/ssl.https
-- includes need to be located in: /usr/local/share/lua/5.2/ and /usr/local/lib/lua/5.2/
-- Download and install usrlocalsharelua52.tar.gz from: http://www.domoticz.com/forum/download/file.php?id=3677
--> wget -O /tmp/usrlocalsharelua52.tar.gz "http://www.domoticz.com/forum/download/file.php?id=3677"
--> cd /usr/local/share/lua/5.2/
--> sudo tar -xvf /tmp/usrlocalsharelua52.tar.gz
-- Download and install usrlocalliblua52.tar.gz from: http://www.domoticz.com/forum/download/file.php?id=3676
--> wget -O /tmp/usrlocalliblua52.tar.gz "http://www.domoticz.com/forum/download/file.php?id=3676"
--> cd /usr/local/lib/lua/5.2/
--> sudo tar -xvf /tmp/usrlocalliblua52.tar.gz
-- end - Prerequisites --------------------------------------------------------------------------
-- # Crontab entries ---------------------------------------------------------------------------
-- !!! do this part when you have completed setting all variables below and things are working. !!!
--> # presence detection script is shelled every 2 minutes to ensure it remains active. The script dected whether it is already running
--> */2 * * * * lua /home/pi/domoticz/scripts/presence.lua -batch >> /var/tmp/presence_check.log
--
--### Start Define all required variables #############################################
ScriptName="presence.lua" -- set to the scriptfilename, used for checking occurences
server_url="http://192.168.0.??:8080" -- domoticz url
-- update LoopLog with latest time. This file can be used to check whether the process is still running with monit
-- Define "" when you don't want to use Monit.
-- Monit definition used:
-- check file Presence with path /var/tmp/presence-monit.log
-- stop program = "/usr/bin/pkill -f presence" timeout 60 seconds
-- if timestamp > 2 minutes then restart
-- if 5 restarts within 5 cycles then timeout
-- Monit_check_log="" -- don't create this extra Monit logfile
Monit_check_log="/var/tmp/presence-monit.log"
--
LoopTimeShort=10 -- Sleep Timer used when one of the phones is not found to recheck it
LoopTimeLong=30 -- Sleep Timer used when all phones are present
FailTimeout=120 -- Time used to determine the phone is really gone.
LoopTime=LoopTimeLong
debug=2 -- defines the logging level.
-- 0=basic info is logged
-- 1=some extra info
-- 2=all available info used only in case of issues
-- Phone configuration table ---------------------------------------------------------------
TelName = {} -- name of the telephone
TelIP = {} -- Ip address (put on "" when on;y using BT)
TelBT = {} -- BT mac address
TelIDX = {} -- IDX of dummy Domoticz On/Off switch for the phone
TelFail = {} -- count of checks that failed subsequently -> used by the script
TelFailTime = {} -- Time of the first failure -> Used by the script
-- first phone to check -------------------------------------------------------------------
Rec = 0
TelName[Rec] = "Phone1"
TelIP[Rec] = "192.168.0.xx"
TelBT[Rec] = "AA:BB:CC:DD:EE:FF"
TelIDX[Rec] = "??"
TelFail[Rec] = 0 -- don't change
TelFailTime[Rec] = 0 -- don't change
-- Second phone to check (remove block when only one phone is needed ----------------------
Rec = Rec +1
TelName[Rec] = "Phone2"
TelIP[Rec] = "192.168.0.XX"
TelBT[Rec] = "AA:BB:CC:DD:EE:XX"
TelIDX[Rec] = "??"
TelFail[Rec] = 0 -- don't change
TelFailTime[Rec] = 0 -- don't change
--------------------------------------------------------------------------------------------
TelCheckVar="" -- User Variable in Domoticz which can be used to find the last time the phones were checked.
-- Leave empty when not used.
--### End Define all required variables #############################################
-- Load necessary Lua libraries
http = require "socket.http";
socket = require "socket";
https = require "ssl.https";
JSON = require "JSON";
--
-- "2" only works when shelled from crontab else use "3" when testing from commandline
-- so ensure that you add the -batch when running it from crontab!
-- check howmany scripts are running with this name.
local file = io.popen('ps x | grep "'..ScriptName..'"|grep -cv grep')
local output = file:read('*all')
local rc = {file:close()}
output = string.gsub(output,"\n","") -- remove newline from output
if debug > 1 then
print ('cmd-> ps x | grep "'..ScriptName..'"|grep -cv grep => rc:'..tostring(rc[1])..' output:'..tostring(output))
end
if arg[1] == "-batch" and output == "2" then
print("batch and no=2 so not running yet")
elseif output == "1" then
print("no=1 so not running yet")
else
print("Already running -> Exit")
os.exit(0)
end
--### Start Define all required LUA functions #############################################
function sleep(n)
os.execute("sleep " .. tonumber(n))
end
-- retrieve status from domoticz
function retrieve_status(idx)
local t, jresponse, status, decoded_response
t = server_url.."/json.htm?type=devices&rid="..tostring(idx)
if debug>=2 then
print("JSON request <"..t..">")
end
jresponse, status = http.request(t)
if jresponse ~= nil then
decoded_response = JSON:decode(jresponse)
result = decoded_response["result"]
record = result[1]
status = record["Status"]
else
status = "Failed"
end
if debug>=2 then
print("Status JSON request "..status)
end
return status
end
-- Change state of Switch in Domoticz
function SwitchName(idx,state)
local status
if string.lower(state) == "on" then
state = "On";
elseif string.lower(state) == "off" then
state = "Off";
end
t = server_url.."/json.htm?type=command¶m=switchlight&idx="..idx.."&switchcmd="..state;
if debug>=2 then print("JSON request <"..t..">") end
jresponse, status = http.request(t)
if jresponse ~= nil then
result = JSON:decode(jresponse)
status = result["status"]
else
status = "Failed"
end
--
if status ~= "OK" then
print(os.date("%X").." !!!! SwitchName Not OK -> JSON feedback: ", jresponse)
else
if debug>=2 then
print("JSON feedback: ", jresponse)
end
end
return
end
-- Check and update switch in Domoticz
function domo_status(Name,Fail,PrevFail,FailTime,IDX,source,newstatus)
curstate = retrieve_status(IDX)
if debug>=1 then
print(os.date("%X").." "..IDX.." "..Name.." current="..curstate.." New="..newstatus.." from="..source.." fail="..Fail.." prevfail="..PrevFail.. " time="..os.time()-FailTime)
end
-- skip rest of process in case the call to domoticz failed
if curstate == "Failed" then
return
end
if Fail == 1 and curstate == "On" then
print(os.date("%X").." ---- phone failed -> retrying "..Name)
end
if PrevFail > Fail and curstate == "On" then
print(os.date("%X").." ---- phone connected again "..Name.." bron:"..source)
end
if (newstatus == "Off" and os.time()-FailTime >= FailTimeout and curstate ~= newstatus)
or (newstatus == "On" and curstate ~= newstatus) then
print(os.date("%X").." #### Switch phone "..Name.." "..newstatus.." bron:"..source.." ("..Fail..")" )
SwitchName(IDX,newstatus)
end
end
--### End Define all required functions #############################################
--############################################
--# Main loop
--############################################
-- List record to log that are being monitored
for Rec in pairs(TelName) do
curstate = retrieve_status(TelIDX[Rec])
print(os.date("%X").." ---- Starting monitoring for "..TelName[Rec].." ("..TelIDX[Rec]..") CurState="..curstate.." IPaddres="..TelIP[Rec].." BTmac="..TelBT[Rec])
end
print("Starting")
-- create poll file to check for Monit
if Monit_check_log ~= "" then
os.execute("echo " .. os.date("%Y-%m-%d %H:%M:%S") .. " > " .. Monit_check_log)
end
-- Loop to monitor all devices
while true do
--
timenow = os.time()
if debug>=1 then
print(os.date("%X").." ".."=================================================================")
end
for Rec in pairs(TelName) do
-- first try a IP ping as that is the fastest check
PrevFail=TelFail[Rec]
if TelIP[Rec] ~= "" then
ping_success=os.execute('ping -c1 -w2 ' .. TelIP[Rec].." > /dev/null")
else
ping_success=false
end
if ping_success then
TelFail[Rec] = 0
TelFailTime[Rec] = 0
domo_status(TelName[Rec],TelFail[Rec],PrevFail,os.time(),TelIDX[Rec],"Ping","On")
else
-- If Ping fails try the BT check with hcitool which is faster and less CPU than l2ping
bt_success=os.execute('hcitool name ' .. TelBT[Rec]..'|grep ".*" > /dev/null')
-- check for characters returned .. if nothing then phone not found
if bt_success==nil then
TelFail[Rec] = TelFail[Rec] + 1
-- set the failtime at first failure to find phone
if TelFail[Rec] == 1 then
TelFailTime[Rec] = os.time()
end
domo_status(TelName[Rec],TelFail[Rec],PrevFail,TelFailTime[Rec],TelIDX[Rec],"Both","Off")
LoopTime=LoopTimeShort -- set looptime lower when a phone isn't present
else
TelFail[Rec] = 0
TelFailTime[Rec] = 0
domo_status(TelName[Rec],TelFail[Rec],PrevFail,os.time(),TelIDX[Rec],"BT","On")
end
end
end
-- update uservariable with the last status check done time.
if TelCheckVar ~= "" then
t = server_url..'/json.htm?type=command¶m=updateuservariable&vname=' .. TelCheckVar .. '&vtype=2&vvalue=' .. os.date("%X") .. '';
if debug>=2 then print("JSON request <"..t..">") end
jresponse, status = http.request(t)
if jresponse ~= nil then
result = JSON:decode(jresponse)
status = result["status"]
else
status = "Failed"
end
if status ~= "OK" then
print(os.date("%X").." !!!! Set variable ".. TelCheckVar .." Not OK -> JSON feedback: ", jresponse)
else
if debug>=2 then
print("JSON feedback: ", jresponse)
end
end
end
-- sleep the number of seconds defined in LoopTime
if os.time() - timenow <= LoopTime then
if debug>=1 then
print(os.date("%X").." ".."sleep "..LoopTime-(os.time() - timenow))
end
sleep(LoopTime-(os.time() - timenow))
end
LoopTime=LoopTimeLong
-- update LoopLog with latest time. This file can be used to check whether the process is still running with monit
if Monit_check_log ~= "" then
os.execute("echo " .. os.date("%Y-%m-%d %H:%M:%S") .. " > " .. Monit_check_log)
end
end
Thanks,
Jos
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
-
- Posts: 8
- Joined: Friday 30 March 2018 22:51
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: Presence detection based on IP and Bluetooth
Great, will check it out tonight and report back. Many thanks.
-
- Posts: 8
- Joined: Friday 30 March 2018 22:51
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: Presence detection based on IP and Bluetooth
Update:
So I have been running the script from the command line now with no crashes and it all seems very happy. Will run from crontab overnight and report back.
Quick question on functionality. I noticed that when only one device is connected (I have two that I'm monitoring) and the ping frequency increases in order to provide better reconnect detection, it seems to be pinging both devices at the increased frequency. Is this by design?
And great script by the way, pretty much instant detection when I enable wireless and bluetooth on phone (bluetooth detection is especially quick!).
So I have been running the script from the command line now with no crashes and it all seems very happy. Will run from crontab overnight and report back.
Quick question on functionality. I noticed that when only one device is connected (I have two that I'm monitoring) and the ping frequency increases in order to provide better reconnect detection, it seems to be pinging both devices at the increased frequency. Is this by design?
And great script by the way, pretty much instant detection when I enable wireless and bluetooth on phone (bluetooth detection is especially quick!).
- jvdz
- Posts: 2266
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
Correct, the pause time decreases when one device is not detected and configured with:
LoopTimeShort=10 -- Sleep Timer used when one of the phones is not found to recheck it
LoopTimeLong=30 -- Sleep Timer used when all phones are present
The script is based on work of others that supported a single device and converted that to LUA and added multiple device support with a single script, but haven't bothered to try to complicate the code and simply increase the loop speed for all.
Ideas on how to do that differently?
I am using this script now for about 2 years and it has ran fine without issues supporting also 2 devices,
Jos
LoopTimeShort=10 -- Sleep Timer used when one of the phones is not found to recheck it
LoopTimeLong=30 -- Sleep Timer used when all phones are present
The script is based on work of others that supported a single device and converted that to LUA and added multiple device support with a single script, but haven't bothered to try to complicate the code and simply increase the loop speed for all.
Ideas on how to do that differently?
I am using this script now for about 2 years and it has ran fine without issues supporting also 2 devices,
Jos
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
-
- Posts: 18
- Joined: Wednesday 07 March 2018 18:22
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: The Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
Nice script/work! I'm going to implement this at home this weekend!jvdz wrote: ↑Friday 06 April 2018 9:14 Correct, the pause time decreases when one device is not detected and configured with:
LoopTimeShort=10 -- Sleep Timer used when one of the phones is not found to recheck it
LoopTimeLong=30 -- Sleep Timer used when all phones are present
The script is based on work of others that supported a single device and converted that to LUA and added multiple device support with a single script, but haven't bothered to try to complicate the code and simply increase the loop speed for all.
Ideas on how to do that differently?
I am using this script now for about 2 years and it has ran fine without issues supporting also 2 devices,
Jos
- jvdz
- Posts: 2266
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
Somehow your question intrigued me and triggered a new version which now works as follows:rlg6767 wrote: ↑Thursday 05 April 2018 23:51 Quick question on functionality. I noticed that when only one device is connected (I have two that I'm monitoring) and the ping frequency increases in order to provide better reconnect detection, it seems to be pinging both devices at the increased frequency. Is this by design?
You define the looptime ( 10 seconds is the default)
When a device failed it will do a check each loop
When a device is active it will be check one time in 3 loops (30 seconds).
This way it does save a little processing time.
Also updated the device definition table into one table making it simpler to define the devices.
It is running for me for a couple of hour now and all seems to be running fine.
Let me know in case there are questions or issues. Will update the initial post after a couple of days testing.
Jos
Code: Select all
-- ==============================================================================================
-- Presence detection script using both fixed IP and BlueTooth to ensure proper detection
-- ==============================================================================================
-- -Prerequisites -------------------------------------------------------------------------------
-- Install bluetooth support:
--> sudo apt-get update # Update package list
--> sudo apt-get upgrade # Upgrade system
--> sudo apt-get install bluetooth bluez-utils blueman
--
-- Perform a scan for BT devices: (make sure your device is visible on BT)
--> hcitool scan
--
-- Find the proper directory for your PI bt in /var/lib/bluetooth/??:??:??:??
-- For the found device add a pin code to pincodes file: # use existing MAC folder
--> echo "<MAC> 0000" > /var/lib/bluetooth/??:??:??:??/pincodes
-- Test device by doing: hcitool name <MAC>
--
-- optionally could need to first Pair device when previous doesn't work. Worked for me without this
--> rfcomm connect 0 <MAC> 10 #and fill pin 0000 on phone/device
-- The rfcomm command can fail, no problem.
--
-- Changed the timeout "Page timeout: 8192 slots (5120.00 ms)" to " Page timeout: 4096 slots (2560.00 ms)"
--> sudo hciconfig hci0 pageto 4096
--
-- Install LUA 5.2 when its not installed yet:
--> sudo apt-get install lua5.2
--
-- require some LUA libraries: SOCKET.HTTP/SOCKET/JSON/ssl.https
-- includes need to be located in: /usr/local/share/lua/5.2/ and /usr/local/lib/lua/5.2/
-- Download and install usrlocalsharelua52.tar.gz from: http://www.domoticz.com/forum/download/file.php?id=3677
--> wget -O /tmp/usrlocalsharelua52.tar.gz "http://www.domoticz.com/forum/download/file.php?id=3677"
--> cd /usr/local/share/lua/5.2/
--> sudo tar -xvf /tmp/usrlocalsharelua52.tar.gz
-- Download and install usrlocalliblua52.tar.gz from: http://www.domoticz.com/forum/download/file.php?id=3676
--> wget -O /tmp/usrlocalliblua52.tar.gz "http://www.domoticz.com/forum/download/file.php?id=3676"
--> cd /usr/local/lib/lua/5.2/
--> sudo tar -xvf /tmp/usrlocalliblua52.tar.gz
-- end - Prerequisites --------------------------------------------------------------------------
-- # Crontab entries ---------------------------------------------------------------------------
-- !!! do this part when you have completed setting all variables below and things are working. !!!
--> # presence detection script is shelled every 2 minutes to ensure it remains active. The script dected whether it is already running
--> */2 * * * * lua /home/pi/domoticz/scripts/presence.lua -batch >> /var/tmp/presence_check.log
--
--### Start Define all required variables #############################################
ScriptName="presence.lua" -- set to the scriptfilename, used for checking occurences
Domoticz_Server_Url="http://192.168.xx.xx:8080" -- Define Domoticz server URL
-- update LoopLog with latest time. This file can be used to check whether the process is still running with monit
-- Define "" when you don't want to use Monit.
-- Monit definition used:
-- check file Presence with path /var/tmp/presence-monit.log
-- stop program = "/usr/bin/pkill -f presence" timeout 60 seconds
-- if timestamp > 2 minutes then restart
-- if 5 restarts within 5 cycles then timeout
-- Monit_check_log="" -- don't create this extra Monit logfile
Monit_check_log="/var/tmp/presence-monit.log"
--
LoopTime=10 -- recheck Timer used for the phones not detected
-- A phone that is detected with only be checked each 3rd loop
FailTimeout=120 -- Time used to determine the phone is really gone.
debug=0 -- defines the logging level.
-- 0=basic info is logged
-- 1=some extra info
-- 2=all available info used only in case of issues
-- Phone configuration table ---------------------------------------------------------------
-- idx = Domoticz device idx for the switch of the Phone
-- ip = ipaddress to check for the phone. No IP check done when left ""
-- bt = BlueTooth macaddress to check for the phone. No BT check done when left ""
local TelCfgName = {
["Phone1"]={idx=??,ip="192.168.??.??",bt="??:??:??:??:??:??"},
["Phone2"]={idx=??,ip="192.168.??.??",bt="??:??:??:??:??:??"}}
--------------------------------------------------------------------------------------------
local TelCheckVar="" -- User Variable name in Domoticz which can be used to find the last time the phones were checked.
-- Leave empty when not used.
--### End Define all required variables #############################################
-- include is located: /root/usr/local/share/lua/5.2
-- Load necessary Lua libraries
http = require "socket.http";
socket = require "socket";
https = require "ssl.https";
JSON = require "JSON";
--
-- "2" only works when shelled from crontab else use "3" when testing from commandline
-- so ensure that you add the -batch when running it from crontab!
-- check how many scripts are running with this name.
local file = io.popen('ps x | grep "'..ScriptName..'"|grep -cv grep')
local output = file:read('*all')
local rc = {file:close()}
output = string.gsub(output,"\n","") -- remove newline from output
if debug > 1 then
print ('cmd-> ps x | grep "'..ScriptName..'"|grep -cv grep => rc:'..tostring(rc[1])..' output:'..tostring(output))
end
if arg[1] == "-batch" and output == "2" then
print("batch and no=2 so not running yet")
elseif arg[1] == "-debug" then
print("Testing the script from commandline... used for development.")
elseif output == "1" then
print("no=1 so not running yet")
else
print("Already running -> Exit")
os.exit(0)
end
--### Start Define all required LUA functions #############################################
function sleep(n)
os.execute("sleep " .. tonumber(n))
end
-- retrieve status from domoticz
function retrieve_status(idx)
local t, jresponse, status, decoded_response
t = Domoticz_Server_Url.."/json.htm?type=devices&rid="..tostring(idx)
if debug>=2 then
print("JSON request <"..t..">")
end
jresponse, status = http.request(t)
if jresponse ~= nil then
decoded_response = JSON:decode(jresponse)
result = decoded_response["result"]
record = result[1]
status = record["Status"]
else
status = "Failed"
end
if debug>=2 then
print("Status JSON request "..status)
end
return status
end
-- Change state of Switch in Domoticz
function SwitchName(idx,state)
local status
if string.lower(state) == "on" then
state = "On";
elseif string.lower(state) == "off" then
state = "Off";
end
t = Domoticz_Server_Url.."/json.htm?type=command¶m=switchlight&idx="..idx.."&switchcmd="..state;
if debug>=2 then print("JSON request <"..t..">") end
jresponse, status = http.request(t)
if jresponse ~= nil then
result = JSON:decode(jresponse)
status = result["status"]
else
status = "Failed"
end
--
if status ~= "OK" then
print(os.date("%X").." !!!! SwitchName Not OK -> JSON feedback: ", jresponse)
else
if debug>=2 then
print("JSON feedback: ", jresponse)
end
end
return
end
-- Check and update switch in Domoticz
function domo_status(Name,Fail,PrevFail,FailTime,IDX,source,newstatus)
curstate = retrieve_status(IDX)
if debug>=1 then
print(os.date("%X").." "..IDX.." "..Name.." current="..curstate.." New="..newstatus.." from="..source.." fail="..Fail.." prevfail="..PrevFail.. " time="..os.time()-FailTime)
end
-- skip rest of process in case the call to domoticz failed
if curstate == "Failed" then
return
end
if Fail == 1 and curstate == "On" then
print(os.date("%X").." ---- phone failed -> retrying "..Name)
end
if PrevFail > Fail and curstate == "On" then
print(os.date("%X").." ---- phone connected again "..Name.." bron:"..source)
end
if (newstatus == "Off" and os.time()-FailTime >= FailTimeout and curstate ~= newstatus)
or (newstatus == "On" and curstate ~= newstatus) then
print(os.date("%X").." #### Switch phone "..Name.." "..newstatus.." bron:"..source.." ("..Fail..")" )
SwitchName(IDX,newstatus)
end
end
--### End Define all required functions #############################################
--############################################
--# Main loop
--############################################
-- List record to log that are being monitored
for Name in pairs(TelCfgName) do
-- initialise workfields used by the script
TelCfgName[Name].TelFail=0
TelCfgName[Name].TelFailTime=0
TelCfgName[Name].LoopCount=3
curstate = retrieve_status(TelCfgName[Name].idx)
print(os.date("%X").." ---- Starting monitoring for "..Name.." ("..TelCfgName[Name].idx..") CurState="..curstate.." IPaddres="..TelCfgName[Name].ip.." BTmac="..TelCfgName[Name].bt)
end
-- create poll file to check for Monit
if Monit_check_log ~= "" then
os.execute("echo " .. os.date("%Y-%m-%d %H:%M:%S") .. " > " .. Monit_check_log)
end
-- Loop to monitor all devices
while true do
--
timenow = os.time()
if debug>=1 then
print(os.date("%X").." ".."=================================================================")
end
for Name in pairs(TelCfgName) do
-- only check every 3rd time when detected
if TelCfgName[Name].LoopCount < 3 and TelCfgName[Name].TelFail == 0 then
TelCfgName[Name].LoopCount = TelCfgName[Name].LoopCount + 1
else
TelCfgName[Name].LoopCount = 1
-- first try a IP ping as that is the fastest check
PrevFail=TelCfgName[Name].TelFail
if TelCfgName[Name].ip ~= "" then
ping_success=os.execute('ping -c1 -w2 ' .. TelCfgName[Name].ip.." > /dev/null")
else
ping_success=false
end
if ping_success then
TelCfgName[Name].TelFail = 0
TelCfgName[Name].TelFailTime = 0
domo_status(Name,TelCfgName[Name].TelFail,PrevFail,os.time(),TelCfgName[Name].idx,"Ping","On")
else
-- If Ping fails try the BT check with hcitool which is faster and less CPU than l2ping
bt_success=os.execute('hcitool name ' .. TelCfgName[Name].bt..'|grep ".*" > /dev/null')
-- check for characters returned .. if nothing then phone not found
if bt_success==nil then
TelCfgName[Name].TelFail = TelCfgName[Name].TelFail + 1
-- set the failtime at first failure to find phone
if TelCfgName[Name].TelFail == 1 then
TelCfgName[Name].TelFailTime = os.time()
end
domo_status(Name,TelCfgName[Name].TelFail,PrevFail,TelCfgName[Name].TelFailTime,TelCfgName[Name].idx,"Both","Off")
else
TelCfgName[Name].TelFail = 0
TelCfgName[Name].TelFailTime = 0
domo_status(Name,TelCfgName[Name].TelFail,PrevFail,os.time(),TelCfgName[Name].idx,"BT","On")
end
end
end
end
-- update uservariable with the last status check done time.
if TelCheckVar ~= "" then
t = Domoticz_Server_Url..'/json.htm?type=command¶m=updateuservariable&vname=' .. TelCheckVar .. '&vtype=2&vvalue=' .. os.date("%X") .. '';
if debug>=2 then print("JSON request <"..t..">") end
jresponse, status = http.request(t)
if jresponse ~= nil then
result = JSON:decode(jresponse)
status = result["status"]
else
status = "Failed"
end
if status ~= "OK" then
print(os.date("%X").." !!!! Set variable ".. TelCheckVar .." Not OK -> JSON feedback: ", jresponse)
else
if debug>=2 then
print("JSON feedback: ", jresponse)
end
end
end
-- sleep the number of seconds defined in LoopTime
if os.time() - timenow <= LoopTime then
if debug>=1 then
print(os.date("%X").." ".."sleep "..LoopTime-(os.time() - timenow))
end
sleep(LoopTime-(os.time() - timenow))
end
-- update LoopLog with latest time. This file can be used to check whether the process is still running with monit
if Monit_check_log ~= "" then
os.execute("echo " .. os.date("%Y-%m-%d %H:%M:%S") .. " > " .. Monit_check_log)
end
end
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
-
- Posts: 8
- Joined: Friday 30 March 2018 22:51
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: Presence detection based on IP and Bluetooth
Sorry for the slow reply. I can confirm the script is working really well from a cron job. Will happily test your new script out. The rationale behind the comment around whether the frequency of pings etc slows down for both devices was from both a CPU cycle and also mobile battery viewpoint. I.e. if the phone is at home it may adversely affect battery life with the additional pings.
I had a quick question on the bluetooth side of things. I find that the script will find the mobile phone once but then won't see it again after that. I must admit I didn't completely follow the bluetooth config with setting the pin code etc as I could see it was initially seeing the device. Also, I don't know where I would tell the phone that a pin code is required, and what it is set to etc. Is this vital?
Many thanks for a great script!!
I had a quick question on the bluetooth side of things. I find that the script will find the mobile phone once but then won't see it again after that. I must admit I didn't completely follow the bluetooth config with setting the pin code etc as I could see it was initially seeing the device. Also, I don't know where I would tell the phone that a pin code is required, and what it is set to etc. Is this vital?
Many thanks for a great script!!
- jvdz
- Posts: 2266
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Presence detection based on IP and Bluetooth
How do you figure the BT only works one time? do devices start failing after that when the ping doesn't respond?rlg6767 wrote: ↑Tuesday 10 April 2018 22:26 I had a quick question on the bluetooth side of things. I find that the script will find the mobile phone once but then won't see it again after that. I must admit I didn't completely follow the bluetooth config with setting the pin code etc as I could see it was initially seeing the device. Also, I don't know where I would tell the phone that a pin code is required, and what it is set to etc. Is this vital?
The BT test will only be done in case the ping is failing.
As to BT setup process: I simply copied that from the another person's information, followed it and it worked, so never questioned whether all steps are needed.
Jos
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
Who is online
Users browsing this forum: No registered users and 1 guest