Sending GET requests

devicetype
developers

(Euan) #1

Okay, I’m struggling here:

I’m very simply trying to send an HTTP GET request to a device on my local network. I don’t need a reply; I don’t (at this stage) need to get any user input. Simply send a string when a contact is opened.

The flow is: contact.open -> send GET to local device.

I realise that I need a hubAction as the device is local. I’ve worked my way through the tutorials etc, but it seems about as clear as mud. The tutorials concentrate on far more complicated examples.

Some say you need a device handler and SmartApp to do this. Others say it can be done in a SmartApp only. Some say the IP and port must be in hex, some say not.

Can anyone supply a clear, definitive answer on what is required for, what should be, a very simple app?

My many thanks in advance!


(Joshua Lyon (SharpTools.io Dashboard)) #2

Use the HubAction with the IP:Port as a HOST parameter and make sure the hub action is returned from your command method:

def myCommand() {
    def result = new physicalgraph.device.HubAction(
        method: "GET",
        path: "/yourpath?param1=value1&param2=value2",
        headers: [
            HOST: "192.168.1.10:80"
        ]
    )
    return result
}

In order to handle responses in a device, you’ll need the DNI (device network ID) of your device in SmartThings set to either the IP:PORT in hex or the MAC address of the target device and the response will show up in parse(). If you want to see the responses in a SmartApp, you’ll have to subscribe to the location and handle the response yourself.

There’s some work being done on adding callbacks to hubaction… this isn’t officially documented yet, but you can see an example of it in some of the official device types in the SmartThings GitHub repo:

sendHubCommand(new physicalgraph.device.HubAction("""GET /setup.xml HTTP/1.1
HOST: ${deviceNetworkId}
""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}", [callback: "setupHandler"]))
void setupHandler(hubResponse) {
	String contentType = hubResponse?.headers['Content-Type']
	if (contentType != null && contentType == 'text/xml') {
		def body = hubResponse.xml
		def wemoDevices = []
		String deviceType = body?.device?.deviceType?.text() ?: ""
        ...

HubAction callbacks
SmartApp locationHandler called instead of device parse
(Alan Penner) #3

This is a shame. I’m trying to use those undocumented callbacks, and I guess they’re undocumented for a reason. They don’t really seem to work well. If I just send out a single request, it seems okay, but if I send out a whole bunch of requests with callbacks, I get the responses sent to the wrong functions. And there doesn’t seem to be a way to get the request ID when you make an HTTP request, so there’s no way to match them up with the ID returned in the response. Looks like it’s just hubActionObject.requestId. I guess I can manage all the requests myself to track which goes where, but that seems like a ton of work that shouldn’t be necessary.