Using Fing as a new way to detect smartphone presence

Posted on
Wed Aug 28, 2013 2:49 am
bip.philippe offline
Posts: 58
Joined: Feb 20, 2013
Location: France

Using Fing as a new way to detect smartphone presence

Hi,

As a happy owner of the new Airport Extreme, I discovered that SNMP is no more available in this device.

I would like to replace the SNMP log by use of Fing.

Are you considering that ?

BTW, I already have experience in using Fing and python dev.
Instead of rewriting all the things that smartphone radar is already doing perfectly, I am considered to add this as a new feed for smartphone radar by myself.

Regards,
Berbard

Posted on
Sat Sep 07, 2013 4:04 pm
emergent offline
Posts: 51
Joined: Aug 30, 2013

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

This would be very helpful to me if you were able to do it.

Posted on
Sat Sep 07, 2013 9:11 pm
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

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

whats the difference to simply doing ping?

FING does some scanning and formatting, but besides that is there any additional info?

Karl

Posted on
Sun Sep 08, 2013 9:13 am
bip.philippe offline
Posts: 58
Joined: Feb 20, 2013
Location: France

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

Fing runs discover rounds of network devices - whereas ping can only ping device you know -. It creates a log that contains this info :

=IP address
=Custom Name of the Node (assigned in a .properties file)
=The state (UP/DOWN)
=The timestamp of last state change
=The host name
=The MAC address
=The Hardware vendor

This log is updated on a regular basis (every minute or so).

Regards,

Posted on
Sun Sep 08, 2013 4:40 pm
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

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

first try to use fing to look for MAC address on network

steps:

1. download fing from http://www.overlooksoft.com/download site and install (with option key pressed to enable install)

2. then copy the attached code into applescript and compile and export to … /indigo 6/scripts/attachments
--- it needs your admin password as fing requires to be run with sudo. replace XXXXXXX in
set yourPassward to "XXXXXX" with your password.
!!!PLEASE BE AWARE THAT THIS IN CLEAR TEXT!!!!
although it likely will not leave your computer.

3. create scheduled action: "check myiphone" with embedded applescript eg:
set found to readfing("00:1E:E5:FA:4E:E4") -- this is the MAC address the programm will be looking for -- you have to know this. use fing to find it once: just type "fing" in terminal
if found = true then
do what ever you need to do
else
do what ever you need to do
end

4. you can check the data in /Users/yourid/Documents/fingdata and finglog


-- first time this script gets executed it waits (delay 10) for 10 secs to make sure that fing is running.

happy using

Karl



Code: Select all
-- use fing to check if device with certain MAC address is on network
--
--
-- Karl Wachs
-- Sep 8 2013
-- V 0.53
-- added sudo requirement for fing, needs sudo password
-- no need for directory modification,  use script to find current ID
--
-- using example script from outlooksoft web page
-- 
--
-- starts fing if not active
-- deletes data and log file before start
-- fing will stay active and will create log file and data file.  log file will continuously increase.  data file is analzed by this script
-- regular read seems to conflict with fing, use cat with pipe into applescript variable.
-- other info can be anayzed,  ie date of last change, device up down,..  see code      set theXXX to item x of    at the end..
--
--  creates 2 files:  ~/Documents/fingdata   and finglog
--
--
(* example how to call:
set found to readfing("00:1E:E5:FA:xx:xx")  -- this could be the MAC address of eg an iPhone
tell application "indigoServer"
   set value of variable "iphoneInHouse" to found   -- variable iphoneInHouse has to be created first
end
*)


on readfing(themacAddressToFind)
   
   global theDir
   global yourPassword
   global theFile
   global theLog
   set userName to short user name of (system info)
   set theDir to "/Users/" & userName & "/Documents/"
   set theFile to "fingdata"
   set theLog to "finglog"
   set yourPassword to "XXXXXXXXXXXX"
   
   -- init if needed
   setupFing()
   
   
   -- now check if macAddress is present
   
   set found to findtheMacaddress(themacAddressToFind)
   
   return found
   
end readfing





