Skip to main content

Scripting Data Source

The Scripting data source executes a single JavaScript (ECMAScript) script on a cron schedule and allows that script to set values on multiple data points in a single execution. It is similar to the Meta data source but differs in two important ways: the script runs at the data source level (not per-point), and it can set values on any of its points using the set() function rather than returning a single value. This makes it ideal for complex calculations that produce multiple outputs, simulation models, and coordinated multi-point updates.

The scripting engine uses the Rhino JavaScript implementation, providing a full ECMAScript environment without browser DOM objects. Script context (variables and their states) is maintained across executions for the lifetime of the data source runtime, enabling stateful computations.

Overview

PropertyValue
ModulemangoAutomation-ScriptingDS
ProtocolN/A (scripted)
DirectionScripted
Typical UseAdvanced multi-point scripting with autonomous execution

Prerequisites

  • Knowledge of JavaScript for writing the data source script.
  • Optionally, existing data points from other data sources to serve as external context inputs.
  • Understanding of cron expressions for scheduling script execution.

Configuration

Data Source Settings

SettingDescription
NameA descriptive name for the data source.
XIDA unique identifier across all data sources.
Cron patternA cron expression that determines when the script executes. A cron pattern generator wizard is available by clicking the icon next to the field.
Execution delay (seconds)Number of seconds to delay script execution after the cron pattern fires. This allows external context points to update in case of network or processing latency. The script still executes with the timestamp of when the cron pattern originally fired, not including the delay.
Sets HistoricalWhen checked, the script can execute set directives even when the point being set already has a more recent value. Required for backfilling historical data.
Log levelControls the level of log messages written to the script log file. Options include None (no logging), Trace, Debug, Info, Warn, Error, and Fatal. If set to None, no messages are written (although a log file may still be created).

External Context

The External context allows points from other data sources to be included in the script's execution context.

SettingDescription
PointThe external data point to include.
Variable nameThe name by which the point can be referenced in the script. Must be unique across all context variables (both external and data source points).

Script

The main script is an arbitrary JavaScript program. The execution context includes:

  • All data source points (referenced by their configured variable names)
  • All external context points (referenced by their configured variable names)
  • POINTS -- a list of all point names included in the context (both data source and external), enabling dynamic lookup at runtime
  • LOG -- a logging object with methods: trace(), debug(), info(), warn(), error(), and fatal(), corresponding to Log4J log levels
  • Functions and variables from global scripts (automatically included)

The print() and println() functions are available for debugging during testing but are discarded during normal data source runtime.

Use the Validate button to test-execute the script without actually setting any point values. The values that would have been set are displayed in the results area below the script editor.

note

If global scripts are modified, the Scripting data source must be restarted to reload them.

Data Point Configuration

SettingDescription
Variable nameThe name by which the point object can be referenced in the script.
Data typeThe Mango data type (Binary, Multistate, Numeric, or Alphanumeric). Values provided by set() are automatically coerced to this type where possible.
SettableWhether the point can be set from outside the data source's script (e.g., from the UI or REST API).
Updates contextWhether setting this point's value triggers execution of the data source's script. Do not set values to points that update the context from within the script itself, as this will cause recursive execution.

Setting Point Values from Scripts

The primary mechanism for updating point values is the set(value, timestamp) function on each point object:

// Set a numeric point to a value at the current execution time
myPoint.set(42.5);

// Set a point with a specific timestamp (epoch milliseconds)
myPoint.set(42.5, 1708099200000);

Key behaviors of the set() function:

  • Local points (belonging to this data source) are updated directly.
  • External points are set and annotated. External points can only be set if they are configured as settable.
  • The value is coerced to the point's data type. If coercion fails, a data type error event is raised.
  • The optional timestamp parameter is an epoch value in milliseconds. If omitted, the execution time (the cron fire time, not including the execution delay) is used.

Differences from the Meta Data Source

AspectMeta Data SourceScripting Data Source
Script scopePer-point (one script per data point)Per-data-source (one script for all points)
Output mechanismScript return valueset() function calls
Multiple outputsNo (one value per script)Yes (any number of set() calls)
Context persistenceReset each executionMaintained across executions
Disabled pointsRaise "missing point" eventsDo not raise events (but may cause script errors if not handled)

Example: Lorenz Attractor Simulation

The following script implements the Lorenz equations. Three numeric points must be defined with variable names x, y, and z. A cron pattern of 0/2 * * * * ? runs the script every 2 seconds.

if (x.value == 0 && y.value == 0 && z.value == 0) {
// Initial point values
y.set(1);
}

if (typeof(rho) == "undefined") {
rho = 28;
sigma = 10;
beta = 8/3;
dt = 0.01;
}

dx = sigma * (y.value - x.value);
dy = x.value * (rho - z.value) - y.value;
dz = x.value * y.value - beta * z.value;

x.set(x.value + dx * dt);
y.set(y.value + dy * dt);
z.set(z.value + dz * dt);

Note the use of typeof() to check whether constants need to be initialized. Because the script context persists across executions, this pattern effectively initializes variables only on the first run after data source startup.

Common Patterns

Coordinated Multi-Point Calculations

When a single computation produces multiple related outputs (e.g., calculating both real power and reactive power from voltage and current readings), the Scripting data source is more efficient and maintainable than creating multiple Meta points with duplicate logic.

Simulation and Modeling

Use the persistent script context to maintain state variables for physical simulations, PID models, or finite state machines. The Lorenz attractor example above demonstrates how differential equations can be solved iteratively with state carried forward between executions.

Scheduled Data Processing

The cron-based scheduling allows scripts to run at specific times (e.g., midnight for daily calculations, the top of each hour for hourly aggregations). Combined with the execution delay, this ensures that upstream data sources have had time to complete their polls before the script runs.

Logging and Diagnostics

Use the LOG object to write diagnostic information to the log file during normal operation:

LOG.info("Processing started, x=" + x.value + ", y=" + y.value);

Set the Log level to the appropriate threshold to control verbosity.

Troubleshooting

Script Execution Errors

  1. Undefined variable -- ensure all referenced point variable names match exactly (case-sensitive) and that the points are enabled.
  2. Type coercion error -- the value passed to set() must be convertible to the point's configured data type.
  3. Recursive execution -- if a point with Updates context checked is set from within the script, the script will re-execute. This can cause infinite loops or unexpected behavior.

External Context Points

  1. The script executes even if external context points are disabled. If the script does not handle this condition (e.g., checking for null values), it may throw exceptions.
  2. Disabled local points (on this data source) do not raise "missing point" events as they do in the Meta data source, but accessing their values in the script may fail.

Stale Context After Global Script Changes

If you modify a global script, the Scripting data source must be restarted to load the updated global script definitions. Until restarted, the data source continues using the previous version.

Execution Delay Not Working as Expected

The execution delay postpones script execution but does not change the timestamp used for set() calls. The timestamp corresponds to the moment the cron pattern fired. If you need the timestamp to reflect the actual execution time, compute it explicitly within the script.