How I built a Sonos replacement app in 2014
Back in 2014 in my spare time I built an app to replace the default Sonos app used to control multiple speakers in a home. It was a little challenging so I thought I’d share the process. You can check out most of the code on Github.
![](https://nathan.run/screenshots/2014-01-01-play-icon.png)
Finding the API
First off I needed to understand how the existing app was communicating with speakers on the local network. Sonos doesn’t really have an official API so I had to do some digging with Wireshark.
![](https://nathan.run/screenshots/2014-01-01-play-wireshark.png)
Wireshark reveals all the network traffic, which allowed me to see what requests were being passed between the speakers and the app. Sonos uses UPnP and this established a base understanding of what was needed to build a new app.
Making a better experience
What bothered me most about the current app was it didn’t give me the controls I needed quickly. Most of the time all I wanted to do was change the volume and pair speakers (I also really wanted to make my living room play out of the Line-In input quickly without any fuss). Here were a couple solutions:
![](https://nathan.run/screenshots/2014-01-01-play-sketches.jpg)
I went through a bunch of iterations, mostly because it was fun. iOS 7 shipped in the middle of it all which forced me to simplify things and learn a new emerging visual language.
![](https://nathan.run/screenshots/2014-01-01-play-001.png)
![](https://nathan.run/screenshots/2014-01-01-play-002.png)
![](https://nathan.run/screenshots/2014-01-01-play-003.png)
![](https://nathan.run/screenshots/2014-01-01-play-004.png)
![](https://nathan.run/screenshots/2014-01-01-play-005.png)
![](https://nathan.run/screenshots/2014-01-01-play-006.png)
Each mocked version above was built to some degree. You can see all the iterations on Github. A lot of this is still in development and I’ll try to push improvements when they’re ready.
What about desktop?
Then I realized I wanted more than just an app on my phone, sometimes I’d be on my laptop and want to quickly adjust volume. So I decided to build a menu bar app. Volume is all I really needed here so I didn’t implement anything else.
![](https://nathan.run/screenshots/2014-01-01-play-desktop.png)
This was a lot easier once I abstracted out all the bits needed to control Sonos into a little library called SonosKit.
Can it be smarter?
The above was all nice but I began to notice another annoyance—I didn’t like having to turn my speakers off when I left my apartment. I had already figured out how to turn all my lights off with IFTTT so why not make this work with Sonos. Using a Raspberry Pi and a Sonos command-line interface I hooked up a very basic home REST API where I could detect my phone leaving a location using a geofence.
Now when I leave it makes a request to my home and the music turns off.
![](https://nathan.run/screenshots/2014-01-01-play-arduino.jpg)
Next up
The next thing I’m working on (aside from finishing some of the above stuff) is a way to determine an optimal state without having to interact with anything. By learning more about my listening habits I could automatically start playing one of three podcasts before going to bed or automatically start playing jazz on the weekends. All things I manually do on a pretty regular basis. Then I’m curious if I can use music to effect my mood—after a stressful day (i.e. lots of meetings on my calendar) I could let Sonos know and maybe start playing some chill music when I walk into my apartment.