on setupFing()
   global theDir
   global theFile
   global theLog
   global yourPassword
   --check if fing is already running, if not start it.
   set pgmToFind to "fing.bin"
   set theResponse to " "
   try
      set theResponse to do shell script "ps aux | grep '" & pgmToFind & "' | awk '{print $2}' "
   end try
   
   -- if pgmToFind is running then theResponse has 3 lines with 1 PID from :     ps, xxxx itself and one more --- have not figured out which one..
   set noOfWords to count words of theResponse
   if noOfWords < 3 then -- if not running start script, remove old temp files and start fing
      set cmd to "rm " & theDir & theFile & " &"
      do shell script cmd
      set cmd to "rm " & theDir & theLog & " &"
      do shell script cmd
      set cmd to "echo " & yourPassword & " | sudo -S fing -o table,csv," & theDir & theFile & "  log,csv," & theDir & theLog & "  >/dev/null  2>&1 &"
      do shell script cmd
      delay 10
   end if
   -- fing is running or has started
   
   return
   
end setupFing




-------------------
on findtheMacaddress(themacAddressToFind)
   
   set found to false
   global theFile
   global theDir
   set noOfDevices to 0
   
   --delay 10 --wait until fing has finished at least once
   set cmd to "cat " & theDir & theFile
   try
      set FingContents to (do shell script cmd)
      set noOfDevices to (count paragraphs of FingContents)
   end try
   if noOfDevices < 2 then -- read not successful .. must be more than 1 devices on network
      return false
   end if
   
   set AppleScript's text item delimiters to {";"}
   set nextDevice to 0
   repeat while nextDevice < noOfDevices
      set nextLine to paragraph (nextDevice + 1) of FingContents
      set theItems to every text item of nextLine
      
      set theIPNumber to item 1 of theItems as text
      set theHostName to item 2 of theItems as text
      set theStatus to item 3 of theItems as text
      set theDate to item 4 of theItems as text
      set theAssignedName to item 5 of theItems as text
      set themacAddress to item 6 of theItems as text
      set theVendor to item 7 of theItems as text
      --   display dialog themacAddress
      
      if themacAddress = themacAddressToFind then
         if theStatus = "UP" then set found to true
         set nextDevice to 9999 -- stop repeat
      end if
      
      set nextDevice to nextDevice + 1
      
      
   end repeat
   
   return found
   
end findtheMacaddress




Posted on
Mon Sep 09, 2013 12:49 am
bip.philippe offline
Posts: 58
Joined: Feb 20, 2013
Location: France

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

Thanks for digging the subject, Karl.

The remaining question is for Travis : does he consider do had using fing as an alternative way for Smartphone Radar to follow devices ?

Regards,
Bernard

Posted on
Mon Sep 09, 2013 7:38 am
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

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

Neat find Bernard. I just installed Fing on my Mac and iPhone. Both work very well.

And thanks for sharing the AppleScript Karl.

Image

Posted on
Mon Sep 09, 2013 7:45 am
travisc offline
User avatar
Posts: 346
Joined: Sep 07, 2010
Location: Toronto, Canada

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

I'm too busy with work to get any time to play with this now. Feel free to add it try adding it to the plugin if you want to try it out. Though the fact that it needs to run as root may be a problem.

Posted on
Mon Sep 09, 2013 7:51 am
Dewster35 offline
Posts: 1030
Joined: Jul 06, 2010
Location: Petoskey, MI

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

kw123 wrote:
2. then copy the attached code into applescript and compile and export to … /indigo 6/scripts/attachments
--- it needs your admin password as fing requires to be run with sudo. replace XXXXXXX in
set yourPassward to "XXXXXX" with your password.
!!!PLEASE BE AWARE THAT THIS IN CLEAR TEXT!!!!
although it likely will not leave your computer.


This is great Karl! Any chance that you could somehow have this get keychain access rather than storing your admin password in the clear like this?

Posted on
Mon Sep 09, 2013 10:08 am
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

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

will try... next piece to learn how to do...

goal is to have this thing running in the background and updating variables on state of connected devices.

QUESTIONS: I have ~ 24 IP devices on my network. In order for this thing to work well it would need to have a mapping form MAC-address to device name. One could do a scan and present a table to the user to add a device name. But sometimes not all IP devices are "alive" (eg wifi cameras, phones) and devices get replaced and added or removed. That would lead to a bit more complications. Would it be sufficient to just manage the key 1-3 devices (ie cell phones) to check if user is present? .. the real question is: what does the user want to do with the info:
1. security , which devices are on my network?
2. check if certain few devices are online?

AND as soon as the iphone goes dark it does shows up as "down" in fing .. with timestamp of last check. When it comes alive the fing "log-file" shows and entry within seconds, while the "table-file" output changes only after the next scheduled run of Fing (1/minute).


