Skip to main content

Sonos Control with the Amazon Echo - How I did it

I've had my Amazon Echo for a year or so and one thing that I've wanted ever since I purchased it, is to be able to use voice commands to control my Sonos speakers.  I waited patiently (OK  not patiently) for Sonos skill to appear on the Echo but it still hasn't come.  I was encouraged when Sonos announced it was going to focus more on voice but still nothing.  Isn't there any way to control my Sonos with my Echo?

Yes - sort of.

WARNING: This post is not for the faint of heart because the solution is not trivial.

So, I found a project on github that uses another project on github combined with a custom skill on
the Echo via a web service hosted by AWS Lambda.  OK, that was the easy part.  I knew that going in.  That's why, initially, I waited.  There must be an elegant solution out there.  I searched and waited and searched again and waited again.  Finally I decided to give it a try.  If it worked it would be really cool.  If it didn't, well I'm no worse off than before.

Now that it was decided, I sat down and went through the instructions provided by Ryan Graciano.  Here are the instructions with my extra notes.

Get jishi's node-sonos-http-api working

  1. Install node.js on a server on the same network as your Sonos.
    • Oddly enough, I didn't see this step which may have been a good thing because I may have done it wrong.  
  2. Grab and run it on that server. On Mac, it's "npm install", then go to the directory created and "npm start".
    • So I tried the command and, not unexpectedly, it failed miserably.  OK now I have to find out what "npm" is and how to install it.  Here's what I did.
      • I found the npm website and created an account (not sure if I really needed to do that)
      • Downloaded the program from 
        • This was hard to find because there are a lot of options and it took a bit to find the right one (it was the node-v6.3.1-x86.msi for my 32 bit Windows machine) 
      • Installed the program 
    • Then I had to grab the node-sonos-http-api - the instructions say use the following command "npm install"  
      • Tried it and it failed spectacularly (tons of error and warning messages) 
      • One of the first errors was "Error: not found: git" - I guess I need git as well 
        • Download git from 
        • Install git 
        • I chose to use the windows cmd.exe and the rest were the defaults 
        • Tried it again - it errored off 
        • Remembered that I just installed git so my DOS window that was already open wouldn't have the new environment variables.  I closed the window and opened an new one 
        • Tried it again - SUCCESS 
          • There were some warnings but it worked!
  3. Take the node-sonos-http-api/presets.json that I have here and drop it into your node-sonos-http-api root directory. Modify it to use your speaker names and your favorite stations. Don't worry about the "uri" field - it's unused. Make sure the preset names are lowercase (like "test" and "rock" in my example). NOTE: You can skip this step if you only want to use Playlists and Favorites, which require no configuration.
    • OK - I found the directory on the website that referenced the presets.json file but, instead of downloading the file, it brought up the file text.
      • Fine - I copied the file text (control c is my friend)
    • Found the node-sonos-http-api root directory and created the presets.json file with the data I copied from the web page.
  4. Test it by hitting http://yourserverip:5005/zones
    • I opened up Internet Explorer and tested it out - it worked!!
  5. If you get a response, great! Now try playing something: http://yourserverip:5005/preset/[your_preset_name]. Or, play a Playlist or Favorite (example: http://yourserverip:5005/kitchen/playlist/myplaylist). To stop, use /pauseall.
    • Also worked!
  6. If you have problems, make sure you are on the same network as your Sonos AND make sure you don't have a Sonos client running on the same machine. The client can interfere with the node.js server.

