Wednesday, May 30, 2018

Restarting an AirPort via AppleScript

Apples airports are great devices, but like so many “appliances” they need a restart once in a while. Apple has the newer models pretty well locked down. There is no web interface, nothing you can hit with a curl command and no SNMP or anything else to talk to to tell it to restart itself.

After I lost my entire wifi network the other day and I had to restart it manually I decided it was time to tackle the AirPort Utility via User Interface Scripting. It turns out you can do this, sort of... There are either bugs in the AirPort utility and it’s implementation of user interface scripting, even though you’re not supposed to have to implement it, it’s just there because of the OS, or there are some limitations to it that aren’t clearly documented.

The applescript to restart an airport is pretty simple actually, this handler will do it, sometimes:

on restartAirportByName(theName)
tell application "System Events"
tell process "AirPort Utility"
click (first image of group 1 of scroll area 1 of window 1 where its name starts with theName)
click menu item "Restart…" of menu "Base Station" of menu bar 1
end tell
end tell

end restartAirportByName


Note that handler doesn’t actually launch the AirPort Utility first, You should do something like:

launch application “AirPort Utility”
delay( 5)

Before calling that.

There are some gotchas right away, the ellipsis in the Restart menu item name is a UTF8 ellipsis character and not just three periods. If you use three periods it won’t be able to find the menu to click.

It won’t work if the application is hidden or the main window minimized. It does not have to be frontmost, but it cannot be hidden in any way.

The name of the “process” is case sensitive. It must have the same case as the actual application in order to match, even though much else of AppleScript is not case sensitive this is. It must be “AirPort Utility” or it won’t work.

Next the script or the host of the script must have assistive access turned on in order to use the UI scripting at all. You have to do that in the System Preferences, Privacy & Security pane under Assistive Access. This will also break if you are saving the script as an application and make any edits to it. You must go in and uncheck and recheck the checkbox next to the application you created or it will know that you changed it and won’t let it access the UI. Again, you don’t get the helpful error message that you’d get if you hadn’t added it to the list at all telling you that assistive access is not enabled for this program, it just fails to be able to do anything.

Beyond that there is something weird about how AirPort Utility processes the event, or there is a limitation for processes not specifically started by a user which may be the case. I would expect those to generate an error specifically telling you that you don’t have privs. Sometimes, or all the time depending on the OS version you get an error about a bad index when trying to get a reference to window 1. I’ve tried accessing the window by name and several other hacky work arounds but it doesn’t seem to matter. If you run the script from a program that has assistive access turned on, but wasn’t launched by the user you’ll definitely get this error at least once, and then it might start working for the second time. Or it might not.

In my testing the best solution is to embed that bit of script into an applescript saved as an application. Then you can give it privs to use assistive access and just launch it, or use some other system to launch the app. That seems to work. At least on OSX 10.13. There still seem to be problems doing these things on 10.12.

I’ve wrapped that and a whole lot more scanning and checking code including the ability to monitor your internet connection and get your external IP address into a larger script that talks to my home automation software of choice XTension (well it should be my choice as I’m one of the developers) which will definitely be useful for other XTension users as long as they are running an OS version that includes a less buggy AirPort Utility. That code is free and open and if you are interested in how to get the rest of that info out of it it’s also fully documented with comments in the code here.

No comments:

Post a Comment

.code { background:#f5f8fa; background-repeat:no-repeat; border: solid #5C7B90; border-width: 1px 1px 1px 20px; color: #000000; font: 13px 'Courier New', Courier, monospace; line-height: 16px; margin: 10px 0 10px 10px; max-height: 200px; min-height: 16px; overflow: auto; padding: 28px 10px 10px; width: 90%; } .code:hover { background-repeat:no-repeat; }