Parse() only receives data from HTTP hubAction when tapped in app, but not on auto-refresh

Hi, I’m having problems creating a simple device Handler to refresh/poll data from a HTTP get request.

The get request returns a body with a percentage value (radiator valve opening).

When I tap on the ‘refresh’ tile in my device handler, it works and I can parse the data and update the UI tile with the correct value.

The problem is when smartthings calls refresh() on it’s own (without me tapping on UI) - as the hubAction command is created but parse() is never called with data.

What is going on? I’m at a loss.

//capability "Refresh"
def refresh() {
	log.debug "refresh()"
// build empty command array
    def cmds = []
    cmds << runCmd("0")
    //return the array of hubAction commands
    log.debug "refresh() cmds: $cmds"
    return cmds
}


private runCmd(String varCommand) {
	def host = DeviceIP
	def hosthex = convertIPtoHex(host).toUpperCase()
	def porthex = convertPortToHex(DevicePort).toUpperCase()
	device.deviceNetworkId = "$hosthex:$porthex"
	def userpassascii = "${HTTPUser}:${HTTPPassword}"
	def userpass = "Basic " + userpassascii.encodeAsBase64().toString()
	def DevicePostGet = "POST"
	log.debug "The device id configured is: $device.deviceNetworkId"

	//def path = DevicePath
	def path = "/get-valve-max?cube=144F47"
	//log.debug "path is: $path"
	//log.debug "Uses which method: $DevicePostGet"
	def body = ""
	//log.debug "body is: $body"

	def headers = [:]
	headers.put("HOST", "$host:$DevicePort")
	headers.put("Content-Type", "application/x-www-form-urlencoded")

	log.debug "The Header is $headers"
	def method = "GET"

	log.debug "The method is $method"

    def hubAction = new physicalgraph.device.HubAction(
			method: method,
			path: path,
			body: body,
			headers: headers
			)
    return hubAction
}

logs when called by smartthings:

65c75a5a-e466-4c98-bed8-4f997511b8c9  12:32:18 AM: debug refresh() cmds: [GET /get-valve-max?cube=144F47 HTTP/1.1 
Accept: */* 
User-Agent: Linux UPnP/1.0 SmartThings 
HOST: 192.168.0.24:812 
Content-Type: application/x-www-form-urlencoded 

]
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:32:18 AM: debug The method is GET
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:32:18 AM: debug The Header is [HOST:192.168.0.24:812, Content-Type:application/x-www-form-urlencoded]
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:32:18 AM: debug The device id configured is: C0A80018:032C
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:32:18 AM: debug refresh()
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:31:25 AM: debug poll()
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:31:18 AM: debug refresh() cmds: [GET /get-valve-max?cube=144F47 HTTP/1.1 
Accept: */* 
User-Agent: Linux UPnP/1.0 SmartThings 
HOST: 192.168.0.24:812 
Content-Type: application/x-www-form-urlencoded 

]
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:31:18 AM: debug The method is GET
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:31:18 AM: debug The Header is [HOST:192.168.0.24:812, Content-Type:application/x-www-form-urlencoded]
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:31:18 AM: debug The device id configured is: C0A80018:032C
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:31:18 AM: debug refresh()

logs when refresh tile tapped in mobile app:

