Skip to main content

Preprocessor Directives

Preprocessor directives

Insert formula text "#include"

This directive can be used to insert formula text from a resource or an external file. The syntax used determines which source is addressed.

#include "aResource"
#include 'aResource'
#include <aFile>

The resource specified as a string is transferred to the source text, taking into account the decoder specified there or as text.

The file specified in <...> is transferred to the source code. Absolute and relative paths are permitted, whereby relative paths are searched for starting from fixed directories (search paths). Elements in %...% are replaced by the corresponding value of the environment variable.

Search paths under WINDOWS:

  • %USERPROFILE%/mm_lib/

  • %LOCALAPPDATA%/optimeas.osg.com/mm_lib/

  • %APPDATA%/optimeas.osg.com/mm_lib/

Search paths under LINUX/YOCTO:

  • /sdi/config/mm_lib/

  • /sdi/apps/smartcore/mm_lib/

  • /var/lib/mm_lib/

  • /usr/local/lib/mm_lib/

  • /usr/lib/mm_lib/

Remove time reference "#timeless"

As described in the introduction, the Math module always processes the data from the various sources of the smartCORE accurately. This ensures that, for example, a current and voltage signal are correlated appropriately to calculate a power.

However, there are also data sources that only provide new values extremely rarely. This could be, for example, measurement data from a weather station that is only queried and written to the smartCORE channels every 10 minutes or data from a timetable that is only queried and updated by a server once a day.

Data that is transferred from the smartCORE to the Math module times out after the adjustable time inputTimeoutS and is then used with the same time offset and the last value, even though its validity has not been confirmed by recent measurements or queries. As a result, all calculations that depend on this are still executed correctly but delayed by this time period.

This delay can have unfavorable effects on the display of MQTT data in the cloud or for control tasks.

The directive #timeless can be used to resolve the time reference of certain input channels for the Math module. The channel names can be passed to the directive in a list with a comma as a separator. If the names contain characters other than those permitted for an identifier, they must be set in '...' or "...". The use of the $'...' syntax is not permitted, as only one attribute of the channel is set here.

#timeless <varName>, <varName2>, ...

The input channels marked in this way are then always valid from the start to the end of the respective calculation interval evaluationTimeMs in relation to the respective system time.

Timeless Schema

In the example shown, the calculation of the formula set is carried out at the times t0,t_0, t1t_1 and t2t_2. Up to the time t0t_0, only the value y0y_0 was set on the channel. Up to time t1t_1, the signal source supplies the data points y1,y_1, y2y_2 and y3y_3. The data points y4y_4 and y5y_5 are only produced up to time t2t_2, although their time stamp is still before t1t_1.

The immediately preceding data set of the channel is always used for the start of the interval, regardless of how old it is. So for the interval ]t0,t1]]t_0,t_1] the data point y1,y_1, for the interval ]t1,t2]]t_1,t_2] the data point y5y_5.

If new data values happen to fall into the current calculation interval and are already entered there in good time, they are taken into account with their time points. For the interval ]t0,t1]]t_0,t_1], these are the data points y2y_2 and y3y_3.

The validity of the most recent available data set (here y3y_3) is automatically extended to the end of the interval (here t1t_1), so that this channel cannot ultimately hold up any calculations that depend on it.

The price for this is that short signal changes that lie within this extended validity range may no longer be included in the calculations. In the example, the data point y4y_4 is "overlooked" as it lies in a time interval that has already been supplemented by the automatism. However, assuming that these channels only rarely provide data, this should not be a problem.

Definition of functions "#define"

Under Construction This function is in preparation.

Debug information "#dump"

warning

For Debugging Only This preprocessor directive is intended exclusively for diagnostics and development. It produces a lot of informal output in the smartCORE log file and should therefore only be used for short periods of time.

The parameter of the #dump directive is a comma-separated key or key-value list and affects the following formula text:

#dump <key>, <key>=<value>, ...
KeyValueDescription
treeReturns the translated object tree. See below for interpretation.
node<uint>Adds a specific object node for continuous monitoring (*,**).
var<str>Adds a regex expression to select channel names whose accesses are to be logged (*)
trace<enum>switches the data flow output for
- in inputs,
- out outputs or
- io both data directions
free.
clearDeletes all dump settings for the following code section.

