I would use my Integration Toolkit's tags()
function with a some custom dataset properties. The first would be a list of base tags you wish to monitor, possibly dynamically updated. The second would be a three-column dataset containing the suffixes you wish to add to the base tag paths, and the corresponding output column name you wish, and the output column type to use. Likely just a constant in your design. The third custom property would be a flat list of each of those merged with property suffixes, as needed. Its expression binding would look something like this:
unionAll(
asMap('completePath', 'str'),
flatten(
forEach(
{Root container.baseTagList},
forEach(
{Root container.suffixes},
asList(
concat(it(1)[0], it()[0])
)
)
)
)
)
Then the final expression would feed that list to the tags()
function, wrapped to yield the N+1 × M output dataset. Something like this:
unionAll(
asPairs( // Used to concatenate lists here
asMap('Tag', 'str'),
forEach(
{Root container.suffixes},
it()[1], // Column name
it()[2] // Column type
)
),
forEach(
groupBy(
forceQuality( // So missing props don't break us.
tags({Root Container.mergedPaths}, 50), // Fifty millis dwell for smooth updates.
192
),
transform(
lastIndexOf(it()[0], "."),
if(
value() >= 0, // If a dot is present, take everything before it.
left(it()[0], value()),
it()[0] // Otherwise, use the whole (base) tag path
)
)
), // Yields grouped rows by base tag path
asPairs( // Used to concatenate lists here
asList(it()[0]), // grouped tag path to match the "Tag" column
transform( // Make a dictionary by property suffixes with tag values
asMap(
forEach(
it()[1], // Dataset of base tag group, paths+values
transform(
lastIndexOf(it()[0], "."),
if(
value() >= 0, // If a dot is present, take it and after.
substring(it()[0], value()),
"" // Otherwise, use an empty string
)
),
it()[1] // Value read.
)
),
forEach( // Look up each suffix to assemble the row
{Root container.suffixes},
value()[it()[1]]
)
)
)
)
)
My tags()
function will be much more efficient than any kind of script, as it will subscribe to the actual tags intelligently.
The above looks rough at first glance, but well worth the effort.
https://www.automation-pros.com/toolkit/doc/
Note, include a suffix with an empty string to get the live tag value itself.
Also note: untested....