Expression Editor

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.

Writing 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:

Strings in Expressions

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”$

 

Back to top

String Comparison

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.

 

Back to top

Data Type Conversion

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”

 

Back to top

Point Extension Syntax

The Point Extension Syntax (PES) allows for retrieving additional information related to OPC tags, such as quality and timestamp.

 

To use the PES:

  1. Prefix your tag name with “tag:”

  2. Postfix your tag name with “#” followed by a PES token.

Valid PES tokens are:

The following are example expressions using a valid PES request:

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.

 

Back to top

Arithmetic Expressions

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

   

 

Back to top

Relational Expression

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

 

Back to top

Logical Expressions

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)

 

 

 

    CASE WHEN THEN

 

    Switch Statement

 

 

 

    &&

 

    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

 

 

 

Back to top

Bitwise Expressions

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.

 

Back to top

Code Blocks

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.

 

Back to top

Functions Expression

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

 

    Array Functions

 

 

    Time Span Functions

 

 

    Date and Time Functions

 

 

String Functions

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

Array Functions

 

Symbol

Description

    isarray(value)

    Is Array Value

    array(value1, ..., valueN)

    Create Array

    createarray(length)

    Creates an Empty Array with the Specified Length

    typedarray(elementType, value1, ..., valueN)

    Create Typed Array

    createtypedarray(elementType, length)

    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

    setlen(array, length)

    Modify the Number of Elements Stored in the Array

    getat(array, index)

    Get Value at Array Index

    setat(array, index, value)

    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

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

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

 

Time conversion functions are implemented by forwarding the calls to the .NET equivalents. In .NET a DateTime object can be of 3 possible kinds (determined by the Kind property):

Conversions may have different results depending on the Kind property.

For example, this is the conversion table for tolocal based on the Kind property:

 

 

Kind

Result

   Local

   No conversion

   Utc

   Converted to local time

   Unspecified

   Assumed Utc, converted

   to local

 

For the toutc function:

 

Kind

Result

   Local

   Converted to Utc

   Utc

   No conversion

   Unspecified

   Assumed local, converted

   to Utc

 

 

As you can see the Kind.Unspecified has 2 opposite behaviors depending on the function you are calling. Even converting from string to datetime can give you different kinds. Consider:

 

tolocal(todatetime("2022-03-29T15:00:00")) à returns 17:00 because the conversion from string returns 15:00 with Kind.Unspecified (assumed UTC)

tolocal(todatetime("2022-03-29T15:00:00Z")) à returns 17:00 because the conversion from string returns 15 with Kind.Utc (UTC)

tolocal(todatetime("2022-03-29T15:00:00+02")) à returns 15:00 because the conversion from string returns 15:00 with Kind.Local (local, so no conversion)

 

Back to top

 

See Also:

Rules/Expression Editor

Expressions in the Data Browser

Global Expressions

Switch Statement

Code Blocks and Looping