Skip to main content

Language reference

This reference discusses the structure of the formula set.

Structure of the formula set

A formula set consists of a list of terms connected and terminated by ; characters, as well as optional comments and control constructs.

Control construct
Term 1; // optional comment
Term 2;
Term 3; /* description */

Terms

A term is

  • a constant Boolean or numeric value or a string
    Examples: false, 14, -23.5, "Hello"

  • a variable name
    Examples: Speed, $"GPS.Location"

  • a term grouped by a parentheses operator
    Examples: (Term + Term) * Term, [Term, Term, Term],

  • A term modified by a unary operator
    Examples: ! Term, - Term, ~ Term

  • a pair of terms linked by an operator
    Examples: Term = Term, Term + Term, Term ? Term : Term

  • a list of terms linked by ,-operators
    Term, Term, Term, ...

  • a function call
    function(...)

  • A configuration object delimited by {...}.
    The configuration object follows its own syntax, e.g., simplified JSON encoding.

Terms, operators, and functions are processed exclusively according to the temporal availability of data; the order in which they are written does not affect the calculation.

Comments

As in the programming languages C and C++, comments either begin with // and then end automatically at the end of the line, or they begin with /* and end with */ . The notation /* ... */ can be nested like a parenthetical expression.

// The comment begins "-no string here and [-no matrix here

s1 = "this is a text"; // comment starts here
s2 = "continues here";

// Helpful marking for complex data structures
Tensor = [ /* Slice 1: */ [ [111, 112]
, [121, 122] ]
, /* Slice 2: */ [ [211, 212]
, [221, 222] ]
, /* Slice 3: */ [ [311, 312]
, [321, 322] ] ];

/* This section is only for commissioning.
T1 = 12.34 * Tensor;
*/

The character string // is ignored if it appears in a string marked with "..." or '...' or within a /* ... */ comment. In the example, the assignments to a and e are not interpreted, but the assignment to z is.

/* // is ignored in the block comment */
s1 = "This is // text and neither a comment nor a formula: 1+1";
/*
a = b + c;
e = f * g;
// */ z = b / g;

The comment start and end markers /*...*/ are ignored if they are written after a "visible" //. In the example, the comment block itself is now commented out, the assignments to a and e are executed, but the assignment to z is no longer executed.

// /* and */ are ignored in line comments.
// /*
a = b + c;
e = f * g;
// */ z = b / g;
note

If a block comment /*...*/ that has been started is not closed, this is displayed as an error.

Control constructs

Control constructs begin at the start of the line with a # character and run until the next line end that is not hidden in a brace level. The structure of a control construct follows a defined syntax depending on its function. Comments can be inserted.

#controlA <parameter>
#controlB <name>[<parameter>](<parameter>){<code>}
#controlC <key>, <key>=<value>, …

Control constructs can be used to influence the functions of the Math Module Compiler, the processing of variables, and the execution of the code.

A control construct can thus have an effect on the terms noted below.

The control constructs are listed in this document.

Implementing the desired functionality

Toolbox

Functions and operators in the following categories are available for implementing the desired functionality:

  • Arithmetic-logical operators
  • Mathematical-trigonometric functions
  • Temporal filter functions (such as differentiation and integration of functions)
  • Numerical algorithms (e.g., FFT, matrix decomposition, interpolation, prediction)
  • Sampling of measurement data
  • Counting functions and timers
  • Selection functions, bit-oriented functions, and functions for converting data types (casts)
  • Support for sequences of expressions and assignments
  • Text (string) functions

As the Math Module continues to be developed, new functions are constantly being added and, of course, errors in existing functions are being corrected. Depending on the smartCORE version rolled out, a specific version is available. This is also displayed in the log file in the form of a sequential catalog number, in the example V11:

...|...|...|INFO   |module.math:  (II)  "Welcome to mathExpression library, git '0ed7f17-dirty', build 'Feb  2 2026 15:30:55'"
...|...|...|INFO |module.math: (II) "Package 'mathExpCore', V11 (using V11)"