as for SUDO: I don't know "overlook" (the company that does fing). They are selling a smartphone app and an enterprise version. FING is free. I could not find any comments about trustworthiness of overlook.. any info?


Karl

Posted on
Mon Sep 09, 2013 10:13 am
Dewster35 offline
Posts: 1030
Joined: Jul 06, 2010
Location: Petoskey, MI

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

kw123 wrote:
will try... next piece to learn how to do...

goal is to have this thing running in the background and updating variables on state of connected devices.

QUESTIONS: I have ~ 24 IP devices on my network. In order for this thing to work well it would need to have a mapping form MAC-address to device name. One could do a scan and present a table to the user to add a device name. But sometimes not all IP devices are "alive" (eg wifi cameras, phones) and devices get replaced and added or removed. That would lead to a bit more complications. Would it be sufficient to just manage the key 1-3 devices (ie cell phones) to check if user is present? .. the real question is: what does the user want to do with the info:
1. security , which devices are on my network?
2. check if certain few devices are online?

AND as soon as the iphone goes dark it does shows up as "down" in fing .. with timestamp of last check. When it comes alive the fing "log-file" shows and entry within seconds, while the "table-file" output changes only after the next scheduled run of Fing (1/minute).


as for SUDO: I don't know "overlook" (the company that does fing). They are selling a smartphone app and an enterprise version. FING is free. I could not find any comments about trustworthiness of overlook.. any info?


Karl


