Simplified HTTP API (node.js)


Userlevel 4
Badge +14
Hi, I'm starting a new thread regarding this (old one here https://en.community.sonos.com/advanced-setups-229000/sonos-with-nodejs-my-attempt-33834) since that one grew out of hand.

I have made some major improvements to the simple HTTP API that I've built, and it now also comes with a pre-composed raspberry pi image that runs from a RAM-drive (based on AlpineLinux) for even simpler installation.

This software is useful for simple integration with home automation in mind, or for small hobby projects.

For more information, see http://jishi.github.io/node-sonos-http-api/

File issues at github https://github.com/jishi/node-sonos-http-api/issues

Have fun!

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.

43 replies


And finally for my local library I've found the following commands.
code:
/Playroom/musicsearch/library/song/red+hot+chili+peppers+dark+necessities

This command is a "search" command. It is searching for a song that matches the criteria. The command is working, but it is not that what I want. So I'm looking for a better way to select and play a specific song from my local library.


I would be very happy if you can support me with some hints.

Many thanks
Regards


There is no convenient way to "queue and play" form local library today. It would make sense to support that in the same manner as the music services, I just haven't looked at it. I'll create an issue for it in github and look at it when I get the time. It's a good suggestion.



Hi jishi,
first thanks for your work!
Just read your post from January 2017 and wanted to ask you if there is totay a more or less convenient way to 'queue and play' from a local library?

Best wishes from Cologne
Hello StarNab. Can I ask you how you got the Spotify musicsearch to work?
I just figured out about the "musicsearch" usage. That's awesome...
Man congratulations and thanks for this awesome work.
I just finished integration on my RPI. Actually i added voice control on top of it with Jasper, Sphinx and Google speech API.
This way I can change the current playlist without touching a button.
Next step would be to be able to play a Spotify artist radio on the go. I saw a musicsearch.js action class. Could this achieve what I want ? As it is not documented I'm not sure.

Thanks again for your work man
JIshi, awesome work. I've used and contributed to the github.com/bencevans/node-sonos lib for a few projects. Your lib has come a long way since I first checked it out. I'm going to migrate to it and I'll let you know how it works.

Thanks!
Scott
Userlevel 4
Badge +14
Hi Jishi,

Is it possible to move a sub between rooms using the api?

Cheers,
Dave


Not at the moment. I have been thinking about it, and it should be possible but can't say when I will be able to build it. If a lot of people seem to want it, a higher probability that I will build it. Please open an issue at github so people can vote for it.

Hi,
I don't understand how to install this. I Need a step-by-step description for a raspberry Pi with Raspian.
Thank you very much,
Baenker


Sorry, there are clear instructions on the README on how to install it, and you can find guides on how to get the latest version of node.js all over the internet. I have also helped several people in closed issues at github, please read through them to see if you can find the answers you need.
Badge
Hi Jishi,

Is it possible to move a sub between rooms using the api?

Cheers,
Dave
Userlevel 2
Hi,
I don't understand how to install this. I Need a step-by-step description for a raspberry Pi with Raspian.
Thank you very much,
Baenker
Badge

Looks like you are depending on some chrome native functions for the network traffic. You might already be aware of this, but https://github.com/siboulet/zonos is a chrome implementation of the Sonos network stack that might help you.

However, for maximum flexibility, having a separate server with no networking boundaries would be a lot easier.


That indeed looks like an implementation to copy from, which is better than relying on a cordova plugin.

Will post if I got it to work.
Userlevel 4
Badge +14
Hi Jishi

Thank you for your prompt reply. I already suspected (and feared) this would be the case. But now I know, at least I can finally go to sleep :)

Next step is I to figure out how to do the same in angular2, which should be doable.

Regards

Tom


Looks like you are depending on some chrome native functions for the network traffic. You might already be aware of this, but https://github.com/siboulet/zonos is a chrome implementation of the Sonos network stack that might help you.

However, for maximum flexibility, having a separate server with no networking boundaries would be a lot easier.
Badge
Hi Jishi

Thank you for your prompt reply. I already suspected (and feared) this would be the case. But now I know, at least I can finally go to sleep :)

Next step is I to figure out how to do the same in angular2, which should be doable.

