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


"KEY_3": function (player) {
player.coordinator.replaceWithFavorite("162.4 | NOAA Weather Radio (Weather)");
player.coordinator.play();
return true;
},


Hi, it takes some time to get comfortable with the asynchronous execution model that you use in this case.

The .replaceWithFavorite(string favoriteName, function callback) takes two arguments, where the latter is a function declaration. this function will be invoked when the execution is done, and that is where you need to invoke the play command.

So:

code:

"KEY_3": function (player) {
player.coordinator.replaceWithFavorite("162.4 | NOAA Weather Radio (Weather)", function (success) {
if (success) player.coordinator.play();
});
return true;
},


Also, the callback will get 1 argument which is true/false depending on if the invokation was successful or not.
Userlevel 2
I have a question about using the favorites command in your sonos-ir-control script.

I have little programming experience and none in Javascript so please forgive my simple questions. This is also the first time I've used a Raspberry Pi and the closest thing I've used to Linux was Unix and that was ~15 years ago.

I have modified your sonos-IR-Control.js file to map to my IR commands. To execute playlist commands I use the following:

"KEY_3": function (player) {
player.coordinator.replaceWithFavorite("162.4 | NOAA Weather Radio (Weather)");
player.coordinator.play();
return true;
},

I have tried copying the replaceWithFavorite command from your http-api but had issues getting "success" part of the function to work.

As a result I added the play command after the favorite command, but for certain favorites the timing is off and the play command is sent too early and missed.

If you have the time and patience could you help me get the replacewithfavorite command into the remote-IR script?

Thanks
Userlevel 4
Badge +14

For the favorites with the http-api: so i get with "favorites" all favorites titles and then with "favorite/..title..." get the uri and filter all favorites with the proper uri to get only radio-favorites? Is that correct? Or is there a simpler solution?
But for this i have the problem that a favorite starts playing immediat.


Well, for now you will need to check the uri to make the distinction. I will see if I can extract more info about it, but it's possible that it will just say "Spotify playlist" "Itunes radio" and stuff like that...

The reason that it starts immediately is because the http api will send play after a successful invokation, see row 217 in https://github.com/jishi/node-sonos-http-api/blob/master/lib/sonos-http-api.js:

code:

case "favorite":
player.coordinator.replaceWithFavorite(options.value, function (success) {
if (success)
player.coordinator.play();
});


You could just remove that, or if you come up with a way to make it selectable or configurable. Do you want different behavior on different favorites, or different behavior permanently?
Userlevel 2
Thanks for you answers!