(*) Option can be named more than once.

(**) Node numbers from the object tree

Examples:

#dump tree
#dump node=5, node=9
#dump var='Temp.*', trace=out

Output of the object tree

The output of the object tree using #dump tree provides detailed information on the functional relationships of the defined formula set. The evaluation is reserved for optiMEAS experts.

        +---o [0]: sequencer, bareImpl, op: ';' listOfArgs
> out: nullptr
+---o [1]: operatorNode, followInputs, op: '=' orderR2L
| > out: { n:'duration', s:[upLnk, wrVar], *rd[0], *wr[1], h:'=', empty}
| +---o [2]: operatorNode, followInputs, op: '*' orderL2R
| > out: { n:'', s:[upLnk], *rd[1], *wr[2], h:'*', empty}
| | +---o [3]: varPoolSource, followInputs
| | | > var: { n:'wv2', s:[rdVar], *rd[3], empty}
| | | > out: { n:'', s:[upLnk], *rd[2], *wr[3], empty}
| | +---o [4]: constValueNode, constValue
| | | > out: { n:'', s:[upLnk, const], *rd[2], *wr[4], [1]={t: INF, d: TrustedTimestamp }, [0]={t: 0, d: (cScalar, cInt) 59}}}

Trace outputs for a data flow connection element (out: or var:, channel or TS_Stream) have the following compact structure:

{ n:'duration', s:[upLnk, wrVar], *rd[0], *wr[1], h:'=', [9]={t: 48, d: (cScalar, cDbl) 54.978065}, ... [0]={t: 20, d: (cScalar, cDbl) 0.000000}}

This means:

AbbreviationFlagsDescription
n:'...'the name of the channel, if it is a variable
s:[]status flags of the channel
upLnkup-link, connection from a sub-node to the parent node
rdVarRead Variable, input variable, is provided by the smartCORE and is only read
wrVarWrite Variable, output variable, can be returned to the smartCORE
inzInitializer, has an initializing node
constConstant value, the value does not change during runtime.
discrDiscrete evaluation, this channel is calculated in discrete sampling steps
ev@0Evaluate at Start, the discrete channel has been initialized
evDTEvaluate Delta-T, a sampling step has been calculated for the discrete channel
explExplicit name, variable was defined with the $'...' syntax and must exist in the smartCORE
fldEField element, channel feeds a specific data field in a multidimensional structure (vector, matrix, ...)
privPrivate, A variable that was created by a function block and is used exclusively by it
noTnoTime, this channel was marked as #timeless and is always valid until the end of the calculation interval.
nRecNoRecursion, this variable may not be used in a recursion loop.
*rd[]The indices of the object nodes that have read access to the channel
*wr[]The index of the object node that has write access to the channel
*@0[]The index of the object node that performs the initialization of the discrete channel.
h:'...'Reference to the function of the writing node, e.g. '*' or 'sin(...)'
[n]={}the stored sample at the most recent position n (corresponds to the number of entries - 1) with...
t:timestamp in ns since 01.01.1070, INF (infinite) or NAV (invalid)
d:Data value with (structure, type) value or TrustedTimestamp, i.e. the previous value remains valid up to this point in time. The time can grow monotonically in each calculation interval.
[0]={}the stored sample at the oldest position (optional)

Track calculation process "#monitor"

For Debugging Only WARNING! This preprocessor directive is intended exclusively for diagnostics and development. It produces a lot of informal output in the smartCORE log file and should therefore only be used for short periods of time.

Monitoring the internal buffers "#warn"

For Debugging Only WARNING! This preprocessor directive is intended exclusively for diagnostics and development. It produces a lot of informal output in the smartCORE log file and should therefore only be used for short periods of time. In addition, this option generates additional CPU load and may only be used temporarily under observation !!!

The parameter of the #warn directive is a comma-separated key or key-value list and affects the following formula text:

KeyValueDescription
maxbuflen<uint>Monitors the maximum number of data records in a data queue. A warning is issued if the limit is exceeded. The limit is increased by 25% of maxbuflen for the following message.
timeout<dbl>Monitors the time interval between the first data sample and the execution time. A warning is issued if this time is greater than the set value in s.
clearClears all warning settings for the following code section.

Examples:

#warn maxBufLen=10, timeout=1000
// Formula text for monitoring
#warn clea