Updated() not activated anymore in custom Device Handlers?

I used to rely on the “updated()” method to automatically reinitialize my custom Device Handler every time I saved a new version and started testing it using the IDE Simulator.
I did a Device Handler modification today, but when installed thru the Simulator, the “updated()” method does not seem to execute anymore.
Is that a new restriction or a new bug ?

Note that I am using a V1 Hub.

And yes, I suppose I can work around this using a state. variable and an explicit call to “updated()”, but I already have so many workarounds inside my code…

I just tried it without using the simulator and it works.

Well, may be it is a Simulator specific bug, although it seems curious.

The simulator has always been flaky and buggy.

Don’t use the simulator to test with because you’ll end up wasting time troubleshooting bugs that don’t exist and potentially miss bugs that do exist so you’re better off doing all your testing with the actually device…

2 Likes

Sorry, I was not clear enough : I am NOT using a virtual simulated Device, I am doing all my tests by uploading from the IDE (Save / Location / Preferences / device / Physical Devices / Install) new versions of my custom Handler onto a dedicated actual test Device.
Then I trace my Handler execution using “Live Logging”.
And because the execution trace I put into “updated()” does not show up in “Live Logging”, I know “updated()” has not been executed after the Handler’s uploading, as it used to do before.

I can easily add an explicit command to manually force execution of “updated()” whenever I update my Handler, but I would prefer to have the Handler automatically detect it has been updated.
Any idea how to do that ?
It would be easy to do if I could read from within my Handler the “Last Updated” attribute which shows up in IDE / Show Device (like : “2020-01-01 4:47 PM CET”), but I could not find this attribute within the Documentation.

I spent a few more hours experimenting and finally understood… NOTHING.

I have 2 versions of my custom Handler which can run on the same Device (long story…).
When I install Version#1 on my physical Device, the updated() method for Version#1 is NOT activated (abnormal).
When I install Version#2 on the same physical Device, the updated() method for Version#2 ++IS++ activated (as it should).
When I uninstall Version#2, which reverts the Device’s handler to Version#1, the updated() method for Version#1 ++IS++ activated (as it should).

It is 100% reproducible.
What is extremely curious is that this strange behavior never happened before, or more precisely it did not exist 6 months ago AFAIK.

If anybody has any idea how such a strange behavior can occur…
One more oddity to add to SmartThing platform behavior, one which cost me hours of worthless investigations :dizzy_face:

Are you definitely using the right way the updated method?

https://docs.smartthings.com/en/latest/ref-docs/smartapp-ref.html#updated

Called when the preferences of an installed app are updated. Typically unsubscribes and re-subscribes to Events from the configured devices and unschedules/reschedules jobs.

My understanding, that it should execute when you do change the settings of the device in on the settings page.

I am not sure what would be the “wrong way” to use the “updated()” method, except that the URL you provided is for SmartApps while I am using it within a custom Device Handler.

Anyway, it does not explain why the same “updated()” method sometimes work, and sometimes does not. Nor why the same updated() code always worked fine 6 months ago.
Nor why it finally executes when I UNinstall some draft version of the Handler.

A suspect could have been the trace, which is highly unreliable, but all the problems I had with “log.debug” where random missing entries, but I have never seen a case where ALL log.debug entries within a given method would ALL disappear once, then ALL reappear in a second occurrence.

It is in the SmartApp section, but referenced from the Scheduling.

Scheduling

Device Handlers can schedule future executions, just like SmartApps.

https://docs.smartthings.com/en/latest/device-type-developers-guide/other-available-apis.html

You can learn about scheduling in the Scheduling guide.

Updated is meant to be used for redoing any scheduling together with installed and uninstalled methods.

You can just swap a DH for a device, it doesn’t matter how many drafts you have under different names.

It is not uploading anything to your device. You might have some conceptual misunderstandings.

It took me for a while to understand this, but you are indeed using the Simulator of the IDE. Yes, not with a simulated device, but with a physical device l.

You can just change the DH for the Device itself, after publishing and using the Classic App to test it meanwhile looking at live logging.

@GSzabados : thanks for the detailed answer.

Since English is not my native language, my explanations may have not been precise enough, but I still don’t understand from your answer what I should do differently.

  1. you confirm the “updated()” method (or “installed()” method) is legitimate within any custom Device Handler
  2. when I develop a new version of this Handler within the IDE, the only way I have to temporally activate it for testing purpose on one of my physical Devices (and NOT for the others) is to use the “Simulator”
  3. yes, I know every part of my Handler executes within the SmartThings cloud (I have a v1 Hub).
  4. after I “Install” my new version, the Handler code executed for my test Device is the one I just uploaded in the Cloud
  5. the Live Logging then shows all physical events from the physical Device (like open/close) as well as all log.debug traces from the new Handler’s code
  6. when I “Uninstall” this new version from the IDE, the SmartThings cloud reverts to execution of the previously published version of my Handler, as shown by Live Logging traces

I don’t understand how I could use the Classic App to test my Handler, it works for SmartApps (des)activation but NOT for Device Handlers.

So my unreliable execution of the “updated()” method for any new version of my Handler under test remains unexplained. Especially since it worked fine 6 months ago.

The Simulator was never reliable.

You can do the following. Create a copy of your current device handler, name it differently, like add at the end v2. Save and Publish. Go to the device in the IDE what you want to test on, edit it and swap the DH to v2 (Self published). Meanwhile you can have another window open with the Live Logging.
Have your phone ready to test the device in that. As you swap the DH, the phone will control the device through that. It might take to exit and go back to the device if you do difference on the tiles. I guess you still do testing with the Classic App. (The swapping method works well for the new app to test too.)

Updated would trigger if you go to the settings and hit save.

Otherwise is your code not calling the updated method somewhere else? Like part of installed or uninstalled or refresh or something?

After our discussion, I added as an afterthought the installed() method, which does nothing except calling the updated() method.
AFAIK, it does not make any positive or negative difference, especially since it is always the updated() method which gets automatically called (sometimes) when I install a new Handler…

@geeji, here is how updated() should work and should be used.

I’ve not played with writing device handlers for several months, but as I remember things, it was (and presumably still is) very common to see installed() methods calling the updated() method in many handlers. However it also seemed to be redundant as updated() seemed to be called anyway.

If updated() is meant to be called after settings are updated, then it sort of made sense that it would be called on install too, as you might not need to change the settings and so it would never be called. On the other hand maybe they expected developers to have considered that possibility. So it has never been clear to me how it was intended things were supposed to work.

It all sounds rather curious. Which is a lot better than if the reverse was happening and updated() stopped being called in the live environment, as that could break a lot of stuff.

You can try the initialize method too. Look at examples in the public github repo, like the ecobee DH.

© 2019 SmartThings, Inc. All Rights Reserved. Terms of Use | Privacy Policy

SmartThings; SmartApps®; Physical Graph; Hello, Home; and Hello, Smart Home are all trademarks of the SmartThings, Inc.