Personally, how I would use this are for:
1. Know when residents of the house are home or away.
2. Know when guests are home or away (I've setup a lot of our guests with their mac addresses into SPR so that my housemode switches to company when they are there.)

Posted on
Mon Sep 09, 2013 10:55 am
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

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

FING script update:
this one does not need to have the password in the script. user will be asked to allow password access.
The getPW section gets the password. The password will still be visible in the applescript EVENTS window as clear text during execution.



Code: Select all
-- use fing to check if device with certain MAC address is on network
--
--
-- Karl Wachs
-- Sep 8 2013
-- V 0.6
--  added get sudo password into script. no need to enter password, but user will be prompted to allow keychain access
-- added sudo requirement for fing, needs sudo password,
-- no need for directory modification,  use script to find current ID
--
-- using example script from outlooksoft web page
-- 
--
-- starts fing if not active
-- deletes data and log file before start
-- fing will stay active and will create log file and data file.  log file will continuously increase.  data file is analzed by this script
-- regular read seems to conflict with fing, use cat with pipe into applescript variable.
-- other info can be anayzed,  ie date of last change, device up down,..  see code      set theXXX to item x of    at the end..
--
--  creates 2 files:  ~/Documents/fingdata   and finglog
--
--
--example how to call:


set found to readfing("00:1E:E5:FA:xx:xx") -- this could be the MAC address of eg an iPhone
display dialog found
(*
tell application "IndigoServer"
   set value of variable "iphoneInHouse" to found -- variable iphoneInHouse has to be created first
end tell
*)

on readfing(themacAddressToFind)
   
   global theDir
   global userName
   global theFile
   global theLog
   set userName to short user name of (system info)
   set theDir to "/Users/" & userName & "/Documents/"
   set theFile to "fingdata"
   set theLog to "finglog"
   
   -- init if needed
   setupFing()
   
   
   -- now check if macAddress is present
   
   set found to findtheMacaddress(themacAddressToFind)
   
   return found
   
end readfing





on setupFing()
   global theDir
   global theFile
   global theLog
   global userName
   --check if fing is already running, if not start it.
   set pgmToFind to "fing.bin"
   set theResponse to " "
   try
      set theResponse to do shell script "ps aux | grep '" & pgmToFind & "' | awk '{print $2}' "
   end try
   
   -- if pgmToFind is running then theResponse has 3 lines with 1 PID from :     ps, xxxx itself and one more --- have not figured out which one..
   set noOfWords to count words of theResponse
   if noOfWords < 3 then -- if not running start script, remove old temp files and start fing
      set cmd to "rm " & theDir & theFile & " &"
      do shell script cmd
      set cmd to "rm " & theDir & theLog & " &"
      --      
      set yourPassword to getPW(userName)
      --      
      do shell script cmd
      set cmd to "echo " & yourPassword & " | sudo -S fing -o table,csv," & theDir & theFile & "  log,csv," & theDir & theLog & "  >/dev/null  2>&1 &"
      do shell script cmd
      delay 10 --wait until fing has finished at least once
   end if
   -- fing is running or has started
   
   return
   
end setupFing




-------------------
on findtheMacaddress(themacAddressToFind)
   
   set found to false
   global theFile
   global theDir
   set noOfDevices to 0
   
   -- read data
   set cmd to "cat " & theDir & theFile
   try
      set FingContents to (do shell script cmd)
      set noOfDevices to (count paragraphs of FingContents)
   end try
   
   if noOfDevices < 2 then -- read not successful .. must be more than 1 devices on network
      return false
   end if
   
   -- now parse each line and check if MAC address is listed
   set AppleScript's text item delimiters to {";"}
   set nextDevice to 0
   repeat while nextDevice < noOfDevices
      set nextLine to paragraph (nextDevice + 1) of FingContents
      set theItems to every text item of nextLine
      
      set theIPNumber to item 1 of theItems as text
      set theHostName to item 2 of theItems as text
      set theStatus to item 3 of theItems as text
      set theDate to item 4 of theItems as text
      set theAssignedName to item 5 of theItems as text
      set themacAddress to item 6 of theItems as text
      set theVendor to item 7 of theItems as text
      
      if themacAddress = themacAddressToFind then -- mac address found
         if theStatus = "UP" then set found to true -- is it UP or DOWN?
         set nextDevice to 9999 -- stop repeat
      end if
      
      set nextDevice to nextDevice + 1
      
      
   end repeat
   
   return found
   
end findtheMacaddress



on getPW(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)
end getPW



Posted on
Mon Sep 09, 2013 12:49 pm
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

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

this keychain access with ... security ... seems to pick the first username that it finds and returns that password. SO IF YOU HAVE THE SAME USERID ON DIFFERENT SYSTEMS IT WILL PICK ONE OF THOSE TO RETURN THE PASSWORD. if the password is the same you are ok , if not you might get the wrong password.

still thinking how to solve that.. the man page for "security" it pretty long..

Karl

Posted on
Mon Sep 09, 2013 11:21 pm
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

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

This version runs continuously in back ground and updates variables, which can be used as trigger.
just start once.

more details in the code.

this is alpha, but seems to work

Karl

[edit]
V 8.1 fixed quotes in one statement
[/edit]


Code: Select all

-- fingscan.app
-- build list of network devices using FING
-- runs in background, iddles for 30 secs then checks if FING has found new configs
-- creates variables with ipdevice info
--
--
-- Karl Wachs
-- Sep 9 2013
-- V 0.81
-- 0.81 one code fix, if IP number change: wrong quotes for variable
--
--
--

-- 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)
-- 
--  setup trigger "IPdevice22 down"
--      trigger if any change to ipDevice22
--      condition ipDevice22 must contain ";down"   down (without ; )probably also works, but your might have a device up or down or vendor 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 ever30 seconds and check fingdata for new info
-- will create/ update varibales ipDevicenn  nn = 01 .. 999
-- 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 poerONoff = 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.  data file is analzed by this script
-- regular read seems to conflict with fing, use cat with pipe into applescript variable.
--
-- needs to be fixed:
-- does not allow non consequtive ipDevice03 ..05  04 missing
-- double check get password
-- requires display dialog to run if new device detected, might be a problem if lauched in background
--


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
   set userName to short user name of (system info)
   set theDir to "/Users/" & userName & "/Documents/"
   set theFile to "fingdata"
   set theLog to "finglog"
   global numberofDevices
   
   -- init if needed
   setupFing()
   idle
end run


