Expression

Expression represents a result of executing a JavaScript function specified in code. Expressions are organized in a hierarchy that forms the structure of OPC UA items, where the folder is a group of expressions, and the variable is an expression. The execution of the expression code is made manually (via the OPC UA variable), periodically or on tag changning, depending on the set of triggers. In the general case, expressions must have correct syntax, contain the keyword return and return the result that can be presented in the format of the returned data type, for example:

return Math.sin(Math.PI / 2);

or

if (context.data['tag_flag'].state.value == true)
	return FahrenheitToCelsius(context.data['tag_temperature'].state.value);
else return context.data['tag_temperature'].state.value;

For each expression, a global object context is defined, which can be used to access context-dependent properties and methods, i.e., during the execution of an expression, the context object is filled with the data of the expression currently being executed. For example, the following code is given for all expressions:

if (context.expression.id == 'MyExpression')
  return 111;
else if (context.expression.id == 'NotMineExpression')
  return 999;
else return 0;

In this case, MyExpression will return 111, NotMineExpression will return 999, and all others will return 0. The above mentioned script can be declared in modules as a function, which will be an example of code reuse. Then, the expression will return a function as a result.

Module1 code:

function getResult() {
if (context.expression.id == 'MyExpression')
  return 111;
else if (context.expression.id == 'NotMineExpression')
  return 999;
else return 0;
}

Expressions code:

return getResult();

Transformation of expression script into binary code involves several steps:

  • Syntax check of the expression code

  • Linking the imported modules (whose code also passes syntax check)

  • Building the expression (converting the resulting code into binary code)

Note that the procedure of binary code creation may lead to memory shortage. For example, there are several thousand expressions defined on the server and they all use the same 10 KB module. In this case, the module code will be linked to each expression, so the module code will be copied into RAM as many times as the number of expressions defined on the server. Let's assume that the module code was erroneously changed and the module size increased to 500 KB. In this case, an avalanche-like increase in RAM consumption will occur (~ 50 times), which may cause the server to crash. To eliminate such problems, the server can be run in safe mode.

All expressions are executed in an isolated context, i.e. variables and objects defined in the code are not shared, a special mechanism is provided for data transfer between expressions.

Last updated