Conditional execution, loops

Due to the continuous processing of streaming, time-stamped data, each term can be understood as an electrical component or filter in an electrical circuit. This makes the implementation of classic control constructs that influence the flow of the formula text meaningless. Therefore, the following language elements or their variants are not found in the calculation module:

  • IF-THEN-ELSE
  • WHILE-DO
  • REPEAT-UNTIL
  • FOR-TO-DO, FOR-EACH
  • SWITCH-CASE

However, there are various functions that can be used, for example, to select from different signal sources. This would correspond to a relay or multiplexer in circuit technology.

Other functions allow values to be stored at a specific point in time or changes in values or edges to be detected.

For similar reasons, there is currently no implementation for user-defined procedures or functions.

Time-correct calculation

All terms, operators, and functions always process and produce time-stamped data, which is typical for smartCORE. This data is calculated with time correctness, whereby an output value is usually calculated for each input timestamp of the data streams involved in a term. The signal curve between two timestamps is assumed to be constant (0th order hold element) with reference to the older value in the time interval, i.e., the older value applies until immediately before the timestamp of the younger value. Further processing of the data can therefore only take place if all input values involved in the term also have valid values at a given point in time. The valid time range for calculation ends for a data stream with its most recent timestamp. The following table shows an example of two timestamped data sources A and B and a calculation:

TimeABA + B
1(not defined)10(not defined)
2515
32025
53035
8838
1394049
26545
27242
30(pending)50(pending)

This means that for data that is rarely provided or, for example, is no longer delivered due to the shutdown of a system component, all dependent calculations are initially processed only up to this most recent timestamp and then blocked there. The Math module offers various options for defusing these blocking situations.

The parameter evaluationTimeMs only specifies the time interval in ms during which the interpreter processes all data points available at that time across all terms (batch processing). This involves a certain amount of "blind power." Therefore, the interval should be set at least long enough so that data can be processed in each cycle, but preferably also short enough so that the number of individual data points remains within a manageable range (approx. < 100). For example, if you only have data sources that deliver new values every 2 seconds, you could set evaluationTimeMs to 5000 ms. For data sources that deliver their data points at 1 kHz, an evaluationTimeMs of 100 ms is more appropriate. A shorter cycle time is also useful if the results of the formula set are to be used to perform control tasks in the process.

Due to the timely processing of the data, the order of the expressions in the formula set is ultimately irrelevant. However, for reasons of readability, it is recommended to only use variables that have been previously assigned.

Time-discrete calculation

Time-correct calculation cannot be implemented if variables are traced back to themselves with a circular reference. An example of such a construct is the implementation of a simple weighted filter algorithm:

y_out = weight * y_out + (1 - weight) * x_in;

According to the rule introduced above, y_out is recalculated for all points in time defined by the input data weight, y_out, and x_in. While weight and x_in are set independently as constants (and are therefore always valid) or are carried over from a measurement signal, y_out is not filled at all at first. What defines the first value for y_out? And if this is set with a timestamp, y_out can be calculated up to exactly this timestamp at most – i.e., not at all, because this point in time has already been assigned.

In control engineering and programming languages, however, the above expression is interpreted to mean that the "new" y_out value is derived from the "old" y_out according to the specification. The "new" y_out is then one sampling step in the future, so that the next calculation can be performed accordingly.

yout(t+Δt)=wyout(t)+(1w)x(t)y_{out}(t+\Delta t)=w \cdot y_{out}(t) + (1-w) \cdot x(t)

The Math module recognizes circular references (even indirect ones) and converts the affected variables to a discrete calculation rule. The variables now advance at a fixed time interval and grid determined by the parameter discreteSampleTimeMs. All discrete calculations are clocked to the grid.

To solve the question of the initial value, a special syntax is defined that is only executed once: the suffix @0 is appended to the variable when the start value is assigned:

y_out@0 = x_in;
y_out = weight * y_out + (1 - weight) * x_in;

