UDT Binding Not working After Find & Replace

So I want to provide as much detail about this as possible since I am not sure if it was the specifics steps I went through that caused this or if it can be re-created in another manner.

I am creating a UDT that will match up nearly identically with a PLC UDT. The quickest way I came up with doing this was to bring in a PLC tag of the Data type and copy its structure into the new UDT.

This worked fine but I then needed to change the tag bindings in the structure to be more “universal” to all my tags of that type. I figured the easiest way would be to use find and replace to change the necessary values.

After using find and replace, I opened the UDT and found that the bindings didn’t appear to be working correctly (note image below where text isn’t light gray and italics like a correctly bound tag)

Furthermore, I found that it is not easy to work around this. I tried to edit the value and just click commit to see if that fixes it. The tag text looked correct after this but after applying, closing and re-opening the binding appeared to be broken again.

I found that the way to get it to work properly was to copy the binding, remove the binding and the paste it back in and it stayed.

Hopefully I explained that well.

Create another tag in your UDT and bind its opcitempath dynamically by referencing your params, then copy the UDT as json to clipboard. Paste into notepad and compare your new tag with your tag without a dynamic binding, and you’ll notice that the one without is missing the binding formatting (i.e. a dictionary that contains the data type and the expression).

Not at my laptop to be more specific sorry

I created a script that fixes up any props that use braces that don’t have bindings, and convert them to bindings

I took a look at the json and see what your saying. I thought something like that might be happening and should have looked at the json to prove it. I did not think of writing a script to fix this, I will have to write one to do the same as I have a few more UDTs like this to make and this is the most expedient way to get it done. Thanks for providing the insight!

1 Like

Just wanted to update with the script I created to work around this issue for anyone else who may need it. I just tied it to a button on a “test” screen and hit it when I make new udt(s) with copy/replaced bindings.

Here is the code:

opcItem = 'opcItemPath'
logpaths = list()
logger = system.util.getLogger('FixTagLog') #logger for logging fixed tags

#get udt definitions
udts = system.tag.browse('[default]', filter= {'tagType':'UdtType', 'recursive':'True'})

for udt in udts: #get opc type tags inside udts
	opcTags = system.tag.browse(udt['fullPath'], filter= {'tagType':'AtomicTag', 'valueSource':'opc', 'recursive':'True'})
	for tag in opcTags:
		config = system.tag.getConfiguration(tag['fullPath'])
		#get tag config and check for proper binding
		if isinstance(config[0][opcItem],(str, unicode)) and '{' in config[0][opcItem]:
			#if binding isn't correct, fix it and edit tag
			binding = config[0][opcItem]
			tagpath = str(config[0]['path']).rsplit('/',1)[0]
			config[0][opcItem] = {'bindType':'parameter', 'binding':binding}
			editConfig = system.tag.configure(tagpath, config,'o')
			if 'Good' in str(editConfig):
if logpaths:
	logger.info('Fixed tag binding at paths: %s' %logpaths) #logs tags changed/errors