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

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.
Userlevel 2
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!
Userlevel 4
Badge +14
OK - pull request sent!

Thank you very much! Hopefully this resolves this issue for a few users.
Userlevel 2
OK - pull request sent!
Userlevel 2
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.
Userlevel 4
Badge +14
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.
Userlevel 2
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!
Userlevel 2
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?
Userlevel 4
Badge +14
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!
Badge
Thanks for your work. I've been using AirSonos for a couple weeks, and its awesome.
Userlevel 4
Badge +14
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.
Userlevel 4
Badge +14
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.
Badge
Excellent - many thanks Matt and Jishi:D
Userlevel 4
Badge +14
Thanks for the quick fix, I have merged the pull request now.
Badge +1
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.
Badge +1
Out of interest, what IDE do you use? Nodeclipse?

I just use sublime text and the command line.
Badge
Really sorry about this. I tested basic pairing with just the sonos-discovery, but didn't try it "live" with anything like the web controller.

Let me pair up a couple of my Sonos tonight, and get the web controller installed, and get this debugged.

Sorry again. I hate that I broke something that was working so well for folks.


Many thanks Matt, I'll have another look this evening too. Out of interest, what IDE do you use? Nodeclipse?

Cheers,
Dave.
Badge +1
Really sorry about this. I tested basic pairing with just the sonos-discovery, but didn't try it "live" with anything like the web controller.

Let me pair up a couple of my Sonos tonight, and get the web controller installed, and get this debugged.

Sorry again. I hate that I broke something that was working so well for folks.
Badge
Hi Jishi (and Matt!),

Looks like Matts pull request #14 (add sub functionality) has introduced a problem in sonos-discovery...

I have a stereo pair of play 1's and a bridge. When I fire up the web controller I see my devices listed in the console output, but I don't see any rooms listed in the UI so basically I can't control/play anything. If I separate the play 1's they both become visible as separate rooms in the UI and all works as expected.

Everything works fine if I regress pull request #14 and #15 in sonos-discovery.

I'll see if I can figure out what the problem is myself, but I must admit I'm struggling with node.js a little bit:)

Thanks both for your work - looking forward to trying some ifttt recipes too;)

Cheers,
Dave.
Badge +1
I've gotten voice feedback working: when the player is paused or stopped, double pressing the button puts you in favorites mode. The LED pulses, and your first favorite is spoken through the Sonos Zone. A twist of the knob says the next favorite, and so on. Pressing the knob once plays the last spoken favorite. Pressing twice (or doing nothing for 30 seconds) exits favorites mode back to a paused Sonos.

The code is a disaster (when I code, I charge ahead full speed without care for comments or structure), so I'll spend the next few days cleaning it up, and working on the feel of the wheel turn/speaking timing, and get the new code posted.

On a side note, I'd love for the PowerMate to have something like a magnetic haptic capability: setting the PowerMate to a certain mode introduces little "notches" in the turning motion. This would make selecting individual favorites far easier, and less of a cautious turn of the wheel.

Jishi, I issued a pull request for a slight change that was helpful to me, but that will break other installs. Feel free to discard if you like. Just wanted to get it out there.
However I just realized, I don't know what would happen for random playback, because I don't know when the random sequence is set, and if it get reset if you disable the queue temporarily. That might perhaps be a bit of a problem.

I'd imagine using a Controller calls the same methods. If you load and shuffle a queue, start a radio station (queue goes into 'Not in Use' mode) then play the same track you previously interrupted, the 'Next' track is still the same one as before. The 'Next' track remains correct even if you resume further into the queue (meaning if you read ahead to know the play order, then skip back, interrupt the first track with radio, then resume at what would have been 4th in the shuffle, the 5th appears in 'Next').

I was curious 🙂
Userlevel 4
Badge +14
Thanks. That's a neat solution. I've figured out how to set the mp3 url, then set the queue uri back, but how can I get (and then restore) the queue (and even track, though less important) position?

You need to note the trackno that was active, then use the seek() method to restore it after you have re-enabled the queue. If you have noted the elapsed time as well, you can trackSeek() as well, before you invoke play().

However I just realized, I don't know what would happen for random playback, because I don't know when the random sequence is set, and if it get reset if you disable the queue temporarily. That might perhaps be a bit of a problem.
Badge +1
FYI, you can play an MP3 on the player without touching the queue. A SetAVTransportURI call will change what is currently playing to a single item which doesn't affect the queue (similar to a radiostation). However, you would loose the queue position and track position, but that could be saved before hand and restored after.


Thanks. That's a neat solution. I've figured out how to set the mp3 url, then set the queue uri back, but how can I get (and then restore) the queue (and even track, though less important) position?
Userlevel 4
Badge +14
This would go through the Pi's speaker, mostly because I don't want to destroy the Sonos queue by shoving an MP3 at it.


FYI, you can play an MP3 on the player without touching the queue. A SetAVTransportURI call will change what is currently playing to a single item which doesn't affect the queue (similar to a radiostation). However, you would loose the queue position and track position, but that could be saved before hand and restored after.

To restore the queue, you just call SetAVTransportURI and set it to "x-rincon-queue:RINCON_12345678901201400#0" where the RINCON_xxxxxxxxx is the UUID of the player (I don't know why it needs the uuid, I don't think you can set a player to play another players queue...).

Worth noting is that you don't need to use the x-rincon-mp3radio: scheme for it neither, you can just set it to a connectable http url like: http://192.168.0.100:1234/tts.mp3 and it will play it straight up. It just need to end in .mp3 for it to read is as an mp3.

A bit more work, and maybe you don't want the sound through your Sonos anyway, but I just wanted to point out that possibility.
Badge +1
Wow, that's a neat combo! Ever considered adding an LCD display to make use of the wheel even more? Thinking about the favorites short coming. If you had like double press, then roll wheel to select favorite. Or if you could make a logical blink sequence to feeback which favorite you select.

Double press, blink once. If you turn the wheel, it would blink twice, trice etc and then press it again selects the favorite.


Actually, what I'm looking at now is caching the favorites whenever I receive a "favorites" emit, and then using some kind of text-to-speech to read the favorites when the wheel is turned and the zone player is off. This would go through the Pi's speaker, mostly because I don't want to destroy the Sonos queue by shoving an MP3 at it.

I considered (and am still considering) the LCD thing, but the text to speech thing sounds more fun! :D

I'll keep the thread up to date.