Sonos with node.js, my attempt!



Show first post
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 2
It now also supports playMode in presets.

Example:

code:

{
"players": [
{ "roomName": "room1", "volume": 15},
{"roomName": "room2", "volume": 25}
],
"state": "stopped",
"favorite": "my favorite name",
"playMode": "SHUFFLE"
}


Valid values are: NORMAL, REPEAT_ALL, SHUFFLE_NOREPEAT, SHUFFLE

The most confusing part of it is that "SHUFFLE" is with implicit repeat on. I might change the format to something like:

code:

"playMode": {"repeat": "on", "shuffle": "off"}


Maybe that would be easier to comprehend.



Great updates!
I think that the second option would be better, especially if you will implement the Crossfade option as well.
Userlevel 4
Badge +14
It now also supports playMode in presets.

Example:

code:

{
"players": [
{ "roomName": "room1", "volume": 15},
{"roomName": "room2", "volume": 25}
],
"state": "stopped",
"favorite": "my favorite name",
"playMode": "SHUFFLE"
}


Valid values are: NORMAL, REPEAT_ALL, SHUFFLE_NOREPEAT, SHUFFLE

The most confusing part of it is that "SHUFFLE" is with implicit repeat on. I might change the format to something like:

code:

"playMode": {"repeat": "on", "shuffle": "off"}


Maybe that would be easier to comprehend.
Userlevel 4
Badge +14
I have added support for:

groupVolume
groupMute
mute (single player)
repeat
shuffle

I rewrote the previous groupmute/volume implementation and because of that, the calls for volume and mute are now different (this doesn't concern the http-api, only sonos-discovery).

enjoy.
Userlevel 2
Seems like I had a bad fallback. I pushed a fix for it to sonos-discovery. Remove your node_modules folder and run npm install again.

Much better, thanks!
Userlevel 4
Badge +14
Seems like I had a bad fallback. I pushed a fix for it to sonos-discovery. Remove your node_modules folder and run npm install again.
Userlevel 4
Badge +14
Looking forward to play with the upcoming fixes!

Just pushed a commit where the issue with players not leaving the group is fixed. Enjoy.
Userlevel 4
Badge +14
So, now it's possible to use favorites in your presets. It will replace the queue if it's a queue. If it's a radio, it will just start playing it and leave the queue intact.
Userlevel 2
Yeah, that's a glitch. If the first player already is a coordinator, I need to check which group members it has and detach the ones that shouldn't be part of it. Right now it just works with the players listed. It worked in an earlier version where I always detached the coordinator, but that became kind of choppy if you reapplied the same preset twice. I will fix it in the coming days.

uri is only useful for line-ins and hardcoded http-streaming urls. The x-sonosapi-stream urls require the DIDL metadata in order to be applicable. Next on the todo is to support favorites in presets as well, that should be a no brainer to solve.


Looking forward to play with the upcoming fixes!
Userlevel 4
Badge +14

The group still contains 3 speakers. However if ungrouping all speakers first and then send the command it works ok. It doesn't load the Radio from the URI command either.


Yeah, that's a glitch. If the first player already is a coordinator, I need to check which group members it has and detach the ones that shouldn't be part of it. Right now it just works with the players listed. It worked in an earlier version where I always detached the coordinator, but that became kind of choppy if you reapplied the same preset twice. I will fix it in the coming days.

uri is only useful for line-ins and hardcoded http-streaming urls. The x-sonosapi-stream urls require the DIDL metadata in order to be applicable. Next on the todo is to support favorites in presets as well, that should be a no brainer to solve.
Userlevel 2
Thanks for the new preset options - perfect!

But some problems with grouping speakers. If I have 3 speakers grouped (Bathroom, Kitchen, Master Bedroom) and would like to regroup two of them.

Sending the following
code:
{"players":[{"roomName":"Bathroom","volume":15},{"roomName":"MasterBedroom","volume":25}],"state":"stopped","uri":"x-sonosapi-stream:s47341?sid=254&flags=32"}


Server output
code:
{ action: 'preset',
value: '%7B%22players%22:[%7B%22roomName%22:%22Bathroom%22,%22volume%22:15%7D,%7B%22roomName%22:%22Master%20Bedroom%22,%22volume%22:25%7D],%22state%22:%22stopped%22,%22uri%22:%22x-sonosapi-stream:s47341?sid=254&flags=32%22}' }
applying preset { players:
[ { roomName: 'Bathroom', volume: 15 },
{ roomName: 'Master Bedroom', volume: 25 } ],
state: 'stopped',
uri: 'x-sonosapi-stream:s47341?sid=254&flags=32' }
applying preset { players:
[ { roomName: 'Bathroom', volume: 15 },
{ roomName: 'Master Bedroom', volume: 25 } ],
state: 'stopped',
uri: 'x-sonosapi-stream:s47341?sid=254&flags=32' }
skipping breakout because already coordinator
current volume 15
setting volume 15
current volume 25
setting volume 25
callback
STATUS: 200
volume success? true
Volume
STATUS: 200
Volume
STATUS: 500


The group still contains 3 speakers. However if ungrouping all speakers first and then send the command it works ok. It doesn't load the Radio from the URI command either.
Userlevel 4
Badge +14
So, I spent the evening with coming up with a rather unique feature (haven't seen it yet anywhere else, enlighten me if I'm wrong!).

I call it "volume enforcement", which basically means that you can "lock" the volume for all your players, both up and down. This might be useful at a party, in an office environment, or just when you are going to sleep (if another family member decides to have a party in your house or something).

How it works? When you tell it to lock volumes, it will register the current volume for all players, and every time the volume changes, it will just send another volume adjustment to reset it back to whatever it was. This will of course not be rock solid, but might be useful never the less.

This is part of the http-api, since it needs some sort of trigger to function.

I might change it to only lock for increasing volume, since this effectively makes it impossible to mute a player with the buttons. If you have any feedback regarding that, please let me know.
Userlevel 2
Thanks, yes I removed my real Mac-address... ;)