Regards

Tom
Userlevel 4
Badge +14
Hi @jishi,

Thanks for the library. I have working with it for a while, trying to understand the code. I am experimenting to build an Angular2 service out of it - with Observables (first experiments on https://github.com/Tommertom/ng2sonos).

I am struggling to understand how you get to all the data from the Sonos system. For example, the AlbumArtUri for a Radio stream. I have put some trackers on the soap.invoke method to see if that returns values, but it doesn't. Where do you get that data from? And how many soap calls are needed to build the Sonossystem data tree (volume, position, etc.)?

Anyway, hope you can indicate where I can find this in the code.

Regards,

Tom


Hi Tom.

Most of the data is actually "evented" from the players, meaning that they do HTTP POST requests to my software with state changes. That's why you don't see them on the soap.invoke calls, because those are mostly explicit calls for action from the user (play, pause, skip change track etc). The only exception to that is the GetPositionInfo call which is used periodically to "sync" the current state, in case it has gotten out of sync. The code that is responsible for handling these requests are the NotificationListener, which emits it and then each player handles their own data to update their state.

You also need to subscribe to the events, in order to make the Sonos players send these requests. This is handled in the Subscriber class.

Hope that helps!
Badge
Hi @jishi,

Thanks for the library. I have working with it for a while, trying to understand the code. I am experimenting to build an Angular2 service out of it - with Observables (first experiments on https://github.com/Tommertom/ng2sonos).

I am struggling to understand how you get to all the data from the Sonos system. For example, the AlbumArtUri for a Radio stream. I have put some trackers on the soap.invoke method to see if that returns values, but it doesn't. Where do you get that data from? And how many soap calls are needed to build the Sonossystem data tree (volume, position, etc.)?

Anyway, hope you can indicate where I can find this in the code.

Regards,

Tom

There is no convenient way to "queue and play" form local library today. It would make sense to support that in the same manner as the music services, I just haven't looked at it. I'll create an issue for it in github and look at it when I get the time. It's a good suggestion.

that would be great.

Many thanks to you. You did a really great job.
Userlevel 4
Badge +14

And finally for my local library I've found the following commands.
code:
/Playroom/musicsearch/library/song/red+hot+chili+peppers+dark+necessities

This command is a "search" command. It is searching for a song that matches the criteria. The command is working, but it is not that what I want. So I'm looking for a better way to select and play a specific song from my local library.


I would be very happy if you can support me with some hints.

Many thanks
Regards


There is no convenient way to "queue and play" form local library today. It would make sense to support that in the same manner as the music services, I just haven't looked at it. I'll create an issue for it in github and look at it when I get the time. It's a good suggestion.
Hi,
really great job - I got your api working on my RaspberryPi.

But there are a few things open which I couldn't find out. Maybe I'm blind :-)

I get an event every time the current track changes. That works fine. I can save the json element of the state. Now I like to play a track again. But how can I start a specific track? My tracks are from my music library, from spotify and from apple music. Those tracks aren't saved in any playlist or favorite list.

What I'm doing wrong? Can someone post an example for me?

Regards


I'm not really following your question. You need to provide more details for me to be able to help you. "Event every time", are you using the webhook?

Tracks are usually part of the queue, So you usually just do a trackSeek to the correct trackNo if you want to jump back and forth between sources, but I'm guessing that is not what you are asking. Again, if you could be more specific and paint the scenario, I might be able to give you an answer.


Hi jishi,
thanks for your response.

Let me try to explain better what I like to do. Sorry for my late response and my bad english.

I've installed your http-api on a RaspberryPI and I'm using the webhook.
So I get a call every time a new song gets played at one of my players. This works very fine. I'm saving the message data (ok, not the whole message) to a database (mongdb). I've written an Android app which displays all saved entries from that database.

Now I like to play one of those songs. My tracks are coming from AppleMusic, a local library and maybe Spotify in the future. I know from where a song originally comes from.

Since my last post here I've found some solutions:

For songs from AppleMusic I found the following command
code:
/RoomName/applemusic/{now,next,queue}/song:{songID}

With this command I'm able to play a song from AppleMusic.

For songs from Spotiy, there must be the following command. I couldn't test it since now, because I currently have no Spotify account:
code:
/RoomName/spotify/now/spotify:track:4LI1ykYGFCcXPWkrpcU7hn


And finally for my local library I've found the following commands.
code:
/Playroom/musicsearch/library/song/red+hot+chili+peppers+dark+necessities

This command is a "search" command. It is searching for a song that matches the criteria. The command is working, but it is not that what I want. So I'm looking for a better way to select and play a specific song from my local library.


I would be very happy if you can support me with some hints.

Many thanks
Regards
Userlevel 4
Badge +14
Hi jishi!
Is there a way to know when the dicoveryprocess i done? Maybe a webhook?


You will receive a topology-change webhook as soon as it has discovered your system, if you have defined a webhook. So yes, there is.
Badge
Hi jishi!
Is there a way to know when the dicoveryprocess i done? Maybe a webhook?
Badge
Some really great work you've done here!
Yesterday I installed it on a Raspberry PI running Windows IoT Core and it worked without any changes at all!


Are you saying that this works without any issues with the Chakra engine version of node.js? That's good to know!


Yepp 🙂 I installed the Node.js addition to Visual Studio from here: https://github.com/ms-iot/ntvsiot. Then I created a new project of the type "Basic Node.js Web Server (UWP)", copied all the files from your project and deployed to the PI with Windows IoT Core.



It just worked!
Userlevel 4
Badge +14
Some really great work you've done here!
Yesterday I installed it on a Raspberry PI running Windows IoT Core and it worked without any changes at all!


Are you saying that this works without any issues with the Chakra engine version of node.js? That's good to know!
Userlevel 4
Badge +14
Hi,
really great job - I got your api working on my RaspberryPi.

But there are a few things open which I couldn't find out. Maybe I'm blind :-)

