I am using Ignition v8.1 Perspective module and a table component to display servo locations and servo descriptions in a view that will act as a manual servo control faceplate (will use one of these views for every servo).
The servo locations are in one tag and the location descriptions are in another tag.
I bound both of those tags to custom properties on the table which then had a script transform to return a list.
Finally, I had a script on the props.data that would combine the two lists to display them in the table:
x = []
for i in range(len(self.custom.Locations)):
x.append({'Location': self.custom.LocationsDesc[i], 'Value': self.custom.Locations[i]})
return x
This works most of the time...but occasionally when i navigate to the view that this lives on, it seems like there is a race condition in which the data script that combines the two custom properties runs before the two custom properties actually have values. Therefore I will get an error that looks like:
Could anyone shed some light on the correct way to accomplish this? I would like this table to display the locations and descriptions and update if either of those change values.
Ah yes, meant to add that and forgot. For the locations:
# sort the items in the order they come from PLC array
sorted_items = sorted(value.items(), key=lambda kv: int(kv[0]))
x = []
for k, v in sorted_items:
try:
v = round(float(v),4)
except:
v = None
x.append(v)
self.refreshBinding("props.data")
return x
and for the descriptions:
# sort the items in the order they come from PLC array
sorted_items = sorted(value.items(), key=lambda kv: int(kv[0]))
x = []
for k, v in sorted_items:
x.append(v)
self.refreshBinding("props.data")
return x
I had the refreshBinding in there to force the table update each time the custom properties changed. If you would suggest a completely different "architecture" to use for this I'd be open to hear it.
I would agree with this assumption. What triggers the binding on props.data?
You could use an expression structure on props.data that point to your custom properties then update your transform script to handle things more gracefully. You could safely remove the refreshBindings since any change in these 2 tag bindings would trigger the props.data.
I am assuming that because these are using value that they are transforms. What type of binding is it, and what is it bound to? Perhaps a tag binding, based on the comment. If that is the case, what is the type of the tag?
It seems like this could be consolidated into an expression structure and two Indirect tag bindings to point at the appropriate servo. But you haven't provided enough information for me to say for sure.
I would be interested to know how exactly the original map was/is constructed.
What potential value are you trying to avoid with the try?
The try is to avoid errors when there is no location or location description for a certain index. So the PLC stores 24 possible locations and location descriptions, but not all them will always be populated. So to avoid issues with the round(float()) code i added the try/except.
Would be interested in hearing your expression suggestion if what I have set up seems like it could be configured that way.
Can you screenshot the binding editor on your table data? Are you using an expression structure binding with your two custom props as key values?
Looking a the script producing the table data, I suspect not. (you should be using one. They have a default option set to wait for initial values to come in, but they also let the binding update whenever any of the key values change)
The reason however that you're seeing that error is because the two keys have bindings on them, and this defaults to setting them to be non-persistent. This means that the keys and their values themselves are not stored with the view's config, so when it loads in the client, the keys literally don't exist until the bindings run and create them
I believe this is working now! I have not used the expression structure before so I was missing the point for a while there but had a colleague @jrsandell94 give some pointers.