HTTP Response using sendHubCommand in DeviceHandler


(Mitchell Atchley) #1

I’m struggling to get the callback on sendHubCommand to actually work. I’m connecting to a WiFi enabled Arduino. When I send the command, the Arduino is receiving the http command and enabling the GPIO port that I’m expecting. The Arduino sends a response back with a status of the device, but I never get response in the DeviceHandler. Neither the parse or calledBackHandler methods ever get invoked. I have confirmed the response from the Arduino is responding using Postman.

The device is just a minimote so I have a push event on a button:

def push1() { sendEvent(name: "lblPush2", value: "default", descriptionText: "", isStateChange: true, displayed: false) sendEvent(name: "lblPush3", value: "default", descriptionText: "", isStateChange: true, displayed: false)
def deviceNetworkId = "84:F3:EB:B4:96:CE"  //  "192.168.1.160:80"
// The deviceNetworkId is the MAC address
def ip = "192.168.1.160:80"

sendEvent(name: "button", value: "pushed", data: [buttonNumber: 1, action: "pushed"], source: "COMMAND", descriptionText: "$device.displayName button 1 was pushed", isStateChange: true)
log.debug("Sending HTTP")
return sendHubCommand(new physicalgraph.device.HubAction("""GET HTTP/1.1 /?gpio=$buttonIndex\r\nHOST: $ip\r\n\r\n""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}"))

//pushed(1)

}

I’ve tried using sendHubCommand without saying return, then I’ve tried defining the optional param to explicitly set the call back to parse or calledBackHandler.

Parse method implemented:

def parse(description) {
log.debug(“parse called”)
//def msg = parseLanMessage(description)
//log.debug($description)

sendEvent(name: "lblPush2", value: "pushed", descriptionText: "", isStateChange: true, displayed: false)   

}

calledBackHandler implemented:

void calledBackHandler(physicalgraph.device.HubResponse hubResponse) {
log.debug(“call back called”)

sendEvent(name: "lblPush3", value: "pushed", descriptionText: "", isStateChange: true, displayed: false)   

}

In the parse and calledBackHandlers I put log lines and changed the state of 2 other buttons, just as debugging steps to see if it’s actually calling the methods. Neither the log lines show up in the IDE nor do the buttons change their state on the device, so I’m only left to assume the methods are not being called and/or the sendHubCommand doesn’t know how to handle a HTTP response. Anyone had any luck with something similar? I’ve followed probably over a dozen different posts trying various methods as well as Samsung’s documentation, or lack thereof, and I’m just not getting a response back into SmartThings.


#2

Did you try searching the forum? There are literally dozens of articles on this subject you can find by simply searching HTTP response.


#4

I can’t see it in your code, but are you storing the IP address in int or hex?


(Mitchell Atchley) #5

I had the IP in hex, originally but same result the Arduino gets the request, but no response is handled by SmartThings. I found a post that said the MAC address was better to use, so I switched to it. Does it also need to be in hex?


#6

It already is. But I don’t think it is supposed to have the : in them.


(Mitchell Atchley) #7
def push1() { sendEvent(name: "lblPush2", value: "default", descriptionText: "", isStateChange: true, displayed: false) sendEvent(name: "lblPush3", value: "default", descriptionText: "", isStateChange: true, displayed: false)
def deviceNetworkId = "84F3EBB496CE"  //  "192.168.1.160:80"
// The deviceNetworkId is the MAC address
def ip = "192.168.1.160:80"

sendEvent(name: "button", value: "pushed", data: [buttonNumber: 1, action: "pushed"], source: "COMMAND", descriptionText: "$device.displayName button 1 was pushed", isStateChange: true)
log.debug("Sending HTTP")
return sendHubCommand(new physicalgraph.device.HubAction("""GET HTTP/1.1 /?gpio=$buttonIndex\r\nHOST: $ip\r\n\r\n""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}"))

//pushed(1)

}

I dropped the colons out of the MAC address, but still have the same result, HTTP Get makes it to the Arduino, it enables the GPIO, but never get a return in SmartThings. If I use Postman or Chrome and send the same request, I can see the response of the device status is coming back from the Arduino. I’m just at a loss as to how to get it to pick up the response, it’s just acting like it’s not receiving the call back. What’s funny is if I use the optional argument to explicitly set the call back method on the sendHubCommand method, it does invoke the method I specify there after sending the HTTP request, but the HubResponse object returned is Null when it goes into and throws a JavaIO exception as a result.


(Dan) #8

Have you taken a look at my ST_Anything project yet? Embedded within it is a set of Arduino Libraries named “SmartThings…” which implement bidirectional communications between the ST Hub and Arduino-type devices.


(Mitchell Atchley) #9

Nope, but I’ll gladly check it out.


(Dan) #10

What are you trying to accomplish with the Arduino? I’m always curious how others are using the platform. :grinning:


(CopyCat73) #11

It’s probably your device network ID which isn’t encoded properly as hex. It should look something like C0A80005:0050

I usually use these methods to encode:

private String convertIPtoHex(ipAddress) { 
    String hex = ipAddress.tokenize( '.' ).collect {  String.format( '%02x', it.toInteger() ) }.join()
    return hex

}

private String convertPortToHex(port) {
	String hexport = port.toString().format( '%04x', port.toInteger() )
    return hexport
}

And then put this in your method:

def hosthex = convertIPtoHex(ip).toUpperCase()
def porthex = convertPortToHex(port).toUpperCase()
device.deviceNetworkId = "$hosthex:$porthex"

(Mitchell Atchley) #12

I have the 2Gig GC2 alarm panel at my home. Unfortunately the ZWave interface on it does not allow access to the alarm functions or state. There is a IFTTT terminal on the side of the panel, but it only allows access to the alarm state not the functions. They really just want you to use it as your Zwave hub, but it’s just absolutely horrible as a hub and of course limited customization. I would just change the panel, but it it’s prewired into my home and includes several wireless proprietary 3.45MHz sensors. So, I just soldered into one of the keyfobs, wired that to a relay module, and programmed a web server into the Arduino ESP8266. Then wrote a device handler for minimote in SmartThings and added a device that uses my device handler.


(Mitchell Atchley) #13

I’ll give this a go when I get home, before I try out the ST Anything libraries.


(Dan) #14

So, it appears that you just need to control 4 digital outputs from the ESP8266 from SmartThings, correct?

If so, you can do that easily using ST_Anything. Just take a look at the sample sketch below. It actually implements timed relay outputs so all you have to do is send an ‘on’ command from ST and the code automatically takes care of the timing of the output (user definable) and keeps ST up to date as well.

If your panel can output signals, you can tie those in as well to know about things like overall Alarm status and/or individual zones.

The following example is more designed to replace the entire panel. I know this is not what you want, especially with your existing wireless switches. But, it gives you an example of what is possible if your existing panel can provide some digital output signals.


(Mitchell Atchley) #15

Just wanted to update you that I got it up in running with ST Anything in about 30 minutes and it works amazingly. Can activate the relays and it holds the button on the fob like it needs to for about 3 seconds. I will probably have to tweak it a bit, as it shows the device on during the button press, then off a few seconds later after the press. I need it to say that it’s in that state entirely, so will have to tweak it a bit to change the state of the tiles on the relay devices in smartthings.


(Dan) #16

Glad to hear it is working for you. At the top of each device’s .cpp and .h file you will the documentation for the device, explaining the options.


(Mitchell Atchley) #17

I just put a static variable on the delayedrelay class to keep up with the last pin that was activated, then just updated the besmart, update, and refresh methods to check this static variable for a change when sending the on/off message back to SmartThings. So, the result is the switch shows on in SmartThings even after the relay turns off, and when I turn another relay on, shortly thereafter, it updates SmartThings and shows the other switch off. Works good enough for my purposes.