Expressions
Expressions are a type of value supported in several different parts of an adapter script. Expressions allow a value to be calculated as a kind of mathematical or logical formula using other identifiers. Identifiers are variables or data sources defined in the script.
Variables come from the variables section of a config. A variable is a named list of operations applied to other variables or data sources.
Data sources are defined in other sections specific to a particular connectivity type. Some examples of data sources would be:
- Pins for Labjack U3/T4/T7 integrations
- Registers and coils for Modbus-TCP integrations
- Tags for Ethernet/IP and OPC-UA integrations
- Declared keys for MTConnect and MTConnect Adapter integrations
Some expressions used within variable definitions also support the special "this" identifier. The this
identifier
represents the result of the previous step in the variable's operation list.
Here are a few example expressions:
Convert a temperature from C to F
(temp-in * 9 / 5) + 32
Check if either is running
spindle-1 or spindle-2
Check if a pin is in a specific range
AIN0 > 1.2 and AIN0 < 3.4
Check if an execution key is set to STOPPED
exec == 'STOPPED'
Cause a counter to reset after counting up to 10
this >= 10
Property Access
Certain data sources may produce objects or arrays instead of scalar
values. Most transforms that expect expressions can access properties in the form of this.propertyname
.
For example:
this.temperature * 9 / 5 + 32
If a data source provides items that are already a compound object, it's possible to index into those directly, even at multiple levels. For example:
oil.temperature * 9 / 5 + 32
If a property's name includes spaces or other characters that would make it illegal as an identifier, a square bracket syntax can be used to index into objects instead. For example:
system['X.01'].message
Update Triggers
Variables and data sources are treated the same way in an expression. When any variable or data source referenced within an expression updates, the entire expression is immediately re-computed. This will cause cascading updates to occur where the expression is used.
For example, if an expression is used in the middle of a variable definition, an expression update will cause the entire variable's operation list to be re-executed with the last data it received. If this causes the variable's value to change, then any other expression that references the variable will be re-computed as well. Avoid creating circular update loops via expressions.
Expressions can also appear in data item and condition definitions, which are responsible for outputting data to the MachineMetrics cloud. If an expression update changes the value of the data item or condition, the update will immediately be sent out.
Operators
Expressions support the following operators:
- Arithmetic: +, -, *, /, % (modulus), ^ (power)
- Boolean: and, or, not
- Bitwise: &, |, ~, ^|, <<, >>, >>>
- Relational: >, <, >=, <=, ==, !=
- Conditional expression: (statement) ? (yes) : (no)
Expressions support grouping statements with parentheses. Parentheses can be nested arbitrarily deep and are useful for more complex logic or forcing order of operations.
Examples:
(temp-in * 9 / 5) + 32
AIN0 > 1.2 and AIN0 < 3.4
hv-relay-on ? hv-analog : (lv-analog * 10)
Functions
While many capabilities within adapter scripts are supported through chaining operations, some functions are also available within expressions. Expression functions are available anywhere expressions can be used.
Functions are invoked by placing an opening and closing parentheses immediately after the function name, with any parameters placed within the parentheses as a comma-separated list. A nested function call can be used within the parameter list.
Examples:
AIN0 + abs(AIN1)
round(abs(spindle-speed), 2)