Indirect properties

Much like indirect tags, I would like to define an indirect property.
I would also like an expression function that would allow me to know if the indirect property can resolve itself at run time and allow me to specify a default/fallback value if it doesn’t.

Or have I missed something in the manual again :scratch:

The components on your screen shouldn’t be changing in runtime, so you don’t generally need to have indirect property paths. If you want to, you can make an Expression and use Logic functions like if(), switch(), etc. to choose between existing properties.

If you really want to do something dynamic, then you can make a Dynamic Property somewhere and populate the value with a script. You can use the scripting functions to create a dynamic path. ie:component = "compName1" value = event.source.parent.getComponent(component).intValue

It is a bit of a corner case I admit. I’m building templates that reference other components. Specifically dynamic properties. To make life really easy, I just want to enter a component name and then use code to complete the path.

I was hoping to use expressions but scripts will do.

Thanks Bobby.

[quote]component = "compName1" value = event.source.parent.getComponent(component).intValue[/quote]

How can you get a component when you don’t have an event?

You will need to find some event that triggers a change. I don’t know what it is without knowing more about your screen, but you will probably have a property polling somewhere that you can use its propertyChange event. At the worst case, you can add a timer to the screen and use the propertyChange event on that.

As a side note, is the dynamic property the only part of the path that is changing? There are depreciated functions getPropertyValue() and setPropertyValue() that used to be required to interact with Dynamic Properties. Because Ignition is backward compatible, they still exist.#get a dynamic property's value from the parent container val = event.source.parent.getPropertyValue('dynamProp1')

So I have this device templated. It can connect to a number of other devices (up to 4).

I really want to get some data (also in dynamic properties) from the connected devices. Process that data and then drive properties on the template.

So I have defined a number of dynamic properties:
*connectedDevice1
*connectedDevice1Value
*connectedDevice1Colour
*connectedDevice2
*etc

And then I want go say:
connectedDevice1Value = {‘connectedDevice1’+’.Value’}
connectedDevice1Colour = {‘connectedDevice1’+’.Colour’}
etc

This way I only have to set connectedDevice1 = ‘devicename’ and everything just works.
I could use tags, but there are many types of connected devices and they each have there own set of tags. My thought was I could use dynamic properties to create a consistent API.

Is there a reason that you want to have special Dynamic Property names? Why can’t you name them 1 though 4? If you do that, you can set default values for each so if you don’t need all of them, you can ignore them.

Also, you can create a dataset instead of individual properties and access the info from there using the try() function. To add up to 4 rows of values:try(toInt({Root Container.Button.values}[0,"value"]),0)+ try(toInt({Root Container.Button.values}[1,"value"]),0)+ try(toInt({Root Container.Button.values}[2,"value"]),0)+ try(toInt({Root Container.Button.values}[3,"value"]),0)

I don’t need special names. They can be anything. (I am creating them after all). I just need all templates that I create to have the same named property.

As for datasets, I would still have to populate them manually.

I want to keep it simple.
*create the component from the template
*enter the connected device names in dynamic properties
*done

Any other way requires selecting a property, opening a binding screen, linking to a tag/property, etc

I want to be able to create and link up lots of these components fast and at a glance be able to see that they are connected correctly.

Using indirect properties will allow me to do this. It’s very powerful for tags. I think it could be just as powerful for properties.

:bulb: Is there any way to reference self() in an expression to the the component the expression is attached to :scratch:

Anything in the expression that is in red (ie in {}) will follow the component when the name changes. For example, if you have a text field with this expression:{Root Container.Text Field.count}When you duplicate it, the name of the new component is Text Field 1 and the expression automatically changes to:{Root Container.Text Field 1.count}This eliminates the need for a self variable.

can I go {Root Container.Compontent}.parent.getComponent(‘name’) ?

No, that style is only used in scripting. We don’t have the ability in binding to do indirect properties. In scripting we can only do indirect properties if they are dynamic properties because of the:

getPropertyValue
setPropertyValue

functions on components with dynamic properties.

While then my feature request stands.

I would like to be able to use indirect properties the same way I can use indirect tags.

Forgive me for going back to basics here, but I don’t understand what you’re getting at. Your motivating example confused me. What would you hope ‘devicename.Value’ to resolve to?

[quote=“Robert”]So I have this device templated. It can connect to a number of other devices (up to 4).

I really want to get some data (also in dynamic properties) from the connected devices. Process that data and then drive properties on the template.

So I have defined a number of dynamic properties:
*connectedDevice1
*connectedDevice1Value
*connectedDevice1Colour
*connectedDevice2
*etc

And then I want go say:
connectedDevice1Value = {‘connectedDevice1’+’.Value’}
connectedDevice1Colour = {‘connectedDevice1’+’.Colour’}
etc

This way I only have to set connectedDevice1 = ‘devicename’ and everything just works.
I could use tags, but there are many types of connected devices and they each have there own set of tags. My thought was I could use dynamic properties to create a consistent API.[/quote]

I have two components A and B. I have created templates for both of them. When I build a screen with them, I have to connect them together because their behavior is based on the others state.
eg: if A is a wire, and B is a breaker, I want the wire to be red if the breaker is closed with current going through it.

I can bind properties in A to tags that drive B, but I have many A’s and many versions of B (C,D,E,F) and the tags are different for each of B,C,D,F… If I can create standard properties for my different breakers, them when I connect A to one of them I can set a single property in A to the name of B (or C,D,E…) and then drive the other linked properties in A based on that. except I can’t :frowning: because the property path must be full and complete.

So now I have to link a number of properties in A to properties in B and then I can’t move things around and change the connections without unbinding all those connections (in both A and B) because I’m not allowed to do bad things.

Clear enough?

(Waiter, this coffee tastes like mud! But sir, it was fresh ground this morning.)

Unfortunately you can’t do anything like connectedDevice1Value = {‘connectedDevice1’+’.Value’} in an expression binding, they are all static. You could in scripting (event.source.parent…) but that adds a lot of unnecessary complexity. The best thing I can think of is to make a single component out of each pair of components. ie: AB, AC, AD, etc. It will mean that you could have a lot more saved in your custom palette, but then you don’t have to worry about the bindings.

Couldn’t you do this with a switch expression?

switch({setting}, 'B','C','D','E', {B.Something}, {C.Something}, {D.Something}, {E.Something}, -1)

switch/device name is customer dependent. Every project will be different and the number of combinations quickly becomes unmanageable.

If we can’t do indirect properties, I will have to wait for this and this to be completed.