Will continue my testing tonight. The Web-controller looks very cool but I think it might be a bit heavy weight for me. Just want to have a few predefined buttons that should trigger some custom actions like your new IR remote project.

Looks like I can get Morning, Mute and Stop All buttons running quite easily now.
Userlevel 4
Badge +14

On my wish list:
- Queue management, add/remove/clear spotify tracks and/or playlists.
- Control shuffle/repeat/crossfade
- No autoplay when changing presets

My goal is to have a simple mobile GUI with some presets buttons;
Morning - Group all players, set volumes, start radio.
Evening - Group some players, set volumes, set shuffle, set repeat, set crossfade, replace queue with spotify playlist.
Party - Same as above but different playlist and maybe moving items in queue to play select item as next song.
Mute - Muting or changing volume in selected rooms.
Stop all - Stop all players with a single click (useful when leaving the home).

I've tried some of the unsupported APIs and this is the best so far, keep up the good job!


Control shuffle/repeat etc is next on my todo.
You can disable Auto-play on the preset by adding the following to your preset:

code:

{ "state": "stopped",
players:
[ { roomName: 'Bathroom', volume: 11 },
{ roomName: 'Kitchen', volume: 11 },
{ roomName: 'Master Bedroom', volume: 11 },
{ roomName: 'Living Room', volume: 10 } ] }


It's not part of my example, but should be.
Party mode is also an idea I've had for a long time. I started a .NET based app for it, but I never finished it. I will probably do a web-based version instead based on this API, that handles multiple clients (think, smartphone control).

You might want to check out the web controller-project that I started in your case, since the http-api is just a wrapper around sonos-discovery. If you plan on hosting a web client, you should probably skip that layer. https://github.com/jishi/node-sonos-web-controller

The web controller isn't working, but you might get the idea on how you can create and host the web client within node completely.

Oh, and finally, I did a commit to fix the null-check as well, but I'm not sure that it will resolve your issue completely. Let me know what kind of error you receive. Oh, I just struck me that you probably anonymized the streamurl, DOH! 🙂
Userlevel 4
Badge +14

