Problem to update states list

Forum rules

This is a legacy forum which is locked for new topics. New topics should be started in one of the other forums under Extending Indigo

Posted on
Tue Feb 14, 2012 4:40 am
Juju offline
User avatar
Posts: 108
Joined: Aug 31, 2011
Location: Toulouse - FRANCE

Problem to update states list

Hello,

I would like to define custom states for a device depending the data it send through a serial port. For that, I decided to define a new property into pluginProps, which is a list containing all states keys. The method getDeviceStateList() just read this property and build an indigo.List() with all states.
First question : my approach is correct ?

The following code is the method analyzing data read from the serial port :
Code: Select all
def   updateDeviceStates(self, dev, tramesTeleinfo):
      for element in tramesTeleinfo.items():
         keyState = element[0]
         valueState = element[1]
         self.debugLog(u"Clé: " + keyState + ", valeur: " + valueState)
         if not keyState in dev.states:
            updatedPluginProps = dev.pluginProps
            if not 'statesKeys' in updatedPluginProps:
               updatedPluginProps[u'statesKeys'] = []
            updatedPluginProps[u'statesKeys'].append(keyState)
            indigo.server.log(u'StatesKeys after update :\n%s' % updatedPluginProps[u'statesKeys'])
            dev.replacePluginPropsOnServer(updatedPluginProps)

            dev.stateListOrDisplayStateIdChanged()

         dev.updateStateOnServer(key=keyState, value=valueState)

It seems "updatedPluginProps[u'statesKeys'].append(keyState)" doesn't do anything ... The next line log the updatedPluginProps[u'statesKeys'] status, but the list is always empty ... What's my problem ?

Posted on
Tue Feb 14, 2012 2:05 pm
matt (support) offline
Site Admin
User avatar
Posts: 21417
Joined: Jan 27, 2003
Location: Texas

Re: Problem to update states list

Your approach sounds okay.

dev.pluginProps returns a special Indigo dictionary which has some subtle differences compared to a normal python dictionary. One of which being that key accessed items are not returned by reference, but by value. So this line:

updatedPluginProps[u'statesKeys'].append(keyState)

is actually appending the keyState to a temporary object returned by the evaluation of updatedPluginProps[u'statesKeys']. That is, it isn't really modifying the dictionary but a transient copy of the dictionary.

We might improve this some day, but in the mean time the solution is to append your keyState to a local variable array, then assign that to the updatedPluginProps. Something like:

Code: Select all
            updatedPluginProps = dev.pluginProps
            if not 'statesKeys' in updatedPluginProps:
               keyList = []
            else:
               keyList = updatedPluginProps[u'statesKeys']
            keyList.append(keyState)
            updatedPluginProps[u'statesKeys'] = keyList
            indigo.server.log(u'StatesKeys after update :\n%s' % updatedPluginProps[u'statesKeys'])
            dev.replacePluginPropsOnServer(updatedPluginProps)

Image

Posted on
Wed Feb 15, 2012 7:33 am
Juju offline
User avatar
Posts: 108
Joined: Aug 31, 2011
Location: Toulouse - FRANCE

Re: Problem to update states list

OK, thanks Matt, that's the solution.

Complementary question : I would like to populate pluginProps[u'statesKeys'] directly from the device configuration UI using a button. Methods associated to buttons are formated as following : myMethod(self, valuesDict, typeId, devId). I haven't problem with existing device
Code: Select all
dev = indigo.devices[devId]
devProperties = dev.pluginProps[u'statesKeys']

but for a new device, devId is equal to 0. So how can I have access to pluginProps ?

Posted on
Wed Feb 15, 2012 10:47 am
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Problem to update states list

pluginProps don't exist for new devices because the device hasn't been saved yet. Rather, you should catch the deviceCreated(self,dev) method (described in the plugin.py section of the docs). You will get the completed dev instance in that method and you can add new states, etc., based on the plugin's config. There is also a deviceUpdated(self, dev) method that you can implement as well which will handle edits.

I have to ask - why would you want to save a states list in a property when the states are already part of the object - that seems unnecessarily redundant.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Thu Feb 16, 2012 5:17 am
Juju offline
User avatar
Posts: 108
Joined: Aug 31, 2011
Location: Toulouse - FRANCE

Re: Problem to update states list

As explained, I catch the custom states by reading data through a serial port. This process is started by clicking a button in the device config UI. So the necessary data is available when the device config UI is open, but not after. Perhaps I could store the data inside the plugin instance as a property, and treat it in the deviceCreated() method when the device is created and its ID defined.

I will try to answer to your question Jay. The device states are updated when the method getDeviceStateList() is called. When this method is executed, I haven't the necessary data to build the custom states, as I have to (and I can't) read it through the serial port (it is already opened by the communication thread with the device).
So I make this with 2 steps :
1) the communication thread analyse and treat continuously data sent by the device, and specialy maintain an up to date states list in the device properties (and warn when the states need to be refreshed by calling stateListOrDisplayStateIdChanged() )
2) when the getDeviceStateList() is called, I have just to read the appropriate device property, and return a well formated states list.

Posted on
Thu Feb 16, 2012 11:04 am
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Problem to update states list

I think the easiest thing to do would be to add a hidden field to the device config ui - then have your button method add the necessary data to that field. If it's complex data, then just encode/decode it in XML or JSON - we include simplejson and XML is built in to Python. JSON is particularly easy to use (IMO) for these types of ad-hoc object-to-string-to-object conversions. Anyway, use the hidden field to store your states list for later processing.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Thu Feb 16, 2012 11:21 am
berkinet offline
User avatar
Posts: 3290
Joined: Nov 18, 2008
Location: Berkeley, CA, USA & Mougins, France

Re: Problem to update states list

Juju wrote:
... I haven't the necessary data to build the custom states, as I have to (and I can't) read it through the serial port (it is already opened by the communication thread with the device). ...
I think there may be another approach you might try. When you first open your serial communications channel, provide a method in that thread that you can call to get the information you need. I have posted a brief description on how I did this in another discussion.

Posted on
Fri Feb 17, 2012 2:57 pm
Juju offline
User avatar
Posts: 108
Joined: Aug 31, 2011
Location: Toulouse - FRANCE

Re: Problem to update states list

Jay, I think your idea is the best one. I will try this.

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 3 guests