Skip to main content
INFO



Source code here: https://github.com/jishi/node-sonos-http-api

Sonos Web Controller draft (work in progress!): https://github.com/jishi/node-sonos-web-controller

Sonos IR control (requires lircd and IR reciever): https://github.com/jishi/node-sonos-remote-control



==============================================================





I know that there already is an attempt at this by this guy: http://forums.sonos.com/showthread.php?t=32643, but I found it to be a bit lacking in functionality so I decided to write up my own.



I have created a simple web-based API using what I have, which could be useful for integrating stuff with other applications. This web based API is inspired by other RESTful APIs, however I don't think it follows the correct guidelines to be called a REST API.



IT supports most basic features like:



play, pause, seek, next, prev, volume, mute, setAVTransportURI



It also supports these advanced fatures:



State of player as JSON, zone info as JSON, Play favorite item, presets (grouping, volume, avTransportURI)



You can read more in the README for each project.



To run it as a service under linux, I suggest using pm2 (https://github.com/Unitech/pm2). You need to run it in forked mode (-x)!



For Windows, you might try Winser http://jfromaniello.github.io/winser/



Cheers!
Out of interest, what IDE do you use? Nodeclipse?



I just use sublime text and the command line.
I've submitted a pull request for to correct my (dumb) mistake. Hopefully it'll be accepted soon, and you'll be back in business.



Sorry again.
Thanks for the quick fix, I have merged the pull request now.
Excellent - many thanks Matt and Jishi:D
I have started working on the mobile version of the web controller, here is a quick screenshot:



http://upload.grabbarna.se/files/Screen%20Shot%202014-07-03%20at%2023.55.09.png



The good thing is that Chrome for Android now supports "Add to homepage" web apps, which means that you can hopefully get a native look and feel on it (Safari for iOS supports it as well).



My first target is an improved volume control (with percentage feedback and easier to adjust at low volumes). I'll try and keep you posted.
If you want to try out the mobile version, you can pull the "mobile" branch from sonos-web-controller, or download this:



https://github.com/jishi/node-sonos-web-controller/archive/mobile.zip



then visit http://IP:8080/m from your mobile browser. Only tested in Chrome for Android as of now. You can also try the "Add to homescreen" feature, which would open it up fullscreen.



Today only prev, play/pause, next and group volume works. And it will control the first zone that it finds, no way to select.
Thanks for your work. I've been using AirSonos for a couple weeks, and its awesome.
Thanks for your work. I've been using AirSonos for a couple weeks, and its awesome.



Thanks, but I can't take credit for AirSonos, haven't been involved in that at all. Looks really neat though!
Just tested the tts functionality and as long as nothing is playing it works great. However the fact that the que is replaced is a bit of a problem. I have seen a few mentions of the ability to save the playstate and then reload it afterwards. Any pointers as to how I could achieve that?
Hi,



I've been working on a little project recently and I've been using the node-sonos-discovery module to handle Sonos events. (Thanks for creating it, BTW, it's fantastic!) However, I think I might have found a small bug ...



During development, I stop/restart the discovery code many times, and it sometimes fails trying to subscribe to UPnP notifications. I see the following error in the console and then the discovery service just hangs:





{ [Error: connect ECONNREFUSED]

code: 'ECONNREFUSED',

errno: 'ECONNREFUSED',

syscall: 'connect' }





After poking about in the sonos.js code I discovered that it was trying to subscribe to events from my Phillips Hue Bridge! Here's an example of the response received:





HTTP/1.1 200 OK

CACHE-CONTROL: max-age=100

EXT:

LOCATION: http://192.168.0.108:80/description.xml

SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/0.1

ST: upnp:rootdevice

USN: uuid:2f402f80-da50-11e1-9b23-0017880a2371::upnp:rootdevice





I might be wrong (I'm not experienced with UPnP), but I assume that the variable PLAYER_SEARCH that is broadcast is intended to filter so that only Sonos devices respond? Maybe this isn't working quite as intended.



I've managed to work around this issue by hacking the code to check if the response contains the following string





urn:schemas-upnp-org:device:ZonePlayer:1





and ignoring any that don't. Not sure if this is the best solution though!



Anyway, thanks again for a great module and I hope this feedback is helpful to you!
Hi,



I've been working on a little project recently and I've been using the node-sonos-discovery module to handle Sonos events. (Thanks for creating it, BTW, it's fantastic!) However, I think I might have found a small bug ...



During development, I stop/restart the discovery code many times, and it sometimes fails trying to subscribe to UPnP notifications. I see the following error in the console and then the discovery service just hangs:







After poking about in the sonos.js code I discovered that it was trying to subscribe to events from my Phillips Hue Bridge! Here's an example of the response received:







I might be wrong (I'm not experienced with UPnP), but I assume that the variable PLAYER_SEARCH that is broadcast is intended to filter so that only Sonos devices respond? Maybe this isn't working quite as intended.



I've managed to work around this issue by hacking the code to check if the response contains the following string







and ignoring any that don't. Not sure if this is the best solution though!



Anyway, thanks again for a great module and I hope this feedback is helpful to you!




You are correct in the assumption that I only scan for devices matching the correct ST, and this has always worked on my network. My best guess is that the Hue does not respect this and replies anyway, in violation to specs.



With this in mind, it would be wise to check this on replying devices as well. If you send me a patch I will review it and merge it. Thanks for sharing the discovery, this might probably happen with a few other devices.
You are correct in the assumption that I only scan for devices matching the correct ST, and this has always worked on my network. My best guess is that the Hue does not respect this and replies anyway, in violation to specs.



With this in mind, it would be wise to check this on replying devices as well. If you send me a patch I will review it and merge it. Thanks for sharing the discovery, this might probably happen with a few other devices.




Thanks for the response!



I've forked the project, and I'm currently testing my patch in a branch.



Once I'm happy, I'll submit a pull request for you to take a look at.
OK - pull request sent!
OK - pull request sent!



Thank you very much! Hopefully this resolves this issue for a few users.
Thank you very much! Hopefully this resolves this issue for a few users.



No problem - thanks again for a great module!



I have a quick question, if that's OK? I notice that if I create a stereo pair from two speakers I get 4 topology-change events in quick succession (although not as a contiguous block - there are also some volume and transport-state events mixed in with the topology-change events.)



The events seem to be identical, so I can't work out why there is more than one! For instance, grouping the speakers creates just a single topology-change event, as I would expect.



It's not a big problem for me, as I can handle it by aggregating the events and treating them as a single topology-change. I was just wondering if this was something you'd experienced and if you knew why it happened?



Thanks!


I have a quick question, if that's OK? I notice that if I create a stereo pair from two speakers I get 4 topology-change events in quick succession (although not as a contiguous block - there are also some volume and transport-state events mixed in with the topology-change events.)



The events seem to be identical, so I can't work out why there is more than one! For instance, grouping the speakers creates just a single topology-change event, as I would expect.





No, never experienced that. Haven't tried the stereo pair though. However, receiving multiple topology events at a rapid rate is a "normal" scenario, I think that if you "ungroup" players you will get that behavior.



I thought I already aggregated this, but seems like I removed that code. It may be a good idea to do so, but remember to act on the last event and not void the following ones, to prevent that you are working on stale data.
No, never experienced that. Haven't tried the stereo pair though. However, receiving multiple topology events at a rapid rate is a "normal" scenario, I think that if you "ungroup" players you will get that behavior.



I thought I already aggregated this, but seems like I removed that code. It may be a good idea to do so, but remember to act on the last event and not void the following ones, to prevent that you are working on stale data.




Thanks for the advice!



And you're right - I get two events when I ungroup, although still just one when I first create the group. I wonder why Sonos does this ...?
Thanks for the advice!



And you're right - I get two events when I ungroup, although still just one when I first create the group. I wonder why Sonos does this ...?




My best guess is that each coordinator will send a topology trigger, one from the player that becomes it's own group, and one from the coordinator of the group which loses a player. However this is mere speculation.
I totally love this. Could not reliably get anything to work with WINE, whether on FreeBSD (my OS) or several of the Linuxes. Tried for months! :)



But this is awesome. Works great in FreeBSD. Thanks for writing it!



Z
This controller is great. I bought 4 players [along with 2 bridges] for my company. 3 will be placed in one building and the 4th in another. My goal is to basically have 2 instances of the controller giving the people in building 1 access to only those speakers and those in building 2 access to only their speaker. Is it possible to force the controller to only 'discover' the particular speaker(s) I want? I want to keep them all on the same network for many reason, but also so that I can control all speaker from another instance of the controller that would discover them all. Sound simple enough?
This controller is great. I bought 4 players [along with 2 bridges] for my company. 3 will be placed in one building and the 4th in another. My goal is to basically have 2 instances of the controller giving the people in building 1 access to only those speakers and those in building 2 access to only their speaker. Is it possible to force the controller to only 'discover' the particular speaker(s) I want? I want to keep them all on the same network for many reason, but also so that I can control all speaker from another instance of the controller that would discover them all. Sound simple enough?



Well, if you separate them as two different systems (households), this would be possible (with a small modification). However, that would not make it possible to control all of them from one controller.



I don't see a simple solution to the latter, if you want to "remove" the possibility to restrict access to some of the players. Maybe it would be possible to implement some sort of IP (or UUID or room-name) based blacklist, but I'm not sure how I feel about that. You would still require to limit the access to the different instances of the controller as well, otherwise they would just open up the other controller anyhow.



If you could elaborate on different user scenarios that you would like to support, I could give you a better answer.
basically i have multiple 'offices' that are all on the same network. I would like to be able to have 'sub' controllers so that 'Jim' can only see his speaker(s) and 'Joan' can only she her speaker(s). I'm not concerned about Jim being able to open up 'Joan's' controller as i can restrict that via apache/htaccess. I just want a way to see only certain speakers when opening up certain controllers?. Please forgive my ignorance, but is there a way to 'turn off' Sonos-Discovery so it doesn't search the network for devices but just use user-set ip addresses to access/control those specific devices?
Just wire up an additional Bridge, then associate the desired players and controllers off it it. Voila, two separate Sonos households which will not see each other.
basically i have multiple 'offices' that are all on the same network. I would like to be able to have 'sub' controllers so that 'Jim' can only see his speaker(s) and 'Joan' can only she her speaker(s). I'm not concerned about Jim being able to open up 'Joan's' controller as i can restrict that via apache/htaccess. I just want a way to see only certain speakers when opening up certain controllers?. Please forgive my ignorance, but is there a way to 'turn off' Sonos-Discovery so it doesn't search the network for devices but just use user-set ip addresses to access/control those specific devices?



So basically, the controller searches for players and the first one that responds will be the one I associate with (like a regular controller). This player will then give me info of the rest of the players that belongs to the same system (household). If you chose to setup two different systems, the controller will only see the first system it finds. To force a controller to a specific system, would require some sort of configuration (which would be easy to implement), but you would still only see players from a specific system, never both at the same time, and you can't pair players from two different systems because of this.



What perhaps would be possible, is to consider all your players a complete system, but controller 1 could not control player 4, and controller 2 could not control player 1,2,3. By control, I mean that they wouldn't be able to adjust volume, change track etc. However, if someone would install the official clients, this can no longer be enforced. The upside would be that you could still group all 4 players together, but would only be controllable by one of the controllers (depending on coordinator, initial player for grouping). This would be a lot more work, and I'm not sure if it's such a good idea either. If you don't have the requirement to group all 4 players together, then the split-system setup is enough.
I would be ok with having two different systems than could only be controlled independently but is that possible on the same LAN?