I get an event every time the current track changes. That works fine. I can save the json element of the state. Now I like to play a track again. But how can I start a specific track? My tracks are from my music library, from spotify and from apple music. Those tracks aren't saved in any playlist or favorite list.

What I'm doing wrong? Can someone post an example for me?

Regards


I'm not really following your question. You need to provide more details for me to be able to help you. "Event every time", are you using the webhook?

Tracks are usually part of the queue, So you usually just do a trackSeek to the correct trackNo if you want to jump back and forth between sources, but I'm guessing that is not what you are asking. Again, if you could be more specific and paint the scenario, I might be able to give you an answer.
Badge
Some really great work you've done here!
Yesterday I installed it on a Raspberry PI running Windows IoT Core and it worked without any changes at all!
Hi,
really great job - I got your api working on my RaspberryPi.

But there are a few things open which I couldn't find out. Maybe I'm blind :-)

I get an event every time the current track changes. That works fine. I can save the json element of the state. Now I like to play a track again. But how can I start a specific track? My tracks are from my music library, from spotify and from apple music. Those tracks aren't saved in any playlist or favorite list.

What I'm doing wrong? Can someone post an example for me?

Regards
Userlevel 4
Badge +14
With stdout I mean the command line output from the server console. For the raspberry image, this is redirected to a log file, but if you are running it manually, it would print out directly to the console.
Thanks so much for providing this API! It is really cool! I'm working on creating a node.js app with a scheduler to turn on my music automatically. I've noticed that occasionally when I give pause and resume commands to my sonos using my computer it will not do anything. If I try to hit the URL and do /zones or anything it will just return a blank array [] . Then, if I hit the play button on the actual sonos it will start working again and will receive commands. Is this a known issue or do you think something could be wrong with my sonos? My whole idea is based around my node server being able to wake up the sonos and start playing a specific playlist, so I would hope it would be possible.

That sounds really odd. If the zones return an empty array, that means the system hasn't been discovered. Are you sure the application isn't constantly restarting for some reason? Try to get the output from stdout when running it, and file an issue at github for it, and I'll take a look.


I looked a little further and it looks like it does return zones. But, if I try pauseall or resumeall using the URL in chrome it doesn't do anything and returns the [] that I mentioned. The app output shows 'resuming all players' each time I make the http request, but nothing happens. If I go over and hit the pause button on the sonos it will resume playing just fine. By output from stdout do you mean a logging file or simply the command line output that is generated?