how to use : valuesDict['refreshCallbackMethod']

Posted on
Sun Jan 14, 2018 11:45 pm
kw123 offline
User avatar
Posts: 8363
Joined: May 12, 2013
Location: Dallas, TX

how to use : valuesDict['refreshCallbackMethod']

As I have now decided to not be indigo 6 compatible in future plugin versions I am trying to add the new features in the API.
eg " valuesDict['refreshCallbackMethod'] " this can really help making menus flow better. .
"""Added support for valuesDict['refreshCallbackMethod'] attribute which allows plugins to specify a UI refreshing callback method that is called approximately every second for updates. The callback method has the same signature as UI button actions and can return both a modified valuesDict and errorsDict for dynamic UI updating."""
From the description above it is not clear how it should be setup.
does the plugin have to return the refreshCallbackMethod at some point in time when in a menu? or how does the plugin tell indigo which one it is?

After defined, I believe I know when to do with it.

Thanks

Karl

Posted on
Mon Jan 15, 2018 11:35 am
matt (support) offline
Site Admin
User avatar
Posts: 21417
Joined: Jan 27, 2003
Location: Texas

Re: how to use : valuesDict['refreshCallbackMethod']

You can define it either in the config UI XML or dynamically from a UI callback (valuesDict['refreshCallbackMethod'] = 'nameOfYourRefreshMethod'). You just set the value to a string name of the method (not an actual method/func instance):
Code: Select all
   def getDeviceConfigUiValues(self, pluginProps, typeId, devId):
      valuesDict = pluginProps
      errorMsgDict = indigo.Dict()
      valuesDict['refreshCallbackMethod'] = 'nameOfYourRfreshMethod'
      return (valuesDict, errorMsgDict)

Once defined the method will be called about every second. The method needs to return quickly – it should do very minimal processing. So if it needs to do more complex calculations or make a hardware/network call, then that should be offloaded to another thread and the refresh callback method should just check for a result state set by the other thread.

The signature for the callback looks like this:
Code: Select all
   def nameOfYourRfreshMethod(self, valuesDict, typeId="", devId=None):
      errorsDict = indigo.Dict()

      # example of how the refreshing method can halt being called every second
      timeToStopRefreshing = False
      if timeToStopRefreshing:
         valuesDict['refreshCallbackMethod'] = None

      return (valuesDict, errorsDict)

Image

Posted on
Mon Jan 15, 2018 11:45 am
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: how to use : valuesDict['refreshCallbackMethod']

I really need to implement this in a couple of my plugins, it's a pretty cool method for doing processing without hanging up the UI.

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Mon Jan 15, 2018 11:49 am
matt (support) offline
Site Admin
User avatar
Posts: 21417
Joined: Jan 27, 2003
Location: Texas

Re: how to use : valuesDict['refreshCallbackMethod']

I use it in the internal Z-Wave plugin when doing inclusion/syncing to provide some basic status updates to the user by hiding/showing different caption texts and other controls. The resulting code isn't the most elegant but it does work pretty well.

Image

Posted on
Mon Jan 15, 2018 11:52 am
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: how to use : valuesDict['refreshCallbackMethod']

A couple of my plugins have a large amount of data to load when the ConfigUI pops up and you get the beachball for 1-3 seconds while it's parsing all of that, this would be a much better way to show the UI instantly and do the processing after they see the window so that they don't think it crashed. I can think of at least a half dozen ways to utilize this if I get off my butt and redesign my UI :roll:

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Mon Feb 12, 2018 11:18 am
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: how to use : valuesDict['refreshCallbackMethod']

Matt, I have an immediate application for this but wanted to ask you something. In my need I have a List object that takes a while to compile and fill out, I could easily pass this on to a thread to do the work while refreshCallBackMethod is active. The problem is that it's a list, so if the refreshCallBackMethod acts like callbackMethod then I assume it would again try to get that list - in which case the only thing I can think of doing would be to use a global variable to store that the list is working, have the list thread update the variable to let us know its done and then when the list is called it will look to that so that refreshCallBackMethod won't constantly cause the list to calc again (of course then clearing the refreshCallBackMethod when done). Whew, that's a mouth full. Does that sound about right?

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Mon Feb 12, 2018 12:48 pm
kw123 offline
User avatar
Posts: 8363
Joined: May 12, 2013
Location: Dallas, TX

Re: how to use : valuesDict['refreshCallbackMethod']

have the same issue: if your list is pretty static you can refresh it init the mac loop (eg self.staticList) every 5 minutes and or at startup and then return self.staticList from in the filter method.
Make sure refresh is not dynamic.

Karl

Posted on
Mon Feb 12, 2018 12:52 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: how to use : valuesDict['refreshCallbackMethod']

kw123 wrote:
if your list is pretty static

