This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

SONOS commands to group players
#1
Hello, is anyone familiar with commands to group players?
I have found a way to get a player out of the group with this command:

Code:
upnpavcmd(IP_address, 1400, 'BecomeCoordinatorOfStandaloneGroup')

Unfortunately I cannot seem to find anything that does the opposite. I already tried to find the proper commands through Wireshark but it seems rather complicated to me.

Thanks in advance for any suggestion.

BR, David
Reply
#2
Hi David,

I think you are looking for 'BecomeGroupCoordinator' but you probably need to pass extra fields like InstanceID, OtherMembers etcetera and you might need to add some extra's to the
upnpcmd function as it is currenty written for the basic operations and some extended functions but not all that are available. 

You should use Device Spy from DeveloperToolsForUPnPTechnologies to browse your sonos and see the needed fields.

Be aware it's time consuming as i know now, i just finished the Sonos app, its working 100% and now i'm running test now to debug and improve the scripting.

Here is already a teaser screenshot for what is comming in the next period (;

BR,

Erwin

Attached Files Thumbnail(s)
   
Reply
#3
Nice work, Erwin! Smile
Reply
#4
Hi,

To group players you need set the uri of each player to the master player. note as you add each player to the group,  this takes time to do, which is why there is an sleep added after each player is placed into the group. Once you have groups the players, set their volume then you can set what to play on the master.

 One BIG note to point out when you work with SONOS implementation you will need to make sure that ALL sonos players are be configured with a static IP.  The only way to do this is use DHCP reservation which is configured for each player in the router.


Event based script

Code:
   upnpavcmd('192.168.0.24', 1400, 'Stop')
   upnpavcmd('192.168.0.24', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>40</DesiredVolume>')
   uri = '<CurrentURI>x-rincon:RINCON_000E58DC0F3601400</CurrentURI><CurrentURIMetaData/>'
   upnpavcmd('192.168.0.8', 1400, 'SetAVTransportURI', uri)
   os.sleep(1)
   upnpavcmd('192.168.0.9', 1400, 'SetAVTransportURI', uri)
   os.sleep(1)
   upnpavcmd('192.168.0.20', 1400, 'SetAVTransportURI', uri)
   os.sleep(1)
   upnpavcmd('192.168.0.25', 1400, 'SetAVTransportURI', uri)
   os.sleep(1)
   upnpavcmd('192.168.0.8', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>20</DesiredVolume>')
   upnpavcmd('192.168.0.9', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>20</DesiredVolume>')
   upnpavcmd('192.168.0.20', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>20</DesiredVolume>')
   upnpavcmd('192.168.0.25', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>20</DesiredVolume>')
   upnpavcmd('192.168.0.24', 1400, 'SnapshotGroupVolume')
   uri = '<CurrentURI>pndrradio:2496906846458345314?sn=1</CurrentURI>'
   meta = uri  .. '<CurrentURIMetaData>&lt;DIDL-Lite xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:upnp=&quot;urn:schemas-upnp-org:metadata-1-0/upnp/&quot; xmlns:r=&quot;urn:schemas-rinconnetworks-com:metadata-1-0/&quot; xmlns=&quot;urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/&quot;&gt;&lt;item id=&quot;OOOX2496906846458345314&quot; parentID=&quot;0&quot; restricted=&quot;true&quot;&gt;&lt;dc:title&gt;Rihanna Radio&lt;/dc:title&gt;&lt;upnp:class&gt;object.item.audioItem.audioBroadcast&lt;/upnp:class&gt;&lt;desc id=&quot;cdudn&quot; nameSpace=&quot;urn:schemas-rinconnetworks-com:metadata-1-0/&quot;&gt;SA_RINCON3_massimo@massmore.com&lt;/desc&gt;&lt;/item&gt;&lt;/DIDL-Lite&gt;</CurrentURIMetaData>'  
   upnpavcmd('192.168.0.24', 1400, 'SetGroupVolume', '<Channel>Master</Channel><DesiredVolume>40</DesiredVolume>')
   upnpavcmd('192.168.0.24', 1400, 'SetGroupMute', '<Channel>Master</Channel><DesiredMute>0</DesiredMute>')
   upnpavcmd('192.168.0.24', 1400, 'SetAVTransportURI', meta)  
   upnpavcmd('192.168.0.24', 1400, 'Play', '<Speed>1</Speed>')

Common Function

Code:
   function upnpavcmd(host, port, cmd, param)
   local client, soap, reqs, service, res, err
   
   require('socket')
   client = socket.tcp()
   client:settimeout(3)
   
   -- try connecting to upnp endpoint
   res, err = client:connect(host, port)
   if not res then
   return nil, err
   end
   
   -- guess service name based on command
 if cmd =='SetGroupVolume' or cmd == 'SetGroupMute' or cmd == 'SnapshotGroupVolume' then
   service = 'GroupRenderingControl'
 elseif cmd == 'SetVolume' or cmd == 'GetVolume' or cmd == 'SetMute' or cmd == 'GetMute' then
   service = 'RenderingControl'
   else
   service = 'AVTransport'
   end
 
   -- soap envelope
   soap = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' ..
   '<s:Body>' ..
   '<u:' .. cmd .. ' xmlns:u="urn:schemas-upnp-org:service:' .. service .. ':1">' ..
   '<InstanceID>0</InstanceID>' ..
   (param or '') ..
   '</u:' .. cmd .. '>' ..
   '</s:Body>' ..
   '</s:Envelope>'
   
   -- http request
   reqs = 'POST /MediaRenderer/' .. service .. '/Control HTTP/1.1\r\n' ..
   'CONNECTION: close\r\n' ..
   'HOST: ' .. host .. ':' .. port .. '\r\n' ..
   'CONTENT-LENGTH: ' .. soap:len() .. '\r\n' ..
   'CONTENT-TYPE: text/xml; charset="utf-8"\r\n' ..
   'SOAPACTION: "urn:schemas-upnp-org:service:' .. service .. ':1#' .. cmd .. '"\r\n' ..
   '\r\n' .. soap
   
   -- send http request
   res, err = client:send(reqs)
   if not res then
   return nil, err
   end
   
   -- get reply and close connection
   res, err = client:receive('*a')
   client:close()
   
   return res, err
   end


thanks,

Roger
Reply
#5
Hello Roger, apparently I forgot to reply to your post. My apologies for that!
Just wanted to thank you because what you suggested works like a charm :-)

Static IP is not an option on the basic router I have, but with the code I got from Erwin van der Zwart I can periodically search for the IP address that matches a specific zone name. So no problem there.

Very happy with this
Reply
#6
Erwin has successfully finished and debugged SONOS app for LogicMachine which we have placed in the app store. Please fee free to test and post your comments/suggestions.
Cheers Erwin van der Zwart!
Reply
#7
Hello, still having a minor problem with grouping and ungrouping players.
I use KNX pushbuttons to control my SONOS players and use following command to stop the player if it's playing (1 toggle button to switch between ON and OFF)

Code:
 -- Pause if status is playing, play otherwise
 if (status_beneden == "PLAYING") then
   upnpavcmd(IP_Beneden, 1400, 'BecomeCoordinatorOfStandaloneGroup')
   upnpavcmd(IP_Beneden, 1400, 'Pause')

This works flawlessly if the player is indeed part of a group: the player is removed from the group and paused, as one would expect  Smile
When the player is not part of a group however the first command causes some sort of stop command and the current playlist is not paused but stopped.
To illustrate this see the attached screenshots:
  • screenshot 1 and 2 when the player was part of a group and was successfully ungrouped
           
  • screenshot 3 and 4 when the player was not part of a group and thus stopped instead of paused
           
Seems like I would need a code to first check whether the player is part of the group so I could avoid the first command line with an IF conditional check.

Any suggestions are kindly appreciated.

Best regards, David
Reply
#8
(07.07.2016, 13:34)rocfusion Wrote: Hi,

To group players you need set the uri of each player to the master player. note as you add each player to the group,  this takes time to do, which is why there is an sleep added after each player is placed into the group. Once you have groups the players, set their volume then you can set what to play on the master.

 One BIG note to point out when you work with SONOS implementation you will need to make sure that ALL sonos players are be configured with a static IP.  The only way to do this is use DHCP reservation which is configured for each player in the router.


Event based script

Code:
   upnpavcmd('192.168.0.24', 1400, 'Stop')
   upnpavcmd('192.168.0.24', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>40</DesiredVolume>')
   uri = '<CurrentURI>x-rincon:RINCON_000E58DC0F3601400</CurrentURI><CurrentURIMetaData/>'
   upnpavcmd('192.168.0.8', 1400, 'SetAVTransportURI', uri)
   os.sleep(1)
   upnpavcmd('192.168.0.9', 1400, 'SetAVTransportURI', uri)
   os.sleep(1)
   upnpavcmd('192.168.0.20', 1400, 'SetAVTransportURI', uri)
   os.sleep(1)
   upnpavcmd('192.168.0.25', 1400, 'SetAVTransportURI', uri)
   os.sleep(1)
   upnpavcmd('192.168.0.8', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>20</DesiredVolume>')
   upnpavcmd('192.168.0.9', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>20</DesiredVolume>')
   upnpavcmd('192.168.0.20', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>20</DesiredVolume>')
   upnpavcmd('192.168.0.25', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>20</DesiredVolume>')
   upnpavcmd('192.168.0.24', 1400, 'SnapshotGroupVolume')
   uri = '<CurrentURI>pndrradio:2496906846458345314?sn=1</CurrentURI>'
   meta = uri  .. '<CurrentURIMetaData>&lt;DIDL-Lite xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:upnp=&quot;urn:schemas-upnp-org:metadata-1-0/upnp/&quot; xmlns:r=&quot;urn:schemas-rinconnetworks-com:metadata-1-0/&quot; xmlns=&quot;urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/&quot;&gt;&lt;item id=&quot;OOOX2496906846458345314&quot; parentID=&quot;0&quot; restricted=&quot;true&quot;&gt;&lt;dc:title&gt;Rihanna Radio&lt;/dc:title&gt;&lt;upnp:class&gt;object.item.audioItem.audioBroadcast&lt;/upnp:class&gt;&lt;desc id=&quot;cdudn&quot; nameSpace=&quot;urn:schemas-rinconnetworks-com:metadata-1-0/&quot;&gt;SA_RINCON3_massimo@massmore.com&lt;/desc&gt;&lt;/item&gt;&lt;/DIDL-Lite&gt;</CurrentURIMetaData>'  
   upnpavcmd('192.168.0.24', 1400, 'SetGroupVolume', '<Channel>Master</Channel><DesiredVolume>40</DesiredVolume>')
   upnpavcmd('192.168.0.24', 1400, 'SetGroupMute', '<Channel>Master</Channel><DesiredMute>0</DesiredMute>')
   upnpavcmd('192.168.0.24', 1400, 'SetAVTransportURI', meta)  
   upnpavcmd('192.168.0.24', 1400, 'Play', '<Speed>1</Speed>')

Common Function

Code:
   function upnpavcmd(host, port, cmd, param)
   local client, soap, reqs, service, res, err
   
   require('socket')
   client = socket.tcp()
   client:settimeout(3)
   
   -- try connecting to upnp endpoint
   res, err = client:connect(host, port)
   if not res then
   return nil, err
   end
   
   -- guess service name based on command
 if cmd =='SetGroupVolume' or cmd == 'SetGroupMute' or cmd == 'SnapshotGroupVolume' then
   service = 'GroupRenderingControl'
 elseif cmd == 'SetVolume' or cmd == 'GetVolume' or cmd == 'SetMute' or cmd == 'GetMute' then
   service = 'RenderingControl'
   else
   service = 'AVTransport'
   end
 
   -- soap envelope
   soap = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' ..
   '<s:Body>' ..
   '<u:' .. cmd .. ' xmlns:u="urn:schemas-upnp-org:service:' .. service .. ':1">' ..
   '<InstanceID>0</InstanceID>' ..
   (param or '') ..
   '</u:' .. cmd .. '>' ..
   '</s:Body>' ..
   '</s:Envelope>'
   
   -- http request
   reqs = 'POST /MediaRenderer/' .. service .. '/Control HTTP/1.1\r\n' ..
   'CONNECTION: close\r\n' ..
   'HOST: ' .. host .. ':' .. port .. '\r\n' ..
   'CONTENT-LENGTH: ' .. soap:len() .. '\r\n' ..
   'CONTENT-TYPE: text/xml; charset="utf-8"\r\n' ..
   'SOAPACTION: "urn:schemas-upnp-org:service:' .. service .. ':1#' .. cmd .. '"\r\n' ..
   '\r\n' .. soap
   
   -- send http request
   res, err = client:send(reqs)
   if not res then
   return nil, err
   end
   
   -- get reply and close connection
   res, err = client:receive('*a')
   client:close()
   
   return res, err
   end


thanks,

Roger


Hello everybody, 

with me this does not work with the following script unfortunately. 
My second Sonos is simply started, but not grouped with the master. 
Can anyone help me? is it possible that you can't group Sonos One with Sonos Beam?

Code:
   upnpavcmd('192.168.2.134', 1400, 'Stop')
upnpavcmd('192.168.2.120', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>40</DesiredVolume>')
   uri = '<CurrentURI>x-rincon:RINCON_000E58DC0F3601400</CurrentURI><CurrentURIMetaData/>'
   upnpavcmd('192.168.2.120', 1400, 'SetAVTransportURI', uri)
   upnpavcmd('192.168.2.120', 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>20</DesiredVolume>')
   upnpavcmd('192.168.2.134', 1400, 'SnapshotGroupVolume')
   uri = '<CurrentURI>pndrradio:2496906846458345314?sn=1</CurrentURI>'
   meta = uri  .. '<CurrentURIMetaData>&lt;DIDL-Lite xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:upnp=&quot;urn:schemas-upnp-org:metadata-1-0/upnp/&quot; xmlns:r=&quot;urn:schemas-rinconnetworks-com:metadata-1-0/&quot; xmlns=&quot;urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/&quot;&gt;&lt;item id=&quot;OOOX2496906846458345314&quot; parentID=&quot;0&quot; restricted=&quot;true&quot;&gt;&lt;dc:title&gt;Rihanna Radio&lt;/dc:title&gt;&lt;upnp:class&gt;object.item.audioItem.audioBroadcast&lt;/upnp:class&gt;&lt;desc id=&quot;cdudn&quot; nameSpace=&quot;urn:schemas-rinconnetworks-com:metadata-1-0/&quot;&gt;SA_RINCON3_massimo@massmore.com&lt;/desc&gt;&lt;/item&gt;&lt;/DIDL-Lite&gt;</CurrentURIMetaData>'  
   upnpavcmd('192.168.2.134', 1400, 'SetGroupVolume', '<Channel>Master</Channel><DesiredVolume>40</DesiredVolume>')
   upnpavcmd('192.168.2.134', 1400, 'SetGroupMute', '<Channel>Master</Channel><DesiredMute>0</DesiredMute>')
   upnpavcmd('192.168.2.134', 1400, 'SetAVTransportURI', meta)  
   upnpavcmd('192.168.2.134', 1400, 'Play', '<Speed>1</Speed>')
Reply


Forum Jump: