Merge readBlocking into getConfiguration for "default" or expression-derived properties?

Anyone know if there's an IE resource (or otherwise) for merging results of readBlocking list into a getConfiguration dict? I have a fairly ugly method, but interested to see other methods (or even rationales NOT to do this).

my method is roughly:
getConfig (recursive) > list of tags with appended .properties I want to resolve > readBlocking > 2D list > dict with full tag path as key > update getConfig items.

Fairly nervous to post my actual code and show the world how ugly and brute-force it is. Hoping some with better coding practices than I might share their solutions.

Are these non-default properties that are returned by getConfig() or are they a list of properties that you're interested in but the tags (for whatever reason) don't have them set?

They’re either default properties that getConfig doesn’t return, or properties that perhaps have an expression relying on UDT parameters

For example opcItemPath is always dynamic for my current project, based on parameters. getConfig returns the parameter expression

{opcServer}/{device}/{path}

, but readBlocking on tag.opcItemPath returns the actual resolved/evaluated path.

Srvopc/tank/level

I suppose I could override missing/default getConfiguration properties with their default static DataTypes via

from com.inductiveautomation.ignition.common.sqltags.model.types import DataType
for tag in system.tag.getConfiguration(‘[provider]Folder/UDTInstance’)[0][‘tags’]
    dataType = tag.get('dataType', DataType.Int1)

But that requires me to make a list of every default property since .GetOrDefault doesn’t appear to be a thing in 8.x anymore, unless I’m mistaken.

Sure I could create a function for that but readBlocking seems easier and more derivative/foolproof

That sounds like my kind of fun, but I'm not sure what you're trying to do. Or rather, why you're trying to do it. What's the goal here ?

1 Like

I guess, I'm not entirely certain what the output that you're looking for is. Can you provide an example of the output that you're looking for after this function has ran?

1 Like

getConfiguration only returns non-default properties, and returns the 'raw' parameter expression string for any tag properties that are defined by expressions (see the opcItemPath example above)

I effectively want a function like getConfig but that does include default values and resolves/evaluates any parameter-expression-defined tag properties.

So:

  1. insert any missing default properties into the getConfiguration result dictionary
  2. update any parameter-expression-defined properties in the getConfiguration result dictionary

This kind of thing was easily handled in 7.9.16 with combination of system.tag.browseConfiguration() + tag.getOrDefault('engUnit')

I've begrudgingly pasted my hacky solution below - please go easy on me. :slight_smile:
In this case I'm updating/overwriting the getConfiguration .engUnit and .opcItemPath dict .values with those same values returned by readBlocking.

I also think my tagPath_eval is slowing the script down significantly, but haven't confirmed. A different version not using eval() seems to work way faster.

p3 = shared.profiler.Profiler("siteConfigs"); p3.start()
siteConfigs = [system.tag.getConfiguration(sitePath, True) for sitePath in sitePaths if system.tag.exists(sitePath)]
if debug: logger.info('siteConfigs = ' + str(len(siteConfigs)))
propsForResolution_dict = {'engUnit':'.engUnit', 'opcItemPath':'.opcItemPath'}
tagPath_eval =("\"%s/%s/%s\" % (siteConfig[0]['path'], UDT_instance['path'], tag['path'])")
tagPaths_dict = {tag:propsForResolution_dict for tag in [eval(tagPath_eval)  for siteConfig in siteConfigs  for UDT_instance in siteConfig[0]['tags']  for tag in UDT_instance['tags']]}
propPathsResolved_dict = {tagPaths_dict.keys()[i]: {propsForResolution_dict.keys()[o]: v for o, v in enumerate(row)} for i, row in enumerate(zip(*[iter([x.value for x in system.tag.readBlocking([tag + prop for tag, props in tagPaths_dict.items() for prop in props.values()])])]*len(propsForResolution_dict)))}
for siteConfig in siteConfigs:
	for UDT_instance in siteConfig[0]['tags']:
		for tag in UDT_instance['tags']:
			tag['engUnit'] = propPathsResolved_dict[eval(tagPath_eval)]['engUnit']
			tag['opcItemPath'] = propPathsResolved_dict[eval(tagPath_eval)]['opcItemPath']
logger.info(str(p3))

tag structure is [provider]SiteFolder/UDTInstance/tags
.engUnit and .opcItemPath properties on each tag are defined by expressions referencing tag parameters (or a combination of parameters) rather than hardcoded

bit more context - the goal is to create a giant table with relevant parameters per column. It's scripted instead of bound because the table view is heavily customized

What does the eval() function look like?

eval() is a python built-in.

1 Like

just evaluates this string so I don't have to use it in 3 places - newbie attempt at consolidating code a bit.

Anyone know if there is already a method to return the "default" of any given tag property without readBlocking or making a custom function myself? I've been in the javadocs extensively, but haven't explicitly looked for this.

Yes. Start here:

https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/com/inductiveautomation/ignition/common/tags/config/properties/WellKnownTagProps.html

Note the .getDefaultValue() method.

1 Like

Thank you very much! That does indeed look familiar - I must've forgotten about it when I realized I needed to evaluate expression-derived tag properties in addition to getting default values.