SONOS Plugin
Posted: Wed Feb 13, 2013 3:24 pm
New in this forum. Have someone createdt a sonos plugin to controll sonos with?
Jostein wrote:Hi.
Have found a way to controll the basic functions of sonos from Eventghost.
I wanted to create a plugin using the python class SoCo, but have not had time.
Have instead made a workaround using a command line tool called ZPCMD made by Osler se:
http://forums.sonos.com/showthread.php?t=12649&page=1
Here are the steps to get it working.
1. Run the file called "UniqueDeviceNames.vbs" (this will create a text file called UniqueDeviceNames.txt on C:\ including the id for your devices.)
2. Register the scripts ZonePlayerController.wsc and ZonePlayerFinder.wsc right click on it and press "register".
3. Right click on the example config file Sonos example.xml click "Edit". In notepad select "edit" on the top bar and then "replace".
In the "find what" box insert: RINCON_000E583EABEC01400
In the "replace with" box insert the uuid of the sonos box you want to controll. (se the text file C:\UniqueDeviceNames.txt)
press "replace all". Save and exit.
4. Open the example config file from EG and test if the commands works. If it works you can copy the sonos folder over to your config file.
If you get an ActiveX error you need to register the scripts using the included bat files. If you dont have the scripts in this folder: "C:\Program Files (x86)\EventGhost\plugins\Sonos\WSC\ZonePlayerController\ZonePlayerController.wsc" you need to edit it to the correct paths in the bat files.
This is not the best way to controll sonos but it is the way i do it. Will try to make a plugin later using the SoCo class as this would make for a cleaner install and also provide a 2 way controll with fedbacks and so on.

Hi Jostein,Jostein wrote:Hi techoguy.
Would be interested in seeing your files, since i beleive your way of controlling sonos is the right way and also the path to go for more advanced control.
I have also wall switches (Smart HDL DLP) that i use for pause, play, and so on. But would like to have some switches for preset radio channels, do you have a script for starting a spesific radio channel?
Regards Jostein
Code: Select all
from xml.dom.minidom import parse, parseString
import httplib
path = "/MediaRenderer/AVTransport/Control HTTP/1.1"
host = "192.168.0.107"
port = 1400
hostport = host + ":" + str(port)
xml = '''<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:GetMediaInfo xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
<InstanceID>0</InstanceID>
</u:GetMediaInfo>
</s:Body>
</s:Envelope>'''
conn = httplib.HTTPConnection(host,port)
conn.request("POST", path, body=xml, headers = {
"Host": hostport,
"SOAPACTION": '''"urn:schemas-upnp-org:service:AVTransport:1#GetMediaInfo"''',
"Content-Type": "text/xml; charset=UTF-8",
"Content-Length": len(xml)
})
print "finding coordinator of group.."
res = conn.getresponse()
print res.status, res.reason
xml = res.read()
dom = parseString(xml)
uri = dom.getElementsByTagName('CurrentURI')[0].childNodes[0].nodeValue
if uri.find("x-rincon:RINCON_") == 0:
coordinator = uri.split(":")[1]
print "current ZP is a slave, coordinator is ", coordinator
path = "/ZoneGroupTopology/Control HTTP/1.1"
xml = '''<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:GetZoneGroupState xmlns:u="urn:schemas-upnp-org:service:ZoneGroupTopology:1" />
</s:Body>
</s:Envelope>'''
conn = httplib.HTTPConnection(host,port)
conn.request("POST", path, body=xml, headers = {
"Host": hostport,
"SOAPACTION": '''"urn:schemas-upnp-org:service:ZoneGroupTopology:1#GetZoneGroupState"''',
"Content-Type": "text/xml; charset=UTF-8",
"Content-Length": len(xml)
})
print "requsting group info..."
res = conn.getresponse()
print res.status, res.reason
xml = res.read()
index = xml.find('UUID="'+coordinator)
host = xml[index+57:index+86].split(":")[1].replace("//","")
else:
print "current zp is coordinator"
path = "/MediaRenderer/AVTransport/Control HTTP/1.1"
hostport = host + ":" + str(port)
xml = '''<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
<InstanceID>0</InstanceID>
<Speed>1</Speed>
</u:Play>
</s:Body>
</s:Envelope>'''
conn = httplib.HTTPConnection(host,port)
conn.request("POST", path, body=xml, headers = {
"Host": hostport,
"SOAPACTION": '''"urn:schemas-upnp-org:service:AVTransport:1#Play"''',
"Content-Type": "text/xml; charset=UTF-8",
"Content-Length": len(xml)
})
print "sending PLAY to ", host
res = conn.getresponse()
print res.status, res.reason
Code: Select all
import httplib
path = "/MediaRenderer/RenderingControl/Control HTTP/1.1"
host = "192.168.0.107"
port = 1400
hostport = host + ":" + str(port)
volume = 5
xml = '''<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:SetRelativeVolume xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1">
<InstanceID>0</InstanceID>
<Channel>Master</Channel>
<Adjustment>+''' + str(volume) +'''</Adjustment>
</u:SetRelativeVolume>
</s:Body>
</s:Envelope>'''
conn = httplib.HTTPConnection(host,port)
conn.request("POST", path, body=xml, headers = {
"Host": hostport,
"SOAPACTION": '''"urn:schemas-upnp-org:service:RenderingControl:1#SetRelativeVolume"''',
"Content-Type": "text/xml; charset=UTF-8",
"Content-Length": len(xml)
})