Device Handler not receiving HubAction to parse()


(Jo) #1

I have a device handler with a command. In the command I have the following code. But my parse() function is not being called with the result. It is strange because it was working for a while and then stopped (I did make some changes but even when I rolled back changes it won’t work anymore.) I even tried changing the device IP because someone mentioned an issue if old device instances were hanging around but that didn’t help either.

device.deviceNetworkId = "$iphex:$porthex"
def result = new physicalgraph.device.HubAction(
‘method’: ‘GET’,
‘path’: “/goform/formMainZone_MainZoneXml.xml”,
‘headers’: [ HOST: “$deviceIp:$devicePort” ]
)
result


(Paul Broadwith) #2

Did you ever get a resolution to this?


(Nate Clark) #3

I’m having the same problem. The parse() function doesn’t get called. Here’s my refresh command:

def refresh() {
  def result = new physicalgraph.device.HubAction(
    method: "GET",
    path: "/" + device.id,
    headers: [
      HOST: "192.168.86.100:80"
    ]
  )
  return result
}

deviceNetworkId is set to C0A85664:50. What causes the parse function to get called? Is it just magic? Sadly it’s not working in my case.


Multiple hubaction commands in one function and parsing the response
Multiple hubaction commands in one function and parsing the response
(Nate Clark) #4

I think I figured it out! In my case the port part of the deviceNetworkId was too short. It needs to be 4 digits. I changed the deviceNetworkId to C0A85664:0050 and it worked.


(Barry Quiel) #5

I just ran into this same problem for a device handler I am working on, and I can confirm setting the device id to : does fix the problem. I’m curious why this works though. My problem didn’t show up until I deleted the device and re-added it. I don’t remember every setting the device network id to IP:PORT when I first created the device.

I guess a few questions:
Does this only happen when you delete and re-create the same device?
How do I set this programatically so if some day I publish public it works for everybody?


(Dave Gutheinz) #6

I do not know that setting deviceID to ‘:’ is a good idea. This will work for one device, but violates the unique ID requirement for many. Also, current paradigm is NOT to use IP:Port as the DNI as this can change and if it does, it is difficult to rediscover the device.

I use the callback definition (versus parse), then parse in the callback. example, where “command” is a command string, and I use the headers to pass command data. This also works if you have a body to pass. The below are EDITS on running code.

Using headers:

private sendCmdtoServer(command, action){
def headers = [:]
headers.put(“HOST”, “$IP:$PORT”)
headers.put(“tplink-command”, command)
sendHubCommand(new physicalgraph.device.HubAction([
headers: headers],
device.deviceNetworkId,
[callback:cmdResponse]
))
}

def cmdResponse(response){
cmdResponse = response.headers[“cmd-response”]
PARSE FUNCTIONS.
}

Using BODY where command is the sent body and response is the received body.

private sendCmdtoServer(encrCmd, cmdResponse){
sendHubCommand(
new physicalgraph.device.HubAction([
body: encrCmd,
headers: [
HOST: “$IP:$PORT”,
]],
device.deviceNetworkId,
[callback: cmdResponse]
)
)
}

def cmdResponse(response){
def cmdResponse = parseJson(response.body)
PARSE DATA

}

hope this what you were looking for. The full code for the first example is for a TP-Link bulb, plug, or switch controlled through a PC bridge.


(Barry Quiel) #7

Thanks for the ideas, and the sample code. Unfortunately no matter what I try it seems the call back response from the HubAction only works if I set the device network id to ip and mac. I’ve tried using both an explicit call back function and leaving it null so that parse gets called. I tried a variety of network device ids, random ascii strings, hex only characters, but the only way a callback is executed is by encoding the ip:port as a hex string in the device network id. I agree with you. All the docs say not to use the ip in the device network id. It feels like there is something fundamentally broken with the call back of LAN based HubAction.


(cjcharles) #8

Did any of you work out a solution to this? Or do you still have the missing response in parse when using a HubAction? For most hubs and people, having a DNI of the device MAC address (without colons) works well, but for some hubs it is giving no response and nothing reaches parse.
Thanks


(Dan) #9

I have never had an issue having parse() called as long as my DNI is the MAC address of the LAN connected device. No delimiters and all UPPERCASE. Full disclosure - my LAN connected devices are Arduinos who always send their response to the hub’s IP + Port. This works on both v1 and v2 hubs.


(cjcharles) #10

Yes, and that is the case with me and my device handlers (+ESP8266s), but this hub is behaving differently… Parse never gets called, yet the commands are being sent correctly.

I.e. the ESP receives the command and does the action and sends back some JSON, but ST never receives it (or if it receives it, it doesnt reach parse). The exact same code is working fine on ~10 hubs, apart from this one…


(cjcharles) #11

This is a growing problem… Ive just had this happen on a second hub now. Unless I encode the IP address and port into HEX then ST doesnt ever receive the JSON response… For me and several others this works with the MAC address, but for these two hubs it doesnt do anything unless you use the IP…

Any ideas anybody? Thanks in advance!


(Michaeltschmidt) #12

Not sure if this will help anyone, but I spent the last 2 days trying to sort this out for myself, and I found after much troubleshooting that node red was returning the hex IP and hex port in all uppercase; however, I was setting the device network ID using lower case. All needed to do was set my hex values to “.uppercase()”, and voila, I could parse the return.

Maybe just me, but sometimes it is the little things.


(David Chiluk) #13

Since some of you appear to have figured this out. Maybe someone can clue me in to what I’m doing wrong here.

def off() {
	log.debug "Executing 'off'"
        
    def offAction = new physicalgraph.device.HubAction(
    	method: "GET",
    	path: "/OFF",
    	headers: [
        	HOST: "192.168.1.61:8080"
    	]
	)
    offAction
}

(Chris Holt) #14

Slightly delayed response as I just found this, but as I have battled this all day:

For sending the command, you are all correct except you needed sendHubCommand(offAction) as you need to initiate the action yourself in an off() routine.

For the parsing, I have discovered the device ID doesn’t need to have a port specified, so the 4 digit issue above caused me all amounts of pain, but remove the :0050 (or whatever your port is) off the network ID and it parses anything for that IP! Argh!