Page 1 of 3

Presence detection based on IP and Bluetooth

Posted: Friday 27 October 2017 17:20
by jvdz
On request:
This is a script I run to detect the presence of 2 telephones together with Domoticz. It is ran with crontab and will update 2 dummy On/Off switches representing the Phones being home or not. It is based on an bash script I found earlier in this forum, converted to LUA and adapted to support multiple phones and using for bluetooth the command "hcitool name" in stead of l2ping as that used much more CPU and took longer.

Below the LUA script and the configuration documentation and prerequisites are included it the header.
Let me know when there are questions. :-)

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

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)
	decoded_response = JSON:decode(jresponse)
	result = decoded_response["result"]
	record = result[1]
	status = record["Status"]
	if debug>=2 then
		print("Status JSON request "..status)
	end
	return status
end
-- 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&param=switchlight&idx="..idx.."&switchcmd="..state;
	if debug>=2 then print("JSON request <"..t..">") end
	jresponse, status = http.request(t)
	result = JSON:decode(jresponse)
	status = result["status"]
	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

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
	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&param=updateuservariable&vname=' .. TelCheckVar .. '&vtype=2&vvalue=' .. os.date("%X") .. '';
		if debug>=2 then print("JSON request <"..t..">") end
		jresponse, status = http.request(t)
		result = JSON:decode(jresponse)
		status = result["status"]
		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

Re: Presence detection based on IP and Bluetooth

Posted: Friday 27 October 2017 18:20
by manjh
I copied the code into a time-driven LUA, went through the header and defined 1 phone with MAC and IP.
Also installed and unzipped the libs in the Pi.
When I run the LUA, this error comes up:

Code: Select all

2017-10-27 18:17:00.573 dzVents: cmd-> ps x | grep "presence.lua"|grep -cv grep => rc:nil output:0
2017-10-27 18:17:00.573 Error: EventSystem: in Presence_test: [string "-- ==========================================..."]:104: attempt to index global 'arg' (a nil value)
this is the complete LUA:

Code: Select all

-- ==============================================================================================
-- Presence detection script using both fixed IP and BlueTooth to ensure proper detection
-- ==============================================================================================

print ("@@@@@@@@@@@@@@@@@@@@@@@@@@@@ start test routine")

-- -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
--
-- require some LUA libraries: SOCKET.HTTP/SOCKET/JSON/ssl.https
-- includes are located in: \\DOMOTICZPI\root\usr\local\share\lua\5.2
-- copy & instructions can be found here: https://www.domoticz.com/wiki/Remote_Control_of_Domoticz_by_Telegram_Bot#Installing_Lua_Libraries
-- 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://10.0.0.199: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] = "Xiaomi Redmi Hans"
TelIP[Rec] = "10.0.0.12"
TelBT[Rec] = "C4:0B:CB:49:5A:88"
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

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)
	decoded_response = JSON:decode(jresponse)
	result = decoded_response["result"]
	record = result[1]
	status = record["Status"]
	if debug>=2 then
		print("Status JSON request "..status)
	end
	return status
end
-- 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&param=switchlight&idx="..idx.."&switchcmd="..state;
	if debug>=2 then print("JSON request <"..t..">") end
	jresponse, status = http.request(t)
	result = JSON:decode(jresponse)
	status = result["status"]
	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

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
	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&param=updateuservariable&vname=' .. TelCheckVar .. '&vtype=2&vvalue=' .. os.date("%X") .. '';
		if debug>=2 then print("JSON request <"..t..">") end
		jresponse, status = http.request(t)
		result = JSON:decode(jresponse)
		status = result["status"]
		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

Re: Presence detection based on IP and Bluetooth

Posted: Friday 27 October 2017 18:33
by jvdz
You can't run this with the domoticz event systems as the script stays active!
This type of functionality doesn't belong in the event system of Domoticz as that is a single threaded system so will wait for the process to end.
Just follow the instructions as provided. ;)

Jos

Re: Presence detection based on IP and Bluetooth

Posted: Friday 27 October 2017 18:51
by manjh
jvdz wrote: Friday 27 October 2017 18:33 You can't run this with the domoticz event systems as the script stays active!
This type of functionality doesn't belong in the event system of Domoticz as that is a single threaded system so will wait for the process to end.
Just follow the instructions as provided. ;)

Jos
Sorry Jos, I am trying to behave as a simple shortsighted user who does not read instructions properly. (Not a big effort for me...)
I'm sure it is my mistake, but perhaps it would be better to split things up. Create a Wiki page, give some text and then in a code block the commands to execute. All the way down.
The way it is now, the instructions are hidden in the code.
Also, I was convinced this was a LUA script... so I expected that it would run in the Domoticz LUA environment.

Re: Presence detection based on IP and Bluetooth

Posted: Friday 27 October 2017 18:56
by jvdz
Hans,
Understand, but simply start at the top of the script header and work your way down through the steps.
Make sure you work your way down all the way so you have also updates all required variables.
Ask when you come across something that isn't clear.
I am not best Wiki writer and honestly don't see a real difference having the Doc's in the Script or in a Wiki other that a Wiki makes it easier to find the scripts in the first place, which is the step you already have taken. ;)

