Controlling Sonos from node.js
A break from endless talk of automated lights and LEDs, and talk of a different part of the home automation project: music. Specifically, whole house audio using Sonos and how to control it via an API.
Sonos and Spotify (Premium) have genuinely changed the way we listen to music. Right now Alexa does not officially support controlling Sonos, but you can add your Sonos network to SmartThings via a not quite official app. This gives very rudimentary control of the system:
Alexa, turn on Kithcen Sonos.
That will effectively “press play” on that device along with all the Sonos kit that is currently grouped to it. To “press stop” you say:
Alexa, turn off Kitchen Sonos.
That’s it. No deeper control than that. It is very, very rudimentary.
I wanted to have more control over the grouping of the systems, volume fading, even the choice of track or playlist.
Step 1: Programmatic Control of Sonos
Enter an excellent bit of node.js code from jishi over on Github: node-sonos-http-api. The description on the repository says it best “A simple HTTP API for Sonos for easy automation. Hostable on any node.js capable device, like a raspberry pi or similar.”
Perfect. For those following along at home that means I can:
- Run this on the Pi I’m already using for Domoticz.
- Create apps on the SmartThings Hub that can call the API.
- Create complex rules that can then be called by Alexa.
I used SSH to connect to my Pi as a non-root user, and installed the code and used pm2 (overkill, maybe) to keep it running:
git clone https://github.com/jishi/node-sonos-http-api.git
cd node-sonos-http-api/
npm install --production
npm start
sudo service --status-all
sudo npm install -g pm2
sudo pm2 startup
pm2 start server.js -x --name "sonos-api"
pm2 dump
Now I can check the app is running with:
$ pm2 status
┌───────────┬──────┬────────┬───┬─────┬───────────┐
│ Name │ mode │ status │ │ cpu │ memory │
├───────────┼──────┼────────┼───┼─────┼───────────┤
│ sonos-api │ fork │ online │ 0 │ 0% │ 41.1 MB │
└───────────┴──────┴────────┴───┴─────┴───────────┘
Use `pm2 show <id|name>` to get more details about an app
With the service up and running, it exposes an API on port 5005. Connecting with a standard browser even shows some simple help:
From the Pi itself, the url: http://localhost:5005/Dining Room/volume/+20
will raise the volume by 20 points. You can add many other actions to the URL to control the system – muting, pausing, skipping or seeking in tracks, even using text to speech to send messages through Sonos.
Now for the fun part. I use a SmartThings routine to fade the lights up when our alarm goes off in the morning. At the same time, Sonos starts playing our wake up playlist. This starts quietly so as to not be too much of a shock, but what I really want is for it to fade up to louder volumes as the lights come up.
Since any of the Groovy code you write for SmartThings runs on the hub – inside your local network – you can consume any API you have access to. In this case I want some Groovy code that takes commands or sensor information from SmartThings and issues commands to the Sonos API. This is exactly the same behaviour we saw with the Domoticz dimmer switch handlers I wrote.
The documentation from Samsung on writing Groovy code for SmartThings is excellent. They have a tutorial that takes you through writing your first App – and all the code for the available apps and devices is in the Github repo to be picked apart for ideas. My next step is to pull apart the Gentle Wake Up app (designed for lights) and use bits of it to change audio. Beyond that, I’m toying with the idea of writing a proper Alexa Skill to allow better voice control of Sonos, but as Sonos and Amazon announced last year that 2017 would see the release of official integration, I’m playing wait and see for now.
SADNESS
Samsung killed Groovy and their developer IDE in September 2022. By this point most people had already moved to Home Assistant anyway. 😛
Enjoy Reading This Article?
Here are some more articles you might like to read next: