Skip to main content

Script editor

The Mango script editor is a built-in code editing environment available wherever scripts are used in the system, including meta data points, scripting data sources, set point event handlers, and the global scripts module. It provides syntax highlighting, validation, test execution, and contextual help to streamline writing and debugging JavaScript within Mango.

Overview

Every scriptable component in Mango presents the same editor interface. Rather than writing scripts in an external text editor and pasting them in, the built-in editor gives you immediate access to context variables, validation feedback, and test execution so you can iterate quickly without leaving the Mango UI.

Where to find the script editor

The script editor appears in several locations throughout Mango:

  • Meta data points -- When creating or editing a meta data point, the script editor is the primary configuration area. Navigate to the data point's edit page and look for the Script text area.
  • Scripting data source -- The scripting data source module provides a script editor for each point and for the data source-level context script.
  • Set point event handlers -- Event handlers that set point values can use a script to calculate the value. The script editor appears when you select "Script" as the set value type.
  • Global scripts module -- The SST Global Scripts page provides an editor for defining functions that are available across all script contexts.

The script editor panel within the meta data point configuration page

Editor layout

The script editor interface consists of several areas:

Script text area

The main editing area where you write your JavaScript code. It supports:

  • Syntax highlighting -- Keywords, strings, numbers, and comments are color-coded for readability.
  • Tab indentation -- Use the Tab key to indent code blocks for better organization.
  • Scrollable area -- The editor expands or can be scrolled for longer scripts.

Context variable list

To the right of (or adjacent to) the script area, you will find the list of context variables. These are the data point references available to your script. Each context variable shows:

ColumnDescription
Variable nameThe JavaScript identifier you use in your script (e.g., sensor1, tempAvg)
Data pointThe data point this variable references
Data typeThe point's data type (Numeric, Binary, Multistate, Alphanumeric)
Update contextWhether changes to this point trigger the script to execute (meta points only)

You assign variable names when you add context points. Choose short, descriptive names since you will reference them frequently in code. Variable names must be valid JavaScript identifiers -- they cannot start with a number or contain spaces.

Help button

Most script editors have an adjacent blue question mark icon. Clicking it opens a contextual help panel that describes:

  • Available context variables and their methods (value, time, last(), ago())
  • Special variables like TIMESTAMP and UNCHANGED
  • Utility objects such as RuntimeManager, DataPointQuery, and DateTimeUtility
  • Global functions loaded from modules (e.g., max(), min(), avg(), sum())

The help content is version-specific, so it always reflects the features available in your installed version of Mango.

Script validation

Before saving, you should always validate your script. Click the check mark (validate) icon next to the script area to run the script in test mode.

What validation checks

Validation performs two things simultaneously:

  1. Syntax check -- The JavaScript engine parses your script and reports any syntax errors such as missing brackets, unterminated strings, or invalid keywords.
  2. Test execution -- The script runs against the current values of all context variables. The result is displayed below the editor without saving any values to the database.

Reading validation results

After clicking validate, the editor displays one of the following:

  • Success with a result value -- A green result area shows the computed value and its data type. This is the value that would be saved if the script ran in production.
  • Script error -- A red error area shows the error message, including the line number where the problem occurred (when available).

If the result value does not match the data type of the target point, Mango will attempt to coerce it. If coercion fails, a script error event is raised at runtime.

The script editor showing a successful validation result with the computed value

Testing scripts from the UI

The validate button is also your primary testing tool. Use it to experiment with your script logic before committing changes.

Test execution behavior

When you click the validate button:

  1. Mango retrieves the current runtime values of all context variables.
  2. The script executes with those values.
  3. The result is returned and displayed, but no values are saved and no events are raised.
  4. Side effects from utility objects (e.g., RuntimeManager.enableDataSource()) do execute during test mode, so use caution with scripts that perform system actions.

Iterative testing workflow

A productive workflow for developing scripts:

  1. Start with a simple script that returns a single context variable's value (e.g., return sensor.value;).
  2. Click validate to confirm the context variable is accessible and has a value.
  3. Incrementally add logic, validating after each change.
  4. Once the script produces the expected result, save the data point.

Context variables available in the editor

Every script context provides the following variables and objects:

Point context variables

Each data point added to the context is available by its assigned variable name. These objects provide:

  • p.value -- The current value of the point.
  • p.time -- The timestamp of the current value (milliseconds since epoch).
  • p.ago(periodType, count) -- The point's value from a specified time ago.
  • p.last(count) -- A list of the most recent count Point Value Time objects.
  • p.lastValue(index) -- A specific historical value by index (0 = most recent).
  • Time component fields: p.millis, p.second, p.minute, p.hour, p.day, p.dayOfWeek, p.dayOfYear, p.month, p.year.

See the JavaScript guide for detailed documentation of these methods and fields.