Cheers,
Jos

Re: Presence detection based on IP and Bluetooth

Posted: Friday 27 October 2017 19:26
by manjh
OK, I will start over and let you know.

The essential difference of a Wiki is that it offers a very clear split between explaining text, and commands to be executed.
When you combine it into one file it becomes fuzzy.
It's Ok for documenting code ("self explaining code"), but when it comes to guiding an inexperienced user it is a different matter.
An example:
-- 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
Instead of "Find the proper directory" I would suggest to show the command how to do this.
Also, that last line is unclear. I managed my way through this, but it required some doing....

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 16:00
by Mace
Looks like a great solution! Have to agree with manjh, that it is rather difficult to read between the code what to do. Maybe for advanced users this is readable, but I'm getting lost already by the fact that I don't know where to put the presence file....

I CAN see that it has a lot of potential, but could really use a better instruction. Maybe someone who does understand the script can write down all the necessary steps when installing it.

I am also willing to work with you in getting this into a clear Wiki. Be prepared for a whole lot of questions, though! ;) Let me know...

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 16:14
by manjh
I tried but decided to roll back for the short term. Also tried the presence detection as it is described in the Wiki.
Result was that my Pi started to reboot frequently,with minutes interval.
I removed the cron entry and restarted, now it is stable.
But Domoticz still suffered somehow.
In the log, I see:

Code: Select all

2017-10-28 16:10:44.342 Domoticz V3.8153 (c)2012-2017 GizMoCuz
2017-10-28 16:10:44.342 Build Hash: 494fff7, Date: 2017-07-30 12:19:41
2017-10-28 16:10:44.343 Startup Path: /home/pi/domoticz/
2017-10-28 16:10:45.174 Sunrise: 08:29:00 SunSet:18:17:00
2017-10-28 16:10:45.175 EventSystem: reset all events...
2017-10-28 16:10:45.331 PluginSystem: Started, Python version '3.4.2'.
2017-10-28 16:10:45.349 Active notification Subsystems: email, nma (2/12)
2017-10-28 16:10:45.352 WebServer(HTTP) started on address: :: with port 8080
2017-10-28 16:10:45.364 WebServer(SSL) started on address: :: with port 443
2017-10-28 16:10:45.367 Proxymanager started.
2017-10-28 16:10:45.416 Starting shared server on: :::6144
2017-10-28 16:10:45.416 TCPServer: shared server started...
2017-10-28 16:10:45.416 RxQueue: queue worker started...
2017-10-28 16:10:47.417 Hardware Monitor: Started
2017-10-28 16:10:47.567 EventSystem: reset all events...
2017-10-28 16:10:47.569 EventSystem: reset all device statuses...
2017-10-28 16:10:47.679 PluginSystem: Entering work loop.
2017-10-28 16:10:48.001 Python EventSystem: Module not found - Trying to initialize.
2017-10-28 16:10:48.004 Python EventSystem: Initalizing event module.
2017-10-28 16:10:48.005 EventSystem: Started
What is wrong here? It boots with 5 minute intervals!

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 17:29
by jvdz
Mace wrote: Saturday 28 October 2017 16:00 I am also willing to work with you in getting this into a clear Wiki. Be prepared for a whole lot of questions, though! ;) Let me know...
I am fine with question. ;)
We can also do this in PM if that's easier and even in Dutch will work.
I do understand that this is a little more technical, but that is expected as that is what domotica is about when participating in a project like this and honestly is part of the fun for me. :)

Jos

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 17:33
by jvdz
manjh wrote: Saturday 28 October 2017 16:14 I tried but decided to roll back for the short term.
-snip-
What is wrong here?
I don't see how this topic could screw up your raspberry like you described and there should not be anything in the crontab until it manually works.
Looking at your log file I really do not see anything wrong there. All warnings are expected in the current production version.

Just take it one step at the time with this script and start with making the BT part working with manual commands as described. Was that working for you?

Jos

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 18:14
by manjh
jvdz wrote: Saturday 28 October 2017 17:33
manjh wrote: Saturday 28 October 2017 16:14 I tried but decided to roll back for the short term.
-snip-
What is wrong here?
I don't see how this topic could screw up your raspberry like you described and there should not be anything in the crontab until it manually works.
Looking at your log file I really do not see anything wrong there. All warnings are expected in the current production version.

Just take it one step at the time with this script and start with making the BT part working with manual commands as described. Was that working for you?

Jos
It was. I could see the dummy device being updated, so all looked well. Unfortunately as side effect the Pi rebooted! This has never happened before, so it must have been caused by something I did or installed.
So I removed the two lines in the crontab that I put in, also removed the files in the scripts directory. Even rebooted the Pi manually just to make sure.
This helped a bit, the Pi does not reboot any longer.
But now Domoticz restarts at five minute intervals. I will try to see if there are any other clues.
Is there a log somewhere, besides the log that I can see on the Domoticz server?

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 18:19
by manjh
forgot to mention, I went back to the method I used before: a simple ping. Added a few params, I'll have to see if that works. Problem I had was that the script would sometimes overrun the 10 sec limit in Domoticz.
This is the statement:

Code: Select all

ping_success = os.execute('ping -c 1 -W 1 ' .. IPArray[i]  )
A related problem that I have, is that I can't get the Wifi on my Android phone to stay on during sleep mode.
I went into Wifi-->advanced and set the "keep always on" flag, but it doesn't help
Also tried several apps that claim they will keep it on: no such luck.
Any hints?

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 18:52
by jvdz
manjh wrote: Saturday 28 October 2017 18:19 Problem I had was that the script would sometimes overrun the 10 sec limit in Domoticz.
Any hints?
Thought we covered that topic earlier not to put this in any script in the event system?
The script I posted can only function as standalone setup.
Still don't understand how this script could crash Domoticz as it does a standard JSON call to set switches.
You will have to start sharing some information with me when you want any help for making this script to work, like LOG file etc.
Other scripts/Setups are out of scope for this topic.

Jos

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 18:57
by manjh
jvdz wrote: Saturday 28 October 2017 18:52
manjh wrote: Saturday 28 October 2017 18:19 Problem I had was that the script would sometimes overrun the 10 sec limit in Domoticz.
Any hints?
Thought we covered that topic earlier not to put this in any script in the event system?
The script I posted can only function as standalone setup.
Still don't understand how this script could crash Domoticz as it does a standard JSON call to set switches.
You will have to start sharing some information with me when you want any help for making this script to work, like LOG file etc.
Other scripts/Setups are out of scope for this topic.

Jos
Jos,
we're talking different LUA scripts here. My script simply does an OS call to execute a ping. I suspect that this would overrun the limit when a device is not live. I now added the -W param to make sure it kills the wait before that time.
I was not referring to your script, I understand it cannot run in the Domoticz LUA environment but needs to be a script in the Pi...

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 19:37
by jvdz
Hans,

I guess I confused you a little... Agree my script totally unable to run in the event system as it stays alive until it fails, but I am also of the opinion you never should run these type of blocking scripts in the event system as they could take seconds to process and during that time no other events can be processed. Any other event will be queued until the script is done, which means it could become sluggish in responding to events at times.

Jos

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 20:02
by manjh
jvdz wrote: Saturday 28 October 2017 19:37 Hans,

I guess I confused you a little... Agree my script totally unable to run in the event system as it stays alive until it fails, but I am also of the opinion you never should run these type of blocking scripts in the event system as they could take seconds to process and during that time no other events can be processed. Any other event will be queued until the script is done, which means it could become sluggish in responding to events at times.

Jos
yup, agreed....

Re: Presence detection based on IP and Bluetooth

Posted: Saturday 28 October 2017 20:56
by manjh
Well, the rebooting of Domoticz seems to have "gone away". I saw it happening clockwork perfect every five minutes, but at some point the problem disappeared and the system has been stable now for several hours.

I hate it when this happens, a problem that "goes away" by itself may decide to come back in the future.... but for now I'm happy. :(

Re: Presence detection based on IP and Bluetooth

Posted: Sunday 29 October 2017 10:45
by manjh
I guess I cheered too soon: the problem has not disappeared! Domoticz still reboots, although not as frequent. :shock:
Is there any other source of information, beside the log on the webpage?

Re: Presence detection based on IP and Bluetooth

Posted: Monday 30 October 2017 22:01
by manjh
manjh wrote: Sunday 29 October 2017 10:45 I guess I cheered too soon: the problem has not disappeared! Domoticz still reboots, although not as frequent. :shock:
Is there any other source of information, beside the log on the webpage?
We'll never know what the cause was. I decided to bite the bullet: saved the Domoticz backups, restored the last backup that I knew was working well, restarted the Pi and restored the Domoticz database.
Everything is now working OK again.

Re: Presence detection based on IP and Bluetooth

Posted: Tuesday 31 October 2017 12:52
by havnegata
jvdz wrote: Friday 27 October 2017 17:20 On request:
This is a script I run to detect the presence of 2 telephones together with Domoticz. It is ran with crontab and will update 2 dummy On/Off switches representing the Phones being home or not. It is based on an bash script I found earlier in this forum, converted to LUA and adapted to support multiple phones and using for bluetooth the command "hcitool name" in stead of l2ping as that used much more CPU and took longer.

Below the LUA script and the configuration documentation and prerequisites are included it the header.
Let me know when there are questions. :-)

Jos
Hello Jos! I've gotten as far as "-- Test device by doing: hcitool name <MAC>" Then I'm writing "hcitool Galaxy S8+ <MAC>" (without the quotes)
Then I get: -bash: syntax error near unexpected token `newline'

Edit: this is working: hcitool name 58:C5:CB:0D:D1:58 (it returns Galaxy S8+) Moving forward :-)