- [Instructor] In building graphics, I will often want
to display a value that isn't being directly provided.
In this example, I'll be reading data
from a "Type A Micrologic" trip unit.
This device only provides the three phase currents
but I want to see average current on the screen.
Ultimately, maybe I have a different device
that provides phase to phase voltages and the average
but I need to calculate the unbalance on my own.
In many situations,
the correct solution is to create a Cicode device
in the database that calculates these values for you.
That way, you can also trend the value, generate alarms,
and perform other Server side operations on it correctly.
Sometimes though, a value is only needed on the display,
which is what we'll do now.
In Graphics Editor,
I have my text object,
and if my function only
requires one value, the solution would be easy.
I could Bind the Content,
set the Bind name correctly
and add a Conversion to the Binding.
The Convert Custom even allows me
to apply JavaScript to the value.
Unfortunately, this method only works
for a single value.
To work with multiple Bindings at once.
We'll need to use more advanced scripting tools.
Instead, I'll delete this Binding
and create three new custom properties
named "Ia", "Ib", and "Ic".
I'll also create Bindings to connect these properties
back to the runtime engine.
I'll name them "Ia", "Ib", and "Ic".
Not for the Script, but so they will automatically bind
if I turn this into a component.
These are the standard "item" names for phase currents.
As always, these need to be formatted as presentation.
(you can select all "Binds" to change attribute values)
As you expect,
I need a Script in my Text as well.
Just like the setpointScript from earlier,
I'll trigger a function called "signal" OnSignalChange.
My function's code will start similarly.
The Text object is the parent of the Script
so "evt.getCurrentTarget" will point to that node.
There are several ways to approach the next step
like our setpointScript.
I could store the three values
into variables and calculate the mean
but I want something a bit more flexible.
I'd like to turn this Script
into a Snippet that can find the mean
of any Bindings attached to an object.
So, how do we get bound values
when we don't know their names?
We have to go down the tree, then back up.
First, I'll use the function getChildNodes()
to find all of my child tags.
I'll also need a totalizer to calculate the mean
and another to store the number of Bindings.
I can't just use the number of child nodes
because there may be nodes other than bindings.
Now I can loop over all the Bind tags.
A skipping index zero.
That one is the "CDATA" tag in closing the function.
I'll first get the child tag
and only continue if its name is Bind.
If so, I'll increment the counter
and extract the bound attribute from that Bind tag.
This line looks a little strange because the attribute
of a Bind tag that stores its target is literally
called "Attribute".
Now I can step back up
to the Text tag and grab the value of the Binding.
Keep in mind that the API returns all values as strings.
So to add this value to the sum,
I'll need to parse it as a floating point value.
Finally, I can set the Text Content attribute
to the sum divided by the number of bindings.
At long last, we can jump to Preview and test our code.
If I plug three values into the Bindings,
the code will automatically update
with the mean of the three.
Note that the output is not a number
until all values are populated.
If a blank value is possible, we might add some code
to ignore a NULL value and calculate
with the remaining values.
If this is an error, we can leave the Text as is
or display a real warning message or symbol.
The last step as before is to make the code reusable.
We've already written a generic function
that doesn't rely on manually entering the Bind names.
So, I can break this out into a Snippet
called "Binding Mean".
If this code is to be used many times
on the same page, though,
I would instead enable Global Scripts
and create the function as part
of the pages on load event.
Finally, if this is to be reused over
and over in the project, I'd push it up
to the deploy JS folder
so it's only loaded once.
These are all options you need to consider
when creating your own JavaScript library.
Next, we'll continue learning how JavaScript
can perform some common graphical operations.
Until then, thank you.