on idle -- every 30 seconds this gets executed
   
   global theDir
   global userName
   global theFile
   global theLog
   set lf to ASCII character 10
   
   -- 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
   if noOfDevices < 2 then -- read not successful .. must be more than 1 devices on network
      return 30
   end if
   
   
   -- 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 noOfDevices
   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
         tell application "IndigoServer"
            set ipDeviceValue to (get value of variable ipDevice) as text
         end tell
         set IndigoIpDevices to IndigoIpDevices & ipDeviceValue
      end if
   end repeat
   
   set newDevice to 0
   set ii to 0
   repeat while ii < noOfDevices
      set ii to ii + 1
      set nextLine to paragraph (ii) of FingContents
      set AppleScript's text item delimiters to {";"}
      set theItems to every text item of nextLine
      
      set theIPNumber to item 1 of theItems as text
      set theHostName to item 2 of theItems as text
      set theStatus to item 3 of theItems as text
      set theDate to item 4 of theItems as text
      set theAssignedName to item 5 of theItems as text
      set themacAddress to item 6 of theItems as text
      set theVendor to item 7 of theItems as text
      
      set same 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)
         set indigoIPNumber to trim(item 3 of theIndigoItems as text)
         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)
         
         if themacAddress = indigomacAddress then ---- mac number found, already in indigo
            set same to jj
            set jj to 999999
            set nickname to item 1 of theIndigoItems
            
         end if
      end repeat
      
      
      if same > 0 then
         set OOSame to same
         if same < 10 then set OOSame to "0" & same as text
         set theDeviceNo to "ipDevice" & OOSame
         set theDeviceValue to indigoNick & ";" & themacAddress & ";" & theIPNumber & ";" & theVendor & ";" & theStatus & ";" & theDate
         
         if theIPNumber = indigoIPNumber then
            if not (theStatus = indigoStatus) then
               tell application "IndigoServer"
                  set the value of variable theDeviceNo to theDeviceValue
               end tell
            else -- no change
               -- do nothing
            end if
         else -- ip number not the same, asign new IP, new status
            tell application "IndigoServer"
               set the value of variable theDeviceNo to theDeviceValue
            end tell
         end if
      else -- new device, set up    
         set newDevice to newDevice + 1
         set theDeviceName to "ipDevice" & (noOfIndigoDevices + newDevice)
         set theText to "please enter nickname for: " & themacAddress & ";" & theIPNumber & ";" & theVendor & ";" & theStatus
         set nickname to the text returned of (display dialog theText default answer "phonexyz")
         
         set theDeviceValue to nickname & ";" & themacAddress & ";" & theIPNumber & ";" & theVendor & ";" & theStatus & ";" & theDate
         tell application "IndigoServer"
            make new variable with properties {name:theDeviceName, value:theDeviceValue}
         end tell
      end if
   end repeat
   
   
   set rightNow to (current date) as text
   
   tell application "IndigoServer"
      set the value of variable "ipDeviceLastUpdate" to rightNow
   end tell
   
   
   return 30
   
end idle





on setupFing()
   global theDir
   global theFile
   global theLog
   global userName
   --check if fing is already running, if not start it.
   set pgmToFind to "fing.bin"
   set theResponse to " "
   try
      set theResponse to do shell script "ps aux | grep '" & pgmToFind & "' | awk '{print $2}' "
   end try
   
   -- if pgmToFind is running then theResponse has 3 lines with 1 PID from :     ps, xxxx itself and one more --- have not figured out which one..
   set noOfWords to count words of theResponse
   if noOfWords < 3 then -- if not running start script, remove old temp files and start fing
      set cmd to "rm " & theDir & theFile & " &"
      do shell script cmd
      set cmd to "rm " & theDir & theLog & " &"
      set yourPassword to getPW(userName)
      do shell script cmd
      set cmd to "echo " & yourPassword & " | sudo -S fing -o table,csv," & theDir & theFile & "  log,csv," & theDir & theLog & " >/dev/null  2>&1 &"
      do shell script cmd
      delay 10 --wait until fing has finished at least once
      
      set rightNow to (current date) as text
      tell application "IndigoServer"
         make new variable with properties {name:"ipDeviceLastUpdate", value:rightNow}
      end tell
      
      
   end if
   -- fing is running or has started
   
   
   
   return
   
end setupFing




on getPW(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)
end getPW

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
Tue Sep 10, 2013 12:57 pm
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

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

FINGSCAN: new version -

fixed some minor problems,
added lots of comments
add checking of FINGlog file, if no change in size, nothing happened:
- no further analysis of data.
- Makes code much more efficient and reacts faster to changes:
---- Between device change and update of variable in indigo is max 65secs


Karl


