UDT Member OPC Item Path Based on Other Tag

I have a UDT that takes a parameter for the AOI_Name. The UDT then uses this AOI_Name in various OPC paths to get various members and tags related to the instance. For example, if AOI_Name is "Pump1" these OPC paths are defined for tags within the UDT:

Amps: [SCP]Pump1.Amps
Volts: [SCP]Pump1.Volts
Index: [SCP]Pump1_Index

Is it possible to add a tag that now uses the "Index" tag in the OPC item path?

Group: [SCP]Group[{Index}]

What I've done for things like this is to set up a parameter named accordingly to match your tag. In this case it could be Index or MotorIndex or something, then set a tag change script on your Index tag that writes to this parameter. Works really well.

Then you just use that parameter like normal.

1 Like

That's what I'm trying to do currently. I may not have the relative path quite right:

def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):

	if currentValue.value:
		system.tag.writeBlocking(["[.]Parameters.Index"], [currentValue.value])

Try this:

def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):

	if currentValue.value:
		system.tag.writeAsync(["[.]../Parameters.Index"], [currentValue.value])

It really depends on how many layers deep your tag is. I usually have mine in folders, so I have to add a few ../ to the front to move up a few folders to get it right. If the tags are in the root of your UDT, no ../ should be needed, buf you have a single folder, the single ../ should be enough.

Edit: Changed to writeAsync also. I believe I had some issues with writeBlocking when I had a lot of tags and they all start up wanting to write at the same time.

If you can avoid doing this, you should. Runtime changes to tag properties cause the tag to restart--a heavyweight operation that does not scale.

No matter what I try I can't get it to work. Index is at the root level of the UDT and the Index parameter has been created. It just won't update.

I guess since I shouldn't do this if I don't have to I'll find some other workaround

It was working, but with one side effect.

When I created the Index parameter I didn't give it an initial value, so it comes in as null.

When the change script runs to update the value it is working for UDT instances where the Index tag is non-zero. For the instances where the Index tag value is 0 the parameter's value doesn't get updated from null for some reason.

Ahh, yeah, I forgot about that. I had the same issue and have been since doing it like that, but just forgot I had to do that to make it work.

So what's the solution? Give the UDT definition a default value of 0?

You can try this as I know it works with strings, but you may have to use 0 by default. On strings, I set a value, apply, then clear it out so it's a 0-length string instead of null and apply again. Not sure if that will work on an integer though.

I've had to do that for strings as well. One you put something into the field for an int it won't allow it to be blank - it'll go to 0 automatically. That should be fine though.

1 Like

If “AOI” in your parameter refers to a Rockwell Add-On Instruction, please reconsider directly addressing AOI instances in your tags, this is a severe performance impact.

What do you mean by "directly addressing AOI instances" ? - I believe this is already what I am doing.

Cannot read some tags inside Rockwell AOI - Ignition Early Access - Inductive Automation Forum

There are a bunch of posts about directly reading AOI’s and why it provides poor performance.

Ok, I see what you are saying now. You're saying don't directly address an AOI's members because it's much slower than addressing a UDT member that is also used by the AOI. - Not gonna happen. Far too many AOIs exist to rebuild them all for Ignition. Seems like Rockwell may have done this on purpose.

If you cannot change the PLC to minimize AOI access, you may want to try my alternate driver. But even that won't help if you cannot make the AOI's underlying data type completely readable. That has to be done with unsealed AOIs, and applies to both AOI parameters and local tags.