Using Fing as a new way to detect smartphone presence

Plugins that users have built. NOTE: plugins that were developed for Indigo versions older than 2022.1 will have to be updated to work with Indigo 2022.1 (Python 3 - see this blog post for details). If the plugin listed here is not in the Plugin Store (which will show updated plugins) then you will need to ask on the appropriate thread below if it has been updated and where you get get the update.
gcoop76
Posts: 2
Joined: Wed Sep 11, 2013 10:00 am

Re: Using Fing as a new way to detect smartphone presence

Post by gcoop76 »

This is great. The problem I have with SPR is that I have several access points. One is a time capsule/airport and the other is a linksys.

I have a suggestion. To get around having to put your password into the file, you can edit the /etc/sudoers file and allow Fing to run from sudo without a password prompt.

Code: Select all

sudo visudo
add this line:

Code: Select all

spanky localhost = NOPASSWD: /usr/bin/fing
That is, if "spanky" is your username (the one who will be executing the applescript and calling fing).

Note that this edits the file in "vi." Use the arrow keys or "j" or "k" to move up and down. Go to the line you want to add the above text and hit "i" for insert. Type or paste it out, then hit "esc." Then hit ":" then type "wq" for "write, then quit"

That should do it. It is important to use visudo to edit your sudoers file since apparently bad things can happen to the permissions of the file if you edit it directly. I just tested it on my Mac OS X Mountain Lion laptop. Works well. Everything else still needs a password for sudo, but not fing.
User avatar
kw123
Posts: 8705
Joined: Sun May 12, 2013 4:44 pm
Location: Dallas, TX
Contact:

Re: Using Fing as a new way to detect smartphone presence

Post by kw123 »

added 4 password options (set passwordOption to 1 or 2 or 3 in code)
-- 0. set password in code
-- 1. ask for password in dialog box -- enter password
-- 2. use keychain to get password -- have to click "allow"
-- 3. sudo without password, works only if fing has been enabled to run without password, see option 3 in code what to do to enable. thanks to "gcoop76"

response time until indigo variable get updated is now: ~ 6 secs for new devices or devices that awake before indigo variable gets updated. -- still 65 sec for devices that go to sleep.
==> checking ling logfile for any changes, logfile gets updated if a devices contacts network (fing is listening to the traffic)


tried to put fing output into indigo sub directory. but is seems that fing does not like spaces in path
tried with ", ' , \" etc creates a error message from fing that input is wrong.

if I don't get any bug reports, next version will be 1.0


Karl



uploaded wrong file.. please use this one.

Code: Select all

