Hubaction() not executed when scheduled via runIn() from device handler?


(Andreas A.) #1

I am trying to write a device handler that connects to a local IP device on automatically pulls new data every 5 minutes (which is the update frequency of the device).

An abbreviated version looks like this:

[…]

def poll() {
  pullData()
}

def refresh() {
  pullData()
}

def pullData() {
  log.debug "Requesting latest data…"
  runIn(300, pullData)
  new physicalgraph.device.HubAction([
    method: "GET",
    path: uri,
    headers: [HOST:getHostAddress()]
  ])
}

def parse(String message) {
  log.debug "Response received…"
  […]
}

From the logs I can clearly see that the pullData() method is called every 5 minutes. However, unless I manually refresh the device in the app (or use Pollster to refresh it), the parse() method is not called.

Is the hubaction not executed from called this way from within the device handler? Anything I can do to make this work without having to resort to Pollster?


(Ben Lebson) #2

Just to confirm, are you setting your DIN to be the IP:PORT in Hex? If you don’t do this then you will not get a response. Also, if you are nesting the function that calls hubAction you need to return your hubAction in order to get it to parse. See one of my devicetypes for an example:


(Andreas A.) #3

Yes - I am. As I said, the parse() function get called correctly when using the refresh tile in the device or using Pollster to call refresh() - it just doesn’t work when pullData() is called via runIn() from within pullData() itself.

I added a return and it doesn’t make a difference…


(Ben Lebson) #4

Could you move the runIn() command into the parse() command, so that it avoids calling the function within itself?


(Andreas A.) #5

Tried that and it didn’t make a difference. The reason I had it in pullData() was that parse() didn’t seem to be called in the first place when pullData() was triggered by a runIn(). It seems to me as if there is something in the hub that causes this to fail…


(JZst) #6

Agreed, it’s probably something that’s turned off on purpose. Makes no sense for me not to be able to have a simple sleep/pause/runIn that works on the DEVICE HANDLER level not SmartApps where it does seem to work.

ST Devs hopefully watching. Here’s a simple call in a Device handler that fails:
runIn(5,sendEvent(name: “rebootnow”, value: “default”))

Fails with this error:
groovy.lang.MissingMethodException: No signature of
method: script14595755330201108996166.null() is applicable for argument
types: () values: [] Possible solutions: now(), run(), dump(), html(java.lang.String), tile(java.util.Map), use([Ljava.lang.Object;)

Hoping to see it fixed/enhanced one day.


(Andreas A.) #7

@slagle Any official statement on this? The ticket I created about this issue (185862) has been closed as “solved” without ever getting any resolution. Creating a follow-up ticket using the links provided doesn’t work either.

It seems as if there is no working way to get any developer help these days :cry:


(Enis Hoca) #8

did this get addressed? @ahndee how did you get around this?


(Andreas A.) #9

I don’t think so.

I use the following function to schedule the hubaction (which is in the pullData function):

def startPoll() {
	unschedule()
	// Schedule polling based on preference setting
	def sec = Math.round(Math.floor(Math.random() * 60))
	def min = Math.round(Math.floor(Math.random() * settings.pollingInterval.toInteger()))
	def cron = "${sec} ${min}/${settings.pollingInterval.toInteger()} * * * ?" // every N min
	log.trace("$device.displayName - startPoll: schedule('$cron', pullData)")
	schedule(cron, pullData)
}

The startPoll function is called in the updated() function for my DTH.


(Enis Hoca) #10

thanks - not pretty but as long as I dont have to write a smartapp and have to deal with this


(JZst) #11

Are you both saying that schedule and unschedule works properly inside of a DTH?

If possible, would love to see the entire DTH code as reference. Thanks for sharing the above as it closes an interesting gap.


(Andreas A.) #12

Here is my DTH:

Please note that the issues SmartThings introduced in the mobile app last Friday currently cause an error (though things work just fine in the simulator).


(JZst) #13

Damn that’s pretty looking, nice work! Thanks again for sharing!!!


(Enis Hoca) #14

Your DH looks very nice will take a look at your code. It could be quite useful for a gas/water meter app that I have been semi working on.

The polling loop didn’t work from within the DH - what worked however was a very whacky thing. I had given up on this and started writing a service manager app, as I was in the beginning of the the app, I saw messages being handled by the DH.

So the trick that worked for me was this - leave the server and port in hex in the NID field, put the scheduler, request and, subscribe to location events from the app, and have a stub handler, now every time the response comes backs it is routed to the DH and the app doesn’t get it. This is probably a walk in the side-effect land, and can break with any release, but it works as of now

Writing this out because it can be used for other interesting models - especially for sensor polling and management