Sonos with node.js, my attempt!


Userlevel 4
Badge +14
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!

This topic has been closed for further comments. You can use the search bar to find a similar topic, or create a new one by clicking Create Topic at the top of the page.

397 replies

Userlevel 4
Badge +14
One theory is that you started it in cluster mode once, which would have made the pm2 daemon hog the relevant ports. When you later on tried in forked mode or forever, it wouldn't bind to them. It should have raised an error though...
Userlevel 2
Hi there :

Do you think if i merged both lib http and web to one server there would be a conflict ?

Many Thanks

Regards

Robert
Userlevel 4
Badge +14
Hi there :

Do you think if i merged both lib http and web to one server there would be a conflict ?

Many Thanks

Regards

Robert


No, that is actually preferred. Use a single instance of SonosDiscovery. I do that my self.
Userlevel 2
Could you upload your version with it combined I am also using the remote control code. I keep blowing it up for some reason ........

:~(
Thank You
Robert
Userlevel 4
Badge +14
Could you upload your version with it combined I am also using the remote control code. I keep blowing it up for some reason ........

:~(
Thank You
Robert


I don't run the IR remote and the web controller together, since they aren't modularized. Adding the http api is no problem, but I need to rework some stuff to make it easier to package it all together. Right now I'm doing a rewrite of all XML parsing to speed things up, but the plan is to create a complete distribution which contains all parts, which you can configure on/off instead. That would probably make it easier to install.
Userlevel 2
We await the new version and thank you the ir part is off the hook and all 3 combined is the answer to complete the package any chance when you look at the code that you could allow us to send tts to the zones for a door bell or announcements etc ( when you have spare time) yea right :)

Thank You for all your hard work........

Regards

Robert
Userlevel 2
Finally got a chance to try this - great work !. Just what I was looking for. Just set it up on a VM.

As a Squeezebox refugee, I was used to embedding the web control for music into other interfaces for geeky home automation projects. After switching to Sonos, I was forced to lose the integration and use separate official applications - always less elegant no matter how nice the dedicated app may be.

Took about 10 minutes to re-integrate into Command Fusion interfaces at home.

Keep up the good work.
Userlevel 2
Good Morning :

Just checking to see if your or will you combine the mod into one so it is easier to install and run ...

Alo trying to install and run pm2 beside fork any other sug for rasp pi to make it run I seems to hitting a wall many thanks

Robert
Userlevel 2
HI Jishi,

How hard would it be possible to put a check so that if a favorite is already playing it won't attempt to reload the same favorite? I have found that certain Internet Radio stations take a long time to load in Sonos. If the command gets sent twice it can cause a long pause in what is playing.

Thanks
Userlevel 4
Badge +14
HI Jishi,

How hard would it be possible to put a check so that if a favorite is already playing it won't attempt to reload the same favorite? I have found that certain Internet Radio stations take a long time to load in Sonos. If the command gets sent twice it can cause a long pause in what is playing.

Thanks


For radiostations, not hard at all. For playlists it would be impossible to make a reliable identification of a certain favorite. It makes sense to not try and load the same radiostation twice.
Userlevel 2
Your software is exactly what I was looking for, great interface, responsive and easy to use.

Keep up the good work, can't way for music library browsing functionnality to be implemented.
Userlevel 2
Agree with guigui. Just got the web-controller up and running on my os-x machine.

And I've ordered a RaPi with IR to try to get your remote working.
Userlevel 2
For those having issues getting lirc setup and configured the best how to I found was here:

http://www.jamesrobertson.eu/blog/2013/may/19/2326hrs.txt
Userlevel 2
I've got node-sonos-remote setup working great but it only manages one speaker at a time, even if they are grouped.

How could I manage the group volume?

Also, would it be possible to create a group. For example a preset that would always join Speaker A+B.
Userlevel 4
Badge +14
I've got node-sonos-remote setup working great but it only manages one speaker at a time, even if they are grouped.

How could I manage the group volume?

Also, would it be possible to create a group. For example a preset that would always join Speaker A+B.


You can invoke
code:
player.coordinator.groupSetVolume("+2")


To control group volume instead. Personally I have mapped the channel up/down on my IR remote to control group volume, which means that to the "actions" object, I have added:

code:
"ch_up": function (player) {
player.groupSetVolume("+1");
return true;
}


Your IR codes probably differs from mine, but hopefully you get the idea. As you probably realize, +1, +2, +3 indicates increment steps (relates to % of volume)

Grouping can be achieved with presets, yes. There's an example preset (called "all") in sonos-lirc.js, you can just change that, and then map it to a key:

code:

var buttonToPreset = {
"KEY_1": "all"
};
Userlevel 2
jishi,

The group volume worked great and I thought the presets was working fine but now I see that it will only group on a fresh start of sonos-remote.

For example:
-Group the speakers via IR key
-Ungroup speakers via the Sonos app
-Attempt to regroup the speakers via IR key; it does not succeed (#1)
-Kill sonos-remote and restart sonos-remote
-Attemp to group via IR key and it does regroup. (#2)

#1:
00 KEY_POWER
before action true
applying preset { players:
[ { roomName: 'Living Room', volume: 51 },
{ roomName: 'Dining Room', volume: 51 } ] }
skipping breakout because already coordinator
after action false
Living Room "urn:schemas-upnp-org:service:RenderingControl:1#SetVolume" STATUS: 200
Dining Room "urn:schemas-upnp-org:service:RenderingControl:1#SetVolume" STATUS: 200
Living Room "urn:schemas-upnp-org:service:AVTransport:1#Play" STATUS: 200
emitting group-volume

#2
00 KEY_POWER
before action true
applying preset { players:
[ { roomName: 'Living Room', volume: 51 },
{ roomName: 'Dining Room', volume: 51 } ] }
skipping breakout because already coordinator
after action false
01 KEY_POWER
before action false
after action false
Living Room "urn:schemas-upnp-org:service:RenderingControl:1#SetVolume" STATUS: 200
Dining Room "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI" STATUS: 200
Dining Room "urn:schemas-upnp-org:service:RenderingControl:1#SetVolume" STATUS: 200
Living Room "urn:schemas-upnp-org:service:AVTransport:1#Play" STATUS: 200
emitting group-volume
emitting group-volume

You can see the contents of my sonos-lirc.js here:

http://ur1.ca/gvtr8

Also, out of curiosity:

-What is the difference between player.coordinator.groupSetVolume and player.groupSetVolume
-Are you using pm2 to run sonos-lirc as a forked daemon on your rapi?

P.S. I appreciate your support but if I'm consuming too much of your time feel free to tell me to bugger off.
Userlevel 4
Badge +14
player is the selected player, which in your case would always be TV Room since you don't have buttons to switch control.

player.coordinator is the coordinator player for a group. This is the player that you "initiated" the group from. According to your preset this would always be TV Room, but if you were to add "TV Room" to "Dining Room" from your Sonos controller, your groupVolume control wouldn't work.

I used pm2 ti run this yes, no problem. I have now switched my raspberry installation to rasplex, which is a bit dumber, so now I just start it with a autostart script like:
node sonos-lirc.js &
It won't restart if it crashes with this approach though.

It's weird that the preset only works one time, I haven't noticed this behavior in my setup. IT doesn't look like it breaks according to your logs either...
Userlevel 2
Bummer okay - I'll just restart the sonos-remote node every 5 minutes or so.
Userlevel 4
Badge +14
Well, that's not really the optimal solution. I would need to get some info about the state of the players before and after you try and group them the second time.

If you could give me the info from http://IP:1400/status/perf

From both players and PM them to me. I only need the first few lines (10 or so), the rest is irrelevant.
Userlevel 2
As I was lacking the music library browsing feature which is my main use, so I decided to start developping it myself. I actually have something working.
It still needs some polishing and some functions (like adding a whole album to the queue for example) are still missing but browsing back and forth between artists and albums does work as well as going back to the previous menu.

jishi (or anyone else) : if you're interested I can send you the code in some way (via mail or github). Feel free to do whatever you want with it.

I do have one question though, one thing that I'm missing is the set of icons used by the Sonos app to have the same look & feel, I was wondering how you got the rest of the design ?

Best regards
Userlevel 4
Badge +14
Did you fork it on github? Then just send me a pullrequest and I'll try and merge it in.

I extracted most of the graphical elements from the Windows application, since they were basically embedded png resources. However, I wanted the gui to scale nicely, so I remade a lot of them in SVG and tried to reproduce most of it using standard css. Today it is only the volume scrubber and the shuffle/repeat/crossfade that are still images extracted from the Sonos application.

If you tell me which one you need I can easily extract them and add to the repo.
Userlevel 2
For now it's on my home git repo but I'll upload it on my fork on github and send you the link.

I'm looking for the icons used for the music library browsing : back icons, Favorites and Music library icons. If you already have them that would help me otherwise I'll try to get them from the windows app too.

I've also looked to implement the "Radio" feature but haven't had the opportunity to do the packet captures to understand how the TuneIn implementation in Sonos works.

Regards
Userlevel 4
Badge +14
For now it's on my home git repo but I'll upload it on my fork on github and send you the link.

I'm looking for the icons used for the music library browsing : back icons, Favorites and Music library icons. If you already have them that would help me otherwise I'll try to get them from the windows app too.

I've also looked to implement the "Radio" feature but haven't had the opportunity to do the packet captures to understand how the TuneIn implementation in Sonos works.

Regards


Let me know if you manage to extract them (I think I used Telerik JustDecompile http://www.telerik.com/products/decompiler.aspx), otherwise I can fix it easily.

I think TuneIn and most music services connect directly from the controller to the services without using the players, which makes it a bit more troublesome to implement. TuneIn doesn't have a free API and you need some credentials (I think) in order to get it to work.
Userlevel 2
Hello again,

You can check my changes on my github forks :
* https://github.com/gfraysse/node-sonos-discovery
* https://github.com/gfraysse/node-sonos-web-controller

Let me know if you feel it is of any interest it lacks some polishing but I'm still working on it.
I still need to get the missing icons and integrate them.
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

Cheers!


Awesome Library! I've used it to create a tool that does store the listening positions of titles longer 10 minutes (configurable). And it restores the last known position when you start it again.

http://www.schrankmonster.de/2014/03/23/give-you-sonos-audiobook-podcast-auto-bookmarker-lose-listening-progress-again/

Of course everything also on Github: https://github.com/bietiekay/sonos-auto-bookmarker