The Expression Editor, shown independently below, is available to assist you in creating local and global expressions for your GENESIS64 applications.
When opened from the Unified Data Manager, it creates an expression that is added to a global expression. However, the Expression Editor also appears on the Expression tab of the Data Browser. In the Data Browser, the expression you create is a local one, suited solely for a local purpose. The expression is not reusable in and of itself, although the editor does provide a drop-down list that lets you see the last 50 expressions that were created it the editor.
Note. For detailed information about the differences between local and global expressions, refer to Expressions in the Data Browser.
Note. If you are creating calculated tags in Hyper Historian, also refer to the functions described in the Performance Calculation Functions topic in Hyper Historian. |
Expression Editor ('Configure the expression' window)
Each button in the Expression Editor displays a list of available functions. In cases such as the Variables button, the OPC tabs of the Data Browser are opened to allow you to make an assignment based on tag values. With this editor, you can build an expression, then use the Check Syntax button at the bottom left to make sure you've built it correctly. The important thing to remember about the Expression Editor is that although it checks your expression syntax, it does not check whether the expression is correctly applied.
The drop-down list at the top of the Edit Expression dialog box keeps track of the last 50 expressions you have entered. The expression entered most recently is the first one in the drop-down list.
Let's take a look at ways to write local expressions.
An expression is a string that defines and evaluates a data connection between a client and an OPC server. During runtime mode, OPC servers resolve the data value for the expression. To indicate that a data connection is an expression, precede the string with the "x=" token, as shown below:
x={{ICONICS.Simulator.1\SimulatePLC.PumpSpeed}}
The OPC tag is surrounded by double braces {{ and }}. Parameters are surrounded by double carets << and >>. For example, the expression for calculating a conversion from Celsius to Fahrenheit reads:
x= (<<Thermometer>>*1.8)+32
Where the <<Thermometer>> parameter will be substituted when the expression is in use.
You can either type your expressions directly into the text box of the Edit Expression dialog box, or you can use the symbols and functions provided that help you use the proper string syntax when writing expressions. There are certain options you can use when writing expressions; they include String Expressions, String Comparison, Data type Conversion and Point Extension Syntax. The Expression Editor also provides buttons that list available functions to assist you in writing expressions; click on one of the hyperlinks to go do a more detailed discussion:
Variables opens another instance of the Data Browser so you can make an assignment based on tag values; refer to Data Type Conversion and Point Extension System (PES), below
Strings can be used in expressions. Constant strings are delimited with double quotation marks. For example:
“Hello World”
Constant strings can also be enclosed between $” and “$ characters. For example:
$”Hello World”$
When comparing strings or numeric data coming from the server as strings, the comparison is based on the orders of the characters. For example, the expression...
x="world" > "hello"
...evaluates as true, because the character “w” comes after the character “h” in alphabetical order.
Sometimes the string comparison may be misleading. For example...
x="20" > "100"
...evaluates as true, because the character "2" comes after the character "1" in the character table. Of course, if there were an expectation of a numeric comparison, 20 < 100 and the above expressions might seem to be evaluated incorrectly, but they are not.
Expressions allow calculations to be performed on incoming data. An OPC server can provide data in one or more data types, such as "float," "long," "integer," "string," etc. Some OPC servers provide numeric data as a string. For example, the numeric value 20 may be provided as the string “20” (character "2" followed by character "0"). This may be lead an incorrect expression evaluation (see the String Comparison section above).
There is a workaround, though. If you add a numerical zero to each of the tags, the logic operators will work properly. For example:
x=({{JC.N1OPC.1.0\HDQTRS\sys2\ad-3.Present Value}}+0) > ({{JC.N1OPC.1.0\HDQTRS\sys2\ad-4.Present Value}}+0)
Some of the functions provided in the Expression Editor use parameters of type numeric. When possible, the Expression Editor automatically converts the string into a number. For example, the string “20” can automatically be converted to the number 20.
But if the string contains alphabetic characters or symbols, then the automatic conversion is impossible. For example, the string “20hello” cannot be converted into a number.
Even if the string contains only numeric characters and valid symbols, there may still be cases in which an automatic conversion is not possible. For example, the string “123.45.23” cannot be converted into a number because it contains two decimal separators.
Sometimes strings and numbers are mixed in expressions. In this case, the Expression Editor attempts to convert the string into a number. For example:
Str + Number, where Str is a string convertible to a Number, results in a Number.
If the string is not convertible into a number, then the result will have a bad quality.
The following is an example of a valid expression:
x=5+”6”
The Point Extension Syntax (PES) allows for retrieving additional information related to OPC tags, such as quality and timestamp.
To use the PES:
Prefix your tag name with “tag:”
Postfix your tag name with “#” followed by a PES token.
Valid PES tokens are:
quality (returns the OPC quality associated with the tag value)
timestamp (returns the timestamp associated with the tag value)
The following are example expressions using a valid PES request:
tag: ICONICS.Simulator\SimulatePLC.Ramp#timestamp
tag: ICONICS.Simulator\SimulatePLC.Ramp#quality
tag:\\pc1\ICONICS.Simulator\SimulatePLC.Ramp#timestamp
tag:\\pc1\ICONICS.Simulator\SimulatePLC.Ramp#quality
Note. Sometimes it may be necessary to enforce the "request data type" to a specific type, such as "string," in order to display the extended syntax information in a process point. |
Symbols on the Arithmetic menu are shown in the figure below.
Arithmetic Symbols Menu
The symbols '+', '-', '*', '/' and '%' use the following format:
parameter symbol parameter
Where parameter is a local variable, an OPC tag, a constant, or another expression. The expression results in a number of any type (float, long, etc.). Some examples are shown in the table below.
Arithmetic Expression Examples
Symbol |
Description |
Example |
Result |
+ |
Addition |
~~var1~~ + ~~var2~~ |
8 + 3 = 11 |
- |
Subtraction |
~~var1~~ - ~~var2~~ |
8 - 3 = 5 |
* |
Multiplication |
~~var1~~ * ~~var2~~ |
8 * 3 = 24 |
/ |
Division |
~~var1~~ / ~~var2~~ |
8/3 = 2.6667 |
% |
Modulus - Calculates the remainder after division |
~~var1~~ % ~~var2~~ |
8 % 3 = 2 |
( |
Open Parenthesis - gives precedence to parts of the calcualtion |
|
|
) |
Close Parenthesis - gives precedence to parts of the calculation |
~~var1~~ /(~~var2~~ + ~~var3~~) |
8 / (3 + 2) = 1.6 |
sin(angleInRadians) |
Sine |
|
|
cos(angleInRadians) |
Cosine |
|
|
tan(angleinRadians) |
Tangent |
|
|
asin(number) |
Arcsine |
|
|
acos(number) |
Arccosine |
||
atan(number) |
Arctangent |
||
sqrt(number) |
Square Root |
||
pow(base, exponent) |
Raise to Power |
||
log(number) |
Logarithm |
||
ln(number) |
Natural Logarithm |
||
exp(number) |
Exponential |
||
abs(number) |
Absolute Value |
||
ceil(number) |
Integer Ceiling |
||
floor(number) |
Integer Floor |
||
round(number) |
Integer Round |
||
round to(number, decimalPlaces) |
Round to Decimal Places |
||
min(number1, ..., numberN) |
Minimum |
||
max(number1, ..., numberN) |
Maximum |
||
sum(number1, ..., numberN) |
Sum |
||
avg(number1, ...numberN) |
Average |
||
isnan(number) |
Is Not a Number |
||
isinfinity(number) |
Is Infinity |
||
pi |
Circumference/Diameter Constant |
||
e |
Natural Logarithmic Base Constant |
Symbols on the Relational menu are shown in the figure below.
Relational Symbols Menu
The symbols '<', '>', '<=', '>=', '==' and '!=' use the following format:
parameter symbol parameter
Where parameter is local variable, an OPC tag, a constant, or another expression. The result of the expression results in a Boolean value (0 or 1). The following table shows some examples of relational expressions.
Relational Expression Examples
Symbol |
Description |
Example |
Result |
< |
Less Than |
~~var1~~ <+ ~~var2~~ |
8 < 3 = 0 |
> |
Greater Than |
~~var1~~ > ~~var2~~ |
8 > 3 = 1 |
<= |
Less Than or Equal |
~~var1~~ <= ~~var2~~ |
8 <= 3 = 0 |
>= |
Greater than or Equal |
~~var1~~ >=/ ~~var2~~ |
8 >= 3 = 1 |
== |
Equal T |
~~var1~~ == ~~var2~~ |
8 == 3 = 0 |
!= |
Not Equal To |
~~var1~~ != ~~var2~~ |
8 != 3 = 1 |
Symbols on the Logical menu are shown in the figure below.
Logical Symbols Menu
The symbols '&&' and '||' use the following format:
parameter symbol parameter
And the symbol '!' uses the following format:
symbol parameter
where parameter is a local variable, an OPC tag, a constant, or another expression for the symbol && or || or !. The result of the expression is the Boolean value (0 or 1). Refer to the table below for some examples of logical expression.
Logical Expression Examples
Symbol |
Description |
Example |
Result |
IF THEN ELSE |
Conditional Branch |
|
|
IFQ THEN ELSE |
Conditional Branch (Strict Quality) |
|
|
|
|
||
&& |
And |
~~var1~~ && ~~var2~~ |
8 && 3 = 1 |
|| |
Or |
~~var1~~ || ~~var2~~ |
8 || 3 = 1 |
/| |
Or (Strict Quality) |
|
|
! |
Not |
!~~var1~~ |
!8 = 0 |
true |
Boolean Constant True |
|
|
false |
Boolean Constant False |
|
|
Symbols on the Bitwise menu are shown in the figure below.
Bitwise Menu
Note. Bitwise operations in the Expression Editor process only positive numbers from 0 to 4,294,967,295, or 00000000 to FFFFFFFF. |
The symbols '&', '|', and '^' of the bitwise group use the following format:
parameter symbol parameter
where parameter is a local variable, an OPC tag, a constant, or another expression.
The symbol '~' of the logical group uses the following format:
~ parameter
The symbols ' shl' and ' shr' of the bitwise group use the following format:
symbol (number, shift by)
Where number must be a local variable, an OPC tag, a constant, or another expression; and shift by sets the number of bits to shift.
The symbol ' bittest' of the bitwise group uses the following format:
BitTest (number, bit position)
Where number is a local variable, an OPC tag, a constant, or another expression; and bit position sets is the position of the bit to test. A bit position of "0" indicates the "less significant" bit.
Note. The BitTest() function in the Expression Editor evaluates only positive numbers from 0 to 2,147,483,648 or in hex from 00000000 to 7FFFFFFF. Negative numbers between -2,147,483,647 and 0 will be converted to the corresponding positive numbers prior to testing. Numbers above the outside ranges will give you unexpected results.
|
Symbol |
Description |
Example |
Result |
& |
And |
~~var1~~ & ~~var2~~ |
8 & 3 = 0 |
| |
Or |
~~var1~~ | ~~var2~~ |
8 | 3 = 11 |
~ |
Not |
~(~~var1~~) |
!8 = -9 |
^ |
Xor |
~~var1~~ ^ ~~var2~~ |
8 ^ 3 = 11 |
shl(number, shiftBy) |
Shift Left |
shl(~~var1~~,3) |
8 << 3 = 64 |
shr(number, shiftBy) |
Shift Right |
shr(~~var1~~,3) |
8 >> 3 = 1 |
bittest(number, bitIndex) |
Bit Test |
(5 , 0) |
1 |
setbit(number, bitIndex, bitValue) |
Set Bit |
|
|
togglebit(number, bitIndex) |
Toggle Bit |
||
0x |
Hexadecimal Constant |
|
|
0t |
Octal Constant |
|
|
0b |
Binary Constant |
|
|
The following two examples use the variables ~~var1~~ and ~~var2~~ in several expressions that use bitwise symbols.
In Example 1, the decimal values for these variables are:
~~var1~~ = 8
~~var2~~ = 10
In Example 2, the decimal values for these variables are:
~~var1~~ = 96
~~var2~~ = 8
Note. The binary values are also listed in the tables below. The representation chosen is 16 bits per variable. |
Symbols on the Code Blocks menu are shown in the figure below.
Code Blocks Menu
As new functionality has been added to the expression engine over the years, expressions have grown more and more complex, difficult to read, and difficult to maintain. To help simplify complex expressions, users can now optionally use Code Blocks, which provide looping functionality and fast access to internal variables.
DECLARE
Optional internal variable declaration section
(example: @myvariable; @mysecondVariable = 10;)
BEGIN
Code section with code lines...
END
Each code block returns a single value. Code blocks can be used by themselves or in line with standard expression editor functions.
Inside the code section of a code block, users can utilize new commands, such as SET, FOR, FOREACH and EXIT.
Click HERE for more info on Code Blocks and Looping.
Symbols on the Functions menu are shown in the figure below.
Note. If you are creating calculated tags in Hyper Historian, also refer to the functions described in the Performance Calculation Functions topic in Hyper Historian. |
The Functions Menu
Symbol |
Description |
quality(value) |
Quality of Value |
setvalue(variable, value) |
Assign a Value to a Variable |
tostring(value) |
Convert to String (Invariant Culture) |
tostringculture(value) |
Convert to String (Current Culture) |
toformat(value, stringFormat) |
Convert to Formatted String (Invariant Culture) |
toformatculture(value, stringFormat) |
Converted to Formatted String (Current Culture) |
tonumber(value) |
Convert to Number (Invariant Culture) |
tonumberculture(value) |
Convert to Number (Current Culture) |
tonumberbase(value, base) |
Convert to Number from Base |
toboolean(value) |
Convert to Boolean (Invariant Culture) |
tobooleanculture(value) |
Convert to Boolean (Current Culture) |
asciitochar(number) |
Convert Ascii Value(s) to Character(s) |
asciitowchar(number) |
Convert Unicode Value(s) to Character(s) |
chartoascii(string) |
Convert Character(s) to Ascii Value(s) |
wchartoascii(string) |
Convert Character(s) to Unicode Value(s) |
|
|
|
|
|
|
|
String Functions
Symbol |
Description |
tringSource, stringMatchPattern, booleanCaseSensitive) |
Wildcard String Compare |
len(string) |
String Length |
getat(string, index) |
Get Character at Index |
substring(string, startIndex, length) |
Extract Substring |
left(string, length) |
Left Substring |
right(string, length) |
Right Substring |
concat(string1, string2) |
Concatenate Strings |
indexof(stringToSearch, stringToFind, startIndex) |
String Search. Note: as of 10.95.4, the indexof() function was modified to make the "startIndex" parameter (the third parameter) optional, and to add a fourth optional parameter for "count". This keeps indexof() consistent with the new functions but will not affect pre-existing projects. |
Lastindexof |
Returns the zero-based index of the last occurrence of a substring within a string or returns the zero-based index of the last occurrence of an item in an array. |
Indexofany |
Returns the zero-based index of the first occurrence within a string of any character from a specific set of characters. |
Lastindexofany |
Returns the zero-based index of the last occurrence within a string of any character from a specific set of characters. |
replace(sourceString, stringFindWhat, stringReplaceWith) |
String Replace |
trim(stringToTrim,charactersToRemove) |
Trim Left and Right |
trimleft(stringToTrim, charactersToRemove) |
Trim Left |
trimright(stringToTrim, charactersToRemove) |
Trim Right |
tolower(string) |
To Lowercase |
toupper(string) |
To Uppercase |
null |
Null Value Constant |
/*comment*/ |
Comment |
Array Functions
Symbol |
Description |
isarray(value) |
Is Array Value |
array(value1, ..., valueN) |
Create Array |
Creates an Empty Array with the Specified Length |
|
typedarray(elementType, value1, ..., valueN) |
Create Typed Array |
Create an Array with the Specified Length Where All Elements are of the Specified Datatype |
|
qarray(excludeBad, excludeUncertain, value1, ..., valueN) |
Create Array with Quality Options |
qtypedarray(excludeBad, excludeUncertain, elementType, value1, ..., valueN) |
Create Typed Array with Quality Options |
len(array) |
Array Length |
Modify the Number of Elements Stored in the Array |
|
getat(array, index) |
Get Value at Array Index |
Set the Value at the Specific Index (Zero-based) |
|
indexof(arrayToSearch, valueToFind, optionalStartIndex, optionalCount) |
Array Item Search |
lastindexof(arrayToSearch, valueToFind, optionalStartIndex, optionalCount) |
Reverse Array Item Search |
min(array) |
Minimum |
max(array) |
Maximum |
sum(array) |
Sum |
avg(array) |
Average |
stddev(array) |
Standard deviation |
stddev(array) |
Standard deviation2 |
variance(array) |
Variance |
variance2(array) |
Variance2 |
median(array) |
Median |
range(array) |
Range |
Time Span Functions
Symbol |
Description |
totimespan(value) |
Convert to TimeSpan (Invariant Culture) |
totimespanculture(value) |
Convert to TimeSpan (Current Culture) |
frommilliseconds(number) |
TimeSpan from Milliseconds |
fromseconds(number) |
TimeSpan from Seconds |
fromminutes(number) |
TimeSpan from Minutes |
fromhours(number) |
TimeSpan from Hours |
fromdays(number) |
TimeSpan from Days |
totalmilliseconds(timespan) |
Total Milliseconds from TimeSpan |
totalseconds(timespan) |
Total Seconds from TimeSpan |
totalminutes(timespan) |
Total Minutes from TimeSpan |
totalhours(timespan) |
Total Hours from TimeSpan |
totaldays(timespan) |
Total Days from TimeSpan |
timesincelastchange(variable, valueDelta, refreshRateTimeSpan) |
Elapsed Time Since Value Changed |
trueforduration(booleanCondition, timespanDuration) |
True for Duration |
Date and Time Functions
Symbol |
Description |
todatetime(value) |
Convert to DateTime (Invariant Culture) |
todatetimeculture(value) |
Convert to DateTime (Current Culture) |
tolocal(dateTime) |
Convert to Local Time |
toutc(dateTime) |
Convert to UTC Time |
gettimeofday(datetime) |
Get Time of Day from DateTime |
getdate(datetime) |
Get Date from DateTime |
millisecond(dateTime) |
Millisecond Fragment |
second(dateTime) |
Second Fragment |
minute(dateTime) |
Minute Fragment |
hour(dateTime) |
Hour Fragment |
weekday(dateTime) |
Day of Week |
day(dateTime) |
Day of Month |
yearday(dateTime) |
Day of Year |
month(dateTime) |
Month Fragment |
year(dateTime) |
Year Fragment |
dayseconds(dateTime) |
Day Total Seconds |
now() |
Get Current Local Date and Time |
utcnow() |
Get Current UTC Date and Time |
currentdatetime(refreshRateTimeSpan) |
Periodically Get Current Date and Time |
currentdatetimeutc(refreshRateTimeSpan) |
Periodically Get Current UTC Date and Time |
today() |
Today |
yday() |
Yesterday |
mintime() |
Minimum Time |
maxtime() |
Maximum Time |
noon(dateTime) |
Noon Time |
bday(dateTime) |
Beginning of Day |
bweek(dateTime) |
Beginning of Week |
bmonth(dateTime) |
Beginning of Month |
byear(dateTime) |
Beginning of Year |
eweek(dateTime) |
End of Week |
emonth(dateTime) |
End of Month |
eyear(dateTime) |
End of Year |
See Also:
Expressions in the Data Browser