System.tag.configure incorrectly overriding multiple UDT tag properties

I need a quick way to programmatically override properties on certain tags inside a UDT. For instance, setting a custom description for multiple iterations of the same device. The solution I’ve come up with is to read the tag configuration using system.tag.getConfiguration and then search through the result and modify the ‘value’ property for the tag in question. Then I pass the modified configuration back into system.tag.configure. I’m able to successfully change the value I want, however, it seems that when I write the modified configuration, other properties on the tag are showing as overridden. The values still match the UDT definition but it doesn’t seem like this is right. Appreciate any ideas on how to prevent unintentionally overriding extra tag properties.

Simplified version of my script (I just hardcoded the property modification to keep the post shorter)

folder = "[default]CP1/Test Folder"
updateTagName = 'UDT Tester'
nodes = system.tag.getConfiguration(folder + '/' + updateTagName, True)

nodes[0]["tags"][0]["tags"][1]["value"] = "Divert 1"
system.tag.configure(folder,nodes)

Multiple properties show as overridden even though I’m only changing the Value property

I’m also seeing this happen in 8.3.1

Where can I download this version from? I’m sure IA would be interested to know as well! :laughing:

I have seen this happen as well in later versions possibly even as late as 8.1.5 although I can’t be sure… I noticed it recently when I found a UDT’s tags had unexpectedly different config from the definition; I can’t remember exactly, but from memory the data type didn’t match. Then I noticed that the UDT instance config was overridden which I thought was strange as I wouldn’t normally do that.
Good to know, and certainly seems like a bug!

@PGriffith

Haha… 8.1.3 :man_facepalming:

I have seen this same issue too still in 8.1.9. It would be nice to see this fixed as I assume that once it is flagged as overridden it will no longer update if you change the parent UDT.

I am still seeing this problem in 8.1.13…
This is a pretty bad bug in my mind as we can’t reliably configure tags to update just one property, without potentially screwing over an entire UDT.
For instance in my UDT i have three expression tags. I want to simply change the expression so that it overrides what the parent UDT has by default. But in doing so, i am getting all sorts of unrelated properties being overridden.

rootPath = "[default]_types_/Basic/Real"
configs = system.tag.getConfiguration(rootPath, True)
###print configs[0]["tags"]
for tag in configs[0]["tags"]:
	###print tag['name']
	if tag['name'] == 'Active':
		print tag['name']
		print tag['expression']
		# Set new expression
		tag['expression'] = "{[.]Value/Alarms.HasActive}"
		
# end for


# Write changes to config definition back to UDT definition
print system.tag.configure(rootPath,configs[0]["tags"],"m")

This yields the following results where not only the “Expression” has been overridden, but so has all sorts of other properties for the tag “Active”.

As a workaround, you could ONLY programmatically update the properties that you are changing (or have already been overridden with a value different than what is configured on the UDT definition itself). This is what I typically do:

tagPath = '[default]some/path/to/udt/tag'
parentPath = str(tagPath).rsplit('/',1)[0]
tagConfig = dict(system.tag.getConfiguration(tagPath, True)[0])
udtPath = '[default]_types_/path/to/udt/tag'
udtConfig = dict(system.tag.getConfiguration(udtPath, True)[0])
del tagConfig['path']	# Tags seem to break if you accidentally write back to the path property
for key in tagConfig:
	if tagConfig[key] == udtConfig.get(key, '') and str(key) != 'name':
		del tagConfig[key]
tagConfig['propertyToBeUpdated'] = 'newPropertyValue'
system.tag.configure(parentPath, tagConfig, "o")

It’s not the ideal solution, but it gets the job done for me.

2 Likes

Interesting… thanks i’ll have a play.
So this is actually configuring a UDT instance right?
Currently i’m trying to configure the UDT itself but i will also need to do this at some point soon.

Are you effectively just stripping out all tagConfig keys except the ‘name’?

Yes, in my example post I was assuming that ‘some’ would be an instance of UDT ‘path’ and ‘to/udt/tag’ would be a folder structure within the UDT where ‘tag’ is the actual tag being configured. This example should still apply if you were modifying a UDT with another parent UDT. the tagPath property in the above example would just be something like ‘[default]types/childUDT/tag’ while udtPath would be something like ‘[default]types/parentUDT/tag’

And yes, I am effectively stripping out all the keys of the tag configuration besides ‘name’ (which is needed to determine which tag is being configured), the key of the property you wanted to update, and any other tag properties whose values differ from the parent UDT’s. If you wanted to revert the child UDT back to the parent UDT’s tag properties entirely, your tagConfig would only consist of the name property.

1 Like

I managed to achieve what i needed by defining only the expression tags i wanted in a totally separate array.

alarmTags = [  
	{
	  "expression": "some expression here",
	  "name": "Active",
	  "tagType": "AtomicTag"
	},
    {
      "expression": "some expression here",
      "name": "Acked",
      "tagType": "AtomicTag"
    },
    {
      "expression": "some expression here",
      "name": "Alarm",
      "tagType": "AtomicTag"
    },
    {
      "expression": "some expression here",
      "name": "AlarmPriority",
      "tagType": "AtomicTag"
    },
]

print system.tag.configure(rootPath,alarmTags,"m")	

Then using that in system.tag.config. That also seems to only override the destination tags that match, and not affect anything else in the UDT.

Maybe thats what IA intended us to do, but i’m still getting my head around this new JSON tag structure and the new config functionality.

I am playing around with changing properties programmatically, most of which are instances of UDTs. If I change a tag property, something like this,

tagPath = 'myPath'
parentPath = str(tagPath).rsplit('/',1)[0]

props = [
            {
                'name': 'Tag1', 
            	'value': 111
            }
        ]
        
tags = [
			{
				"tags":props,
				"name":"New Instance"
			}
		]

print system.tag.configure(parentPath,tags,"m")

I only see the property value for Tag1 get set to override, which is what I want.

However, if I do something similar for alarms,

tagPath = 'myPath'
parentPath = str(tagPath).rsplit('/',1)[0]

alarms = [
            {
                'name': 'Alarm1', 
                "setpointA":10,
                "label":'i changed the label'
            }
        ]
        
tags = [
			{
				"alarms":alarms,
				"name":"Alm1"
			}
		]

print system.tag.configure(parentPath,tags,"m")

it sets the entire alarm to override. Is this normal? Fixable?

I’m using 8.1.17.

From what I have tested in 8.1.10 through 8.1.17, this is normal. Obnoxious, but normal.

And nothing really that we can do to side step the obnoxiousness? :slight_smile:

Not that I have found. Maybe IA has some tricks up their sleeves though? @PGriffith

Travis Cox responded on the side and told me this is the way until perhaps 8.2 when they go to storing tags in file system. Appreciate the clarification on this.

1 Like

Interesting. I wonder how this will be done? just a massive json file? :S I wonder how fast this will be especially for larger tag databases

Not sure. I’m not sure it will be implemented, but they seem to think it’s possible where as right now it isn’t.