Grouping Sonos speakers

This ability would be greatly appreciated.

1 Like

Any updates? Perhaps there is a way to use a groovy device driver to group speakers so that we could create RM rules for various presets? We prefer this over setting up another server running node.js. Hey Google, turn on the party speaker preset!

Anything?

+1 for this!! It would be awesome!

1 Like

@dan.t

Can you explain how you are doing this? This would be a great "app" if we could do something. Thoughts?

I use a node server with the node-sonos-http-api from jishi

It has quite a list of supported sonos actions:

  • play
  • pause
  • playpause (toggles playing state)
  • 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
  • togglemute (toggles mute state)
  • trackseek (parameter is queue index)
  • timeseek (parameter is in seconds, 60 for 1:00, 120 for 2:00 etc)
  • next
  • previous
  • state (will return a json-representation of the current state of player)
  • favorite
  • favorites (with optional "detailed" parameter)
  • playlist
  • lockvolumes / unlockvolumes (experimental, will enforce the volume that was selected when locking!)
  • repeat (on/off)
  • shuffle (on/off)
  • crossfade (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)
  • say
  • sayall
  • saypreset
  • queue
  • clearqueue
  • sleep (values in seconds)
  • linein (only analog linein, not PLAYBAR yet)
  • clip (announce custom mp3 clip)
  • clipall
  • clippreset
  • join / leave (Grouping actions)
  • sub (on/off/gain/crossover/polarity) See SUB section for more info
  • nightmode (on/off, PLAYBAR only)
  • speechenhancement (on/off, PLAYBAR only)
  • bass/treble (use -10 thru 10 as value. 0 is neutral)

For grouping, you can use the join/leave commands:

Grouping

You have basic grouping capabilities. join will join the selected player to the specified group (specify group by addressing any of the players in that group):

/Kitchen/join/Office This will join the Kitchen player to the group that Office currently belong to.

/Kitchen/leave Kitchen will leave any group it was part of and become a standalone player.

You don't have to ungroup a player in order to join it to another group, just join it to the new group and it will jump accordingly.

If you want and app, you could create an app that has a virtual child device that supports speech. The child device could send the "text" to be spoken to the parent app and the parent app groups the sonos speakers before it sends the TTS to the master in the group.

Technically, it should work, might have play around with some timing to make sure that commands don't overlap.

EDIT: There is also a "sayall" command that speaks TTS on all Sonos devices. Not sure how synchronized it is though

The node.js app does work well and I already use it. However, if we could get RM to support grouping speakers, then all of us could simply the setup by using the Sonos devices within Hubitat. We would like to see a Leave and Join command added to Sonos devices. kitchenSonos.join(livingRoomSonos).

Is this possible?

Right now it is not possible within RM and it is also not as trivial as it sounds.....

First, the sonos drivers would need to support the grouping.
Once that is done, technically you could group it then via custom commands in RM.

But I can already see the request:
I have 6 sonos devices, my door opens and I want all of them to speak a message and revert back to what they were playing before.

So you technically would need to

a. Retrieve the current status of all Sonos devices
b. stop what they are playing (if you just start grouping that would play what the master is playing)
c. group them
d. speak
e. ungroup them
f. Make them play what they were playing before (if that is even possible depending on what they were playing)

I use two different sets of Sonos speakers. One set for music, the second for dedicated notifications. I can mute the music, then play the notification, then unmute the music. A little more expensive to have a 2nd set of speakers, but much easier than trying to restore groups and previous tracks.

Again, can it be done via Hubitat Sonos device?

You can, together with the node server

You can do something like this:

Ignore the trigger event, I just selected something to have something. I also added some delays to let the joining happen.

Again, you can't do the grouping via RM directly, it is currently not supported

1 Like

I already have it setup this way, trying to simplify and reduce external dependencies. If node.js can group why can't groovy? Thanks for the suggestion but not what I was looking for.

Because the driver for the Sonos devices currently doesn't support it. It is simply not programmed. I am not saying that it is not possible to change the driver. I was trying to give you a solution with the currently available features.

You can make a feature request in the "Feature Request" category here:
https://community.hubitat.com/c/support/Requests

We are currently in the "Lounge" area and I know that the team doesn't monitor that part of the forum that closely.

Trying to expand on things a bit. I've come up with some logic but I need some help expanding it. I'd like to come up with something that resumes the SONOS after an alert has played on another TTS device. The resume ONLY happens if there was something playing before the alert. It's based on the theory that there is one speaker controlling a group.

The constraints are (for now) that the group never changes and that the alerts are being played on something else (e.g. Alexa or Google Home devices).
The variable is that the group may be or not playing something.

So far I've got something like:
Trigger : Whatever it is
Action: Condition for alert = true
(nested if) - IF (controlling media player) is playing THEN
Send GET to http://IP address:5005/pauseall
END IF
Speak alert to something else
(how do I know there was something playing on the Sonos that I paused?)
Send GET to http://IP address:5005/resumeall
END

I'm having a brain lock on testing for the active node of the SONOS playing something and then sending the GET to resume after the alert.

Take it Hubitat will not be doing this. Too bad. I have an iOS app (SonoSequencr) that allows me to group selected speakers at the touch of a button on my apple watch. Fast and convenient. Would love the ability to do this over http tho (via RM). I have a docker app running sonos api. Not as convenient.

Technically, you can do it via RM using the Sonos API by sending a HTTP GET request to http://[your_sonos_api_IP]:[your_sonos_api_port]/[device_1]/join/[group_1].

Repeat it for each device you want to join to the group.

You can also do it by setting up a preset in the presets directory. Then you could call that preset with http://[your_sonos_api_IP]:[your_sonos_api_port]/preset/preset_name.

1 Like

In response to my earlier post about incurring brain lock, it turns out that things will pause and resume if you send the message on the controlling Sonos for that group.

1 Like

Question on the node.js app. Will it update each speaker with the current track info? Or just the first speaker in the group? Latest release of Sharptools will display the album art for the associated speaker. Works great if the speaker is ungrouped or the lead speaker in the group. If its not, it displays the last track info which looks really funky to listen to Pink Floyd but see Barbara Streisand displayed!!

1 Like

I am not sure. You will have to just test it out. You can do a "status" command in your browser that will tell you what the speakers doing. Maybe that will help.

As for creating something that resembles grouping: I've settled on using the Set Track feature, pointing the player to another one that's already playing what I want in the group, using it from Rule Machine. Note that this does not use node-sonos-http-api.

In my case,

Living Room Sonos: Set Track: x-rincon:RINCON_78XXXXXXXXXX01400

The RINCON_78XXXXXXXXXX01400 number is device UDN. You can get this by inserting the MAC address of the source device (i.e., the device whose audio you want to take over) into RINCON_<MAC-ADDRESS>01400.

2 Likes