adding player to coordinator Bathroom with streamurl x-rincon:RINCON_00000000000000000


I added some entity encoding stuff to support the favorites, I guess there are some scenarios where this will pass null that I need to take into account.

However, that streamurl points to a device with no MAC-adress, which is kind of odd? It should never be all zeros like that.
Userlevel 4
Badge +14
For those who are interested, I pushed a new repository with a proof of concept for IR remote controlling your Sonos using a raspberry pi and a simple IR receiver.

https://github.com/jishi/node-sonos-remote-control

I use this myself with a left over IR remote, that controls the volume for my living room, and I've mapped the number keys to different presets and the media keys for play/pause/prev/next. Very neat.
Userlevel 4
Badge +14
Seems like radio favorites needed to be handled differently than queue favorites. I added simple fix for it, but it might not work for custom radios (TuneIn should be fine though).

I also identified a few bugs in the preset system that I introduced in a rewrite, should work correctly now again.

"npm install" doesn't seem to update dependencies from git repos, so it's usually best to remove the node_modules folder and invoke "npm install" in order to get the latest version of sonos-discovery module.

Let me know if you have any more problems and I will try and sort it out.
Userlevel 2
Muting is working, thanks!
A longer message is awaiting approval...
Userlevel 4
Badge +14
Thank you for your pointers, some bugs that was introduced in my last commits.

I have fixed them and pushed to github now. Enjoy!
Userlevel 2
Yes, you are running 0.6 of node.js, they changed it in 0.7 from "path" to "fs". I haven't run it under 0.6 in a long time, and I focused on 0.8 when I started. It might work, you can try and change this row (however, you might get other problems down the line):

code:
var fs = require('fs');


to

code:
var fs = require('path');


I assume you installed it using apt-get under debian/ubuntu, correct? If you don't want to compile and install it yourself, you can check this out: http://ypcs.fi/howto/2013/03/23/nodejs-debian/


Thanks! I updated to a newer nodejs, and now it works!

Looking forward to experimenting with this :)

Andreas
Userlevel 4
Badge +14
Now, as part of the 4.2 upgrade, the players now remember their queue and queue position it had prior to being grouped with other players.

This is a good thing, since that gives you the possibility to use different coordinators for different presets, and that way, you will be able to switch presets and keep the old queue, if each preset has a unique coordinator.
Userlevel 4
Badge +14
I'm well aware that clock speed is only part of the story, but at 180MHz I wonder if it is fast enough for large JavaScript programs.


Yes, that part worries me too. The raspberry at 700 works pretty good but it can still choke when it has a lot to deal with.

However, it is running a full blown Debian setup, and could probably be stripped down quite a bit. Would be interesting to see how well it would behave.
And today I read about this thing: http://tessel.io/

I'm well aware that clock speed is only part of the story, but at 180MHz I wonder if it is fast enough for large JavaScript programs.
Userlevel 4
Badge +14
If anybody is interested, I did add support for replacing queue with one of your favorites.

example:

code:
http://localhost:5005/TV Room/favorite/MyAwesomePlaylist


Would replace the queue for the current group that TV Room is part of, with the favorite "MyAwesomePlaylist"

I will eventually add support for this in the presets as well, which means that you can resume a specific grouping, with pre-defined volume set and a predefined favorite list.

I will probably use this my self instead of the built in alarm, using the crontab daemon on the raspberry pi and do a 2-step wake-up call 🙂 slow music in the bedroom first 30 minutes, then all players in my apartment with some more up beat playlist.
Userlevel 4
Badge +14
And today I read about this thing: http://tessel.io/
Userlevel 4
Badge +14
I made some improvements to the preset signals, previously it did spam a lot which confused the players and failed to add everyone to the group. I also identify if the coordinator already is a coordinator, and skips the BecomeCoordinatorOfStandaloneGroup call.

It also support predefined presets, which you can store in a file, which gives you the ability to define something like an "all" preset, that you can apply by invoking:

code:
http://localhost:5005/preset/all