Expression Editor

The expression editor assists you in creating local and global expressions for your GENESIS64™ applications.

 

The Expression Editor opens whenever you see the tag icon showing the expression editor button options. ClosedView image

Each button in the Expression Editor displays a list of available functions. For example, the Variables button displays a list of defined inputs you can use in an expression. Variables require curly brackets within the syntax of the expression. For example: {{DataSource}} >= {{HiValue}}. With this editor, you can build an expression and then use the check syntax button (bottom left) to check your expression syntax, but it does not check whether the expression is correctly applied.

 

The Data Browser has an Expression tab, also giving you access to the expression editor. The Data Browser Expression keeps track of the last 50 expressions you have entered. ClosedView image

 

In the Data Browser, the expression you create is a local one, suited solely for a local purpose. For information about the differences between local and global expressions, see Expressions in the Data Browser.

Writing Expressions

An expression is a string that defines and evaluates data connectivity 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 curly brackets {{ 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 is substituted when the expression is in use.

 

When writing expressions, you can type your expressions directly into the edit expression dialog box, including string expressions, string comparison, data type conversion and point extension syntax. The expression editor provides buttons to assist you in writing expressions using the proper syntax. For example, click the Logical button to show available selections. Hover over a function to display descriptive tooltips. ClosedView image

See the details for each expression editor button function:

 

Strings in Expressions: Strings examples:

  • “Hello World” is a constant string delimited with double quotation marks.
  • $”Hello World”$ is a constant strings enclosed between $” and “$ characters.

 

String Comparison: When comparing strings or numeric data coming from the server as strings, the comparison is based on the character order. 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. 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.

 

Data Type Conversion: Expressions allow calculations on incoming data. An OPC server can provide data in one or more data types, such as "float," "long," "integer," or "string." Some OPC servers provide numeric data as a string. For example, the numeric value 20 may be presented as the string “20” (character "2" followed by character "0"), leading an incorrect expression evaluation (see the String Comparison section above).

 

The workaround is to add a numerical zero to each of the tags to enable the logic operators to 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 numeric type parameters. When possible, the expression editor automatically converts the string into a number. For example, the string “20” is automatically converted to the number 20. However, the automatic conversion is impossible if the string contains alphabetic characters or symbols. 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 where 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 string is not convertible into a number, resulting in a bad quality. The following is an example of a valid expression: x=5+”6”

 

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:
    • Prefix your tag name with “tag:”
    • Postfix your tag name with “#” followed by a PES token.

    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

    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.

Arithmetic Expressions

The symbols +,-, *, /and % use the parameter symbol parameter format. 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.

Symbol

Description

Example

Result

+

Addition - adds one value to another

~~var1~~ + ~~var2~~

8 + 3 = 11

 -

Subtraction - subratcts one value from another

 ~~var1~~ - ~~var2~~

8 - 3 = 5

*

Multiplication - multiplies one value by another

 ~~var1~~ * ~~var2~~

8 * 3 = 24

 /

Division - divides one value by another

 ~~var1~~ / ~~var2~~

8/3 = 2.6667

%

Modulus - calculates the remainder after division

 ~~var1~~ % ~~var2~~

8 % 3 = 2

(

Open Parenthesis - designates the start of a group of operations and gives precedence to parts of the calcualtion

 

 

 )

Close Parenthesis - designates the end of a group of operations and gives precedence to parts of the calculation

~~var1~~ /(~~var2~~ + ~~var3~~)

8 / (3 + 2) = 1.6

sin(angleInRadians)

Sine -returns the sine of a specified angel where parameter 1 is angle in radians.

 

 

cos(angleInRadians)

Cosine - returns the cosine of a specified angel where parameter 1 is angle in radians.

 

 

tan(angleinRadians)

Tangent - returns the tangent of a specified angel where parameter 1 is angle in radians.

 

 

asin(number)

Arcsine - returns the angle where the sine is the specified number.

 

 

acos(number)

Arccosine - returns the angle where the cosine is the specified number.

  

atan(number)

Arctangent - returns the angle where the tangent is the specified number.

  

sqrt(number)

Square Root - returns the square root of a specified number.

  

pow(base, exponent)

Raise to Power - returns a number raised to the power.

  

log(number)

Logarithm - returns the base 10 logarithm of a specified number.

  

ln(number)

Natural Logarithm - returns the natural (base e) logarithm of a specified number.

  

exp(number)

Exponential - returns e (natural logarithmic base constant) raised to the specified power.

  

abs(number)

Absolute Value - returns the absolute value of a specified number.

  

ceil(number)

Integer Ceiling - returns the smallest whole number that is greater than or equal to the specified number.

  

floor(number)

Integer Floor - returns the largest whole number that is less than or equal to the specified number.

  

round(number)

Integer Round- the value is rounded to the nearest integer.

  

round to(number, decimalPlaces)

Round to Decimal Places - the value is rounded to nearest integer.

  

min(number1, ..., numberN)

Minimum - returns the smallest value of two or more numbers.

  

max(number1, ..., numberN)

Maximum - returns the largest value of two or more numbers.

  

sum(number1, ..., numberN)

Sum - returns the total value of of two or more numbers.

  

avg(number1, ...numberN)

Average - returns the average value of of two or more numbers.

  

isnan(number)

Is Not a Number - returns true if the specified value is a floating point representation of not-a-number in arithmetic operations, such as zero-divided by-zero.

  

isinfinity(number)

Is Infinity - returns true if the specified value is a floating point representation of infinity, such as dividing a non-zero number by zero.

  

pi

Circumference / Diameter Constant - the ratio of the circumference of a circle to it's diameter.

  

e

Natural Logarithmic Base Constant - represents the natural logarithmic base

  

Back to top

Relational Expression

The symbols<, >, <=, >=, == and != use the parameter symbol parameter format. 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 are examples of relational expressions.

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

The symbols && and || use the parameter symbol parameter format. 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 are examples of relational expressions.

Symbol

Description

Example

Result

IF THEN ELSE

Conditional Branch

 

 

IFQ THEN ELSE

Conditional Branch (Strict Quality)

 

 

CASE WHEN THEN

See 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

The Bitwise symbols &, |, and ^ use use the parameter symbol parameter format. Where parameter is local variable, an OPC tag, a constant, or another expression. Other Bitwise symbols are:

  • Symbol ~ uses ~ parameter
  • Symbols shl uses (number, shiftBy), where number must be a local variable, an OPC tag, a constant, or another expression and shiftBy sets the number of bits to shift left by the specified number of positions.\
  • Symbol for Bit Test bittest function uses bittest(number, bitIndex). Where number is a local variable, an OPC tag, a constant, or another expression; and bitIndex sets is the position of the bit to test. A bit position of 0 indicates the less significant bit.

    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.

The following table uses two examples of variables ~~var1~~ and ~~var2~~ in expressions using the bitwise symbols.

  • In Example 1, the decimal values for these variables are:

    ~~var1~~ = 8

    ~~var2~~ = 10
  • Example 2, the decimal values for these variables are:

    ~~var1~~ = 96

    ~~var2~~ = 8

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

 

 

 

Back to top

Code Blocks

Users can optionally use Code Blocks to help simplify complex expressions. Each code block returns a single value. Code blocks can be used by themselves or in line with standard expression editor functions. Code blocks can provide looping functionality and fast access to internal variables. See Code Blocks and Looping.

 

Back to top

Functions Expression

SymbolDescription

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

SymbolDescription

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

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 Data type

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

stddev2(array)

Standard deviation 2

variance(array)

Variance

variance2(array)

Variance 2

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

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 is converted

   to local

 

For the toutc function:

Kind

Result

   Local

 Converted to UTC

   UTC

 No conversion

   Unspecified

Assumed local is 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