SONOS speaker API overcomes app limitations (Updated 2/27/25)
What are SONOS speakers? I have several Sonos brand speakers in several rooms around my house. Sonos speakers are small, LAN based devices. There’s a Sonos app for your phone or computer. With the app, you can control what sound files play on the speakers. The files can come from a streaming service like Spotify, an Internet radio station, an audio book service like Audible and Libby, and just plain, old music tracks that you downloaded or ripped from vinyl , cassette , and CD (follow the links if you’re too young to know what those are). The speakers provide a flexible listening experience. You can group speakers together so that all the speakers are playing the same thing — in perfect sync! You can have multiple groups — e.g., one playlist running on the 2nd floor speakers, a different playlist simultaneously running on the 1st floor and a third running in the basement. Speakers can either be a mono or paired together into stereo left and right. You can even play a separate playlist on each speaker. This is all controlled via the app. What’s not to like? As much as I like Sonos, I don’t like the app. It’s difficult to find the functions I want to perform. Certain functions are missing. To wit: Every speaker can be set to a different volume level, but there are times when I want to set the volume on all speakers to the same value. For example, when I want to play soft background music during a house party. The app requires that I set the volume for each speaker individually. I’d much prefer a button that says “Set the volume on all the speakers in <<group>> to the same level as the group’s softest/loudest speaker.” What to do? So I searched for “Is there an API to control SONOS speakers?”. It turns out there is! But it’s quite complex. So I asked, “Is there a Python library for the API?” AND THERE IS! It’s called soco and was written by a group of SONOS fans. Here are some of the functions: Get a list of all speakers/groups Get a list of playlists Get the list of tracks queued for a speaker/group Send a playlist to a speaker’s/group’s queue Get/Set the volume on a speaker Play/Pause the queue of a group/speaker I quickly wrote code on my laptop to implement my “volume” function. But I wanted more. What else? My wife wants to blast her workout playlist when she’s in the home gym. But she struggles with the app more than I do and usually has to ask me to do it for her. So I wanted to give her a button on the wall of the gym that she could push. The button would send her workout playlist to the “Gym” group (clearing whatever might have been queued there previously), shuffle the queued list, turn up the volume and starting playing. It didn’t take long to complete the code on my laptop . But how to run this from a button press on the wall? My first attempt was to migrate my “workout” code from my laptop to a Pico W. Total failure. The Pico runs micro-python or CircuitPython — neither of which can support the soco library which has a very deep dependency list. Attempt 2: Migrate to Raspberry Pi Zero W. That actually worked, but, as small as it is, the Zero wouldn’t lend itself to a button on the wall. Attempt 3: I recently learned how to use MQTT and I have a broker running. So I figured to use the Pico W for the button on the wall. On push, it would publish a “sonos/play” message. The MQTT broker sends that message to the RPI Zero W subscriber. The RPI Zero then makes the calls to the SONOS. That worked wonderfully. The only thing that remains is getting the subscriber on the Zero to start up and stay active after a reboot and to make a container for the Pico/button. Let the music play! Enclosure After several prototypes using card stock, I made a case for the circuit. I used the free BOXES.COM tool. Once you choose the kind of enclosure, (closed box, hinged box, drawer box, etc.) you fill out a form with the box dimensions. I picked a closed box and set height, width and depth measurements in millimeters. There are a few other options that deal with kerf, material thickness, etc. Then I downloaded a cut sheet in .svg format and fine tuned it in Inkscape. Fine tuning consisted of adding labels and cutouts for the components. I sent the .svg to the laser cutter and ended up with: a finger joint box. Of course, it wasn’t until after everything was cut that I noticed the knot right where the title is. While I was at it, I created boxes for my CO 2 monitor and my display that cycles between outside temperature and wind chill. The post SONOS speaker API overcomes app limitations (Updated 2/27/25) first appeared on Workshop88 .