In this example, the first available value on the input variable x_in is used as the start value at the immediately following grid point for y_out. From this moment on, the calculation and assignment of y_out runs at a fixed time interval.

warning

Sampling can cause rapid signal changes between two sampling points to be lost. catch(x, {...}) can be used to take critical, faster signal components from the interval into account.

Identifiers and variables

The following conventions apply to the names of variables (signals, channels)

  • The first character must be from the group a-z, A-Z, or _.
  • All subsequent characters must be from the group a-z, A-Z, 0-9, or _.
  • Upper and lower case letters are distinguished.
  • All characters not mentioned, such as umlauts, special characters, brackets, mathematical symbols, and spaces, are not permitted!

All identifiers are case-sensitive, i.e. "varIABLE", "Variable" and "VARiable" are three different identifiers.

It is possible to include data from existing smartCORE channels in the calculation by specifying the channel name. If this requires access to smartCORE channels whose names violate the previous rule, this can be done using the following notations

$'Some + strange.å =channel ů /name!'
$"Some + strange.å =channel ů /name!"

The same applies to channels that are to be returned to the smartCORE and require special naming.

caution

A variable may only be assigned in one place. Variables without a local assignment are searched for as data sources in the context of the smartCORE. This also applies to variables that represent secondary outputs of a function block and are defined with the properties.

Constants

The following identifiers are available as constants in the context of the formula text:

IdentifierValueType
truetrue<bool>
ontrue<bool>
yestrue<bool>
hightrue<bool>
falsefalse<bool>
offfalse<bool>
nofalse<bool>
lowfalse<bool>
pi3.14159265...3.14159265...<dbl>
magic4242<uint>
j(0,1)(0, 1)<cxFlt>

If there are variables in smartCORE with one of these names, the special notation for variables $'…' (see Identifiers) can ensure differentiation. Otherwise, the use of the identifier as a constant takes priority.

Data Types and Type Conversion

Data Types

The Math module selects a suitable data type for each calculation in order to perform the desired operations with the best possible representation. The types are listed below

Data typeNameDescriptionBit lengthMinimumMaximum
boolean<bool>Boolean value1false, no, off, lowtrue, on, yes, high
unsigned integer<uint>Unsigned integer64018446744073709551615
integer<int>Signed integer64-9223372036854775808+9223372036854775807
Smallest resolutionValue range
double<dbl>Double precision floating point number64±5.0E-324±1.7976931348623157E+308
complex float<cxFlt>Single precision complex floating point number (*)2x 32±1.175494E-38
per Re-/Im component
±3.402823E+38
per Re-/Im component
string<str>Text, UTF-8N/AN/AN/A

As a rule, you do not need to worry about the type; when transferred to the smartCORE, it is converted to the specified data type.

info

In this function description, the data type is usually enclosed in angle brackets, e.g., <bool> or <str>.

Automatic type conversion

When processing numeric data using binary operators, the following automatic type conversion takes place with reference to the types of the operators

booluintintdblcxFltstr
boolbooluintintdblcxFltstr
uintuintuintintdblcxFltstr
intintintintdblcxFltstr
dbldbldbldoudblledblcxFltstr
cxFltcxFltcxFltcxFltcxFltcxFltstr
strstrstrstrstrstrstr

This preserves

  • Boolean values remain true/false only
  • The properties of uint values for bit operations are retained
  • The sign is retained when using int values
  • The accuracy of floating point numbers is retained
  • The complex number range is available

Special features for bool

  • When converting to <bool>, the comparison to not equal to 0 is implicitly applied to obtain the truth value.

  • When converting <bool> to a numeric type, false becomes 0 and true becomes 1.

  • When adding two Boolean values, conversion to <uint> takes place.

  • When subtracting two Boolean values, the conversion to <int> is performed.

  • When calculating data fields of type <bool>, the result is always <int>.

