Flex Repeater - Make Dynamic

I have been trying to create a new list of dictionaries by adding the state property into a script transform (of the query) but it doesn't work. I'm sure I'm doing something wrong since I'm not very familiar with scripting. I followed some of the above suggestions with no luck as well.

Show your script transform. We can’t help you correct code we can’t see.

Please use the preformatted text option to loser code. It’s the button that looks like this </>

I can see two ways of doing this:

  1. read all the tags you need in the script transform, and use the values to build the list of dictionnaries
  2. pass the data you need to build the tags paths to the view, as a parameter, and read the tags from there (with a tag binding)

My preferred way would be the second, BUT if you need to sort the instance based on the value of one of those tags, then the first solution will probably be simpler.

So, assuming the tags paths look something like [provider]path/to/{device_name}/current_state and [provider]path/to/{device_name}/current_flow_rate, the script transform on the instances binding would look something like this:

from itertools import chain

devices_names = [item['name'] for item in value]
devices_paths = ["[provider]path/to/{}".format(n) for n in devices_names]
tags_paths = [["{}/current_state".format(p), "{}/current_flow_rate".format(p)] for p in devices_paths]
tags_paths = list(chain(*tags_paths))
tags_values = [qval.value for qval in system.tag.readBlocking(tags_paths)]

states = tags_values[::2]
flow_rates = tags_values[1::2]

params = [
	{
		'name': name,
		'current_state': state,
		'current_flow_rate': flow
	} for name, state, flow in zip(devices_names, states, flow_rates)
]

return sorted(params, key=your_sorting_key)

I separated every step so that it's easy to understand, but this can be 'compacted' a bit.
Let's go over what's going on:

  • devices_names = [items['name'] for item in value]
    Extract the names of your devices from the query results. This may not be correct, as it depends on your query and it's return format.
  • devices_paths = ["[provider]path/to/{}".format(n) for n in devices_names]
    Build a base path to the device's folder/UDT
  • tags_paths = [["{}/current_state".format(p), "{}/current_flow_rate".format(p)] for p in devices_paths]
    Build the tags paths, as a list of lists: [[device1/state, device1/flow], [device2/state, device2/flow], etc...]
  • tags_paths = list(chain(*tags_paths))
    Flatten the list of lists built above into a one-dimension list
  • tags_values = [qval.value for qval in system.tag.readBlocking(tags_paths)]
    Read the tags, and pull their values (readBlocking() returns qualified values)
  • states = tags_values[::2]
    flow_rates = tags_values[1::2]
    Extract the state and flow rate by picking every odd or even items in the list of values
  • params = [
    ....
    ]
    Makes the list of dictionaries containing the parameters. Change the keys to match your parameters names.
  • return sorted(params, key=your_sorting_key)
    Finally, return the sorted list. You'll need to figure out the key, or tell us more about how you want to sort things if you need help with this part.

Thank you for going into this in such detail. It is much appreciated. I will work through this today/tonight and update the status. My next step will take some Python courses.

Hi pascal.

Again, thank you for the details. That is extremely useful for a non Python person. I was able to get the script to work, populate the data and sort based on the value. I found that I was also missing the params on the view which housed the repeaters. I created them within the repeater component, not the view.

The last step would be getting the instances to update as values change. Would that entail another transform on top of the original transform?

This is a more complex issue. I'll think about it a bit.