Attempting dynamic reference tags using expressions; baffled by behavior

I am trying to do somewhat dynamic tag linking without UDTs, and am having a bit of a struggle with the expression language.

First question: is there a good way to reliably prototype expressions? I want to try some out and see what their resulting value is.

Main question:

I have a tag provider called [PROJ] that has all of the imported variables autonamed from my PLC documentation. It is a flat folder that serves as a starting point for my HMI. I then have a tag provider called [HMI] that is to be organized more like the HMI itself. Both of these tag providers have identically named subfolders representing the system they are concerned with.

So I have [PROJ]TB0 which contains all of my named variables, and [HMI]TB0 which will have subfolders representing logical groupings.

Concrete example: I am trying to build a reference sending the boolean [PROJ]TB0/pal_valve_0 to [HMI]TB0/plc/pal/valve_0/state, and I now realize that the variables like {InstanceName} or {ParentInstanceName} are all UDT-specific variables. So I want to do this with more generic path parsing. I know [~] represents the current tag provider, and [.] represents the parent folder of a given tag, with something like [.].. representing the folder above that.

So I am trying to understand how to do this by using a Standard Tag -> Expression -> String and then trying to extract the paths to read them (since I can't figure out a better way to test expressions; dereferencing these would be my next step) and it is really confusing me: the expression "[PROJ]" + {[.]../../..} + "/" + {[.]..} + "_" + {[.]} yields a value of [PROJ]2/3_3. Even just {[.]} yields 3 instead of valve_0 like I would have expected.

I am just terribly confused and hope someone can show me what I am doing wrong! Ill keep at it in the meantime.

Also -- how can I access a property of a tag that is identified by relative location? {[.].Name} yields valve_0 which is good news, but {[.]...Name} doesn't work (I didn't expect it to, really). {[.]../.Name returns null. If I can go for the Name field of the directories above, I can construct a tag path that way.

{[.]} yields 3 (valve_0)
{[.]..} yields 3 (pal)
{[.]../..} yields 2 (PLC)
{[.]../../..} yields 2 (TB0)
{[.]../../../..} yields 2 ([HMI]) -- tag provider level
{[.]../../../../..} yields BrowseValue [value=null, info=null, configVersion=14]

All additional /.. addendums remain with the final response forever, which makes sense at least.

At first I thought maybe the 3 was the depth but I was quickly disabused of that. I have no idea what that number represents -- it should be a folder but what is a folder?

You are going to be endlessly frustrated trying to convert relative stuff to absolute. Also, these relative expressions are only going to be available within expression tags, whether in UDTs or not. Almost none of this will work in UI bindings. But there, you (will) have tagpath parameters to work with.

Please note that there is nothing wrong with UDTs in the tag hierarchy, and their internal tools and parameters are very helpful indeed for many tasks. At no point in yesterday's long rants did I suggest abandoning UDTs entirely--just to not use UDT UI properties.

Ah I see -- a valuable distinction. I willl continue to use UDTs then, just never as a template property. Thank you for clarifying! The path of relative paths was making my eyes try to look straight at each other.

Might be worth rereading yesterday's topic from the top.

Oh I have reread it all multiple times now. But now that I know you weren't telling me to abandon UDT's, I realize that when you say "UDT parameter" you mean the template parameter with type UDT, not the parameters of the UDT. I had thought it was the actual underlying parameters of the UDT itself that were problematic as well as eventually coming to understand that I should not use a whole UDT as a Template Parameter ∴ I should use a non-UDT folder-based tag structure + tag path string template parameter to top level folder. Hence my foray into trying to generate relative linked tags.

I think this line knocked me a bit sideways:

The string tag path IS the template parameter instead of a UDT parameter.

I now read this as the template parameter is string-type that is the tag's path, instead of being UDT-type that is the UDT itself

UDT and <UDT> were being used interchangably occasionally and that I think also threw me off.

Anyway! I think :crossed_fingers: I have it now; is this correct:

  • Template Parameter of type UDT: ILLEGAL
  • Template Parameter of type String, referencing the path of a UDT: PREFERRED

Well, it is legal. I would say Unwise, Limiting, Frustrating, Slow, and, at various times in the life of Ignition, Buggy.

I would add:

  • UI Container Custom Property of type UDT: Unwise

  • UI Component Custom Property of type UDT: Unwise

So too with Vision Client tags and Perspective session custom properties.

Close enough to illegal for me! Possible but a no-no ~ illegal.

I haven't taken a foray into any other things in the meta-category of containers/templates/components, but is there anything that you would recommend ( or at least not not recommend) having a property of type UDT?

Not a single one. It was/is a "feature" looking for an application that it won't crush. "We've invented these cool UDTs for tags! What else can we apply this to?" /not really putting words in IA developer mouths....

Hmmm. Maybe we should ask IA to deprecate them (the UDT UI properties, not UDTs themselves) for v8.3. SO MUCH grief could be avoided long-term.

Copy that. Illegal everywhere.

Honestly the pain I already encountered trying to update them after they were in place makes this sort of a relief. Losing the drag and drop is a drag (:smirk:) but I'll live.

I still have to figure out how to build my UDTs dynamically, but probably Ill eventually be constructing them via script anyway. Can't apparently nest {}'s in the expression language, so I can't do things like {[PROJ]TB0/{InstanceName}} :angry:

JSON import/export.

That works -- lets me build them in something a little more modern than jython 2.7.

I was hoping I could get them a little more dynamic inside of the designer though, where they could grab the correct references simply by being named appropriately :man_shrugging:

Lots of options in system.tag.*.

1 Like

I want to nest {}'s in a UDT expression tag is there no syntax to make this work? It seems crazy to have to hard code the instance name for each UDT tag. Any help is appreciated.

if({[~]WorkCenters/{InstanceName}/TimerTrigger},now(0),0)

This is one of the few cases where the tag() expression function is appropriate.

This worked thank you!!

if(tag('[~]WorkCenters/'+{InstanceName}+'/TimerTrigger'),now(0),0)
if({[~]WorkCenters/W2101/TimerTrigger},now(0),0)

tag | Ignition User Manual (inductiveautomation.com)

Thanks for the speedy reply.