MacOS – How to write an AppleScript that downloads Wi-Fi network status from router’s web interface

applescriptgoogle-chromejavascriptmacostext;

Objectives:

I want to create an AppleScript .scpt file that does the following:

  1. Accesses a router's webpage (i.e., its IP address).

  2. From this webpage, gets the IP addresses that are currently connected to both networks. (By "both networks", I refer to the separate 2.4Ghz and 5.0Ghz wireless networks.)

  3. From the webpage, gets the respective Dbm signal strengths of each connected device (i.e., each connected IP address).


Implementation:

I want one AppleScript list object to contain all of the IP addresses:

  • E.g.: theListOfIPs contains {"192.168.0.1", "192.168.0.", "192.168.0.3", "192.168.0.4", "192.168.0.5", "192.168.0.6.", "192.168.0.7"}.

(I do not have the need to differentiate between the IPs that are connected to the 2.4GHz network and the IPs that are connected to the 5.0GHz network. All IPs should simply be contained in theListOfIPs.)

And, one AppleScript list object to contain their corresponding signal strengths:

  • E.g.: theListOfTheirSignalStrengths contains {"0", "-75", "-40", "0", "0", "-63", "-72"}.

Notes:

  • I would like all of this to be completed "behind the scenes." Unobtrusiveness is really key, because the script will need to periodically check the router's website for network updates.

  • Ultimately, changes to the network status will be written to a .txt log file, and an alert notification will be displayed, when certain conditions are met. I know how to code these components; I need help actually importing the data into the script.

  • Browser of choice: Google Chrome


Background:

I have used the shell command , curl, before, in order to import the unabridged HTML source code of a given website into an AppleScript, as a text object. I understand that, sadly, one cannot similarly or conveniently get all JavaScript elements into an AppleScript as a single text object.

Instead, one must get each and every JavaScript element individually, by some identifier, like its id, class, tag, or name. This makes things more complicated (because you can't simply parse everything in AppleScript).

By using Chrome's Inspect feature, and the Elements pane of Chrome's JavaScript console, I've determined the relevant JavaScript identifiers. The two JavaScript element IDs that contain all IP addresses, as well as their signal strengths, are wifi-24 and wifi-5.

Can someone teach me how to write the necessary JavaScript code correctly, and then parse the resulting HTML text, to isolate the basic network data that I desire?


Best Answer

Based on the discussions had, this should handle the original scope of the question.

Note: This is example code and does not contain much, if any, error handling. I'll leave that to you since this is only a portion of the overall script, once you put all the other pieces together.

--  # 
--  #   Get the target information from theTargetURL in Google Chrome.
--  #   
--  #   Do this in the background, so get the 'tab id' and 'window id' of
--  #   the target URL ('theTargetURL') if it exists, and process accordingly. 

set theTargetURL to "http://192.168.1.1/0.1/gui/#/"

tell application "Google Chrome"
    if running then
        set theWindowList to every window
        repeat with thisWindow in theWindowList
            set theTabList to every tab of thisWindow
            repeat with thisTab in theTabList
                if theTargetURL is equal to (URL of thisTab as string) then

                    --  #   Get the targeted content of the web page which contains the information.
                    --  #   Note that document.getElementById(elementID) can only query one
                    --  #   element at a time, therefore call it twice, once with each elementID.

                    set rawWiFi24HTML to thisTab execute javascript "document.getElementById('wifi-24').innerHTML;"
                    set rawWiFi5HTML to thisTab execute javascript "document.getElementById('wifi-5').innerHTML;"

                    tell current application

                        --  #   Process the 'rawWiFi24HTML' and 'rawWiFi5HTML' variables.
                        --  #   Setup some temporary files to handle the processing.

                        set rawHTML to "/tmp/rawHTML.tmp"
                        set rawIP to "/tmp/rawIP.tmp"
                        set rawDBM to "/tmp/rawDBM.tmp"

                        --  #   Combine the value of  the'rawWiFi24HTML' and 'rawWiFi5HTML' variables into the 'rawHTML' temporary file.

                        do shell script "echo " & quoted form of rawWiFi24HTML & " > " & rawHTML & "; echo " & quoted form of rawWiFi5HTML & " >> " & rawHTML

                        --  # Process the 'rawHTML' into the 'rawIP' and 'rawDBM' temporary files.
                        --  # These files will contain comma delimited content of the targeted info.

                        do shell script "grep 'IP:' " & rawHTML & " | sed -e 's:</span>.*$::g' -e 's:^.*>::g' | tr '\\12' ',' > " & rawIP & "; grep 'device.parsedSignalStrength' " & rawHTML & " | sed -e 's: dBM.*$::g' -e 's:^.*\"::g' | tr '\\12' ',' > " & rawDBM

                        -- Process 'rawIP' and 'rawDBM' temporary files into 'theIPAddressList' and 'theSignalStrengthList' lists.

                        set theIPAddressList to my makeListFromCSVFile(rawIP)
                        set theSignalStrengthList to my makeListFromCSVFile(rawDBM)

                        --  #   Clean up, remove temporary files.

                        do shell script "rm /tmp/raw*.tmp"

                    end tell

                end if
            end repeat
        end repeat
    end if
end tell

--  # Handler used to create a list from a CSV file.

on makeListFromCSVFile(thisFile)
    set thisFilesContents to (read thisFile)
    set AppleScript's text item delimiters to {","}
    set thisList to items 1 thru -2 of text items of thisFilesContents as list
    set AppleScript's text item delimiters to {}
    return thisList
end makeListFromCSVFile




--  #########################################
--  #   
--  #   Checking the output of the code:
--  #   
--  #   The following commands are here just to show the contents
--  #   of the two lists displayed in a default list box, and then a way 
--  #   both lists might be combined, the output of which is logged.
--  #   
--  #   This of course can be removed after testing is finished.
--  #   
tell current application
    --  #
    choose from list theIPAddressList & theSignalStrengthList
    --  #
    repeat with i from 1 to (count of theIPAddressList)
        log "IP: " & item i of theIPAddressList & " @ " & item i of theSignalStrengthList & " Dbm"
    end repeat
    --  #
end tell
--  #   
--  #########################################

I do have to say that generally speaking, one is not supposed to parse HTML with tools like grep and sed, however, for certain pages, like in this use case, it's pretty safe to do. Although, if it breaks, it's not hard to fix.