Expose your server to the outside world

  1. You need some way for Lambda to contact your server consistently. Services like DynDns and will give you a consistent hostname for the outside world to use. If you have an Asus router like I do, then dynamic DNS is actually a built-in / free feature.
    • I have an ASUS router so this should be easy - yay!
  2. On your local router, find the "Port Forwarding" configuration. Forward all inbound requests to 5005 (or configure some other port) to your node server.
    • Logged into router settings 
    • Set up a dns name for my connection ( 
    • WAN -> DDNS 
    • Set up port forwarding  
    • Tested it: 
    • It worked!!
  3. Make sure your server has a locally static IP, so port forwarding doesn't lose track of it.
    • Did that.
  4. Setup your server to auto-start or daemonize the node-sonos-http-api server.
    • I did not do this as I don't intend for my desktop to be a server.  I am aware I will need to manually restart the application if I ever log out or reboot my desktop.
  5. Test it by hitting http://yourdyndnsaddress:5005/zones.
    • It worked!

Create the Alexa Skill that will send events to AWS Lambda

  1. Create a new Skill in the Alexa Skills control panel on Amazon. You need a developer account to do this. The account must be the same as bound to your Echo, and make sure you are logged into that account on You will get access denied if the two accounts are different.
    • I went to and signed up for a new account.
  2. Name can be whatever you want. "Invocation" is what you say (I used "Sonos").
    • I used Sonos as well - it's my Sonos after all
  3. Check Custom Interaction Model if it is not already checked. Click Next
  4. Click Next, taking you to Interaction Model. Create a Custom Slot Type ("Add Slot Type"). Add a new type for PRESETS, another for ROOMS, and a final one for TOGGLES. Into each, copy/paste the contents of echo/custom_slots/PRESETS.slot.txt, echo/custom_slots/ROOMS.slot.txt and echo/custom_slots/TOGGLES.slot.txt.
    • Here once again I copied the text of the files from the github site and pasted them into the appropriate boxes.
  5. Still in Interaction Model, copy this repo's echo/intents.json into the "Intent Schema" field, and echo/utterances.txt into "Sample Utterances".
    • More cutting and pasting.
  6. Don't test yet, just save. Click back to "Skill Information" and copy the "Application ID". You'll need this for Lambda.

Configure the AWS Lambda service that will trigger your node-sonos-http-api server

  1. Create an AWS Lambda account if you don't have one already. It's free!
    • It free! but Amazon still requires a credit card number so they can charge you for any non-free services.  That almost did it for me but I had come this far and I wanted to finish it.
  2. In the Lambda console, look to the upper right. Make sure "N. Virginia" is selected, because not every zone supports Alexa yet.
    • He's not kidding here.  I picked one in the western US and it didn't work at all, I had to recreate my whole service in the N. Virginia zone.
  3. Create a new Lambda function. Skip the blueprint.
  4. Pick any name you want, and choose runtime Node.js.
  5. Go into this repo's lambda/src directory and copy options.example.js to options.js. Edit options.js to have your DynDNS hostname, your port, and the Alexa App ID you just copied.
    • Created a directory on my desktop and copied the text into the options.js file.
    • Made the updates as directed.
  6. In lambda/src, zip up everything. On Mac/Linux, cd src; chmod a+r *.js; zip *.js. Make sure you don't capture the folder, just the files.
    • Once again, I cut and pasted the text from the github source into the files on my desktop.
  7. Choose to upload the zip file for
  8. The default handler is fine. Create a new role of type Basic Execution Role. Pick smallest possible memory and so on.
    • The role options have changed.  I just picked custom role and named it something.  I don't know if that was right or not but it let me continue.
  9. Click Next to proceed. Once created, click "Event Sources".
    • This has been changed to triggers.  It took me a while to figure that out.  I actually tried skipping it at first but the thing wouldn't work.
  10. Add a source. Choose "Alexa Skills Kit".
  11. Test it out. I included a test blueprint in this repo. Click "Test" and copy/paste this repo's lambda/play_intent_testreq.json to test. It will trigger the "test" preset in your presets.json file on your Sonos server. Don't forget to replace the Alexa App Id again.

Connect Alexa Skill to AWS Lambda

  1. In the Lambda console, copy the long "ARN" string in the upper right.
  2. Go back into the Alexa Skill console, open your skill, click "Skill Information", choose Lambda ARN and paste that ARN string in.
  3. Now you're ready to put it all together. Try "Alexa, use Sonos to play test"
And we're done!!  It's going to be so awesome!!  I try it out: "Alexa, tell Sonos to pause all" - It work's!!  "Alexa, tell Sonos to play playlist My Favorites in the Kitchen" - nothing.  "Alexa, tell Sonos to play favorite My Favorites in the Kitchen" - nothing.

OK - I can play and pause but I can't play playlists or favorites.  Not cool.

I do some research and dig through forums.  OK - it looks like it doesn't work right on node.js versions higher than 4.x and I have version 6.3.1. 

So I uninstall node.js 6.3.1 and install version 4.4.7 and restart the server.

Now it works!  Well, mostly.  It has a hard time with multi-word playlists and almost all of my playlists are multi-word.  Well, apart from that, it works.

I'm going to play around with it for a while and, if I can get it working like I want, I'll get a raspberry pi computer and run the whole thing from there.  More to come...


Jeff said…
I have successfully transferred my Sonos controller from my Windows PC to a Raspberry Pi PC. Read how I did it here:

Popular posts from this blog

Insteon: Controller vs Responder

This entry is going to be more of a technical article.  If you're not planning on setting up scenes in an Insteon environment, this isn't for you.  If you are or like me, have been running into some confusion about what should be set up as a controller, what should be a responder, and what should be both.  Here's what I learned.

I've been using Insteon switches for a couple of years now and had set up a few scenes.  When adding a switch to a scene, you have the option of adding it as a controller, a responder, or both.  Not knowing the difference and wanting to cover my bases, I set all of my scenes to both.  Since my scenes were all timing type scenes (e.g. turn on night lights at sunset) it worked fine.  Then I added an 8 button keypad and started programming the buttons to control other lights.  The program for this, of course, is a scene.  Once again, I set every switch and button as both a controller and a responder.  Then I created a scene, specifically for my E…


I just finished reading The Agony and the Ecstasy by Irving Stone. It's a biographical novel of Michelangelo (you know, the famous sculptor/artist whose statue of David and the paintings in the Cistine Chapel are super famous) that gives a very interesting view of his life. It seems that while Michelangelo had a very productive life, it wasn't a very happy one.

One of the first things that I noticed about Stone's portrayel of Michelangelo is that he was obsessed with creating sculptures and a true perfectionist. For a large portion of his life (into his 60s it seems) his every action was calculated toward a goal of sculpting marble - either getting a commission or improving his talent (or both). Not only did he want to sculpt, he wanted his pieces to be as real as possible.

His obsession with carving perfect sculptures drove him to do endless studies of the human form. He even spent months sneaking into a morgue to dissect bodies so he could figure out how the body real…

Insteon Hub - The Achilles Heel of Insteon

A couple of weeks before Christmas, my Insteon hub died.  There were no pyrotechnics or alarms and to the disappointment of the TV generation, nothing exploded and no people were thrown across the room.  What did happen is that I tried to turn on some lights with my Amazon Echo and it told me that it couldn't connect to the Insteon hub.  That's weird - so I took a look at it.

The Insteon hub is a plain, white, square device with a single light on the front that is green when all is well and red when there's a problem (usually a network issue).  I looked at the hub and the light was off.  That's new.  I unplugged it and plugged it back in.  Nothing.  I hit the reset button (which I had never before used).  Nothing.  It was dead as a doornail.

This was quite a surprise.  My hub had served me well for over two years.  Even worse, the two year warranty had expired a couple of months before.  Bother!

However, all was not lost.  All of my Insteon switches still worked.  All…