SONOS commands to group players - david.rombaut@gmail.com - 06.07.2016
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
RE: SONOS commands to group players - Erwin van der Zwart - 06.07.2016
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
RE: SONOS commands to group players - edgars - 07.07.2016
Nice work, Erwin!
RE: SONOS commands to group players - rocfusion - 07.07.2016
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><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="OOOX2496906846458345314" parentID="0" restricted="true"><dc:title>Rihanna Radio</dc:title><upnp:class>object.item.audioItem.audioBroadcast</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON3_massimo@massmore.com</desc></item></DIDL-Lite></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
RE: SONOS commands to group players - david.rombaut@gmail.com - 16.09.2016
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
RE: SONOS commands to group players - edgars - 07.10.2016
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!
RE: SONOS commands to group players - david.rombaut@gmail.com - 14.12.2018
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
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
RE: SONOS commands to group players - lenze90 - 23.02.2019
(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><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="OOOX2496906846458345314" parentID="0" restricted="true"><dc:title>Rihanna Radio</dc:title><upnp:class>object.item.audioItem.audioBroadcast</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON3_massimo@massmore.com</desc></item></DIDL-Lite></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><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="OOOX2496906846458345314" parentID="0" restricted="true"><dc:title>Rihanna Radio</dc:title><upnp:class>object.item.audioItem.audioBroadcast</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON3_massimo@massmore.com</desc></item></DIDL-Lite></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>')
|