My wife just got a new job which has an irregular schedule and long hours. Unfortunately, I’d gotten accustomed to the fact that she always took care of feeding the cat and scooping her litter before I ever even thought about it. Now, a few weeks into this new job, I’m getting myself in trouble when I forget to feed the cat or scoop the litter. I imagine I’ll eventually get used to it, but until I do, I devised a clever way to get automatic reminders without me having to ask my wife her schedule every week and manually create the reminders, which means I’ll be less likely to forget. Hopefully, I’ll start to get used to the routine and I’ll be able to delete this reminder scheme, but until then, here’s how I managed to do it.
I’m one of those that does not normally restart my computer, however lately, the power in my office has been going out on a somewhat regular basis, which got me looking into finally automating the starting up of my iBeacon broadcasting. I had initially created a very quick automator app long ago by recording the 3 clicks it took to start the app, clcik the broadcast button, and then hide the window, but I found that, while it worked when I manually ran it, it always failed upon login (when set as a login item) with this error:
I was able to reproduce this error simply by messing around with (clicking) the mouse as the workflow ran, so I figured that had to have been the problem. Usually when I log in, I get asked for passwords and such and am rearranging windows on desktop spaces they’d been pulled from as a result of the logout. I sent a complaint via apple feedback regarding this issue:
Automator won’t run properly as a Login Item
I created an Automator “app” called “Toggle iBeacon Broadcasting”. I created it using the record feature. All it does is click on the BeaconOSX app in my dock, click the “startBroadcasting” Button, and finally, clicks the yellow hide button of the window. I put it as a Login Item so that my Mac would always be broadcasting an iBeacon signal. However, every time I log in, I get this uninformative error: [The action “Watch Me Do (Toggle iBeacon Broadcasting)” encountered an error. Check the actionʼs properties and try running the workflow again.] And every time I run it there-after, it runs fine. However, I was able to reproduce the error by clicking the mouse while it ran, so perhaps automator should detect stuff like that and pause with a dialog asking if it should proceed? Just a thought.
So since the recorded automator workflow had problems with mouse interference, I decided to try an applescript. The first problem I encountered was obtaining the app interface (and you’ll see this ends up being a recurring issue on multiple fronts). I have a handy applescript called getAppInterface that elucidates an app’s “accessibility” features, and the applescript language necessary to get to them, but I got an error from the system saying that Fastscripts (the menu-bar app I use to run scripts) didn’t have “assistive access” (despite it being in there already):
Error Number:System Events got an error: FastScripts is not allowed assistive access.
I’ve encountered this issue before. Apparently, if you edit a script or an app you’re developing, assistive access must be refreshed. So you have to remove and re-add it from the security preferences pane. More on enabling assistive access below, however something about Fastscripts must be changing, and I didn’t want to get into it. Running the script from applescript however worked and I was able to get the handles I needed to write the applescript that will start up the app, start broadcasting, and hide the window. It’s a pretty simple script:
tell application “BeaconOSX” to activate
tell application “System Events”
tell application process “BeaconOSX”
click button “Start Broadcasting iBeacon” of window “BeaconOSX”
click button “startAdvertising” of window “BeaconOSX”
click button 3 of window “BeaconOSX”
Note that the BeaconOSX app, as written, sometimes changes the button text of the start broadcasting button, so we try both if the first attempt does not work. If the button text is “Stop Advertising”, nothing will happen.
I added the applescript directly to my login items, but upon testing, I eventually concluded that the script was either not running or quietly failing. Regardless, I suspected that the accessibility security features could be again interfering with the functioning of the script and that perhaps Apple just had not built in a way to allow individual scripts assistive access. I didn’t want to deal directly with that, so I sent Apple another piece of feedback:
Too many hoops for login item scripts to get it to work
I had an automator-created recording that was not working (for unrelated reasons), so I wrote an applescript to start an app called BeaconOSX & click it’s broadcast button. The script runs fine manually, but adding it to my login items results in it quietly failing, after which the BeaconOSX window weirdly disappears. (Sometimes I can glimpse it in Mission Control by right-clicking the app in the dock & selecting show All Windows, but it promptly disappears for good once I select it.) Then I tried running it embedded in an automator app set as a login item. Finally I got asked to grant the app access in the security prefs upon login, after which, it worked, albeit very slowly (perhaps 20 seconds after login). The applescript should have worked without the automator wrapper.
Note, the feedback mentions another oddity: the disappearing of the iBeacon window. I do not believe this had anything to do with iBeacon itself, but rather the windowing system losing track of the window – perhaps because of the assistive access issue. Again, I didn’t want to deal with it – I just wanted something that would allow me to start up the broadcast reliably.
To get around this, as I alluded to in the feedback, I returned to Automator to embed the script in an app for which I could enable assistive access. Here’s how to do it:
Create a new automator application (not the default workflow) and drag the “Run Applescript” action from the main library to the pane on the right side and in between the “on run” / “end run” lines, replace whatever’s there with the above applescript. Save that as “StartiBeacon.app” and then add the app to your login items (System Preferences -> Users & Groups -> Current User (left pane) -> Login Items (tab)) by dragging it into the list of login items.
Then go to System Preferences -> Security & Privacy -> Privacy (tab) -> Accessibility (left pane)and add your app there as well. If you do not perform this step, the next time you log in, you will get the following error/notification combo:
Clicking the “Open System Preferences” button will bring you to this preference pane:
All you have to do is check the checkbox next to the StartiBeacon app listed there. Though you may need to unlock the preferences pane by clicking the lock icon in the lower lefthand corner. If you do that, you’ll be asked for your password:
After doing this, the next time you log in, your beacon should start broadcasting automatically, though I noted that it didn’t run for me until about 10-20 seconds after logging in.
This post is more of a description of what I went through to get this all to work. if there is a desire for a simple step-by-step how-to, please request it in the comments. I still have not managed to figure out how to tweak the iBeacon settings to get notifications at the expected distance, though I will say that one thing I’ve learned that is non-intuitive is that the higher you set the power, the better the accuracy of the distance measure. I believe, if I recall correctly, there’s a default distance that’s pretty short, though I’m still very vague on the details. That’ll be part 3 if I ever get it refined to go off just as I get into my office.