Using Fing as a new way to detect smartphone presence

Posted on
Wed Sep 11, 2013 12:01 pm
gcoop76 offline
Posts: 2
Joined: Sep 11, 2013

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

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.

Posted on
Wed Sep 11, 2013 3:03 pm
kw123 offline
User avatar
Posts: 8366
Joined: May 12, 2013
Location: Dallas, TX

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

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


Posted on
Wed Sep 11, 2013 5:17 pm
jrickmd offline
Posts: 109
Joined: Jun 01, 2003
Location: Texas

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

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

Posted on
Wed Sep 11, 2013 5:50 pm
kw123 offline
User avatar
Posts: 8366
Joined: May 12, 2013
Location: Dallas, TX

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

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 karlwachs@me.com and I can walk you through

Karl

Posted on
Wed Sep 11, 2013 6:14 pm
jrickmd offline
Posts: 109
Joined: Jun 01, 2003
Location: Texas

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

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

Posted on
Wed Sep 11, 2013 6:22 pm
kw123 offline
User avatar
Posts: 8366
Joined: May 12, 2013
Location: Dallas, TX

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

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

thanks for catching it.

Posted on
Wed Sep 11, 2013 6:26 pm
kw123 offline
User avatar
Posts: 8366
Joined: May 12, 2013
Location: Dallas, TX

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

-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

Posted on
Wed Sep 11, 2013 11:42 pm
kw123 offline
User avatar
Posts: 8366
Joined: May 12, 2013
Location: Dallas, TX

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

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

Posted on
Thu Sep 12, 2013 7:59 am
Bollar offline
Posts: 528
Joined: Aug 11, 2013

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

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

Posted on
Thu Sep 12, 2013 8:38 am
kw123 offline
User avatar
Posts: 8366
Joined: May 12, 2013
Location: Dallas, TX

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

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

Posted on
Thu Sep 12, 2013 9:15 am
kw123 offline
User avatar
Posts: 8366
Joined: May 12, 2013
Location: Dallas, TX

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

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



Posted on
Thu Sep 12, 2013 9:46 am
kw123 offline
User avatar
Posts: 8366
Joined: May 12, 2013
Location: Dallas, TX

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

"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

Posted on
Thu Sep 12, 2013 10:08 am
Dewster35 offline
Posts: 1030
Joined: Jul 06, 2010
Location: Petoskey, MI

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

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.

Posted on
Thu Sep 12, 2013 10:17 am
Bollar offline
Posts: 528
Joined: Aug 11, 2013

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

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

Posted on
Thu Sep 12, 2013 10:28 am
kw123 offline
User avatar
Posts: 8366
Joined: May 12, 2013
Location: Dallas, TX

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

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

Who is online

Users browsing this forum: No registered users and 39 guests

cron