Special features for uint

  • When subtracting two unsigned <uint> - <uint>, the result is <int> if the second operand is greater than the first. This avoids the usually completely nonsensical, unwanted overflow in sizes of 2^64.

  • When calculating data fields of type <uint>, the result is always <int>.

Manual type conversion

It is also possible to perform a manual type conversion using the following functions

FunctionDescription
bool(x)Conversion of argument x to bool
uint(x)Conversion of argument x to uint
int(x)Conversion of argument x to int
dbl(x)Conversion of argument x to double
str(x)Conversion of argument x to string

Numeric types

Numeric values can also be specified in different number systems directly in the formula text and the configuration objects for the properties of functions. Examples of notations are:

  aBool         = true;         // alt.: false, on, off, yes, no, high, low
anUnsignedInt = 42; // alt.: 42u
aHexUInt = 0x2A; // alt.: 2Ah
anOctUInt = 052; // alt.: 52o
aBinUInt = 0b10'1010; // alt.: 101010b
aSignedInt = -42;
aDouble = 3.14159; // alt.: 1.6022e–19, pi, !! decimal-point
aComplex = 2.7+1.0*j; // alt.: cx(2.7, 1.0)
Group separators

For unsigned (<uint>) or signed (<int>) integers, the individual digits can be divided into groups by inserting a single quotation mark '. This character does not affect the interpretation of the numerical value, but makes it easier to read. It must not appear at the beginning or end of a number.

aHexUInt      = FFe7'0815'337Eh;    // 0815 is not a string here!
aBinUInt = 0b1011'0110'1010;
aLargeInt = 1'000'000'000;
Sign and negation

