Say you have 80 tags and 80 custom properties, and you are interested in assigning the values of the tags to the custom properties 1:1 when the user clicks a button. How would you go about doing this?
It's easy enough to grab the tag values with tag_values = system.tag.readBlocking([tag_path1, tag_path2, ...]), but then how would you go about assigning tag_values[0].value to custom.property1, and tag_values[1].value to custom.property2, and so on?
The only thing I could I could come up with is to create an Array custom property that houses all of the custom property values, then iterate over that with
for x in range(tag_values):
self.getSibling('example').custom.exampleArray[x] = tag_values[x].value
but that comes with the downside of not being able to label the individual custom properties so that I know what they refer to at a glance.
If so, I would structure the tags to be in the same folder and do all the properties from indirect tag bindings using a parameter into the template or popup.
If you're doing it in a script you will have significantly better performance reading a block of them as you're doing that you would if you were to read tags one at a time. Generally, I favor bindings over scripts generally.
Also, note that you can copy a binding in perspective and paste it into a text editor to get the JSON that represents that binding. In some situations this lets you create your bindings in bulk, copy the JSON from your text editor and paste it as a binding on the property you're binding.
The custom properties exist within an SVG component, and I was originally going to use bindings and simply call refreshBinding on each property when the button was clicked, but that doesn't seem to work - the values of the custom properties will only update to the values of the tags they are bound to if the tag value itself changes.
e.g. if I have
tag_1 whose value is false
custom.property_1 that has a direct tag binding to tag_1
If I go and manually change the value of custom.property_1 to true and then call refreshBinding on custom.property_1 it will not update back to false.
Oh, I see. I like using custom properties on embedded SVGs because it allows you to test animations on the SVG by overriding the value in the designer without impacting the binding that controls the animation or writing to tags (which could impact things in the runtime).
That is what I think you're doing but you may not realize it. A binding to a tag should be updating automatically when the value it is bound to changes. If you change the value in the designer it will trigger any bindings that are bound to that property but the binding will still control how it animates at runtime.
Imagine a scenario where you have a circle in your SVG that is bound to a Boolean custom property to animate red if the property is true and gray when the property is false and you bind the custom property to a Boolean tag. You can manipulate the property manually in the designer to make the animation fire (an override) but it will refresh the binding if the value of the tag changes because the binding will be triggered. So you can test the visual animation without impacting anything in the runtime.
Another thing to consider... You can use an expression structure binding if you want an action to trigger if any one of a number of values change.
I have 80 squares on my SVG that can either be colored in or empty with just a border. Each of those 80 squares is bound to a boolean custom property that determines its state.
I also have 80 tags, each corresponding to one of the squares in the SVG. When the user opens the view, the squares are in the same state as the tags, but the user is able to click on a square to invert the state of the square in the SVG (if it is empty when they click, it fills in and vice versa). I've done this by placing empty labels on each square with an onClick event that changes the visibility of the corresponding 'filling' element in the SVG.
At any time, the user can click a button that should 'reset' each of the 80 squares so that they are back in the same state as their respective tag.
Basically there is one system state that represents the actual individual states of the devices (80 booleans that come from OPC Tags), and there is another system state that the user can create by clicking on the different squares to invert each device's individual state.
I've not really tackled something like this before, so I am experimenting and trying to find the method that I like the most.
I would have two sets of tags. One live set and one proposed set. Bind all your props /w bidirectional indirect bindings to the proposed set of tags. Then you have two buttons, reset or confirm. Reset copies live to proposed while Confirm copies proposed to live. And then on screen load you can also trigger the reset.
If you organize the tags in two different folders with identical tag names it makes it quite trivial to do the read/write.
I think this is essentially what I was going for - I have a set of memory tags that are written to when the user clicks on one of the squares, and the memory tags exist in the same folder structure that the OPC tags do.
I hadn't thought about doing a bidirectional binding between the memory tags and the custom props and simply copying the OPC tag values to the memory tag values on reset, though, that's a good idea!