Best Practice to Synchronize Hardware Device State to Virtual Device State (Device Handler)

I have a garage door based on a ESP8266 that runs a REST API for operation. I have a hardware button and an app that use these APIs. In addition, I have written a device handler that uses these APIs.

As long as the garage door is controlled from SmartThings, SmartThings knows what the device’s state is aka whether or not it is open or closed. If I use the hardware button or other app then it gets out of sync.

In the device handler I implemented the refresh functionality so I can get it back into sync but that is a manual action the user has to perform. If there are automations based on the door they wouldn’t fire until the user updated the state manually.

I have found that I can schedule events or run events every X minutes with the runEveryXMinutes (or hours) functions. Is this the best way to solve this problem?

I have control over the firmware but I would really rather not make changes to it since I have never been able to get the creator’s project to compile because of old library dependencies.

Please let me know what is best practice to keep state in synchronization when changing the device firmware is not a possible, feasible, etc.

Also, if I use runEvery1Minute to schedule something will it automatically remove the previous schedule when updating the handler code or how does that work? There is no documentation about that here.

Thanks in advance!

In principle the ‘runEveryXmins’ code should be singular, hence if you update something there should only be one of that thing running, and if you force refresh after 30 seconds then it should shift back the next refresh for another minute. I say should as I have found many strange quirks with this code:

  1. Sometimes it doesnt trigger on time and sometimes the refresh just stops at a random time
  2. I have two 10 minute schedules running for my device handler as it seems to have lost the first schedule so created a new one. I have tried everything to remove this extra schedule but failed, hence you cant rely on it to remove all previous schedules…

Is it the best method, definitely not, a manual poll puts strain on ST servers and doesnt result in immediate updating, plus is open to the errors from above. That said it is undoubtedly the easiest solution to your problem!

The best solution is probably based on the ESP sending an update message to ST whenever it is triggered through the other process (hardware button or miscellaneous app). This is quite easy to do in the firmware and would just require a small bit of JSON to be passed to ST whenever it triggers the open/close method. To be honest I expect this may already be possible in the firmware, or at least something similar, but without more details I dont know if it would be supported by ST.


The polling capability (and associated poll() command) can be used for this.

Of the two solutions which is better and why?

I find poll is less reliable and less configurable than runeveryX. If those are the two solutions you are referring to.
Given they effectively do the same, go for the one with custom refresh times, plus poll isn’t implemented in a great way so sometimes just gives agro, hence I said less reliable.

I ended up doing the runEveryX approach. While reading I noticed that they do not want to call unschedule frequently. However, I did it anyway. It’s worse I think to have multiple schedules and any time the user manually performs the scheduled action the schedule should adjust.

Thanks for your input, both of you.

1 Like