[SOLVED]: How to refresh device after change to device.xml

Posted on
Tue Dec 29, 2015 11:54 pm
zurich offline
Posts: 103
Joined: Aug 11, 2014

[SOLVED]: How to refresh device after change to device.xml

Greetings,

If I make change to a plugin's device.xml file the only way I have found to get the device to see the change is to delete the device and then add it as new. Is there a simpler way to do this?


kind regards,

Z

Posted on
Wed Dec 30, 2015 5:23 am
autolog offline
Posts: 3991
Joined: Sep 10, 2013
Location: West Sussex, UK [GMT aka UTC]

Re: How to refresh device after change to device.xml

Hi Z,
Take a look at the documentation for: Device Base Class Instance Methods

If you use the following code when you invoke deviceStartComm(self, dev) then it should refresh the definition:
Code: Select all
dev.stateListOrDisplayStateIdChanged()
Hope this helps. :)

Posted on
Wed Dec 30, 2015 12:53 pm
zurich offline
Posts: 103
Joined: Aug 11, 2014

Re: [ANSWERED]: How to refresh device after change to device

Greetings,

Thanks to you for reply but I tried adding this method to deviceStartComm(self,dev) but it does not make the change I am looking for. The change I made to the devices.xml file was to add "SupportsStatusRequest" like this :

Code: Select all
         <Field id = "SupportsStatusRequest" type = "checkbox" hidden = "true" defaultValue = "true">
            <Label>Enable status request / refresh button:</Label>
         </Field>

If I delete the device then add it again the "Send Status Request" button functions but if I use dev.stateListOrDisplayStateIdChanged() the button stays grayed out.

kind regards,

Z

Posted on
Thu Dec 31, 2015 5:58 pm
matt (support) offline
Site Admin
User avatar
Posts: 21429
Joined: Jan 27, 2003
Location: Texas

Re: [ANSWERED]: How to refresh device after change to device

The dev.stateListOrDisplayStateIdChanged() method only updates the states list, not the properties of the device. It is used because states are static and cannot be modified outside the XML (thus if you do modify the XML Indigo needs to be told they changed).

For any property changes you can do it at runtime whenever you want like this:

Code: Select all
props = dev.pluginProps
props["SupportsStatusRequest"] = True
dev.replacePluginPropsOnServer(props)

Image

Posted on
Sun Jan 03, 2016 1:13 am
zurich offline
Posts: 103
Joined: Aug 11, 2014

Re: [SOLVED]: How to refresh device after change to device.x

Greetings,

I added your suggestion to my deviceStartComm as below

Code: Select all
def deviceStartComm(self, dev):
        props = dev.pluginProps
        props["SupportsStatusRequest"] = True
        dev.replacePluginPropsOnServer(props)


When I add a new device to the plugin it starts deviceStartComm and begins to do a loop adding and removing the device like this from error log;
props updated for device new device 2
<<-- entering deviceStartComm: new device 2 (9258035 - pluginDevice)
added device "systematicRB""
exiting deviceStartComm1 -->>
<<-- entering deviceStopComm: new device 2 (9258035 - pluginDevice)
removed device "systematicRB"
exiting deviceStopComm -->>


I am need to use your code differently?

kind regards,

Z

Posted on
Sun Jan 03, 2016 5:53 am
DaveL17 offline
User avatar
Posts: 6786
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: [SOLVED]: How to refresh device after change to device.x

Hi Z - unless I'm mistaken, the behavior you're seeing is because replacePluginPropsOnServer() automatically calls deviceStartComm() (putting you in an infinite loop.)

If you are changing the props of the device one time (for example after changing the device's XML file) calling dev.stateListOrDisplayStateIdChanged() within deviceStartComm() will be all you need. However, if you will be updating the device more frequently, dev.replacePluginPropsOnServer() should be used and called at the point you need it--but not from deviceStartComm().

And something that Jay most helpfully reminded me recently: "One thing to keep in mind about props: if you call dev.replacePluginPropsOnServer(), that doesn’t automatically update the dev instance with the new props. So if you reference dev.pluginProps again, you’re going to get the old ones, not the new ones until you get a fresh copy of the dev instance (you can call dev.refreshFromServer() to do that)."

Dave

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Sun Jan 03, 2016 10:36 am
autolog offline
Posts: 3991
Joined: Sep 10, 2013
Location: West Sussex, UK [GMT aka UTC]

Re: [SOLVED]: How to refresh device after change to device.x

As Dave says, you are in a loop :D

You need to do something like this if you are going to include the logic in your device start:
Code: Select all
      props = dev.pluginProps
      if not "SupportsStatusRequest" in props:  # Check if property exists and if it doesn't just add it to the props, save it on the server and return as the device will be restarted
         props["SupportsStatusRequest"] = True
         dev.replacePluginPropsOnServer(props)
         return
      elif props["SupportsStatusRequest"] != True:  # Check if property's required initial value and if not update the property, save it on the server and return as the device will be restarted
         props["SupportsStatusRequest"] = True
         dev.replacePluginPropsOnServer(props)
         return
# At this point the property exists and is set to the correct value - you can now continue starting the device
This code will ensure that the property is set-up and initialised with the required value when the device is started. :)

Posted on
Sun Jan 03, 2016 5:27 pm
zurich offline
Posts: 103
Joined: Aug 11, 2014

Re: [SOLVED]: How to refresh device after change to device.x

Greetings,

Thanks to you gentlemen who replied assistance. I didn't realize that when dev.replacePluginPropsOnServer(props)was called it called deviceStartComm. Obviously this caused the loop.

I moved the code to startup(self) like so and now it works fine:
Code: Select all
   def startup(self):
      self.debugLog(u"startup called")      
      for dev in indigo.devices.itervalues("self"):
         props = dev.pluginProps
         props["SupportsStatusRequest"] = True
         dev.replacePluginPropsOnServer(props)
         self.errorLog("props updated for device %s" %dev.name)

The results are exactly what I was looking for like dis:
Systematic Debug startup called
Systematic Debug props updated for device 1
Systematic Debug props updated for device 2
Systematic Debug props updated for device 3
Systematic Debug props updated for device 4
Systematic Debug props updated for device 5
Systematic Debug props updated for device 6
Systematic Debug props updated for device 7
Systematic Debug props updated for device SystematicRB


My reason for this is to get devices in my plugin to see changes I have made in the devices.xml. Using the dev.stateListOrDisplayStateIdChanged() method will not work as Matt so kindly explained below.

The dev.stateListOrDisplayStateIdChanged() method only updates the states list, not the properties of the device. It is used because states are static and cannot be modified outside the XML (thus if you do modify the XML Indigo needs to be told they changed).


The reason I am using this code is during plugin development I make many changes to the devices.xml and having to delete the device and then add it again is time consuming. Now I can make changed, restart the plugin and I see my changes. Once my plugin is finalized I remove this bit of code.

kind regards,

Z

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 3 guests