Dynamic tag bindings in a property expression?

I have an indicator for a conveyor. it uses 3 different tags from the plc to drive various states. I tried to create an expression that grabs the name of the component to dynamically change the names of these tags so that I can just copy and paste the indicator then change the name. I found that the expression function does not like this.

Code that works looks like this:

if ({[default]ROOT/MAPS/OVLD/S6810_OVLD} = 1, 
	4,
	if ({[default]ROOT/MAPS/FULL/S6810_FULL} = 1,
		3,
	 	if ({[default]ROOT/MAPS/FULL/S6810_AUX} = 1,
	 	1,
	 	0)))

I want this:

if ({[default]ROOT/MAPS/OVLD/ + component.name +_OVLD} = 1, 
	4,
	if ({[default]ROOT/MAPS/FULL/ + component.name +_FULL} = 1,
		3,
	 	if ({[default]ROOT/MAPS/FULL/ + component.name +_AUX} = 1,
	 	1,
	 	0)))

If this can't work is there a different way to make this happen or will I need to copy paste the script and change the names in the script every time I want a new indicator?

Try this:

The expression binding should be modified to wherever your componentName is stored.
"[default]ROOT/MAPS/OVLD/" + {view.custom.componentName}

The expression transform:

if(
	tag({value} + "_OVLD") = 1, 
	4,
	if (
		tag({value} + "_FULL") = 1,
		3,
	 	if (
	 		tag({value} + "_AUX") = 1,
	 		1,
	 		0
	 	)
	)
))

And if the tags are bools it can be reduced to,

if( tag({value} + "_OVLD"), 4,
	if (tag({value} + "_FULL"), 3,
		if (tag({value} + "_AUX") , 1, 0))))

Generally though, we avoid the tag() function. If you explain your configuration a bit more someone will suggest some improvements.

I forgot to mention this is in vision and not perspective. Does this affect anything?

I don't have the options check box in vision.

Also added information: This expression is on a custom template property.

I forgot to mention this is in vision and not perspective.

That would have been nice to know.

Does this affect anything?

Yes. Vision doesn't have expression transforms.

Please edit the question title and add the vision tag from the dropdown.

Caution: While as @Transistor shows, the tag() expression will work, it is strongly recommended that you avoid it's use for basically anything outside of expression tags. Enough of this in the UI will kill your performance.

The proper way to accomplish this type of thing is to use indirect tag bindings. Something like:

  1. Create a custom property to hold the value of each tag.
  2. For each custom property use an indirect tag binding to reference the component name in the tag path.
  3. Then you can change your Expression to the following:
case(
    binEnc( {indicator.AUX},{indicator.FULL},{indicator.OVLD}),
    4,4,
    2,3,
    1,1,
    0
)

NOTE: Order in the binEnc is important. I would be very tempted to change the result for FULL from 3 to 2. Then you could just simply use a binEnc() expression so long as other logic insures that only one of the tags are ever true.

If you want to emulate exactly what your if() expression does that would look like:

case(
    binEnc( {indicator.AUX},{indicator.FULL},{indicator.OVLD}),
    6,4,
    5,4,
    4,4,
    3,3,
    2,3,
    1,1,
    0
)
2 Likes

Sorry about that. I am new to ignition and this is my first post here.

Do I need to replace "Indicator" with something that is specific to my project or is "indicator" a universal descriptor?

Yes, it will be the path to wherever you actually create the custom properties.

component.aux?

If I were to use the path using the root container then it would go against the purpose of making the custom properties in an effort to be able to copy, paste then rename the indicator.

You can make the properties on the comment itself, or better yet create a template and create the properties there. Just make sure that you make the device name property external so you can set it from outside the template.

2 Likes

Adding on, this is called template indirection in the docs. For reference: Template Indirection | Ignition User Manual

Yeah, I am using a template.

Thank you guys, I should be able to figure it out. The information has been incredibly useful.

1 Like

Inside the Indirect tag binding, It does not like component.name.

If I use:

"[default]AEO_MS/MAPS/AUX/"component.name"+"_AUX""

or

"[default]AEO_MS/MAPS/AUX/"+"Component.name"+"_AUX""

It will take it, but it doesn't seem to link to the tags.

Is your template named "component"? If not, that won't work. When you pick a property for the indirection, make sure you're using the picker instead of freely typing in something

Edit: Also, remove your quotes on the indirect tag.

2 Likes