HubSoapAction documentation

How do I send a HubSoapAction to a particular ip and port? There is no documentation for HubSoapAction - but the call does exist. HubAction has a (Map, dni, options) version of the call, but that version is not working on HubSoapAction..

	def soap = new hubitat.device.HubSoapAction([
		path:    path ?: "/MediaRenderer/$service/Control",
		urn:     "urn:schemas-upnp-org:service:$service:1",
		action:  action,
		body:    body,
		headers: [Host: "${ip}:1400", CONNECTION: "close"]]
	)
	sendHubCommand(soap)

does not generate any response on the parse method.. Assuming it is not sending to the ip specified in host header. I don't know where to specify the ip and port to send it to..

Also, I am trying to do this in an app rather than device.. The documentation I THINK says you can only do sendHubCommand from devices not apps - is that correct? If that is the case, I will need to create a device driver just to do the communication.

The documentation is pretty clear on this point - sendHubCommand() is a method only available in driver code.

Yup.

Thanks - can I do an httpPost myself to create the equivalent of hubsoapaction from an app - since that method is available?

I ask because that is also giving me an error (apache.ClientException) - assuming that httpPost cannot be used to local devices - only to the cloud?

httpPost should be ok, that is what Maker API can do to send events. Perhaps post a sample of your code.

1 Like
def sonosRequest(sonos, cmd, values) {
	def ip = convertHexToIP(sonos.getDeviceNetworkId())
	def meta = getCommand(cmd)
	def params = meta['commands'][cmd]['params']
	def paramXml = ''

	params.each {k,v ->
		paramXml = paramXml + sprintf("<%s>%s</%s>", k, 
		groovy.xml.XmlUtil.escapeXml((values.containsKey(k) ? values[k] : params[k]) as String), k)
	}

	def req = sprintf("""<?xml version="1.0" encoding="utf-8"?>
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <s:Body>
        <u:%s xmlns:u="%s">
        %s
        </u:%s>
      </s:Body>
    </s:Envelope>""", cmd, meta['urn'], paramXml, cmd)

	def headers = [
        Host : ip+':1400',
        soapaction : meta['urn']+'#'+cmd,
        'Content-Type' : 'text/xml; charset="utf-8"',
        'Content-Length' : req.length()
    ]

	def url = 'http://'+ip+':1400'+meta['control']
	debug("${url} -> ${headers} -> ${req}")

	httpPost([uri: url, headers: headers, body: req], { data -> parseResponse(data) } )
}

What does the url come out as in the debug log?

http://192.168.2.91:1400/MediaServer/ContentDirectory/Control

and the exact error is..

org.apache.http.client.ClientProtocolException: null 

Is that error coming out in parseResponse? (I'll soon exhaust my knowledge here :slight_smile: )

Nope - httpPost call is causing that error - never gets to parseResponse.

So I assume the headers map and req also come out as expected in the debug log....? From what I've read it could have something to with the contents of the header.

Yeah, thanks that was it.. I removed my content-length and content-type headers and used the contentType param instead and it seems to have gone through! Thanks for your help!!

1 Like

Cool.

Out of interest, are you trying to develop a driver / app to control Sonos speakers?

not exactly - just an add-on to allow me to pick and play favorites/playlists - which does not seem to be possible with the built-in integration.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.