It's not. I thought of that method as well but it needs to be calculated on the fly.

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Mon Feb 12, 2018 2:18 pm
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Re: how to use : valuesDict['refreshCallbackMethod']

Any dynamic list that requires more than a second or so to create in the Python code itself probably needs to be reevaluated. For instance, if you're going out and talking to another process, or doing network communication, then it's likely you need to do some form of caching.

For instance, in my plugins that discover devices on the network, I begin a thread at init time that continually discovers devices and updates a list in the plugin when a new one shows up or a previously discovered one goes away - so the callback is just taking the cached list and formatting it for use in the UI and the background thread is doing the heavy lifting.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Mon Feb 12, 2018 3:08 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: how to use : valuesDict['refreshCallbackMethod']

jay (support) wrote:
Any dynamic list that requires more than a second or so to create in the Python code itself probably needs to be reevaluated.

Blah! Pooh. Boo, hiss. For what I'm trying to achieve it's not that easy and it was my last resort if this wasn't a viable option. I can do it outside of the modal window if I need to it's just not quite as neat as I would prefer.

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Mon Feb 12, 2018 3:30 pm
kw123 offline
User avatar
Posts: 8363
Joined: May 12, 2013
Location: Dallas, TX

Re: how to use : valuesDict['refreshCallbackMethod']

This has helped me quit a bit if you need to loop through devices:
Code: Select all
for dev in indigo.devices.iter("yourpluginid"+",props.isRPIDevice"):
before set
Code: Select all
dev = indigo.devices[12345]
props=dev.pluginProps
props["isRPIDevice"] = True
dev.replacePluginPropsOnServer(props)

or at time when creating a device add the prop to Devices.xml

I have some 500 devices and each time I need to loop through them reducing the scope has helped significantly.

Karl
Last edited by kw123 on Mon Feb 12, 2018 3:54 pm, edited 1 time in total.

Posted on
Mon Feb 12, 2018 3:52 pm
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Re: how to use : valuesDict['refreshCallbackMethod']

Colorado4Wheeler wrote:
Blah! Pooh. Boo, hiss. For what I'm trying to achieve it's not that easy and it was my last resort if this wasn't a viable option. I can do it outside of the modal window if I need to it's just not quite as neat as I would prefer.


A necessary design principle for a variety of reasons, not the least of which is the multiple steps that a round-trip from the Mac client to the plugin has to go through:

Mac Client->Indigo Server->IndigoPluginHost->Plugin code->IPH->IS->MC

So there's already some lag that's just inherent in the design - add multi-second processing on the plugin side and the fact that server has to bottleneck some things and the client UI is blocking, and you get the beachball spinning when things take too long. Adding in even more back and forth (by delaying the drawing lists for example when they take too long) really would just make matters worse.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Mon Feb 12, 2018 4:07 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: how to use : valuesDict['refreshCallbackMethod']

kw123 wrote:
This has helped me quit a bit if you need to loop through devices:

I use similar logic for similar functions and for the same reasons.

kw123 wrote:
I have some 500 devices and each time I need to loop through them reducing the scope has helped significantly.

What I'm doing is very similar but then also has to do something with all the devices which can take up to 10 seconds. I'm sure I could trim a bit here and there but I think as Jay said, it's best to rethink it entirely because I'm so close now that a user has a 50/50 chance of getting a timeout error and that's not good coding.

jay (support) wrote:
A necessary design principle for a variety of reasons

I completely understand, my boo hiss wasn't at you just at the thought of me having to do it my alternative way. I don't know if you code plugins like I do (you don't because you are better at it, but still) but I tend to code up my idea of any given function and then when it gets stuck I tweak code to get my results - meaning I already had good chunk of time invested in this solution and if I could use the refreshCallbackMethod then that's all I needed to make it work without timing out. But I would rather do it right than do it fast.

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Mon Feb 12, 2018 4:14 pm
kw123 offline
User avatar
Posts: 8363
Joined: May 12, 2013
Location: Dallas, TX

Re: how to use : valuesDict['refreshCallbackMethod']

For some really fast thing I have local tables that get updated regularly 1/Minute or when a device gets saved.
With these tables I only need to access the devices needed for the pull down menus if during processing of incoming messages.


Sent from my iPhone using Tapatalk

Posted on
Mon Feb 12, 2018 4:18 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: how to use : valuesDict['refreshCallbackMethod']

kw123 wrote:
For some really fast thing I have local tables that get updated regularly 1/Minute or when a device gets saved.

No amount of caching works for me unless it's a la minute because to keep it up-to-date would require a pretty heavy calculation pretty regularly and I'm trying to keep the CPU and memory of this plugin well in check because I've let a couple others get out of control and I don't want to be there again.

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 6 guests