-- fingscan.app
-- build list of network devices using FING
-- runs in background, iddles for 5 secs then checks if FING has found new configs
-- creates variables with ipdevice info
-- 
--
-- Karl Wachs
-- Sep 12 2013
-- V 0.97
-- 0.81 one code fix, if IP number change: wrong quotes for variable
-- 0.82 added comments, clearer code,  and reset logfile once a day
-- 0.9  added check logfile for any change, if no chang skip checks, faster reaction, and less code excution,  most of the time nothing changes. this will only check size of  file "finglog"  
-- 0.95 check for change in fingdata file. if time stamp changed get all data and update indigo (1/minute)
--  adding a device results in an update of indigo within 6 secs, detection of disconnecting a debvice takes up to 65 secs.  connecting sends traffic, disconnecting in most cases no, have to wait until next ping cycle (1/minute)
-- 0.97 added 4 password options (set passWordOption to  0 or 1 or 2 or 3  see code for details
--
--
-- how to install:
--  copy this script into applescript editor, save into .../indigo 6/scripts/attachments
-- export into …/indigo 6/scripts/attachments  as APP with "stay open after run handler.."
-- then start fingscan using finder (doubleclick on fingscan.app in indigo 6/scripts/attachments
--
--  use in indigo as trigger:
--  setup trigger "IPdevice22 down"
--		trigger if any change to ipDevice22
--		condition ipDevice22 must contain ";down"   down (without ; )probably also works, but you might have a device's name up or down or vendor's name may contain string up or down
-- 		action: whatever you like
--
-- what it does:
-- starts fing if not active
-- deletes data and log file before first start, creates file fingdata and finlog in ~/Documnets/
-- will ask for approval to use keychain for sudofing command
-- will run every 5 seconds and check finglog file size, if changed check fingdata file for new info
-- will create/ update varibales ipDevicenn  nn = 01 .. 99
-- will update ipDeviceLastUpdate with last date/time of last run
-- will ask for each new MAC address to assign nickname
-- ipDevicenn will contain eg    powerONoff;00:04:A3:AD:A5:CB;192.168.1.81;Microchip Technology;up
-- withh powerONoff = nickname, then macaddress, ip, vendor, up/downinfo, date of last change if any
--
-- fing will stay active and will create log file and data file.  log file will continuously increase.  finglog file is checked for changed file size, fingdata file is analzed by this script
-- regular read seems to conflict with fing, we use cat with pipe into applescript variable.
--
-- needs to be fixed: 
-- does not allow non consequtive ipDevice03 ..05     eg 04 missing .. deleted variable
-- tried to put fing output files into indigo directory, but fing does not like spaces in directories, so i put the outputfiles into User/yourid/Documents/fing/ fingdata and finglog
--
--
-- added 4 password options
-- 0.  set password in code
-- 1. ask for password in dialog box
-- 2. use keychain to get password
-- 3. sudo without password works only o=if fing has been enabled to run without password, see option 3 in code what to do.
--  uses ~ 0.1-1% of one cpu  (mostly 0.1%)


on quit -- enable quit
	continue quit
end quit

on run -- this is done only once at time of "open"
	global debug
	global theDir
	global userName
	global theFile
	global theLog
	global lastLogFilesize
	global logFilesize
	global noOfDevices
	global FingContents
	global noOfIndigoDevices
	global IndigoIpDevices
	global lastUpdate
	global passwordOption
	global yourPassword
	set yourPassword to "" -- use this if paaswordOption = 0
	set passwordOption to 3 --  0= set password in code,  1= use keychain to get password, 2 = enabel fing to not require password, 3 = enter password when running
	set userName to short user name of (system info)
	set theDir to "/Users/" & userName & "/Documents/fing/"
	set theFile to "fingdata"
	set theLog to "finglog"
	set lastLogFilesize to 0
	set logFilesize to 0
	set newDevice to 0
	set lastUpdate to ""
	
	-- init if needed
	setupFing()
	
	-- send to idle
	idle
	
	-- finish main pgm from now on on idle takes over
end run


on idle -- every 30 seconds this gets executed
	
	global theDir
	global userName
	global theFile
	global theLog
	global lastLogFilesize
	global logFilesize
	global newDevice
	global noOfDevices
	global FingContents
	global noOfIndigoDevices
	global IndigoIpDevices
	global lastUpdate
	
	
	set noOfLines to 0
	set AppleScript's text item delimiters to {";"}
	
	-- update indigo with time stamp
	set theTime to text -8 thru -1 of ((current date) as «class isot» as string)
	
	
	-- check file size of logfile, if its larger than last time, new data
	set cmd to "ls -l " & theDir & theLog & "| awk '{print $5}'"
	set logFilesize to do shell script cmd
	if logFilesize > lastLogFilesize then -- there must be a new entry in finglog
		
		-- read latest fingdata log file (just last line)
		getFingIPlogdata()
		
		if noOfDevices < 1 then -- read not successful .. must be more than 0 devices changed on network
			set lastLogFilesize to logFilesize
		else -- yes there is really new data to use:
			-- use last line of FINGlog for new information
			set nextLine to paragraph 1 of FingContents
			set theItems to every text item of nextLine
			set theLOGIPNumber to item 3 of theItems as text
			set theLOGStatus to item 2 of theItems as text
			set theLOGDate to item 1 of theItems as text
			set theLOGmacAddress to item 6 of theItems as text
			set theLOGVendor to item 7 of theItems as text
			
			-- get all devices stored in indigo  into IndigoIpDevices, same format as from FING
			getIndigoIPDEvices()
			-- compare to indogo info
			set newDevice to 0
			compareToIndigo(theLOGmacAddress, theLOGIPNumber, theLOGVendor, theLOGStatus, theLOGDate)
		end if
		
	end if
	
	-- check if fingdata was updated (once a minute)
	set cmd to "ls -l " & theDir & theFile & "| awk '{print $8}'" -- time stamp of last change of file
	set thisUpdate to do shell script cmd
	
	if not (thisUpdate = lastUpdate) then -- updated  FINGdata file
		set lastUpdate to thisUpdate -- remember this time stamp
		
		-- read latest fingdata file	
		getFingIPData()
		if noOfDevices > 1 then -- read not successful .. must be more than 1 devices on network
			-- get all devices stored in indigo  into IndigoIpDevices, same format as from FING
			set newDevice to 0
			getIndigoIPDEvices()
			
			-- all data read now compare if anything new
			set ii to 0
			-- loop through FING data
			repeat while ii < noOfDevices
				set ii to ii + 1
				set nextLine to paragraph (ii) of FingContents
				set theItems to every text item of nextLine
				
				set themacAddress to item 6 of theItems as text
				if not (themacAddress = theLOGmacAddress) then
					set theIPNumber to item 1 of theItems as text
					set theStatus to item 3 of theItems as text
					set theDate to item 4 of theItems as text
					set theVendor to item 7 of theItems as text
					-- 			set theAssignedName to item 5 of theItems as text  -- not used
					--			set theHostName to item 2 of theItems as text -- not used
					
					compareToIndigo(themacAddress, theIPNumber, theVendor, theStatus, theDate)
				end if
			end repeat
			
			set theTime to text -8 thru -1 of ((current date) as «class isot» as string)
		end if
	end if
	
	-- house keeping, update ipDeviceLastUpdate and reset logfile once a day
	-- update indigo with time stamp
	try -- just in case indigo is down, dont crash this program
		tell application "IndigoServer"
			set the value of variable "ipDevsLastUpdate" to theTime
		end tell
	end try
	
	return 5 -- idle for 5 seconds
	
end idle



on setupFing()
	global theDir
	global theFile
	global theLog
	global userName
	global theIndigoFolder
	global passwordOption
	global yourPassword
	
	--check if fing is already running, if not start it.
	set theApp to "fing.bin"
	set theResponse to " "
	
	
	
	
	-- find indigo folder  (copied from Nathan Sheldon etrack.app)
	set theIndigoFolder to ""
	tell application "Finder"
		-- Verify one of the supported Indigo versions exists.
		set ii to 20
		repeat while ii > 1
			set theFolder to "/Library/Application Support/Perceptive Automation/Indigo " & ii & "/IndigoServer.app"
			if exists theFolder as POSIX file then
				set theIndigoFolder to "/Library/Application Support/Perceptive Automation/Indigo " & ii & "/"
				set ii to 0
			end if
			set ii to ii - 1
		end repeat
	end tell
	
	-- fing dos not handle space in directy names
	--	set theDir to theIndigoFolder & "Scripts/Attachments/fingdata/"
	
	-- create fing directory in attachment folder	
	set cmd to "mkdir '" & theDir & "'  >/dev/null  2>&1 & "
	do shell script cmd
	
	-- check if fing.bin is running	
	try
		set theResponse to do shell script "ps aux | grep '" & theApp & "' | awk '{print $2}' "
	end try
	
	-- if pgmToFind is running then theResponse has 3 lines with PIDs from :     ps, fing itself and one more --- have not figured out which one..
	set ii to count words of theResponse
	
	if ii < 3 then -- if not running start script, start fing
		
		
		-- option 0:  	 set thePassword in code
		-- start fing, send to background, dont wait, creat 2 output files:  one table format file and one logfile
		if passwordOption = 0 then
			set cmd to "echo " & yourPassword & " | sudo -S fing  -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &"
			set yourPassword to ""
		end if
		
		-- option 1:  	 have to use sudo: pipe password from getPW() into sudo
		
		-- start fing, send to background, dont wait, creat 2 output files:  one table format file and one logfile
		if passwordOption = 1 then
			set yourPassword to getPW(userName) -- this has to be looked at, grabs first occurence of userName, if 2 with same username and different passwords this might fail
			set cmd to "echo " & yourPassword & " | sudo -S fing  -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &"
			set yourPassword to ""
		end if
		
		
		-- option 2:  modify system setting so that fing does not need sudo from gcoop76 indido discussions
		(*

sudo visudo

add this line:
CODE: SELECT ALL
spanky localhost = NOPASSWD: /usr/bin/fing
That is, if "spanky" is your username (the one who will be executing the applescript and calling fing).

Note that this edits the file in "vi." Use the arrow keys or "j" or "k" to move up and down. Go to the line you want to add the above text and hit "i" for insert. Type or paste it out, then hit "esc." Then hit ":" then type "wq" for "write, then quit"

That should do it. It is important to use visudo to edit your sudoers file since apparently bad things can happen to the permissions of the file if you edit it directly. I just tested it on my Mac OS X Mountain Lion laptop. Works well. Everything else still needs a password for sudo, but not fing.
*)
		if passwordOption = 2 then
			set cmd to " sudo fing -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &"
			set yourPassword to ""
		end if
		
		--option 3  user will need to enter password		
		if passwordOption = 3 then
			
			tell application "Finder" -- need to go through finder in case this runs in the background
				set yourPassword to the text returned of (display dialog "enter your password" default answer "xxyyzz" giving up after 200)
			end tell
			set cmd to "echo " & yourPassword & " | sudo -S fing -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &"
		end if
		
		
		-- execute option 1,2,3		
		do shell script cmd
		
		delay 10 --wait until FING has finished at least once
		
	end if
	-- fing is running or has started
	
	
	try -- just in case indigo is down, dont crash this program
		set theTime to text -8 thru -1 of ((current date) as «class isot» as string)
		tell application "IndigoServer"
			if not ((exists variable "ipDevsLastUpdate")) then
				make new variable with properties {name:"ipDevsLastUpdate", value:theTime}
			end if
		end tell
	end try
	
	
	return
	
end setupFing


on getIndigoIPDEvices()
	
	global noOfIndigoDevices
	global IndigoIpDevices
	
	-- get all devices stored in indigo  into IndigoIpDevices, same format as from FING
	set AppleScript's text item delimiters to {";"}
	set ii to 0
	set noOfIndigoIpDevices to "0"
	set IndigoIpDevices to {}
	
	set noMore to false
	repeat while ii < 999
		set ii to ii + 1
		set OOii to ii
		if ii < 10 then set OOii to "0" & ii as text
		set ipDevice to "ipDevice" & OOii
		tell application "IndigoServer"
			if not ((exists variable ipDevice)) then
				set noMore to true
				set noOfIndigoDevices to ii - 1
				set ii to 99999
			end if
		end tell
		if noMore = false then
			try -- just in case indigo is down, dont crash this program
				tell application "IndigoServer"
					set ipDeviceValue to (get value of variable ipDevice) as text
				end tell
			end try
			set IndigoIpDevices to IndigoIpDevices & ipDeviceValue
		end if
	end repeat
	return
end getIndigoIPDEvices


on compareToIndigo(themacAddress, theIPNumber, theVendor, theStatus, theDate)
	global noOfIndigoDevices
	global IndigoIpDevices
	global newDevice
	
	
	
	-- then check if any match in indigo data
	set sameMAC to 0
	set jj to 0
	repeat while jj < noOfIndigoDevices
		set jj to jj + 1
		set nextLineIndigo to item jj of IndigoIpDevices as text
		set theIndigoItems to every text item of nextLineIndigo
		set indigomacAddress to trim(item 2 of theIndigoItems as text)
		if themacAddress = indigomacAddress then ---- mac number found, already in indigo… exit loop
			set sameMAC to jj -- this is the device thats the same
			set jj to 999999 -- force loop exit
			set indigoIPNumber to trim(item 3 of theIndigoItems as text) -- get the indigo info for later use
			set indigoStatus to trim(item 5 of theIndigoItems as text)
			set indigoVendor to trim(item 4 of theIndigoItems as text)
			set indigoNick to trim(item 1 of theIndigoItems as text)
		end if
	end repeat
	
	
	if sameMAC > 0 then -- found match in MAC number, now check if anything has changed
		
		-- check if the device that was indicated by the logfile is this one:  then reset to normal search
		
		if (theIPNumber = indigoIPNumber) and (theStatus = indigoStatus) then -- both the same 
			-- do nothing
		else -- ip or status has changed, update indigo variable
			-- check if the device taht was indicated by the logfile is this one:  then reset to normal search
			set OOii to sameMAC
			if sameMAC < 10 then set OOii to "0" & sameMAC as text -- make sequential number 2 digits
			set theDeviceNo to "ipDevice" & OOii
			set theDeviceValue to indigoNick & ";" & themacAddress & ";" & theIPNumber & ";" & theVendor & ";" & theStatus & ";" & theDate
			try -- just in case indigo is down, dont crash this program
				tell application "IndigoServer"
					set the value of variable theDeviceNo to theDeviceValue
				end tell
			end try
			
		end if
		
	else -- new device, set up 	in indigo
		set newDevice to newDevice + 1
		set OOii to noOfIndigoDevices + newDevice
		if OOii < 10 then set OOii to "0" & ii as text -- make sequential number 2 digits
		set theDeviceName to "ipDevice" & OOii
		
		set theText to "FINGSCAN network has found new device,  please enter nickname for new device : " & theDeviceName & "  " & themacAddress & "  " & theIPNumber & "  " & theVendor & "  " & theStatus & "   eg:"
		
		tell application "Finder" -- need to go through finder in case this runs in the background
			set nickname to the text returned of (display dialog theText default answer "phone-xyz" giving up after 60)
		end tell
		
		set theDeviceValue to nickname & ";" & themacAddress & ";" & theIPNumber & ";" & theVendor & ";" & theStatus & ";" & theDate
		try -- just in case indigo is down, dont crash this program
			tell application "IndigoServer"
				make new variable with properties {name:theDeviceName, value:theDeviceValue}
			end tell
		end try
	end if
end compareToIndigo


on getFingIPData()
	
	global noOfDevices
	global FingContents
	global theDir
	global theFile
	set FingContents to {}
	
	-- read latest fingdata file	
	set cmd to "cat " & theDir & theFile
	try
		set FingContents to (do shell script cmd)
		set noOfDevices to (count paragraphs of FingContents)
	end try
	
	return
	
end getFingIPData


on getFingIPlogdata()
	
	global noOfDevices
	global FingContents
	global theDir
	global theFile
	global theLog
	set FingContents to {}
	
	set cmd to "tail -1 " & theDir & theLog -- just get the last line
	try
		set FingContents to (do shell script cmd)
		set noOfDevices to (count paragraphs of FingContents)
	end try
	
end getFingIPlogdata


on getPW(keychainItemName) -- get password from keychain for userid: keychainitemname
	do shell script "security 2>&1 >/dev/null find-generic-password -gl " & quoted form of keychainItemName & " | awk '{print $2}'"
	return (text 2 thru -2 of result) -- return the password part of the string
end getPW


-- trim blanks from string
on trim(someText)
	if someText = "" then return someText
	if someText = " " then return ""
	
	repeat until someText does not start with " "
		set someText to text 2 thru -1 of someText
	end repeat
	
	repeat until someText does not end with " "
		set someText to text 1 thru -2 of someText
	end repeat
	
	return someText
end trim

jrickmd
Posts: 109
Joined: Sun Jun 01, 2003 3:21 pm
Location: Texas

Re: Using Fing as a new way to detect smartphone presence

Post by jrickmd »

kw123 wrote: if I don't get any bug reports, next version will be 1.0
Interested in getting this working. Installed fing and think I followed all the instructions. Have an ipDevsLastUpdate variable that is updated continuously. Tested fing in terminal and it appears to be working correctly based on a simple 'sudo fing' call. Don't see anything else happening... Tried to manually change things in the script to get it working by making the passwordOption = 1 and manually setting 'yourPassword' to my password. Still no joy. What can I do to figure this out?

Thanks,

Rick
Rick
User avatar
kw123
Posts: 8705
Joined: Sun May 12, 2013 4:44 pm
Location: Dallas, TX
Contact:

Re: Using Fing as a new way to detect smartphone presence

Post by kw123 »

if you started fing outside this app, the output files are not set correctly.

try: system monitor, kill fing and fingscan

then "open" fingscan.app (double-click)

if timestamp is updated that means fingscan runs. looks like it does not ready any data from fing.

could you check if you find the files
fingdata
finglog

In the latest version they should be in /Users/yourid/Documents/fing/
open them with text edit or in terminal do cat /Users/yourid/Documents/fing/fingdata and .. finglog
and check if they have any data
should look like:
log:
..
2013/09/11 15:27:18;up;192.168.1.74;;;F0:7D:68:08:5F:D0;D-Link
2013/09/11 15:27:18;up;192.168.1.71;;;F0:7D:68:06:F6:87;D-Link
2013/09/11 15:27:21;up;192.168.1.139;;;D8:A2:5E:63:7D:DF;Apple
2013/09/11 15:27:53;up;192.168.1.52;;;00:1F:5B:30:E9:21;Apple
2013/09/11 15:27:53;up;192.168.1.1;;;00:1E:E5:FA:4E:E4;Cisco-Linksys
..
and fingdata similar, but other sequence (don't know why they had to make that different )


let me know how it goes, or send me an email with your phone # to [email protected] and I can walk you through

Karl
jrickmd
Posts: 109
Joined: Sun Jun 01, 2003 3:21 pm
Location: Texas

Re: Using Fing as a new way to detect smartphone presence

Post by jrickmd »

kw123 wrote:if you started fing outside this app, the output files are not set correctly.

try: system monitor, kill fing and fingscan

then "open" fingscan.app (double-click)

if timestamp is updated that means fingscan runs. looks like it does not ready any data from fing.
Had 2 fing.app running. Ran into a problem with this line:

Code: Select all

		if OOii < 10 then set OOii to "0" & ii as text -- make sequential number 2 digits
& ii needs to be changed to OOii

Will keep you up to date as I continue to hack at it tonight.

Thanks for much for this contribution! Looks awesome so far.

Rick
Rick
User avatar
kw123
Posts: 8705
Joined: Sun May 12, 2013 4:44 pm
Location: Dallas, TX
Contact:

Re: Using Fing as a new way to detect smartphone presence

Post by kw123 »

yes .. that was for new devices.. I had all devices loaded, did not run into that section anymore.

thanks for catching it.
User avatar
kw123
Posts: 8705
Joined: Sun May 12, 2013 4:44 pm
Location: Dallas, TX
Contact:

Re: Using Fing as a new way to detect smartphone presence

Post by kw123 »

-one fix for variable OOii,
-fixed some logic, added heat beat variable
-- added count of status changes up / down for each device


this is my last change ! ;-)

Karl
v 0.980

Code: Select all

-- fingscan.app
-- build list of network devices using FING
-- runs in background, iddles for 5 secs then checks if FING has found new configs
-- creates variables with ipdevice info
-- 
--
-- Karl Wachs
-- Sep 12 2013
-- V 0.98
-- 0.81 one code fix, if IP number change: wrong quotes for variable
-- 0.82 added comments, clearer code,  and reset logfile once a day
-- 0.9  added check logfile for any change, if no chang skip checks, faster reaction, and less code excution,  most of the time nothing changes. this will only check size of  file "finglog"  
-- 0.95 check for change in fingdata file. if time stamp changed get all data and update indigo (1/minute)
--  adding a device results in an update of indigo within 6 secs, detection of disconnecting a debvice takes up to 65 secs.  connecting sends traffic, disconnecting in most cases no, have to wait until next ping cycle (1/minute)
-- 0.97 add 4 password options (set passWordOption to 0 or 1 or 2 or 3  see code for details
-- 0.971 OOI varibale fix, 
-- 0.973 set lastLogFilesize to logFilesize was at the wrong place, 
-- bad logic with logMACaddress fixed  (was old code from old logic)
-- add heartbeat (-1 / 1)  display in indigo everytime it runs
-- change ipDevsLastUpdate to last time variables where fully checked or any new device added etc
-- 0.98  added counter of number of up/down of each device
--
-- how to install:
--  copy this script into applescript editor, save into .../indigo 6/scripts/attachments
-- export into …/indigo 6/scripts/attachments  as APP with "stay open after run handler.."
-- then start fingscan using finder (doubleclick on fingscan.app in indigo 6/scripts/attachments
--
--  use in indigo as trigger:
--  setup trigger "IPdevice22 down"
--		trigger if any change to ipDevice22
--		condition ipDevice22 must contain ";down"   "down" (without ";" ) probably also works, but you might have a device's name up or down or vendor's name may contain string up or down
-- 		action: whatever you like
--
-- what it does:
-- starts fing if not active
-- creates fing directory in  ~/Documnets/  for data
-- will ask for approval to use keychain for sudofing command / userid .. see password options
-- will run every 5 seconds and check finglog file size, if changed check fingdata file for new info
-- will create/ update varibales ipDevicenn  nn = 01 .. 99
-- will update ipDevsLastUpdate with last date/time of last change
-- will update ipDevsAlive  toggle 1/-1 everytime it run as heat beat
-- will ask for each new MAC address to assign nickname
-- ipDevicenn will contain  nickname;macaddress;ip#;vendor;up/downinfo;date of last change if any;#of"up/downs"
--                           eg:iPHONE4-dad;14:8F:C6:74:87:58;192.168.1.148;Apple;up;2013/09/12 00:28:11;2
-- fing will stay active and will create log file and data file.  log file will continuously increase (fing will reset at ~ 350kb).  finglog file is checked for changed file size, fingdata file is analzed by this script once it changes
-- regular read seems to conflict with fing, we use cat with pipe into applescript variable.
--
-- needs to be fixed: 
-- does not allow non consequtive ipDevice03 ..05     eg 04 missing .. deleted variable
-- tried to put fing output files into indigo directory, but fing does not like spaces in directories, so i put the outputfiles into User/yourid/Documents/fing/ fingdata and finglog
--
--
-- added 4 password options
-- 0.  set password in code
-- 1. ask for password in dialog box
-- 2. use keychain to get password
-- 3. sudo without password works only o=if fing has been enabled to run without password, see option 3 in code what to do.
--  uses ~ 0.1-2% of one cpu  (mostly 0.1%)


on quit -- enable quit
	continue quit
end quit

on run -- this is done only once at time of "open"
	global debug
	global theDir
	global userName
	global theFile
	global theLog
	global lastLogFilesize
	global logFilesize
	global noOfDevices
	global FingContents
	global noOfIndigoDevices
	global IndigoIpDevices
	global lastUpdate
	global passwordOption
	global yourPassword
	global alive
	set yourPassword to "" -- use this if paaswordOption = 0
	set passwordOption to 3 --  0= set password in code,  1= use keychain to get password, 2 = enabel fing to not require password, 3 = enter password when running
	set userName to short user name of (system info)
	set theDir to "/Users/" & userName & "/Documents/fing/"
	set theFile to "fingdata"
	set theLog to "finglog"
	set lastLogFilesize to 0
	set logFilesize to 0
	set newDevice to 0
	set lastUpdate to ""
	set alive to 1
	
	-- init if needed
	setupFing()
	
	-- send to idle
	idle
	
	-- finish main pgm from now on on idle takes over
end run


on idle -- every 30 seconds this gets executed
	
	global theDir
	global userName
	global theFile
	global theLog
	global lastLogFilesize
	global logFilesize
	global newDevice
	global noOfDevices
	global FingContents
	global noOfIndigoDevices
	global IndigoIpDevices
	global lastUpdate
	global anyChange
	global alive
	
	set anyChange to 0
	
	
	set noOfLines to 0
	set AppleScript's text item delimiters to {";"}
	
	-- update indigo with time stamp
	set theTime to text -8 thru -1 of ((current date) as «class isot» as string)
	
	
	-- check file size of logfile, if its larger than last time, new data
	set cmd to "ls -l " & theDir & theLog & "| awk '{print $5}'"
	set logFilesize to do shell script cmd
	if logFilesize > lastLogFilesize then -- there must be a new entry in finglog
		set lastLogFilesize to logFilesize
		-- read latest fingdata log file (just last line)
		getFingIPlogdata()
		
		if noOfDevices > 0 then -- read not successful .. must be more than 0 devices changed on network
			-- yes there is really new data to use:
			-- use last line of FINGlog for new information
			set nextLine to paragraph 1 of FingContents
			set theItems to every text item of nextLine
			set theLOGIPNumber to item 3 of theItems as text
			set theLOGStatus to item 2 of theItems as text
			set theLOGDate to item 1 of theItems as text
			set theLOGmacAddress to item 6 of theItems as text
			set theLOGVendor to item 7 of theItems as text
			
			-- get all devices stored in indigo  into IndigoIpDevices, same format as from FING
			getIndigoIPDEvices()
			-- compare to indogo info
			set newDevice to 0
			compareToIndigo(theLOGmacAddress, theLOGIPNumber, theLOGVendor, theLOGStatus, theLOGDate)
		end if
		
	end if
	
	-- check if fingdata was updated (once a minute)
	set cmd to "ls -l " & theDir & theFile & "| awk '{print $8}'" -- time stamp of last change of file
	set thisUpdate to do shell script cmd
	
	if not (thisUpdate = lastUpdate) then -- updated  FINGdata file
		set lastUpdate to thisUpdate -- remember this time stamp
		
		-- read latest fingdata file	
		getFingIPData()
		if noOfDevices > 1 then -- read not successful .. must be more than 1 devices on network
			-- get all devices stored in indigo  into IndigoIpDevices, same format as from FING
			set newDevice to 0
			getIndigoIPDEvices()
			
			-- all data read now compare if anything new
			set ii to 0
			-- loop through FING data
			repeat while ii < noOfDevices
				set ii to ii + 1
				set nextLine to paragraph (ii) of FingContents
				set theItems to every text item of nextLine
				set themacAddress to item 6 of theItems as text
				set theIPNumber to item 1 of theItems as text
				set theStatus to item 3 of theItems as text
				set theDate to item 4 of theItems as text
				set theVendor to item 7 of theItems as text
				-- 			set theAssignedName to item 5 of theItems as text  -- not used
				--			set theHostName to item 2 of theItems as text -- not used
				
				compareToIndigo(themacAddress, theIPNumber, theVendor, theStatus, theDate)
			end repeat
			
		end if
	end if
	
	-- house keeping, update ipDeviceLastUpdate and reset logfile once a day
	-- update indigo with time stamp and heat beat
	
	if anyChange > 0 then
		try -- just in case indigo is down, dont crash this program
			tell application "IndigoServer"
				set the value of variable "ipDevsLastUpdate" to theTime
			end tell
		end try
	end if
	
	set alive to -alive -- flip everytime fingscan runs
	try -- just in case indigo is down, dont crash this program
		tell application "IndigoServer"
			set the value of variable "ipDevsAlive" to alive
		end tell
	end try
	
	
	return 5 -- idle for 5 seconds
	
end idle



on setupFing()
	global theDir
	global theFile
	global theLog
	global userName
	global theIndigoFolder
	global passwordOption
	global yourPassword
	
	--check if fing is already running, if not start it.
	set theApp to "fing.bin"
	set theResponse to " "
	
	
	
	(* not needed anymore
	-- find indigo folder  (copied from Nathan Sheldon etrack.app)
	set theIndigoFolder to ""
	tell application "Finder"
		-- Verify one of the supported Indigo versions exists.
		set ii to 20
		repeat while ii > 1
			set theFolder to "/Library/Application Support/Perceptive Automation/Indigo " & ii & "/IndigoServer.app"
			if exists theFolder as POSIX file then
				set theIndigoFolder to "/Library/Application Support/Perceptive Automation/Indigo " & ii & "/"
				set ii to 0
			end if
			set ii to ii - 1
		end repeat
	end tell
	-- fing does not handle space in directory names
	--	set theDir to theIndigoFolder & "Scripts/Attachments/fingdata/"
	
	
	*)
	
	
	
	-- create fing data folder	
	set cmd to "mkdir '" & theDir & "'  >/dev/null  2>&1 & "
	do shell script cmd
	
	-- check if fing.bin is running	
	try
		set theResponse to do shell script "ps aux | grep '" & theApp & "' | awk '{print $2}' "
	end try
	
	-- if pgmToFind is running then theResponse has 3 lines with PIDs from :     ps, fing itself and one more --- have not figured out which one..
	set ii to count words of theResponse
	
	if ii < 3 then -- if not running start script, start fing
		
		-- option 0:  	 set thePassword in code
		if passwordOption = 0 then
			set cmd to "echo " & yourPassword & " | sudo -S fing  -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &" -- start fing, send to background, dont wait, create 2 output files:  one table format file and one logfile
			set yourPassword to "" -- dont keep password around
		end if
		
		-- option 1:  	 have to use sudo: pipe password from getPW() into sudo
		if passwordOption = 1 then
			set yourPassword to getPW(userName) -- this has to be looked at, grabs first occurence of userName, if 2 with same username and different passwords this might fail
			set cmd to "echo " & yourPassword & " | sudo -S fing  -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &" -- start fing, send to background, dont wait, create 2 output files:  one table format file and one logfile
			set yourPassword to "" -- dont keep password around
		end if
		
		
		-- option 2:  modify system setting so that fing does not need sudo from gcoop76 indido discussions
		(*
sudo visudo

add this line:
CODE: SELECT ALL
spanky localhost = NOPASSWD: /usr/bin/fing
That is, if "spanky" is your username (the one who will be executing the applescript and calling fing).

Note that this edits the file in "vi." Use the arrow keys or "j" or "k" to move up and down. Go to the line you want to add the above text and hit "i" for insert. Type or paste it out, then hit "esc." Then hit ":" then type "wq" for "write, then quit"

That should do it. It is important to use visudo to edit your sudoers file since apparently bad things can happen to the permissions of the file if you edit it directly. I just tested it on my Mac OS X Mountain Lion laptop. Works well. Everything else still needs a password for sudo, but not fing.
*)
		if passwordOption = 2 then
			set cmd to " sudo fing -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &" -- start fing, send to background, dont wait, create 2 output files:  one table format file and one logfile
			set yourPassword to "" -- dont keep password around
		end if
		
		--option 3  user will need to enter password		
		if passwordOption = 3 then
			
			tell application "Finder" -- need to go through finder in case this runs in the background
				set yourPassword to the text returned of (display dialog "enter your password" default answer "xxyyzz" giving up after 200)
			end tell
			set cmd to "echo " & yourPassword & " | sudo -S fing -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &" -- start fing, send to background, dont wait, create 2 output files:  one table format file and one logfile
			set yourPassword to "" -- dont keep password around
		end if
		
		
		-- execute option 0,1,2,3		
		do shell script cmd
		
		delay 10 --wait until FING has finished at least once
		
	end if
	-- fing is running or has started
	
	
	try -- just in case indigo is down, dont crash this program
		set theTime to text -8 thru -1 of ((current date) as «class isot» as string)
		tell application "IndigoServer"
			if not ((exists variable "ipDevsLastUpdate")) then
				make new variable with properties {name:"ipDevsLastUpdate", value:theTime}
			end if
			if not ((exists variable "ipDevsAlive")) then -- heat beat flip everytime it runs
				make new variable with properties {name:"ipDevsAlive", value:"-1"}
			end if
		end tell
	end try
	
	
	return
	
end setupFing


on getIndigoIPDEvices()
	
	global noOfIndigoDevices
	global IndigoIpDevices
	
	-- get all devices stored in indigo  into IndigoIpDevices, same format as from FING
	set AppleScript's text item delimiters to {";"}
	set ii to 0
	set noOfIndigoIpDevices to "0"
	set IndigoIpDevices to {}
	
	set noMore to false
	repeat while ii < 999
		set ii to ii + 1
		set OOii to ii
		if ii < 10 then set OOii to "0" & ii as text
		set ipDevice to "ipDevice" & OOii
		tell application "IndigoServer"
			if not ((exists variable ipDevice)) then
				set noMore to true
				set noOfIndigoDevices to ii - 1
				set ii to 99999
			end if
		end tell
		if noMore = false then
			try -- just in case indigo is down, dont crash this program
				tell application "IndigoServer"
					set ipDeviceValue to (get value of variable ipDevice) as text
				end tell
			end try
			set IndigoIpDevices to IndigoIpDevices & ipDeviceValue
		end if
	end repeat
	return
end getIndigoIPDEvices


on compareToIndigo(themacAddress, theIPNumber, theVendor, theStatus, theDate)
	global noOfIndigoDevices
	global IndigoIpDevices
	global newDevice
	global anyChange
	set anyChange to 1
	
	-- then check if any match in indigo data
	set sameMAC to 0
	set jj to 0
	repeat while jj < noOfIndigoDevices
		set jj to jj + 1
		set nextLineIndigo to item jj of IndigoIpDevices as text
		set theIndigoItems to every text item of nextLineIndigo
		set indigomacAddress to trim(item 2 of theIndigoItems as text)
		if themacAddress = indigomacAddress then ---- mac number found, already in indigo… exit loop
			set sameMAC to jj -- this is the device thats the same
			set jj to 999999 -- force loop exit
			set indigoIPNumber to trim(item 3 of theIndigoItems as text) -- get the indigo info for later use
			set indigoStatus to trim(item 5 of theIndigoItems as text)
			set indigoVendor to trim(item 4 of theIndigoItems as text)
			set indigoNick to trim(item 1 of theIndigoItems as text)
			try
				set indigoNoOfChanges to 0
				set indigoNoOfChanges to trim(item 7 of theIndigoItems as text)
			end try
			
		end if
	end repeat
	
	
	if sameMAC > 0 then -- found match in MAC number, now check if anything has changed
		
		-- check if the device that was indicated by the logfile is this one:  then reset to normal search
		
		if (theIPNumber = indigoIPNumber) and (theStatus = indigoStatus) then -- both the same 
			-- do nothing
		else -- ip or status has changed, update indigo variable
			-- check if the device taht was indicated by the logfile is this one:  then reset to normal search
			set OOii to sameMAC
			if sameMAC < 10 then set OOii to "0" & sameMAC as text -- make sequential number 2 digits
			set theDeviceNo to "ipDevice" & OOii
			set theDeviceValue to indigoNick & ";" & themacAddress & ";" & theIPNumber & ";" & theVendor & ";" & theStatus & ";" & theDate & ";" & indigoNoOfChanges + 1
			try -- just in case indigo is down, dont crash this program
				tell application "IndigoServer"
					set the value of variable theDeviceNo to theDeviceValue
				end tell
			end try
			
		end if
		
	else -- new device, set up 	in indigo
		set newDevice to newDevice + 1
		set OOii to noOfIndigoDevices + newDevice
		if OOii < 10 then set OOii to "0" & OOii as text -- make sequential number 2 digits
		set theDeviceName to "ipDevice" & OOii
		
		set theText to "FINGSCAN network has found new device,  please enter nickname for new device : " & theDeviceName & "  " & themacAddress & "  " & theIPNumber & "  " & theVendor & "  " & theStatus & "   eg:"
		
		tell application "Finder" -- need to go through finder in case this runs in the background
			set nickname to the text returned of (display dialog theText default answer "phone-xyz" giving up after 60)
		end tell
		
		set theDeviceValue to nickname & ";" & themacAddress & ";" & theIPNumber & ";" & theVendor & ";" & theStatus & ";" & theDate & ";1"
		
		try -- just in case indigo is down, dont crash this program
			tell application "IndigoServer"
				make new variable with properties {name:theDeviceName, value:theDeviceValue}
			end tell
		end try
	end if
end compareToIndigo


on getFingIPData()
	
	global noOfDevices
	global FingContents
	global theDir
	global theFile
	set FingContents to {}
	
	-- read latest fingdata file	
	set cmd to "cat " & theDir & theFile
	try
		set FingContents to (do shell script cmd)
		set noOfDevices to (count paragraphs of FingContents)
	end try
	
	return
	
end getFingIPData


on getFingIPlogdata()
	
	global noOfDevices
	global FingContents
	global theDir
	global theFile
	global theLog
	set FingContents to {}
	
	set cmd to "tail -1 " & theDir & theLog -- just get the last line
	try
		set FingContents to (do shell script cmd)
		set noOfDevices to (count paragraphs of FingContents)
	end try
	
end getFingIPlogdata


on getPW(keychainItemName) -- get password from keychain for userid: keychainitemname
	do shell script "security 2>&1 >/dev/null find-generic-password -gl " & quoted form of keychainItemName & " | awk '{print $2}'"
	return (text 2 thru -2 of result) -- return the password part of the string
end getPW


-- trim blanks from string
on trim(someText)
	if someText = "" then return someText
	if someText = " " then return ""
	
	repeat until someText does not start with " "
		set someText to text 2 thru -1 of someText
	end repeat
	
	repeat until someText does not end with " "
		set someText to text 1 thru -2 of someText
	end repeat
	
	return someText
end trim
User avatar
kw123
Posts: 8705
Joined: Sun May 12, 2013 4:44 pm
Location: Dallas, TX
Contact:

Re: Using Fing as a new way to detect smartphone presence

Post by kw123 »

does anyone know how to not show the applescript icon in the doc for an app that is running?

I have tried to modify the info.plist - add:
<key>NSUIElement</key>
<true/>

no change.


Karl
Bollar
Posts: 528
Joined: Sun Aug 11, 2013 3:14 pm

Re: Using Fing as a new way to detect smartphone presence

Post by Bollar »

This is neat -- thanks for putting all the work into it! Cool how you make the updates work through variables.

Two questions:

1. Is it possible to have Fing allow scheduled updates to Fingbox as well? I see my updates stopped when I start Fing from the script.

2. I assume it's okay to edit the device name in the variable list?
Insteon / Z-Wave / Bryant Evolution Connex /Tesla / Roomba / Elk M1 / SiteSage / Enphase Enlighten / NOAA Alerts
User avatar
kw123
Posts: 8705
Joined: Sun May 12, 2013 4:44 pm
Location: Dallas, TX
Contact:

Re: Using Fing as a new way to detect smartphone presence

Post by kw123 »

1. Is it possible to have Fing allow scheduled updates to Fingbox as well? I see my updates stopped when I start Fing from the script.
==> don't know, not using fingbox. I read their Documentation online, but it is not very detailed and does not discuss how things get synchronized. I send some emails to their help line but have not received and answer (I have not bought anything) May be - as you have purchased one of their products- you can ask them.. here the questions I have asked:
- output files can not be put into directories that include a space (ie ../Indigo 6/ ..), any plan to fix this?
- can frequency of updates be changed?

2. I assume it's okay to edit the device name in the variable list?
==> yes, nickname can be modified, everything else will be overwritten by fingscan next time there is a change of that ipDevice (ie up/down or ipNumber)
==> you MUST not change the MAC number, that's the key to link to fing-output, if you change that, that device becomes an orphan and will never be updated, and a new ipDevice gets created.


Karl
User avatar
kw123
Posts: 8705
Joined: Sun May 12, 2013 4:44 pm
Location: Dallas, TX
Contact:

Re: Using Fing as a new way to detect smartphone presence

Post by kw123 »

V .99

-- added "activate" before display dialog, to make sure pop windows for new devices goes into foreground
-- fixed situation when indigoNoOfChanges is not a number, set to 0 (try .. on error set … to 0)

Code: Select all

-- fingscan.app
-- build list of network devices using FING
-- runs in background, iddles for 5 secs then checks if FING has found new configs
-- creates variables with ipdevice info
-- 
--
-- Karl Wachs
-- Sep 12 2013
-- V 0.99
-- 0.81 one code fix, if IP number change: wrong quotes for variable
-- 0.82 added comments, clearer code,  and reset logfile once a day
-- 0.9  added check logfile for any change, if no chang skip checks, faster reaction, and less code excution,  most of the time nothing changes. this will only check size of  file "finglog"  
-- 0.95 check for change in fingdata file. if time stamp changed get all data and update indigo (1/minute)
--  adding a device results in an update of indigo within 6 secs, detection of disconnecting a debvice takes up to 65 secs.  connecting sends traffic, disconnecting in most cases no, have to wait until next ping cycle (1/minute)
-- 0.97 add 4 password options (set passWordOption to 0 or 1 or 2 or 3  see code for details
-- 0.971 OOI varibale fix, 
-- 0.973 set lastLogFilesize to logFilesize was at the wrong place, 
-- bad logic with logMACaddress fixed  (was old code from old logic)
-- add heartbeat (-1 / 1)  display in indigo everytime it runs
-- change ipDevsLastUpdate to last time variables where fully checked or any new device added etc
-- 0.98  added counter of number of up/down of each device
-- 0.99 added "activate" before display dialog, to make sure pop windows for new devices goes into foreground
--       fixed situation when indigoNoOfChanges is not a number, set to 0 (try .. on error  set … to 0)
--
-- how to install:
--  copy this script into applescript editor, save into .../indigo 6/scripts/attachments
-- export into …/indigo 6/scripts/attachments  as APP with "stay open after run handler.."
-- then start fingscan using finder (doubleclick on fingscan.app in indigo 6/scripts/attachments
--
--  use in indigo as trigger:
--  setup trigger "IPdevice22 down"
--		trigger if any change to ipDevice22
--		condition ipDevice22 must contain ";down"   "down" (without ";" ) probably also works, but you might have a device's name up or down or vendor's name may contain string up or down
-- 		action: whatever you like
--
-- what it does:
-- starts fing if not active
-- creates fing directory in  ~/Documnets/  for data
-- will ask for approval to use keychain for sudofing command / userid .. see password options
-- will run every 5 seconds and check finglog file size, if changed check fingdata file for new info
-- will create/ update varibales ipDevicenn  nn = 01 .. 99
-- will update ipDevsLastUpdate with last date/time of last change
-- will update ipDevsAlive  toggle 1/-1 everytime it run as heat beat
-- will ask for each new MAC address to assign nickname
-- ipDevicenn will contain  nickname;macaddress;ip#;vendor;up/downinfo;date of last change if any;#of"up/downs"
--                           eg:iPHONE4-dad;14:8F:C6:74:87:58;192.168.1.148;Apple;up;2013/09/12 00:28:11;2
-- fing will stay active and will create log file and data file.  log file will continuously increase (fing will reset at ~ 350kb).  finglog file is checked for changed file size, fingdata file is analzed by this script once it changes
-- regular read seems to conflict with fing, we use cat with pipe into applescript variable.
--
-- needs to be fixed: 
-- does not allow non consequtive ipDevice03 ..05     eg 04 missing .. deleted variable
-- tried to put fing output files into indigo directory, but fing does not like spaces in directories, so i put the outputfiles into User/yourid/Documents/fing/ fingdata and finglog
--
--
-- added 4 password options
-- 0.  set password in code
-- 1. ask for password in dialog box
-- 2. use keychain to get password
-- 3. sudo without password works only o=if fing has been enabled to run without password, see option 3 in code what to do.
--  uses ~ 0.1-2% of one cpu  (mostly 0.1%)


on quit -- enable quit
	continue quit
end quit

on run -- this is done only once at time of "open"
	global debug
	global theDir
	global userName
	global theFile
	global theLog
	global lastLogFilesize
	global logFilesize
	global noOfDevices
	global FingContents
	global noOfIndigoDevices
	global IndigoIpDevices
	global lastUpdate
	global passwordOption
	global yourPassword
	global alive
	set yourPassword to "" -- use this if paaswordOption = 0
	set passwordOption to 3 --  0= set password in code,  1= use keychain to get password, 2 = enabel fing to not require password, 3 = enter password when running
	set userName to short user name of (system info)
	set theDir to "/Users/" & userName & "/Documents/fing/"
	set theFile to "fingdata"
	set theLog to "finglog"
	set lastLogFilesize to 0
	set logFilesize to 0
	set newDevice to 0
	set lastUpdate to ""
	set alive to 1
	
	-- init if needed
	setupFing()
	
	-- send to idle
	idle
	
	-- finish main pgm from now on on idle takes over
end run


on idle -- every 30 seconds this gets executed
	
	global theDir
	global userName
	global theFile
	global theLog
	global lastLogFilesize
	global logFilesize
	global newDevice
	global noOfDevices
	global FingContents
	global noOfIndigoDevices
	global IndigoIpDevices
	global lastUpdate
	global anyChange
	global alive
	
	set anyChange to 0
	
	
	set noOfLines to 0
	set AppleScript's text item delimiters to {";"}
	
	-- update indigo with time stamp
	set theTime to text -8 thru -1 of ((current date) as «class isot» as string)
	
	
	-- check file size of logfile, if its larger than last time, new data
	set cmd to "ls -l " & theDir & theLog & "| awk '{print $5}'"
	set logFilesize to do shell script cmd
	if logFilesize > lastLogFilesize then -- there must be a new entry in finglog
		set lastLogFilesize to logFilesize
		-- read latest fingdata log file (just last line)
		getFingIPlogdata()
		
		if noOfDevices > 0 then -- read not successful .. must be more than 0 devices changed on network
			-- yes there is really new data to use:
			-- use last line of FINGlog for new information
			set nextLine to paragraph 1 of FingContents
			set theItems to every text item of nextLine
			set theLOGIPNumber to item 3 of theItems as text
			set theLOGStatus to item 2 of theItems as text
			set theLOGDate to item 1 of theItems as text
			set theLOGmacAddress to item 6 of theItems as text
			set theLOGVendor to item 7 of theItems as text
			
			-- get all devices stored in indigo  into IndigoIpDevices, same format as from FING
			getIndigoIPDEvices()
			-- compare to indogo info
			set newDevice to 0
			compareToIndigo(theLOGmacAddress, theLOGIPNumber, theLOGVendor, theLOGStatus, theLOGDate)
		end if
		
	end if
	
	-- check if fingdata was updated (once a minute)
	set cmd to "ls -l " & theDir & theFile & "| awk '{print $8}'" -- time stamp of last change of file
	set thisUpdate to do shell script cmd
	
	if not (thisUpdate = lastUpdate) then -- updated  FINGdata file
		set lastUpdate to thisUpdate -- remember this time stamp
		
		-- read latest fingdata file	
		getFingIPData()
		if noOfDevices > 1 then -- read not successful .. must be more than 1 devices on network
			-- get all devices stored in indigo  into IndigoIpDevices, same format as from FING
			set newDevice to 0
			getIndigoIPDEvices()
			
			-- all data read now compare if anything new
			set ii to 0
			-- loop through FING data
			repeat while ii < noOfDevices
				set ii to ii + 1
				set nextLine to paragraph (ii) of FingContents
				set theItems to every text item of nextLine
				set themacAddress to item 6 of theItems as text
				set theIPNumber to item 1 of theItems as text
				set theStatus to item 3 of theItems as text
				set theDate to item 4 of theItems as text
				set theVendor to item 7 of theItems as text
				-- 			set theAssignedName to item 5 of theItems as text  -- not used
				--			set theHostName to item 2 of theItems as text -- not used
				
				compareToIndigo(themacAddress, theIPNumber, theVendor, theStatus, theDate)
			end repeat
			
		end if
	end if
	
	-- house keeping, update ipDeviceLastUpdate and reset logfile once a day
	-- update indigo with time stamp and heat beat
	
	if anyChange > 0 then
		try -- just in case indigo is down, dont crash this program
			tell application "IndigoServer"
				set the value of variable "ipDevsLastUpdate" to theTime
			end tell
		end try
	end if
	
	set alive to -alive -- flip everytime fingscan runs
	try -- just in case indigo is down, dont crash this program
		tell application "IndigoServer"
			set the value of variable "ipDevsAlive" to alive
		end tell
	end try
	
	
	return 5 -- idle for 5 seconds
	
end idle



on setupFing()
	global theDir
	global theFile
	global theLog
	global userName
	global theIndigoFolder
	global passwordOption
	global yourPassword
	
	--check if fing is already running, if not start it.
	set theApp to "fing.bin"
	set theResponse to " "
	
	
	
	(* not needed anymore
	-- find indigo folder  (copied from Nathan Sheldon etrack.app)
	set theIndigoFolder to ""
	tell application "Finder"
		-- Verify one of the supported Indigo versions exists.
		set ii to 20
		repeat while ii > 1
			set theFolder to "/Library/Application Support/Perceptive Automation/Indigo " & ii & "/IndigoServer.app"
			if exists theFolder as POSIX file then
				set theIndigoFolder to "/Library/Application Support/Perceptive Automation/Indigo " & ii & "/"
				set ii to 0
			end if
			set ii to ii - 1
		end repeat
	end tell
	-- fing does not handle space in directory names
	--	set theDir to theIndigoFolder & "Scripts/Attachments/fingdata/"
	
	
	*)
	
	
	
	-- create fing data folder	
	set cmd to "mkdir '" & theDir & "'  >/dev/null  2>&1 & "
	do shell script cmd
	
	-- check if fing.bin is running	
	try
		set theResponse to do shell script "ps aux | grep '" & theApp & "' | awk '{print $2}' "
	end try
	
	-- if pgmToFind is running then theResponse has 3 lines with PIDs from :     ps, fing itself and one more --- have not figured out which one..
	set ii to count words of theResponse
	
	if ii < 3 then -- if not running start script, start fing
		
		-- option 0:  	 set thePassword in code
		if passwordOption = 0 then
			set cmd to "echo " & yourPassword & " | sudo -S fing  -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &" -- start fing, send to background, dont wait, create 2 output files:  one table format file and one logfile
			set yourPassword to "" -- dont keep password around
		end if
		
		-- option 1:  	 have to use sudo: pipe password from getPW() into sudo
		if passwordOption = 1 then
			set yourPassword to getPW(userName) -- this has to be looked at, grabs first occurence of userName, if 2 with same username and different passwords this might fail
			set cmd to "echo " & yourPassword & " | sudo -S fing  -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &" -- start fing, send to background, dont wait, create 2 output files:  one table format file and one logfile
			set yourPassword to "" -- dont keep password around
		end if
		
		
		-- option 2:  modify system setting so that fing does not need sudo from gcoop76 indido discussions
		(*
sudo visudo

add this line:
CODE: SELECT ALL
spanky localhost = NOPASSWD: /usr/bin/fing
That is, if "spanky" is your username (the one who will be executing the applescript and calling fing).

Note that this edits the file in "vi." Use the arrow keys or "j" or "k" to move up and down. Go to the line you want to add the above text and hit "i" for insert. Type or paste it out, then hit "esc." Then hit ":" then type "wq" for "write, then quit"

That should do it. It is important to use visudo to edit your sudoers file since apparently bad things can happen to the permissions of the file if you edit it directly. I just tested it on my Mac OS X Mountain Lion laptop. Works well. Everything else still needs a password for sudo, but not fing.
*)
		if passwordOption = 2 then
			set cmd to " sudo fing -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &" -- start fing, send to background, dont wait, create 2 output files:  one table format file and one logfile
			set yourPassword to "" -- dont keep password around
		end if
		
		--option 3  user will need to enter password		
		if passwordOption = 3 then
			
			tell application "Finder" -- need to go through finder in case this runs in the background
				activate
				set yourPassword to the text returned of (display dialog "enter your password" default answer "xxyyzz" giving up after 200)
			end tell
			set cmd to "echo " & yourPassword & " | sudo -S fing -o table,csv,\"" & theDir & theFile & "\"  log,csv,\"" & theDir & theLog & "\"  >/dev/null  2>&1 &" -- start fing, send to background, dont wait, create 2 output files:  one table format file and one logfile
			set yourPassword to "" -- dont keep password around
		end if
		
		
		-- execute option 0,1,2,3		
		do shell script cmd
		
		delay 10 --wait until FING has finished at least once
		
	end if
	-- fing is running or has started
	
	
	try -- just in case indigo is down, dont crash this program
		set theTime to text -8 thru -1 of ((current date) as «class isot» as string)
		tell application "IndigoServer"
			if not ((exists variable "ipDevsLastUpdate")) then
				make new variable with properties {name:"ipDevsLastUpdate", value:theTime}
			end if
			if not ((exists variable "ipDevsAlive")) then -- heat beat flip everytime it runs
				make new variable with properties {name:"ipDevsAlive", value:"-1"}
			end if
		end tell
	end try
	
	
	return
	
end setupFing


on getIndigoIPDEvices()
	
	global noOfIndigoDevices
	global IndigoIpDevices
	
	-- get all devices stored in indigo  into IndigoIpDevices, same format as from FING
	set AppleScript's text item delimiters to {";"}
	set ii to 0
	set noOfIndigoIpDevices to "0"
	set IndigoIpDevices to {}
	
	set noMore to false
	repeat while ii < 999
		set ii to ii + 1
		set OOii to ii
		if ii < 10 then set OOii to "0" & ii as text
		set ipDevice to "ipDevice" & OOii
		tell application "IndigoServer"
			if not ((exists variable ipDevice)) then
				set noMore to true
				set noOfIndigoDevices to ii - 1
				set ii to 99999
			end if
		end tell
		if noMore = false then
			try -- just in case indigo is down, dont crash this program
				tell application "IndigoServer"
					set ipDeviceValue to (get value of variable ipDevice) as text
				end tell
			end try
			set IndigoIpDevices to IndigoIpDevices & ipDeviceValue
		end if
	end repeat
	return
end getIndigoIPDEvices


on compareToIndigo(themacAddress, theIPNumber, theVendor, theStatus, theDate)
	global noOfIndigoDevices
	global IndigoIpDevices
	global newDevice
	global anyChange
	set anyChange to 1
	
	-- then check if any match in indigo data
	set sameMAC to 0
	set jj to 0
	repeat while jj < noOfIndigoDevices
		set jj to jj + 1
		set nextLineIndigo to item jj of IndigoIpDevices as text
		set theIndigoItems to every text item of nextLineIndigo
		set indigomacAddress to trim(item 2 of theIndigoItems as text)
		if themacAddress = indigomacAddress then ---- mac number found, already in indigo… exit loop
			set sameMAC to jj -- this is the device thats the same
			set jj to 999999 -- force loop exit
			set indigoIPNumber to trim(item 3 of theIndigoItems as text) -- get the indigo info for later use
			set indigoStatus to trim(item 5 of theIndigoItems as text)
			set indigoVendor to trim(item 4 of theIndigoItems as text)
			set indigoNick to trim(item 1 of theIndigoItems as text)
			try
				set indigoNoOfChanges to 0
				set indigoNoOfChanges to trim(item 7 of theIndigoItems as text)
				set indigoNoOfChanges to indigoNoOfChanges + 0
			on error
				set indigoNoOfChanges to 0
			end try
			
		end if
	end repeat
	
	
	if sameMAC > 0 then -- found match in MAC number, now check if anything has changed
		
		-- check if the device that was indicated by the logfile is this one:  then reset to normal search
		
		if (theIPNumber = indigoIPNumber) and (theStatus = indigoStatus) then -- both the same 
			-- do nothing
		else -- ip or status has changed, update indigo variable
			-- check if the device taht was indicated by the logfile is this one:  then reset to normal search
			set OOii to sameMAC
			if sameMAC < 10 then set OOii to "0" & sameMAC as text -- make sequential number 2 digits
			set theDeviceNo to "ipDevice" & OOii
			set theDeviceValue to indigoNick & ";" & themacAddress & ";" & theIPNumber & ";" & theVendor & ";" & theStatus & ";" & theDate & ";" & indigoNoOfChanges + 1
			try -- just in case indigo is down, dont crash this program
				tell application "IndigoServer"
					set the value of variable theDeviceNo to theDeviceValue
				end tell
			end try
			
		end if
		
	else -- new device, set up 	in indigo
		set newDevice to newDevice + 1
		set OOii to noOfIndigoDevices + newDevice
		if OOii < 10 then set OOii to "0" & OOii as text -- make sequential number 2 digits
		set theDeviceName to "ipDevice" & OOii
		
		set theText to "FINGSCAN network has found new device,  please enter nickname for new device : " & theDeviceName & "  " & themacAddress & "  " & theIPNumber & "  " & theVendor & "  " & theStatus & "   eg:"
		
		tell application "Finder" -- need to go through finder in case this runs in the background
			activate
			set nickname to the text returned of (display dialog theText default answer "phone-xyz" giving up after 60)
		end tell
		
		set theDeviceValue to nickname & ";" & themacAddress & ";" & theIPNumber & ";" & theVendor & ";" & theStatus & ";" & theDate & ";1"
		
		try -- just in case indigo is down, dont crash this program
			tell application "IndigoServer"
				make new variable with properties {name:theDeviceName, value:theDeviceValue}
			end tell
		end try
	end if
end compareToIndigo


on getFingIPData()
	
	global noOfDevices
	global FingContents
	global theDir
	global theFile
	set FingContents to {}
	
	-- read latest fingdata file	
	set cmd to "cat " & theDir & theFile
	try
		set FingContents to (do shell script cmd)
		set noOfDevices to (count paragraphs of FingContents)
	end try
	
	return
	
end getFingIPData


on getFingIPlogdata()
	
	global noOfDevices
	global FingContents
	global theDir
	global theFile
	global theLog
	set FingContents to {}
	
	set cmd to "tail -1 " & theDir & theLog -- just get the last line
	try
		set FingContents to (do shell script cmd)
		set noOfDevices to (count paragraphs of FingContents)
	end try
	
end getFingIPlogdata


on getPW(keychainItemName) -- get password from keychain for userid: keychainitemname
	do shell script "security 2>&1 >/dev/null find-generic-password -gl " & quoted form of keychainItemName & " | awk '{print $2}'"
	return (text 2 thru -2 of result) -- return the password part of the string
end getPW


-- trim blanks from string
on trim(someText)
	if someText = "" then return someText
	if someText = " " then return ""
	
	repeat until someText does not start with " "
		set someText to text 2 thru -1 of someText
	end repeat
	
	repeat until someText does not end with " "
		set someText to text 1 thru -2 of someText
	end repeat
	
	return someText
end trim


User avatar
kw123
Posts: 8705
Joined: Sun May 12, 2013 4:44 pm
Location: Dallas, TX
Contact:

Re: Using Fing as a new way to detect smartphone presence

Post by kw123 »

"Bollar"

1. Is it possible to have Fing allow scheduled updates to Fingbox as well? I see my updates stopped when I start Fing from the script.

==> could you check where FING writes the data when you use Fingbox? we could just use that directory to write the data,

Also FING can create many output files with different formats and directories
eg: add table,text,"/this/is/the/output/file/fingtext" to the fing command line if you want to create a file /this/is/the/output/file/fingtext with format table text

Karl
Dewster35
Posts: 1033
Joined: Tue Jul 06, 2010 6:29 pm
Location: Petoskey, MI

Re: Using Fing as a new way to detect smartphone presence

Post by Dewster35 »

Finally getting around to trying this out and I'm getting the following error message in the event log.


Schedule Check Dave iPhone
Error script error: «script» doesn’t understand the readfing message. (-1708)

I have the scheduled action running every 10 seconds for now for testing purposes. All I am doing with that action is changing a variable from home to away.
Bollar
Posts: 528
Joined: Sun Aug 11, 2013 3:14 pm

Re: Using Fing as a new way to detect smartphone presence

Post by Bollar »

kw123 wrote:"Bollar"

1. Is it possible to have Fing allow scheduled updates to Fingbox as well? I see my updates stopped when I start Fing from the script.

==> could you check where FING writes the data when you use Fingbox? we could just use that directory to write the data,

Also FING can create many output files with different formats and directories
eg: add table,text,"/this/is/the/output/file/fingtext" to the fing command line if you want to create a file /this/is/the/output/file/fingtext with format table text

Karl
I will check. I do see that if Fing is started with no parameters, it will launch all FingSentinel files found in /usr/lib/fing/launchd

The one file, com.overlooksoft.FingSentinel.plist is as follows:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>com.overlooksoft.FingSentinel</string>
        <key>RunAtLoad</key>
        <true/>
        <key>Disabled</key>
        <false/>
        <key>GroupName</key>
        <string>wheel</string>
        <key>UserName</key>
        <string>root</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/bin/fing</string>
                <string>--sentinel</string>
        </array>
        <key>KeepAlive</key>
        <true/>
        <key>StandardErrorPath</key>
        <string>/var/log/fing/stderr.log</string>
        <key>StandardOutPath</key>
        <string>/var/log/fing/stdout.log</string>
</dict>
</plist>
Right now, I have two instances of fing.bin running and FingBox and FingScan both appear to be working correctly.
Insteon / Z-Wave / Bryant Evolution Connex /Tesla / Roomba / Elk M1 / SiteSage / Enphase Enlighten / NOAA Alerts
User avatar
kw123
Posts: 8705
Joined: Sun May 12, 2013 4:44 pm
Location: Dallas, TX
Contact:

Re: Using Fing as a new way to detect smartphone presence

Post by kw123 »

Dewster35 wrote:Finally getting around to trying this out and I'm getting the following error message in the event log.


Schedule Check Dave iPhone
Error script error: «script» doesn’t understand the readfing message. (-1708)

I have the scheduled action running every 10 seconds for now for testing purposes. All I am doing with that action is changing a variable from home to away.

I have stopped the readfing path. the "NEW" and "IMPROVED" one is fingscan.

difference: fingscan runs continuously, creates a whole list of all ipdevices on your network with info on last change, # of changes etc.
trigger on change on any change of variable ipDdevicenn and check for contains "up" or "down" to drive action.

Karl
Post Reply

Return to “User Plugins”