Scheduled polling in a device handler

there is a DH i am using that does not execute its polling on a scheduled basis but only when refreshed from the app. i am trying to update the DH with scheduled polling every 5 minutes. i have identified that adding this statement should cause the poll method to be scheduled to run every 5 minutes:

runEvery5Minutes(poll)

however, what is not clear to me is where i would include this statement. there is no configured(…) or updated(…) or installed(…) or uninstalled(…) or such methods in the DH. so, not sure where i would include the above statement?

also, if the DH is removed how do i unschedule this poll(…) method?

thank you.

EDIT: other than metadata and preferences blocks the only def methods in it are parse(…) and poll(…)

I would put it right after preferences, as the below example. You can then activate it on initial installation of the device or by selecting the preferences pages and pressing ‘DONE’. Unless absolutely necessary, I would not recommend more frequently than 15 minutes.

> def installed() {
> 	updated()
> }
> 
> def updated() {
> 	unschedule()
> 	runEvery15Minutes(refresh)
> 	runIn(2, refresh)
> }
2 Likes

thank you, much appreciated. one other related question, do i also need an uninstalled(…), something like this?

def uninstalled() {
unschedule()
}

no, not really. Uninstall is optional.

what does the runIn(2, refresh) do? when trying it, it seemed like it was refreshing the device Right Now page every 2 seconds.

also to be clear, i swapped out refresh in these statements with poll which is the polling method in this DH. should i have literally left it as “refresh”?

runEvery15Minutes(refresh)
runIn(2, refresh)

thank you.

You do not have to do that. I do for my device handlers for initial installation to get the current state immediately.

ok, thank you again!

Unless something has changed recently, you can’t send commands to a device by returning them from a method executed by a schedule, even if you wrap them with response.

You can still make a device self poll, but you have to use sendHubAction.

If you need an example, look at any of my siren DTHs.

BTW, don’t put “updated()” inside of the “installed() method”. The “updated()” method automatically gets executed twice when the device is installed.

The updated() runs as specified. (The refresh is defined as a command in the Device Handler.0 When invoked through updated(), it:
a. Runs almost immediately (runIn(2, refresh)
b. Runs every 15 minutes (runEvery15Minutes(refresh) (It will use any of the run-in intervals). I can also use the chron scheduling to schedule events and they work.

refresh() sends hub commands to get the state / response data needed. Both times it executes a state update and (in some device handlers) updates some non-state values requested and received from the device.

I am also aware that a refresh() command will usually automatically run every 15 minutes (without scheduling); however, (1) sometimes it does not (for some reason), and (2) sometimes you may want 5 minute refresh for some reason -which I recommend against.

Agree with the execute twice on installation. Thankfully, installation is a one-time event. But I will fix in my Device Handlers. Thanks for the response.

@krlaframboise thank you for pointing to that example. have no experience with DH so bear with me if these are simple things one should know.

heres what i included in the DH. what i am finding is if i uncomment the line below the poll() method keeps getting called every 2 seconds instead of being run once 2 seconds after updated() is called on saving preferences. what am I missing here?

def updated() {
   log.debug "updated()"
   unschedule(poll)
//   runIn(2, poll)
   runEvery5Minutes(poll)
}

also, am finding that updated() is being called on a recurring schedule even though i only went to preferences and clicked the Done button at 9:06:37 AM. not sure why that would be?

  9:14:31 AM: debug 1502869971638
  9:14:31 AM: debug poll()
  9:14:31 AM: debug updated()
  9:11:43 AM: debug 1502869971638
  9:11:43 AM: debug poll()
  9:11:43 AM: debug updated()
  9:08:43 AM: debug updated()
  9:07:11 AM: debug 1502869971638
  9:07:11 AM: debug poll()
  9:07:12 AM: debug updated()
  9:06:54 AM: debug 1502869971638
  9:06:54 AM: debug poll()
  9:06:54 AM: debug updated()
  9:06:37 AM: debug updated()
  9:06:37 AM: debug updated()
  9:06:34 AM: debug 1502869971638
  9:06:34 AM: debug poll()
  9:06:35 AM: debug updated()

thank you.

Zigbee might not have this problem, but last time I tested a zwave device you had to explicitly use sendHubAction because returning the commands from a scheduled method didn’t work the way it’s supposed.

If you manually tap the Refresh tile, execute it directory from the updated method, or execute the command from a SmartApp the device will receive the commands returned from the method, but not when executed by a schedule within the DTH.

The refresh() command does NOT get executed automatically by SmartThings. I’ve written over 30 DTHs and if refresh() was called automatically I’d be having tons of problems.

If you implement the Poll capability, it’s supposed to execute the poll() command every 10-15 minutes, but SmartThings actually executes it anywhere from a couple times an hour to once every couple of days.

The polling interval might be more reliable with zigbee devices, but zigbee devices usually there’s no reason to poll a zigbee device because of their reporting feature.

1 Like

You need to post the poll method for me to see what’s happening, but it looks like you’re executing the updated method from within the poll method.

its this one. all i have done is add the def updated() method as above, to the tail.

The code you posted doesn’t have an updated method or any log lines that say “updated”…

Most contact sensors sleep and can’t be polled, but it looks like that’s not a zigbee or zwave device so it might not.

right, originally it did not. I added these lines to the bottom of the DH. its actually for doing a HTTP GET to see if a server is awake or sleeping since ICMP ping is not supported from the hub.

def updated() {
   log.debug "updated()"
   unschedule(poll)
//   runIn(2, poll)
   runEvery5Minutes(poll)
}

thank you.

I’m not familiar with that type of DTH, but I don’t see anything that would cause it to execute the poll method more often than every 5 minutes.

Does that HTTP GET actually work?

ok, thank you. i actually did some more testing and finding that even without the updated(), ST calls the poll method every 2 to 3 minutes.

the best i have been able to determine is, the HTTP GET / throws a 400 when the server is available but the http connection status reports the status as being close. when the server is unavailable it just seems to return a NULL response. i am using this with a NAS and webcore to wake up the NAS when its media time. dont believe this GET method would work as a replacement for ping.

I could be wrong, but I think your get request needs additional information, like the host…

yes, i think that may have been a hub v1 of doing things. i am heavily modify the DH and currently this is what i use:

def hubAction = new physicalgraph.device.HubAction(
	method: "GET",
	path: "/", 
    Headers: [HOST: "$hosthex:$porthex"]
)     

i still havent figured out how to control the polling interval. seems like ST calls the poll method every so often. any way to control the polling interval?

thank you.

Name the method something other then “poll”.