It would be nice if you can implement the trackseek in the http-api. As your api delivers both, it's not important for me if there is a parsing or not.
I am experimenting with python and hacked a little script for the raspberry GPIOs with a button (my event which triggers the switch of the favorites) and a bunch of LEDs.
So for this i need python (cause i didn't find a propper nodejs-api) and your http api comes right in, because making requests is very easy in python.
My python script keeps track of which favorite is currently playing.

For the favorites with the http-api: so i get with "favorites" all favorites titles and then with "favorite/..title..." get the uri and filter all favorites with the proper uri to get only radio-favorites? Is that correct? Or is there a simpler solution?
But for this i have the problem that a favorite starts playing immediat.

Crap 😉 ... no good nodejs raspberry-gpio api yet, and no good python api for sonos which supports favorites yet.
Userlevel 4
Badge +14
Hello,

nice work. I already use your http api on my raspi.

2 Questions:

Is it possible to seek in a track? Go to a specific time on the current track?

Is it possible to change the queue with a favorite but not start playing.

What i want to do in my python program is:
  • favorite A is playing.
  • get an event (buttonpress e.g.)
  • Save the current state of the track. (where the queue is based on favorite A)
  • Change the queue with a favorite B.
  • Start playing favorite B.
  • get an event (buttonpress e.g.)
  • Switching back to favorite A. Start playing from the track and position which was saved in the first step.



Third Question:
Is it possible to get more information on the favorites? If it is a Radio Station or a List?

thx


Hi. I have implemented trackSeek in the discovery-library (mainly for the web controller), so it would be easy enough to add it to the http api as well. It takes elapsed time in seconds, but it would be possible to add some sort of parsing as well if that is needed ("0:05" instead of just 5, "1:04" instead of 64).

Your second question, regarding switching between favorites. It would be possible, but note that you can not know which favorite that is playing (unless you store it yourself, and only control it using your python script). Are you planning on using a regular keyboard? If you are familiar with js, I have an example here: http://upload.grabbarna.se/files/keyboard.js

That way, you wouldn't need to work through the HTTP API but instead speak directly with the sonos-component in node.js, meaning that you can run it inside the http api.

3. I think there might be info if it is a playlist or a radio, otherwise you can work it out from the uri. There are only a few prefixes that are for radio, the once I have identified is:

code:

if (item.uri.startsWith("x-sonosapi-stream:") || item.uri.startsWith("x-sonosapi-radio:") || item.uri.startsWith("pndrradio:")) {
Userlevel 2
Hello,

nice work. I already use your http api on my raspi.

2 Questions:

Is it possible to seek in a track? Go to a specific time on the current track?

Is it possible to change the queue with a favorite but not start playing.

What i want to do in my python program is:
  • favorite A is playing.
  • get an event (buttonpress e.g.)
  • Save the current state of the track. (where the queue is based on favorite A)
  • Change the queue with a favorite B.
  • Start playing favorite B.
  • get an event (buttonpress e.g.)
  • Switching back to favorite A. Start playing from the track and position which was saved in the first step.



Third Question:
Is it possible to get more information on the favorites? If it is a Radio Station or a List?

thx
Userlevel 2
Jishi
Thanks to you I now have a Raspberry Pi that I shoehorned into an empty Sonos Bridge. It required some modification but it just barely fits inside. I also placed an IR transmitter inside the case so it looks like a nice clean finished component. Just power, ir wire and a network cable out of the back of the bridge.


Hi Nice solution with the Raspberry Pi in a Bridge box. I have think to do the same but just run the Rasberry Pi unboxed so far.
But I love to just use my spare Apple TV remote to pause/change volum then the phone ring.
This is a thing that Sonos totally have missed to mount a simple IR recivier in all Sonos speakers.

And agin great work Jishi!
Userlevel 4
Badge +14
Hello,

can i also work with the Janos Web Controller under an Xampp server?

Do i need some other as Xampp?

Thanks, best regards Thomas


I don't know what you want to achieve. My implementation is completely standalone and doesn't require anything else than node.js. Don't confuse it with the Janos application.

Look at the first post, I have updated it with a downloadable link with all dependencies already met. You just unzip it to a folder and start it with:

node server.js

And you should be good to go.
Userlevel 4
Badge +14
Hello,

I want to thank you for taking the time to write provide us with this project.

I was able to install everything and have the node running and able to open up the player in a web browser, however, i have a quick quesetion - how do you invoke the http commands (could you please explain in layman's term?)


The HTTP commands are a separate component than the web controller. You can run them at the same time, even using the same backend, but that requires some modifications to the files. The preferred way is to extend the web controller with the http api, but it will be harder to maintain atm. I might distribute a zip with them both active, for those who wants to use it.
Badge +2
A open request :

I am trying as I am not really a programmer ....

To add a group of functions to play a tts mp3 file.

Logic:
Scan whole system remember the state of the system whats playing vol mute unmute etc.

then create a mp3 file format from text file add it to the Que then play that file based on a preset created then return the system back to orig state.

This could be used as a weather alert system doorbell anything that may come across even text messages. from your cell . I want to set it up with my Google calender

Anyone interested in creating this?

Regards

Robert
Userlevel 2
Jishi,

I wanted to thank you for dedicating the time and effort into this project. I had been searching Hi and Low for a solution that would allow me simple control of my Sonos system (Start Playing a Favorite, Skip Tracks) using my current remote system (a URC MSC400 with several remotes around the house).

I had been using a Sonos plug-in for Homeseer but a whole Win7 PC dedicated for controlling Sonos was overkill.

Thanks to you I now have a Raspberry Pi that I shoehorned into an empty Sonos Bridge. It required some modification but it just barely fits inside. I also placed an IR transmitter inside the case so it looks like a nice clean finished component. Just power, ir wire and a network cable out of the back of the bridge.

Using the process described here: http://blog.rueedlinger.ch/2013/03/raspberry-pi-and-nodejs-basic-setup/ The RPi will boot and run your remote control node script.

Its been working great for controlling Sonos via IR commands

I have a couple of questions about issuing play commands and setting up direct control over zones (trying to avoid using the player.cordinator) but for the moment I just wanted to say thank you!
Userlevel 2
Hello,

can i also work with the Janos Web Controller under an Xampp server?

Do i need some other as Xampp?

Thanks, best regards Thomas
Userlevel 2
Sorry but i didn`t get it to work, when i will install the npm i get some errors...


C:\Program Files (x86)\nodejs>npm install
npm WARN package.json npm@1.3.21 No README data
npm WARN package.json github-url-from-git@1.1.1 No repository field.
npm WARN package.json ronn@0.3.8 'repositories' (plural) Not supported.
npm WARN package.json Please pick one as the 'repository' field

> npm@1.3.21 prepublish C:\Program Files (x86)\nodejs
> node bin/npm-cli.js prune --prefix=. --no-global && rm -rf test/*/*/node_modul
es && make -j32 doc


module.js:340
throw err;
^
Error: Cannot find module 'C:\Program Files (x86)\nodejs\bin\npm-cli.js'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:902:3

npm ERR! npm@1.3.21 prepublish: `node bin/npm-cli.js prune --prefix=. --no-globa
l && rm -rf test/*/*/node_modules && make -j32 doc`
npm ERR! Exit status 8
npm ERR!
npm ERR! Failed at the npm@1.3.21 prepublish script.
npm ERR! This is most likely a problem with the npm package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node bin/npm-cli.js prune --prefix=. --no-global && rm -rf test/*/*
/node_modules && make -j32 doc
npm ERR! You can get their info via:
npm ERR! npm owner ls npm
npm ERR! There is likely additional logging output above.
npm ERR! System Windows_NT 6.1.7601
npm ERR! command "C:\\Program Files\\nodejs\\\\node.exe" "C:\\Program Files\\nod
ejs\\node_modules\\npm\\bin\\npm-cli.js" "install"
npm ERR! cwd C:\Program Files (x86)\nodejs
npm ERR! node -v v0.10.24
npm ERR! npm -v 1.3.21
npm ERR! code ELIFECYCLE
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! C:\Program Files (x86)\nodejs\npm-debug.log
npm ERR! not ok code 0

Who can help me, thanks...
Userlevel 2
Hello,

I want to thank you for taking the time to write provide us with this project.

I was able to install everything and have the node running and able to open up the player in a web browser, however, i have a quick quesetion - how do you invoke the http commands (could you please explain in layman's term?)

Now you can control your system by invoking the following commands:

http://localhost:5005/zones http://localhost:5005/lockvolumes http://localhost:5005/unlockvolumes http://localhost:5005/pauseall[/{timeout in minutes}] http://localhost:5005/resumeall[/{timeout in minutes}] http://localhost:5005/preset/{JSON preset} http://localhost:5005/preset/{predefined preset name} http://localhost:5005/{room name}/{action}[/{parameter}]

Example:

http://localhost:5005/living room/volume/15 (will set volume for room Living Room to 15%)

http://localhost:5005/living room/volume/+1 (will increase volume by 1%)

http://localhost:5005/living room/next (will skip to the next track on living room, unless it's not a coordinator)

http://localhost:5005/living room/pause (will pause the living room)

http://localhost:5005/living room/favorite/mysuperplaylist (will replace queue with the favorite called "mysuperplaylist")

http://localhost:5005/living room/repeat/on (will turn on repeat mode for group)

The actions supported as of today:

play
pause
volume (parameter is absolute or relative volume. Prefix +/- indicates relative volume)
groupVolume (parameter is absolute or relative volume. Prefix +/- indicates relative volume)
mute / unmute
groupMute / groupUnmute
seek (parameter is queue index)
next
previous
state (will return a json-representation of the current state of player)
favorite
lockvolumes / unlockvolumes (experimental, will enforce the volume that was selected when locking!)
repeat (on/off)
shuffle (on/off)
pauseall (with optional timeout in minutes)
resumeall (will resume the ones that was pause on the pauseall call. Useful for doorbell, phone calls, etc. Optional timeout)


Am I supposed to open that as a link in a web browser? My player's room name is called "Living Room" and I'm trying to use the below command:
http://localhost:5005/living room/volume/15

If I paste the above in a web browser, I get a message saying I cannot connect to the server. I've also tried to replace 'localhost' with the server's IP address, same result.

Sorry for the silly question, I'm just looking for ways to automate things from within my phone,
Userlevel 4
Badge +14
Hello,

i like install it on windwos 7 system.

- i have download the node and web zip files.
- i have installed the node this will be fine
- the zip file i have unzipped to a folder
- in cmd i have "npm install" but then i get this logfile

0 info it worked if it ends with ok
1 verbose cli [ 'C:\\Program Files (x86)\\nodejs\\\\node.exe',
1 verbose cli 'C:\\Program Files (x86)\\nodejs\\node_modules\\npm\\bin\\npm-cli.js',
1 verbose cli 'install' ]
2 info using npm@1.3.21
3 info using node@v0.10.24
4 verbose node symlink C:\Program Files (x86)\nodejs\\node.exe
5 error install Couldn't read dependencies
6 error package.json ENOENT, open 'C:\Program Files (x86)\nodejs\package.json'
6 error package.json This is most likely not a problem with npm itself.
6 error package.json npm can't find a package.json file in your current directory.
7 error System Windows_NT 6.1.7601
8 error command "C:\\Program Files (x86)\\nodejs\\\\node.exe" "C:\\Program Files (x86)\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install"
9 error cwd C:\Program Files (x86)\nodejs
10 error node -v v0.10.24
11 error npm -v 1.3.21
12 error path C:\Program Files (x86)\nodejs\package.json
13 error code ENOPACKAGEJSON
14 error errno 34
15 verbose exit [ 34, true ]

Can somenoe help me what the error is, what can i do? And how can i install the web controller?

Thanks best regards Thomas


You need to to stand in the unzipped folder before you invoke not install. Not your node folder.
Badge +2
No worry Have a good vacation sorry to bother you let me know when your back ...;)
Userlevel 2
Hello,

i like install it on windwos 7 system.

- i have download the node and web zip files.
- i have installed the node this will be fine
- the zip file i have unzipped to a folder
- in cmd i have "npm install" but then i get this logfile

0 info it worked if it ends with ok
1 verbose cli [ 'C:\\Program Files (x86)\\nodejs\\\\node.exe',
1 verbose cli 'C:\\Program Files (x86)\\nodejs\\node_modules\\npm\\bin\\npm-cli.js',
1 verbose cli 'install' ]
2 info using npm@1.3.21
3 info using node@v0.10.24
4 verbose node symlink C:\Program Files (x86)\nodejs\\node.exe
5 error install Couldn't read dependencies
6 error package.json ENOENT, open 'C:\Program Files (x86)\nodejs\package.json'
6 error package.json This is most likely not a problem with npm itself.
6 error package.json npm can't find a package.json file in your current directory.
7 error System Windows_NT 6.1.7601
8 error command "C:\\Program Files (x86)\\nodejs\\\\node.exe" "C:\\Program Files (x86)\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install"
9 error cwd C:\Program Files (x86)\nodejs
10 error node -v v0.10.24
11 error npm -v 1.3.21
12 error path C:\Program Files (x86)\nodejs\package.json
13 error code ENOPACKAGEJSON
14 error errno 34
15 verbose exit [ 34, true ]

Can somenoe help me what the error is, what can i do? And how can i install the web controller?

Thanks best regards Thomas
Userlevel 4
Badge +14
Jimmy:

Happy Holiday to you and yours and thank you for a amazing project......

Regards

Robert


Thanks, I will be silent for 3 weeks but don't be alarmed, I haven't abandoned it, yet. :)

Happy holidays!
Badge +2
Jimmy:

Happy Holiday to you and yours and thank you for a amazing project......

Regards

Robert
Userlevel 4
Badge +14
Ok Thanks, I understand the difference between keyboard reading in Linux and Windows. The question was more if the rest of the remote code would execute in windows so I could do some tests by changing code and so on just to learn how it works. I assume the only code to deal with is sonos-lirc.js ?

Yes it would. I use Windows as my development platform so that isn't a problem. Node.js is fairly platform agnostic.
Userlevel 2
Unfortunately, reading out keystrokes is highly linux-specific, so you won't be able to test that. This is because you want it to run in the background, and not be dependent on an active console session. It would be possible to enable auto login and a bash startup script but I don't think it would be a nice solution...

Ok Thanks, I understand the difference between keyboard reading in Linux and Windows. The question was more if the rest of the remote code would execute in windows so I could do some tests by changing code and so on just to learn how it works. I assume the only code to deal with is sonos-lirc.js ?
Userlevel 4
Badge +14
Thanks Jishi,
I will do some test with the std rpi keyboard first before adding in the flirc. I supose it will work fine to run the remote node code on windows first just for me to learn how the code is working (after removing the lirc code)?


Unfortunately, reading out keystrokes is highly linux-specific, so you won't be able to test that. This is because you want it to run in the background, and not be dependent on an active console session. It would be possible to enable auto login and a bash startup script but I don't think it would be a nice solution...
Userlevel 2
No, I don't have that code in github. I will have to dig through my home laptop or the rpi to see if I still have it. It was merely a prototype and I could reproduce it once again probably.

See here:

http://forums.sonos.com/showpost.php?p=192751&postcount=13

And here (my question regarding it, a bit technical):

http://stackoverflow.com/questions/15742172/would-it-be-possible-to-read-out-physical-keyboard-strokes-in-node-js


Thanks Jishi,
I will do some test with the std rpi keyboard first before adding in the flirc. I supose it will work fine to run the remote node code on windows first just for me to learn how the code is working (after removing the lirc code)?
Userlevel 4
Badge +14
No, I don't have that code in github. I will have to dig through my home laptop or the rpi to see if I still have it. It was merely a prototype and I could reproduce it once again probably.

See here:

http://forums.sonos.com/showpost.php?p=192751&postcount=13

And here (my question regarding it, a bit technical):

http://stackoverflow.com/questions/15742172/would-it-be-possible-to-read-out-physical-keyboard-strokes-in-node-js
Userlevel 2
I did a version that reads out keystrokes instead of data from the lirc socket. That could be used for flirc instead. However, you still need to program your flirc, and that requires a graphical UI as I understand it. I don't think it will be that much easier. Do you already have a flirc receiver or are you planning on buying it? If the keyboard mapping is stored in the dongle, then I can see the simplicity of it. Then you can program it on your laptop/desktop and then plug it into the rpi, is that the case?

Yes the flirc could (and should) esy be setup for any remote in Windows and then moved to the target platform, in this case the rpi.
http://flirc.tv/ I have ordered it but not got it yet. https://www.m.nu/flirc-universal-ir-remote-receiver-p-1116.html

Were could I find your early rpi version with keystroke instead of IR on the GIT hub?

Citate from this link http://thepihut.com/pages/flirc-a-review-of-the-ultimate-media-centre-companion

The key is that FLIRC reports itself to the operating system as a standard USB Human Interface Device (HID), so any modern OS will be able to read it as if it was a keyboard. Even if the device or OS you want to use FLIRC on has no included support for remote controls, you can program FLIRC to “press” keys that the system will understand. For example, I was able to program FLIRC to interpret the directional pad on my remote to standard keyboard arrow keys; I then plugged FLIRC into my Android device and was able to navigate through the applications with my remote.

This allows for incredible flexibility. Being able to program FLIRC from a different device than what you end up using it on and the fact that it emulates a USB keyboard means you can use FLIRC where other products would be useless.