Built-in objects

ObjectDescription
TIMESTAMPSet this to override the result's timestamp (milliseconds since epoch)
UNCHANGEDReturn this to prevent the point from updating its value
RuntimeManagerAccess to data source enable/disable, point set commands
DataPointQueryQuery data points by RQL from within the script
DateTimeUtilityDate/time helper methods for calculations
JsonEmportAccess to Mango's JSON import/export system
LOGLogger object for writing messages to the Mango log

Global functions

If the SST Global Scripts module is installed, convenience functions are available in all script contexts:

  • max(a, b, c, ...) -- Returns the maximum value.
  • min(a, b, c, ...) -- Returns the minimum value.
  • avg(a, b, c, ...) -- Returns the average of all values.
  • sum(a, b, c, ...) -- Returns the sum of all values.

Debugging techniques

Using the LOG object

The LOG object writes messages to the Mango application log (ma.log). This is the primary debugging tool for scripts that run in production.

LOG.info("Script started, sensor value = " + sensor.value);

var result = sensor.value * calibration.value;
LOG.info("Calculated result = " + result);

if (result > threshold.value) {
LOG.warn("Result exceeds threshold: " + result + " > " + threshold.value);
}

return result;

Available log levels:

MethodUse case
LOG.trace(message)Very detailed diagnostic output (usually filtered out)
LOG.debug(message)Diagnostic messages for development
LOG.info(message)General informational messages
LOG.warn(message)Warning conditions that may indicate a problem
LOG.error(message)Error conditions that need attention

To see debug and trace messages, you need to adjust the log level for the scripting package in your log4j2.xml configuration file.

Inspecting intermediate values

When a script produces an unexpected result, break it down by logging intermediate calculations:

var raw = sensor.value;
LOG.info("raw = " + raw);

var scaled = raw * 0.01;
LOG.info("scaled = " + scaled);

var offset = scaled + calibrationOffset.value;
LOG.info("offset = " + offset);

return offset;

Checking for null values

A common source of errors is accessing a context variable that has no value yet (the point has never been updated). Always check for null:

if (sensor.value == null) {
LOG.warn("sensor has no value yet");
return UNCHANGED;
}
return sensor.value * 2;

Common script errors and how to fix them

ErrorCauseSolution
ReferenceError: x is not definedThe variable name does not match any context variableCheck the variable name in the context list matches exactly (case-sensitive)
TypeError: Cannot read property 'value' of nullThe context variable has no value (point never updated)Add a null check before accessing .value
SyntaxError: Unexpected tokenSyntax mistake such as missing bracket or semicolonReview the indicated line number for typos
Script result is nullThe script does not return a valueAdd a return statement at the end of the script
Coercion errorReturned value cannot be converted to the point's data typeReturn a value matching the expected type (number for Numeric, boolean for Binary)
Script execution timeoutScript runs longer than the allowed execution timeReduce loop iterations, avoid infinite loops, simplify logic

Performance considerations

Scripts execute on the Mango server's JVM, and poorly written scripts can degrade system performance.

Execution time limits

Mango enforces a configurable timeout for script execution. If a script does not complete within the allowed time, it is terminated and a script error event is raised. The default timeout is typically 15 seconds. You can adjust this in mango.properties:

# Script execution timeout in milliseconds
script.timeout=15000

Memory usage

Each script execution allocates memory for variables, intermediate results, and historical data queries. To minimize memory usage:

  • Limit last() calls -- Requesting large numbers of historical values (e.g., sensor.last(10000)) loads all those values into memory. Use the smallest count that meets your needs.
  • Avoid storing large arrays -- Building large arrays in a loop consumes memory that is not released until the script completes.
  • Use ago() instead of last() when possible -- If you only need a value from a specific time period ago, ago() retrieves a single value rather than a list.

Polling frequency impact

For meta data points, the script executes every time a context variable updates. If a context variable updates every second and the script takes 500ms to execute, you are consuming significant server resources. Strategies to manage this:

  • Limit update context triggers -- Only check the "Update context" box for variables whose changes should trigger recalculation.
  • Use UNCHANGED to skip unnecessary updates -- Return UNCHANGED when the inputs have not changed meaningfully.
  • Consider execution frequency -- If the script only needs to run every 5 minutes, use a cron pattern or reduce the update frequency of the source points.

Script complexity guidelines

ComplexityExecution timeRecommendation
Simple arithmetic< 1 msNo concerns
Conditional logic with a few branches< 5 msNo concerns
Loops over last(100) values10-50 msAcceptable for most deployments
Loops over last(1000) values50-500 msMonitor execution time, consider reducing
External queries (DataPointQuery)100-1000 msUse sparingly, cache results if possible
JSON import/export operations500+ msAvoid in frequently executing scripts