Expressions

An expression is simply the right-hand side of an assignment to the attribute it is attached to. It can be as simple as an assignment of an Input, Instance, Complex Data Element, or as complex as a computation on one or more Inputs, Instance Attributes or Complex Data Elements. The expression forms the basis for conditioning data.

Expressions can be used for Instances, Custom Conditions, Flow Triggers, and other areas within the product. The syntax for an expression is basic JavaScript. The Intelligence Hub uses GraalVM to execute the JavaScript in expressions.

This section covers examples, as well as ways to create reusable functions and import 3rd party libraries.

Sample Expressions

Expression Description
{{Connection.OPC_Server.Room2BTSTAT_CV}} A simple assignment of the raw value associated with input Room2B_TSTAT_CV on connection OPC_Server.
{{SQL.QueryAssetInfo.AssetID}} A complex data element assignment. Some connectors (e.g., REST, Sparkplug, SQL) return complex data values that contain one or more element values. In this example, a SQL connection named SQL has an input called QueryAssetInfo that returns a result set for which the element AssetID value is assigned.
{{Connection.OPC_Server.LineAPartsProduced}} + {{Connection.OPC_Server.LineBPartsProduced}} Assigns the summation of two inputs named LineAPartsProduced and LineBPartsProduced on connection OPC_Server.
{{Connection.OPC_Server.ProductID}}.split("-") Assuming the raw value of ProductID is a string value that is always formatted as follows: AA-BBBBB-C-DDD. Assigns the substring BBBBB from input ProductID on connection OPC_Server.
Math.sin({{Connection.OPC_Server.DeviceSignal}}) Calculates the sine of the raw value associated with input Signal on connection OPC_Server and assigns the result.
{{Instance.ServerRoom_Thermostat}} A simple assignment of a modeled instance within a parent modeled instance definition.
{{Instance.ServerRoom_Thermostat}}.Current > {{ServerRoom_Thermostat}}.Max A logical expression that tests if the value associated with attribute Current of instance ServerRoom_Thermostat is greater than the value associated with attribute Max of the same named instance.
var data = [1,2,{{Connection.opc.tag}}]; data Build an array from a primitive tag
{{Connection.opc.arraytag}}.slice(0,2) Return a part of an array.
javascript
// Build a complex value (JSON) from primitives
var value = {
	"employees": {
		"name": "steve",
		"value": {{Connection.opc.tag}}
    }
};
value
javascript
// Iterate an array of complex data (CSV in this example) and return the row that meets a given condition. 
var retRow = ({{Connection.csv.data}}).forEach(function (item, index) {                                 
	if(parseInt(item["07A7"]) === 916){                       
		retRow = item;                                                    
	}
};
retRow

Functions

In some cases, there are snippets of JavaScript code that get reused in many expressions across many Instances. This can be code that checks for a certain set of values or performs other logic. Functions are a way to write these once, and reuse them anywhere in the product that supports JavaScript, including expressions, triggers, and conditions.

To access Functions, navigate to Functions in the configuration’s Main Menu. Enter the JavaScript in the Code section. Functions can be tested by selecting Run. This executes the JavaScript in the browser and outputs the results to the right of the Code panel.

Often to test a function, you must write some test code to call the function and log output results to the console. Keep in mind when saving these changes that functions are instantly available to all running Flows. Only Save once you have confirmed the functions work as expected.

Graphical user interface, text, application Description automatically generated

Expression Imports

The Intelligence Hub supports importing npm-compatible CommonJS modules and using them in expressions. For example, there may be a parsing library required to parse a custom formatted payload.

To use this feature 3rd-party modules must be installed within the expression-imports directory of the hub’s directories.appData directory. Use the npm install command from the expression-imports directory to install 3rd-party modules for use by the hub.

See Application Settings for more information about configuring the appData directory and enabling expression imports.

NOTE: CommonJS packages that rely on built-in Node.js core Modules or native NPM modules are not supported.

Metadata in Expressions

All values in expressions have meta-data, which includes quality, timestamp, name and other values. To access this meta-data in an expression, use the following syntax:

javascript
hub.withMetadata.{{Connection.opc.tag}}

This expands the value to include the meta data, and allows you to index the metadata in the expression. Here is an example:

json
{
	"alias": "",
	"model": "myModel",
	"name": "myInstance",
	"quality": "Good",
	"timestamp": "2022-07-14T12:23:04.682Z",
	"type": "myModel",
	"value": {
		"temp": 123,
		"pressure": 456
	}
}

For complex types passed to an expression (ex. Instances, SQL input, OPC UA Branch reads, etc) the following additional metadata is available in the expression.

Metadata Description
#model In the case of an Instance, this is the Model name. For inputs and other sources, it’s empty.
#name In the case of an Instance, this is the Instance name. For inputs and other sources, it’s the source name.

Below is an example of how to get and set these values. These values appear by default in the output payload as _model and _name attributes.

json
// Get the values
var instanceName = {{Instance.myInstance}}["#name"]
var modelName = {{Instance.myInstance}}["#model"]

// Set the values. Changes the values of the default _name and _model output attributes
{{Instance.myInstance}}["#name"] = "changeName"
{{Instance.myInstance}}["#model"] = "changeModel"

// Change the values in a child object
{{Instance.myInstance}}.childInstance["#name"] = "changeName"
{{Instance.myInstance}}.childInstance["#model"] = "changeModel"