65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:54 AM: debug off()
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:54 AM: info Turning heat off (demand= 0)
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: debug setLevel() adjusted value 0)
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: debug setLevel(0%)
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: info valveposition: 0%
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: info header OK 200 so update the tile
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: info msg: [index:15, mac:E83935F07D9D, ip:C0A80018, port:032C, requestId:3819b700-3823-4faf-ac3e-5bf92acd53bc, headers:[content-length:2, http/1.1 200 ok:null, connection:close, content-type:text/plain; charset=UTF-8, date:Wed, 22 Nov 2017 00:33:52 +0000], body:0%, header:HTTP/1.1 200 OK 
Date: Wed, 22 Nov 2017 00:33:52 +0000 
Content-Type: text/plain; charset=UTF-8 
Connection: close 
Content-Type: text/plain; charset=UTF-8 
Content-Length: 2, status:200]
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: debug Parsing 'index:15, mac:E83935F07D9D, ip:C0A80018, port:032C, requestId:3819b700-3823-4faf-ac3e-5bf92acd53bc, headers:SFRUUC8xLjEgMjAwIE9LDQpEYXRlOiBXZWQsIDIyIE5vdiAyMDE3IDAwOjMzOjUyICswMDAwDQpDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9VVRGLTgNCkNvbm5lY3Rpb246IGNsb3NlDQpDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9VVRGLTgNCkNvbnRlbnQtTGVuZ3RoOiAy, body:MCU='
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: debug parse()
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: debug refresh() cmds: [GET /get-valve-max?cube=144F47 HTTP/1.1 
Accept: */* 
User-Agent: Linux UPnP/1.0 SmartThings 
HOST: 192.168.0.24:812 
Content-Type: application/x-www-form-urlencoded 

]
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: debug The method is GET
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: debug The Header is [HOST:192.168.0.24:812, Content-Type:application/x-www-form-urlencoded]
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: debug The device id configured is: C0A80018:032C
65c75a5a-e466-4c98-bed8-4f997511b8c9  12:33:53 AM: debug refresh()

Also can anyone explain the difference between using hubAction at httpGet?

This is how my device shows up in the IDE currently. Should it be ‘cloud’ execution if it’s communicating with a server on my LAN?

C0A80018:032C	ACTIVE	Cloud	a minute ago

Did you try to directly return your private method rather than going with the cmd << ?

I have a code that directly send the Hub Command from the refresh and the only difference I see with your code is that.

def refresh() {
log.debug “Executing refresh”

def host = internal_ip 
def port = internal_port
def hosthex = convertIPtoHex(host)
def porthex = convertPortToHex(port)
log.debug "The device id before update is: $device.deviceNetworkId"
device.deviceNetworkId = "$hosthex:$porthex" 

log.debug "The device id configured is: $device.deviceNetworkId"

def path = internal_query_path
log.debug "path is: $path"

def headers = [:] 
headers.put("HOST", "$host:$port")

try {
def hubAction = new physicalgraph.device.HubAction(
method: “GET”,
path: path,
headers: headers
)
state.requestCounter=1
return hubAction

}
catch (Exception e) {
	log.debug "Hit Exception $e on $hubAction"
}

}

You need to use sendHubCommand.

sendHubCommand(hubAction)

def hubAction = new physicalgraph.device.HubAction(
			method: method,
			path: path,
			body: body,
			headers: headers
			)
sendHubCommand(hubAction)

Thanks Steve, I tried this and it worked. I’m still returning the hubAction command as well, perhaps I don’t need to do that now.

What I’m confused about is how come @Philippe_Portes and @erocm1231 have code which does not call sendHubCommand()?

eg @erocm1231’s sonoff code:

def refresh() {
	log.debug "refresh()"
    def cmds = []
    cmds << getAction("/status")
    return cmds
}

private getAction(uri){ 
  updateDNI()
  def userpass
  //log.debug uri
  if(password != null && password != "") 
    userpass = encodeCredentials("admin", password)
    
  def headers = getHeader(userpass)

  def hubAction = new physicalgraph.device.HubAction(
    method: "GET",
    path: uri,
    headers: headers
  )
  return hubAction    
}

I’m finding learning developing smartthings device handlers a bit confusing to be honest, it’s not very straightforward or well documented!

Thanks I’ll try that later.

If I am not.too wrong, this is the same difference between a createEvent and a sendEvent. If you are inside a command (Refresh, Parse, etc…) you don’t need to “send” events. You only need to create them and return them as the command return. St will manage the event firing for you. See the bottom note of http://docs.smartthings.com/en/latest/ref-docs/hubaction-ref.html
That’s why I think the return event I mention is worth a try. Maybe I am wrong, but as you said the documentation is not vsry helpful or sometimes confusing so my practice is to reuse a code that works and adapt it to my usage.