Code: Select all
-- fingscan.app
-- build list of network devices using FING
-- runs in background, idles for 5 secs then checks if FING has found new configs (checking FING logfile)
-- creates variables for each network device "ipDevicenn"  with info on device and current status (nickname, MAC# IP#, Vendor, Up/Down, last change date)
--
--
-- Karl Wachs
-- Sep 10 2013
-- V 0.9
-- 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 change skip further checks, faster reaction, and less code excution,  most of the time nothing changes. this will only check size of  file "finglog"
--
--
--
--
-- 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 poerONoff = 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 / loocked at:
-- does not allow non consequtive ipDevice03 ..05  04 missing
-- double check get password
-- requires display dialog to work if new device detected, might be a problem if lauched in background
--
--
--  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 anyChange
   set userName to short user name of (system info)
   set theDir to "/Users/" & userName & "/Documents/"
   set theFile to "fingdata"
   set theLog to "finglog"
   set lastLogFilesize to 0
   set logFilesize to 0
   set anyChange to "start"
   
   -- 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 anyChange
   
   if not (anyChange = "search") then -- skip logfile check if we are stiil waiting for data to arrive in fingData
      -- check file size of logfile, if its the same, return and check back in 5 seconds
      set cmd to "ls -l " & theDir & theLog & "| awk '{print $5}'"
      set logFilesize to do shell script cmd
      
      -- update indigo with time stamp
      set theTime to text -8 thru -1 of ((current date) as «class isot» as string)
      try -- just in case indigo is down, dont crash this program
         tell application "IndigoServer"
            set the value of variable "ipDeviceLastUpdate" to theTime
            --            log "FINGSCAN: " & logFilesize & "  " & lastLogFilesize & "  " & anyChange
         end tell
      end try
      
      if logFilesize = lastLogFilesize then return 5 -- check back in 5 secs
      
      
      -- something new, remember last file size
      set lastLogFilesize to logFilesize
      if anyChange = "start" then
         set anyChange to "found"
      else
         set anyChange to "search"
      end if
   end if
   
   
   -- 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
   if noOfDevices < 2 then -- read not successful .. must be more than 1 devices on network
      return 30
   end if
   
   
   
   
   -- 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 noOfDevices
   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
   
   
   
   
   -- all data read now compare if anything new
   set newDevice to 0
   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 AppleScript's text item delimiters to {";"}
      set theItems to every text item of nextLine
      
      set theIPNumber to item 1 of theItems as text
      set theHostName to item 2 of theItems as text
      set theStatus to item 3 of theItems as text
      set theDate to item 4 of theItems as text
      set theAssignedName to item 5 of theItems as text
      set themacAddress to item 6 of theItems as text
      set theVendor to item 7 of theItems as text
      
      -- tehn check if any mnatch in indigo data
      set same 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 same 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 same > 0 then -- found match in MAC number, now check if anything has changed
         
         if (theIPNumber = indigoIPNumber) and (theStatus = indigoStatus) then -- both the same
            -- do nothing
         else -- ip or status has changed, update indigo variable
            set anyChange to "found"
            set OOii to same
            if same < 10 then set OOii to "0" & same 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 anyChange to "found"
         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 entry : " & theDeviceName & "  " & themacAddress & "  " & theIPNumber & "  " & theVendor & "  " & theStatus & "   eg:"
         set nickname to the text returned of (display dialog theText default answer "phone-xyz")
         
         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 repeat
   
   -- house keeping, update ipDeviceLastUpdate and reset logfile once a day
   
   
   
   -- reset (= delete) logfile if  logfile if > 500KB
   if logFilesize > 500000 then
      set cmd to "rm " & theDir & theLog & " 2>&1 >/dev/null &" -- delete, dont wait, no error feedback
      do shell script cmd
   end if
   
   -- update indigo with time stamp
   set theTime to text -8 thru -1 of ((current date) as «class isot» as string)
   try -- just in case indigo is down, dont crash this program
      tell application "IndigoServer"
         set the value of variable "ipDeviceLastUpdate" 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 anyChange
   --check if fing is already running, if not start it.
   set pgmToFind to "fing.bin"
   set theResponse to " "
   try
      set theResponse to do shell script "ps aux | grep '" & pgmToFind & "' | 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, remove old temp files and start fing
      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
      
      -- start fing, send to background, dont wait, creat 2 output files:  one table format file and one logfile
      -- have to use sudo: pipe password from getPW() into sudo
      set cmd to "echo " & yourPassword & " | sudo -S fing -o table,csv," & theDir & theFile & "  log,csv," & theDir & theLog & " >/dev/null  2>&1 &"
      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 "ipDeviceLastUpdate")) then
            make new variable with properties {name:"ipDeviceLastUpdate", value:theTime}
         end if
      end tell
   end try
   
   
   return
   
end setupFing




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



Who is online

Users browsing this forum: No registered users and 8 guests

cron