Nested Paths Not Allowed (Perspective)

Hello, I am new to Ignition and still learning.

I am creating a template with Indirect tag bindings. The goal is to have a user click on a pump and a popup will open of a template to auto populate the tags within the template.

I have been making progress using custom parameters and the indirect tag bindings. However, I have ran into an issue where I need a button to change colors based if it is pressed or not. This button needs to see if the pump is in “Hand” AND if the pump is on or off. So if the pump is in “HAND” and you press the “ON” button, the button will change colors to signify the pump is on.

I have very limited knowledge when it comes to expressions and scripting so I came up with the following expression for this:

(!{[default]Sadorus Pump Station/Controller:Global/SBS_PUMP_1/DS_AUTO}) & ({[default]Sadorus Pump Station/Controller:Global/SBS_PUMP_1/DI_ON})

If the pump is NOT in “Auto” AND the pump is “On”, this will bring back a value of 1 which I can transform into a color.

So to make this an indirect binding, I would change the “SBS_PUMP_1/DS_AUTO” and the “SBS_PUMP_1/DI_ON” with the parameter in the template. So it will look like:

(!{[default]Sadorus Pump Station/Controller:Global/{view.params.PumpStateTag}}) & ({[default]Sadorus Pump Station/Controller:Global/{view.params.PumpStatusTag})

However, upon doing so, I get the following error:
“Nested paths not allowed”

Could I have some assistance on this?

First, the logical AND operator is &&

If you need to dynamically call tags from an expression then you need to use the tag() expression function.

https://docs.inductiveautomation.com/display/DOC81/tag

(!tag('[default]Sadorus Pump Station/Controller:Global/'+ {view.params.PumpStateTag}) && (tag('[default]Sadorus Pump Station/Controller:Global/' + {view.params.PumpStateTag}))
2 Likes

Thank you for the reply,

However, upon entering your code, I get a “Error_TypeConversion” error. But it also brings back a value?

Psst! Don’t use tag(). There be dragons.

Use indirect binding to bring those booleans to custom properties in your template. (Internal or on the template’s components.) Then use those properties in your expressions.

1 Like

Do said dragons apply to perspective as well seeing as how you’re already at the gateway?

Well I got it working using the following code:

(!(tag("[default]Sadorus Pump Station/Controller:Global/" + {view.params.PumpStateTag}))) && (tag("[default]Sadorus Pump Station/Controller:Global/" + {view.params.PumpStatusTag}))

However, is using the “tag()” option a bad way to do it?

When you say “Use indirect binding to bring those booleans to custom properties in your template” could you elaborate?

Thank you for the help!

Historically, tag() just slowed Vision down. It tends to crush Perspective.

Create view custom properties for each boolean that would otherwise need the tag() function. Use indirect binding to combine your static and dynamic tag path parts for those booleans to bring their live data into the view. Then construct your expression with those properties in place of the tag() expressions. It also eliminates multiple identical tag() expressions when you use a particular boolean in more than one spot in the expression.

I am in the middle of converting a lot of simple scripting functions to expression bindings for performance reasons, does tag() have worse performance than runScript() when run in the expression bindings?

If you are then calling runScript(), you aren't changing anything's performance. Jython has notable startup overhead.

The tag() expression function has other problems, and should never be used outside of actual expression tags. Really, don't use it in user interfaces. Use custom properties with indirect tag bindings, then use those properties where you would have used the tag() function.

2 Likes

I was calling runScript() but after some digging around on why my perspective session was being so slow, I came to the conclusion that it was partially because of all of the jython environments that had to get booted up for simple UI properties (was this an incorrect conclusion?) and so I am converting the runscript() to expression logic to determine certain properties such as button classes, button text, image paths, etc. In converting these to pure expression binding syntax i am using tag() but you are saying that their is no performance difference between tag() and runScript()? and that I should be creating custom properties with indirect tag bindings and then using those properties in the expression binding syntax?

Could you explain a little more about the difference of these two methods (tag() vs indirect tag bindings on custom properties) in terms of what goes on under the hood?

Thank you, your help is greatly appreciated.

Both have performance problems. In some cases, tag() can be much worse.

That's almost verbatim what I wrote above.

It's complicated. I've written a great deal on this and related topics.

Start here:

Try these next.

1 Like

Thanks, ill take a look