Hi there,
How can I create a dataset that I can use in a table? I have many tags, that i want to display in a table.
Hi there,
How can I create a dataset that I can use in a table? I have many tags, that i want to display in a table.
I presume you want to display live tag values?
You should create a dataset or list containing your tag paths. On the table, configure the column with the tagpath to have a column view instead of normal rendering.
In the specified column view, include an input parameter named value
--this will receive the tag path. Configure custom properties in that column view with indirect bindings to the tag (for the value), and for any tag properties that you want to use to control formatting. (Probably at least the .formatString
and .engUnit
properties.)
Place one or more labels in the column view to actually display the live value, formatted as desired.
You probably want the table itself to be set to virtual mode, so that non-visible rows don't run their live values.
Thanks! Yes i want live values. Where do I create this list or dataset?
To get started, just make it by hand. One complete tagpath string per row.
Yes. Just make the key tagpath
, and the value the string. Just a couple rows to test with. In the columns
property, configure one column using that tagpath, and configure render
to view:
Then make a row-like view as described that accepts the tagpath as its value
parameter.
Thank you! So i get this to work when its created manually.
How can I make this a dynamic dataset? I want to have the amount of rows to be dependent on how many elements there is in a array i.e. Is this possible?
EDIT:
Actually ive managed to create a dataset for a dropdown menu (same situation as above). How can I push data into the rows?
Dynamic UI datasets are typically generated either with a SQL query (binding) of some kind, usually with a transform, or a with a jython script.
You'll have to share your intentions as to how a user is expected to select what tags are of interest.
Allright, so the intension is that i recieve 5 string arrays from MQTT. Each array should have its own column. The number of rows is dependent on how many values there is inside the arrays. Hope this makes sence.
I also want the table height to be adjusted according to the number of rows.
Nope.
Please explain, with examples, the entire data flow, and what the user of your system will do.
Allright, so, the user can manage brewing recipes in a separate system. This system has an API, and this data is sorted in node-red, then published to MQTT, which ignition subscribes to.
An example recipe looks like this. Where the columns are: amount, name, percent, type and color.
The number of different ingredients will vary depending on the recipe. In ignition I want to list all the ingredients the same way in a table.
So, i get a array of string for each of those colomns. So, if there are 4 different ingredients as in the example above, i get those arrays:
["2","2","0.57","0.1"]
["Pale Ale Best Malz", "Pilsen BestMalz", "Caramel Pils BestMalz", "Pale Crystal Malt Thomas Fawcett"]
etc....
Therefore the number of rows, should be dependent on the number of variables in the array.
So, not really a table display question at all.
You have tags with arrays of values that are desired columns. You want to make a dataset with these columns. The python map()
function is probably the right tool. Your python library function will look something like this:
columnTags = ['amount', 'name', 'type', 'color']
# tagFolder should be something like "[mqttProvider]path/to/recipe/folder"
def getDatasetFromArrayTags(tagFolder):
paths = [tagFolder+'/'+c for c in columnTags]
qvList = system.tag.readBlocking(paths)
if all(qv.quality.good for qv in qvList):
columnArrays = [qv.value for qv in qvList]
return system.tag.toDataSet(columnTags, map(None, *columnArrays))
# Any bad quality yields no dataset
return None
The map()
function with a None
conversion function is effectively the same as python's zip()
function, except that it will extend columns with None
to make the columns all the same length, while zip()
uses the shortest column.
Thank you very much for helping me out here. Im not sure where I should write this code?
Hi there,
Should this be made as a seperate script? Or should this be written on the table component? Im a little confused here, sorry
Place the code I wrote in a project library script.
On the table where you want to display this, use an expression binding like so:
runScript('path.to.script.getDatasetFromArrayTags', 0, {path.to.folder.path.prop})
As shown, the code will run once at view startup, and again any time the folder path property changes. If you want it to run repeatedly, change the zero to some number of milliseconds between executions.
Thank you, and sorry for alot of stupid questions here.. But i'm very lost at this...
I'm now using OPCUA, and the tag folder should be default/Brewfather_OPCUA. But I can't see how I can sort out the columns I want to show in table.
And, what folder should this be?
Couple points:
The sample code is to be entered into a script module verbatim. Do not try to place a value in the def
for tagFolder
. tagFolder
is an argument (a type of variable) that comes from the function's caller.
The caller is the runScript function, and the argument is supplied by some string property in your UI that contains the folder path. Spend some time with the docs to understand how runScript
works.
When you create that string property, you can supply a static value for the moment as [default]Brewfather_OPCUA
. (In code, strings like this need to be quoted, btw.)
Your column names are different from mine. You will have to change columnTags
to match your real tag names: arMaltAmount
, ...
Side note: Have you gone through Inductive University? It is vital for newcomers.
Well okay, so I can't use the script as is, I need to install a module for this script? I seached inductiveautomation.com and cannot find this module?
No 3rd-party module required. In the designer, go to the "Scripting" node in the tree. Create a named script module. Place the sample code there.