This post originated from an RSS feed registered with Ruby Buzz
by Patrick Lenz.
Original Post: Last One Out Turn Off the Music
Feed Title: poocs.net
Feed URL: http://feeds.feedburner.com/poocsnet
Feed Description: Personal weblog about free and open source software, personal development projects and random geek buzz.
With the holidays quickly behind us, you’ll likely start leaving your house again. Now, while some don’t like Sonos products for some reason, yours truly likes them tremendously, as voiced numerous times on this very blog.
If you’re anything like me, the first thing you do after you open your eyes is to throw a playlist or two onto your Sonos system, even before you start your morning routine. My playlists have a tendency of running long, though, and more often than not I find myself returning back home with the music still playing, because I was so busy remembering all the things I needed to take with me when I left that I didn’t remember to pause the music.
Given the current availability of location-aware automation tools, I thought it shouldn’t be too hard to find a solution for this that didn’t involve a daily reminder in iOS.
iOS Reminder
Turns out, Sonos refuses to cooperate with services like IFTTT, which would make this a breeze to implement. Bummer. (It also looks like the Sonos Controller for Mac isn’t AppleScriptable. A bummer as well.)
I did, however, find a Ruby implementation of what you could call a “Sonos API”, which is based on UPnP (Universal Plug and Play). With this little gem and a little spit and glue we can still make this work.
What we need
The solution comes down to three ingredients:
The IFTTT iOS App to trigger the actual location change
The aforementioned sonos gem to interface with the Sonos speakers
A (powered on) Mac with Hazel, that watches a folder in Dropbox
Let me walk you through it.
IFTTT Setup
The IFTTT App has a special channel called iOS Location, which can trigger either when you’re entering or leaving a certain location or area.
For the Action, we’re simply creating a file in Dropbox. By default, IFTTT will put this into the IFTTT/iOS Location folder. It’s up to you where you put it, simply remember the file’s location for the Hazel setup a few paragraphs down.
The contents of the file don’t matter, either, although we’ll look at a way to make use of the file contents in the bonus section below.
What is important is the filename. Quick tip: when you initially set up the rule in the iOS App, you have to go back in and edit it in order to be able to set the filename. I’m using sonos_pause in my example, as you can see below.
The IFTTT action
(Now, while I could share the ready-to-consume action directly over IFTTT with you, there’s little point in stopping your Sonos system when you’re leaving my house, I guess.)
Sonos Rubygem
Since the Sonos Controller for Mac doesn’t have an AppleScript dictionary, as mentioned above, we need to resort to other means in order to be able to control the Sonos speakers from afar.
To install the sonos Rubygem, execute the following commands in the Terminal:
$ sudo gem install sonos
(You may have to provide your user's password at this point.)
Sidenote: The latest released version of the Gem has an issue properly detecting stereo pairs and surround/subwoofer setups. I sent a pull-request to fix this. Until that is merged, you can download a patched version of the Gem if you have a stereo pair or a SUB in your environment.
Hazel Rules
In Hazel, add the IFTTT/iOS Location folder as a folder to apply rules to.
For the conditions, all we care about is the fact that the file needs to be called sonos_pause. When such a file is matched, we execute an embedded shell-script, which is quite simple indeed.
(The only reason for the source command is my rbenv environment. You can probably leave it out if you use the stock OS X Ruby setup.)
When the script is done, we move the file to the trash, so that the rule isn’t triggered over and over again.
The Hazel Action to pause Sonos playback
And that’s it! Now, when you leave the geofence you set up in the IFTTT iOS app, a file will be created in you Dropbox, synced to your Mac, where it’s picked up by Hazel to execute the script to pause Sonos playback.
Easy, huh? (Yeah, I know.)
Bonus: Start playback when you get home
Of course, the pause action is easily reversed with a play action.
In IFTTT, set up another recipe to trigger when you enter an area, create a different file in Dropbox (I suggest sonos_play), and add a new Hazel rule to watch for that filename.
Starting to play in a multi-room Sonos setup could be unpredictable, though. For one, you wouldn’t want all rooms to play. And also, the volume could be set to a devastating value, as you could’ve been blasting Gary Clark Jr. before you left the house.
For those reasons, we’ll whip up a script that’s a little more sophisticated. It will purposefully set the volume to a value of 10 before starting playback. And it will take the name of the room to start playing in from the textfile.
Just make sure that you put the exact name of the room to play into your IFTTT Recipe.
The Hazel Action to play Sonos in a specific room
Assuming you have a Sonos setup in the office, this could totally be used for an office prank. If you set up an corresponding Hazel rule, you could, for example, play the intro music to “The Office” when you get into the office. Then again, maybe not.
Future optimisation: Multiple users?
What if you have multiple rooms and multiple Sonos users, meaning that you don't want to pause while there's still somebody at home or at the office? I don’t have a ready-to-share solution for this scenario, but here’s an idea: If everyone is equipped with the IFTTT iOS App, you could track (using the “Append to file” action, maybe) who entered the geofence and only pause Sonos after the last one has left the house again.
Can you come up with any other creative uses for IFTTT with Sonos? Shoot me an email.