Prepending a - operator creates the negative value for each number format (2's complement).

Prefixing the + operator is allowed, but has no function.

The ~ operator inverts the integer at the bit level of a <uint> (example: ~0b1010'0011'1100 -> 0b1111...1111'0101'1100'0011).

Hexadecimal number format

A number in the hexadecimal system (base 16) is represented either by prefixing it with 0x or 0X or by appending the letter h. The possible digits are 0 .. 9, a .. f or A .. F and the group separator.

note

A number specified in the hexadecimal system is always interpreted as unsigned, but can be negated using the - operator or inverted using the ~ operator.

Octal number format

A number in the octal system (base 8) is represented either by prefixing a 0 (zero) or by appending the letter o. The possible digits are 0 .. 7 and the group separator.

note

A number in the octal system is always interpreted as unsigned, but can be negated using the operator - or inverted using the operator ~.

Binary number format

A number in the binary system (base 2) is represented either by prefixing it with 0b or 0B or by appending the letter b. The possible digits are 0 .. 1 and the group separator.

note

A number specified in the binary system is always interpreted as unsigned, but can be negated using the - operator or inverted using the ~ operator.

Character strings (string literals)

Constant strings are enclosed in single ' or double " quotation marks. If a string itself contains a ' or ", this must be marked by preceding it with a \ escape character. Examples:

s1a = '17" (inch)';
s1b = "17\" (inch)";
s2a = "Did it work?";
s2b = 'Did\'t it work?';

In general, special characters in character strings that are used, for example, for regular expressions in text searches or in the interpretation or generation of serial device protocols can be represented by the following escape sequences:

CharacterASCII NameASCII ValueEscape Sequence
Newline (Linefeed)NL (LF)10\n
Horizontal tabHT9\t
Vertical tabVT11\v
BackspaceBS8\b
Carriage returnCR13\r
FormfeedFF12\f
AlertBEL7\a
EscapeESC27\e
Backslash\92\\
Question mark?63\?
Single quotation mark'39\'
Double quotation mark"34\"
Character from octal codeNNN = 000 .. 377
(octal digits)
\oNNN
\o{N...}
Character from decimal codeNNN = 000 .. 255
(decimal digits)
\dNNN
\d{N...}
Character from hex codeNN = 00 .. FF
(hex digits)
\xNN
\x{N...}
UTF character(s) from decimal codeUTF8-MultibyteNNNN = x0000 .. xFFFF
x00000000 .. x0010FFFF
\uNNNN
\UNNNNNNNN
\u{N...}

The characters are always encoded internally in UTF-8 (UTF-8 – Wikipedia).

Arithmetic and logical operators

This section discusses arithmetic-logical operators, including their precedence and associativity.

Associativity

We refer to an operator ° as left-associative if the following applies

a ° b ° c = (a ° b) ° c

and, correspondingly, as right-associative if the following applies

a ° b ° c = a ° (b ° c)

An operator * has a higher precedence (binding strength) than operator + if, regardless of the associativity of both operators, the following applies

a + b * c = a + (b * c)
tip

If the binding of terms is not immediately apparent, it is recommended to enforce the intended evaluation order by making generous use of (...) to enforce the intended evaluation order. Precedence is not always clear, especially with logical operators or comparison operators. For complex expressions, it is also recommended to use several consecutive lines and to align the terms appropriately for clarity.

res = A && (B || (C && D) || (E && (F || G)));    // Variant 1
opt = A && ( B // optional comment
|| (C && D) // optional comment
|| (E && ( F // optional comment
|| G) // optional comment
)
); // Variant 2

Operators

The following table lists the available operators, sorted in ascending order of precedence. All operators listed here work on the data types introduced above. Separate functions are available for bitwise logical operations.

OperatorAssignmentAssociativityDescriptionExampleResult type
;leftsequence of commands executed independently of timey = 7; x = 4void
,leftsequence of individual expressionsa = 4, b = 6, a + blike last expression
+=YESrightcompound assignment with respect to additiona += 17automatic
-=YESrightcompound assignment with respect to subtractiona -= bautomatic
*=YESrightCompound assignment with respect to multiplicationa *= bautomatic
/=YESrightCompound assignment with respect to divisiona *= bautomatic
%=YESrightCompound assignment with respect to modulob %= 4automatic
=YESrightAssignmenta = 23 * bas assigned expression
? :rightTernary operator if-else(a > 23) ? 12 : -50as resulting body
||leftLogical disjunction (OR)a || b<bool>
&&leftlogical conjunction (AND)a && b<bool>
^^leftlogical antivalence (XOR)a ^^ b<bool>
==leftequalitya == b<bool>
!=leftinequalitya != b<bool>
<leftless thana < b<bool>
<=leftless than or equal toa <= b<bool>
>leftgreater thana > b<bool>
>=leftgreater than or equal toa >= b<bool>
+leftadditiona + bautomatic
-leftsubtractiona - bautomatic
*leftmultiplicationa * bautomatic
/leftdivisiona / bautomatic
%leftModuloa % bautomatic
^rightExponentiationa ^ 0.333<dbl>
!rightLogical inversion (NOT)!(a && b)<bool>
~rightbitwise inversion~a<uint>
+rightpositive sign6 / +aautomatic
-rightnegative sign9 * -aautomatic

Assignment operators

important

A variable may only be assigned at exactly one point in the formula text. Variables without a local assignment are searched for as data sources in the context of smartCORE.

In the case of assignment operators, the left side must contain a variable (x, y, …), an element of a previously assigned matrix (V[2], M[0,2], …) or the initialization for a discretely sampled variable (k@0, …) must be on the left side, in which the result is stored. The result of the expression remains the assigned value. This also allows the sequencing of assignments or the use of an assignment within an expression.

Operators for data fields

When the operators +, -, *, and / are applied to data fields (vectors, matrices, tensors), the usual mathematical rules regarding the dimension of the operands and the resulting dimension of the result apply. The following rules apply:

  • For addition and subtraction, the data fields involved must have the same dimension. The operation is performed on the elements with the same indices.

  • A data field can be multiplied by any scalar: DF * s or s * DF. The operation is performed on each element.

  • A data field can only be divided by a scalar: DF / s The operation is performed for each element.

  • For multiplication, the first data field must have as many columns as the second data field has rows. The result contains as many rows as the first data field and as many columns as the second data field. Since vectors do not explicitly distinguish between row and column vectors here, the following rules apply:

    • The product of two vectors of equal length is always the scalar product.

    • For the vector product of 2- and 3-component vectors, use the function Cross(v1, v2).

    • The product of a vector and a matrix reads the vector as a row vector.

    • The product of a matrix and a vector reads the vector as a column vector.

Data field matching

Two data fields are equal if they match exactly in terms of data type, dimension, and all elements. Automatic type conversion does not take place before the comparison. Two data fields are unequal if they do not match the above definition.

Other comparisons are not available.

Braces

The following pairs of braces are also recognized in nested expressions. Each opening brace must be closed correctly in the correct order.

BracketMeaningExample
( ... )Bundling in evaluation order, grouping of function parameters(a+b)/2, max(a, b, 50)
[ ... ]Reserved for representation of vectors, matrices, and tensors and indexing of variables; indexing always counts from 0…(N-1),
for vectors: V[<idx>], row/column vectors are not distinguished
for matrices: M[<row>, <col>] 
for tensors: T[<slice>,<row>, <col>]
a = [1, 2, 3], b = [[1.1, 1.2], [2.1, 2.2]], a[1] + b[0,1]
{ ... }- Bracketing for JSON objects that can be used to parameterize function blocks.
Since these can become very extensive, it is recommended to use a link $ref: '<path>'  to refer to an external JSON resource that is collected in a separate container of the calculation module.
timer({ interval: 60 })
? ... :The expression between ? and : is implicitly enclosed in (...).

Functions

Functions for the Math module are provided by the plugin itself and, in the future, also by additional theme plugins for the Math module. They are generally implemented in C++.

Function call

Each function consists of a function name that follows the usual identifier syntax

  • the first character must be from the group a-z, A-Z, or _
  • all subsequent characters must be from the group a-z, A-Z, 0-9, or _
  • upper and lower case letters are distinguished

followed by a parameter list, which contains a comma-separated list of individual terms in ( ... ) .

When describing complex function blocks, the parameters of the function are also referred to as inputs and the return value of the function as output.

Function call as circuit symbol

Identifiers for namespaces can be prefixed to the function name with a '.'. Otherwise, identifiers for namespaces follow the same rules.

Examples of function calls

   f1  = functionNoParam();
f2 = functionOneParam(x);
f3a = functionOptionalParam(x,a);
f3b = functionOptionalParam(x,a,b);
f3c = functionOptionalParam(x,a,b,c);
f4 = functionWithConfig(x,y,z, {...});

The parameters are divided into mandatory and optional parameters (inputs), as well as a configuration object for the function properties as the last element. The meaning of the parameters can vary depending on the number of parameters used; this can be found in the description of the function.

To avoid redundancies and associated errors, placeholders ... are used in the description of the function. As a rule, all variants with optional parameters are listed, as well as an additional entry in which only the configuration object is described:

f1 = aFunction(x);
f2 = aFunction(x, y);
// Optional configuration for all variants
fx = aFunction(..., { property1: <type>
, property2: <type>
});

If the configuration object is mandatory in a variant, it is also listed directly in this variant as a placeholder.

f1 = bFunction(x, {...});    // Configuration mandatory
f2 = bFunction(x, y, z); // Configuration optional
// Configuration for all variants
fx = bFunction(..., { property1: <type>
, property2: <type>
});

Each use of a function in the formula text is represented by its own instance, in which, for example, states or aggregations can be stored from calculation cycle to calculation cycle. Examples of this are

  • Counters
  • Summators, integrators
  • Filters
  • Hysteresis
  • Logic elements with memory function
  • Functions with time reference

Functions are usually executed and generate an output value when valid values are available for all parameters and at least one parameter has a new timestamp. In addition, some functions are also executed when an (internal) time condition is met.

Certain functions, such as intergrate() or stopwatch(), mark their output data so that subsequent calculations can also be linearly interpolated between two specific data points. This improves the quality of the calculation, as it is known that a constant input signal will result in a linear output signal.

Functions can also place additional output values in the data stream independently of the timestamps of the parameter values or the processing cycle, e.g., if a signal must be reset when a timer expires or if the shape of the output signal is defined by the function itself. Examples of this are the functions posedge() and negedge(), which write a pulse with a duration of 1 nanosecond to the output data stream when an edge is detected.

Configuration of function properties

The behavior of certain functions can be set, optimized, or changed using properties. These properties are passed to the function in a configuration object {...} at the end of the parameter list.

The implemented syntax allows for some simplifications compared to the JSON standard, but also useful extensions, e.g., to clean up the JSON representation in the "math" property from too many \-escape sequences:

  • Property names or ENUM tags do not need to be enclosed in quotation marks.
  • The use of quotation marks "..." and '...' for string assignment is equivalent.
  • For integer values, all notations, such as 0x... or 0..., can be used for input.
  • As an alternative to specifying a numeric value, some properties also allow certain ENUM tags, e.g., to disable the corresponding function ('off'), or to set default values ('def', 'auto', ...).
  • Comments in both notations // ... and /* ... */ are permitted.

The following types are provided for properties:

TypeValuesExample
<bool>true, on, yes, 1
false, off, no, 0
edge: yes
<uint>Integer, positive values
also in 0x (hex) or 0 (octal) notation
range: 0x7F
<int>signed integer valuesmin: -10
<dbl>floating point numbers (decimal point!) also in exponential notation 1.35e-22delay: 13.45
<time>1Floating point numbers as time intervals in seconds, with an extension to optionally enter integer minutes, hours, or days.longPeriod: 9025.3
longPeriod: 2:30:25.3
<date>1Floating point numbers as absolute timestamp (UTC seconds since 01/01/1970), with an extension to optionally specify UTC date+timestamp in ISO format.tBegin: 1770204975.256
tBegin: 2026-02-04T11:36:15.256
<cxFlt>Complex floating point numberpole: (-5, 0.8)
<str>String / text, quotation marks only required if spaces, commas, or special characters are included.storage: 'total_km'
<var>Variant, can take all of the above typespreset: 0x2F
<enum>Specific enumerating tags, see function descriptionmode: peak2
off/<typ>Alternative from enum tags or a regular type <typ>lower: off,
upper: 12.6
[<type>]Comma-separated vector with data of type <type>map: [1,2,4,8]

Using the reserved keyword $ref, the entire content of the configuration can be obtained from a resource. This can be a configuration in the simplified JSON format described above, or any text or even binary content, provided that the function requires and supports it.

   f = someConfigExpectingFunction({$ref:'someNamedResource'});
important

The configuration is basically constant over the runtime. Calculating property values is not permitted. It is not possible to link to variables in the formula set. Some functions have optional parameters for this purpose, which allow settings such as limit values to be changed dynamically.

The properties listed in the documentation are optional unless they are marked as mandatory.

Persistent status information

Certain functions that are preferably used for the aggregation of signals or events can store their internal state via the persistent channels of the smartCORE and, after restarting the software, build on the previously stored state and continue the calculation. Examples of this are

  • Counters
  • Integrators
  • Classifications

To do this, the name for a storage location is specified in the JSON configuration area of the corresponding function using the storage property. The content of this automatically generated and managed variable cannot usually be interpreted by the user or other functional units of the smartCORE. It is not permitted to use the same memory at different locations in the formula text.

tip

If a state related to a physical quantity is persisted in the memory, it is recommended to append an identifier for its unit to the name (e.g., 'totalDistance_km') to simplify the readability and later maintenance of the formula text.

caution

The contents of the persistent memory can only be accessed again using the same function.

In the following example, a meter reading is persisted:

  f = someCounterFunction(someCondition, {storage:'some.counter.variable'});
note

All persistent data is periodically stored as a BLOB in an SQLite database. Entries in this database are not automatically removed.

Footnotes

  1. Available from catalog version 11 onwards. 2