Overview
Scripts are Mango by Radix IoT's extensibility layer, and the first decision is where to put one. Each location has its own trigger, bindings and permissions — and some of what people reach for a script to do is not done with a script at all. This guide covers every place a script actually runs, what fires it, and what it can reach.
Prerequisites
- The module that owns the location you want: Meta Data Source, Scripting, SST Global Scripts, or core for the event handlers
- At least one script engine module installed — Graal.js, Nashorn or Groovy
- Permission to use that engine, and the roles the script needs to read and write the points it touches
Where Scripts Run
| Location | Trigger | Configured in |
|---|---|---|
| Meta data source point | A context point event, or the point's own timer schedule | The meta point's properties |
| Scripting data source point | While Polling is on, every Update period or on a Cron pattern; or when an Updates context point changes | The data source's properties |
| Script event handler | An event is raised, acknowledged, or returns to normal | The event handler |
| Set point event handler | Same, when its action is Set to scripted value | The event handler |
| Email event handler script | Same, before the email is built | The event handler |
| Global scripts | Called from another script — and Validate runs one for testing | Data integration > Global scripts |
| Excel report scripts | After a report generates, or when its email model is built | The report template |
Everything in that table runs on the server. Mango has no browser-side scripting location — see Dashboards below.
Meta Data Source Points
A meta point's value is calculated by a script from other points. It is the most common place to put logic.
- External context points: you add the points and give each row a Key. That key — not the point's own name — is what the script uses. Tick Updates context on each row that should re-run the script; it starts unticked. (Variable name is something else: the meta point's name for itself,
myby default) - Context event type: Update, Change or Logged — which kind of event, on a row with Updates context ticked, re-runs the script
- Timer update event: None, the start of a minute, hour, day, week, month or year, or a Cron pattern for anything else
- Execution delay(seconds): waits before running, and changes how the script executes — see Performance
- Return value: one value, which becomes the meta point's value. Return
UNCHANGED, nevernull, to skip an update
Scripting Data Source Points
The scripting data source runs a script to produce values for its own points. It runs on a schedule when Polling is on — every Update period, or on a Cron pattern with Use cron — or whenever a context point marked Updates context changes. Use it when the script is the producer — polling an external service, generating synthetic values, or doing scheduled work not derived from one source point. It also takes External context points, so it can read existing points too, and has its own Execution delay (seconds).
Event Handler Scripts
The Script handler type gives an event the full scripting environment. It does not run a flat script body — you define callback functions, and Mango calls the one that matches what happened:
eventRaised(event)— requiredeventInactive(event)— required; the event returned to normal or was deactivated, for example at shutdowneventAcknowledged(event)— optional; the event may still be active
A script with logic only at the top level and none of these functions defined runs once at evaluation and then does nothing on an event. There is no escalation trigger here — escalation belongs to the Email handler, which has its own script for shaping the email model and can cancel the send. The Set point handler takes scripts too: choose the action Set to scripted value and it uses an active and an inactive script to compute what to write.
Global Scripts
Global scripts are shared functions, not scheduled jobs — the record holds a script and nothing else: no cron field, no trigger, no schedule. They live at Data integration > Global scripts, which is superadmin only, and their functions become callable from meta points, scripting data source points, and the set point, email and Excel report scripts with no import step. A Script event handler does not load them. Put a calculation you use in several places here once, then call it. Mango ships no such functions itself — the store is empty on a new install — so helpers like avg() exist only because someone wrote them.
Note
To run work on a schedule, the scheduled thing is a data source or a handler, not the global script. A scripting data source with a cron pattern, or a meta point with a timer update event, calling a shared global-script function, is the supported shape.
Validating Incoming Data
There is no script that intercepts a value before it is stored and rejects it. Three real approaches, in order of how much they cost:
- No script at all. A data point's logging properties include Discard extreme values with a Discard low limit and Discard high limit. This is the only mechanism that genuinely drops a bad reading at ingest
- A meta point downstream. Read the raw point in a meta point's context and publish the cleaned value as a second point. The raw point still logs what it received — you are adding a trustworthy point, not editing history
- A global script called from a scheduled location, to sweep and flag in batches after the fact
Dashboards
Mango's dashboard system is deliberately zero JavaScript: dynamic styling, conditional visibility and live data all come from Mango's UI components and AngularJS template expressions, not from user scripts. There is no dashboard script field to fill in.
Warning
Because custom pages are AngularJS templates, their expressions can execute arbitrary JavaScript in the browser of every user who views the page. Mango restricts page creation to superadmin by default and documents this as a cross-site-scripting risk. Do not treat a custom page as a scripting location, and do not widen its edit permission casually.
If you genuinely need your own browser code, the documented route is a separate custom dashboard application — your own controllers and directives in a folder under the installation's overrides directory, served at its own /user-ui/ path and edited outside Mango. Mango's own help recommends the built-in page system instead.
Engines and Permissions
Only a Script event handler chooses its engine, from its Script engine selector. Meta points, scripting data source points, and the set point and email handlers' scripts have no selector: they run JavaScript. What the Script handler offers depends on which engine modules are installed:
- Graal.js (ECMAScript)
- OpenJDK Nashorn (ECMAScript)
- Groovy Scripting Engine (Groovy) — so a Script handler is not necessarily JavaScript
Each engine has its own permission, and so do the sensitive bindings — the script log, Mango services, the runtime context, request and response objects, setTimeout(), standard streams, and loading scripts from the web or the file store. Every location also carries Script roles, the roles the script runs with, which decide the points it can read and write. A script that quietly returns nothing is often one whose roles cannot see its points.
Tip
Not every JavaScript idiom survives the engine boundary. A Java list from Mango has size() and get(i); .length with [i] can leave a loop body silently unexecuted. Use size() and get(i) and it works on every engine.
The Scripting API
Inside any location you get the same core bindings:
- Context points — each context variable carries
value,timeand date parts, history throughago(),past(),prev(),last(),lastValue()andpointValuesBetween(), and writes throughset(value), optionally with a timestamp and an annotation. Ask any context object forhelpto list its own properties - CONTEXT and CONTEXT_POINTS — the runtime context, and a map of variable names to the points behind them
- DataPointQuery and DataSourceQuery —
query(rql)by RQL, with a default limit of 100 (add&limit(-1)for all of them), andbyXid()for a single known point - PointValueQuery — bulk history across several points at once, including rollups, delivered to a callback you supply. Reach for it when a context variable's own history functions are not enough
- RuntimeManager — refresh, enable and disable points and data sources, and
sleep(). Note it does not set values; that isset()on the point - HttpBuilder — HTTP requests without touching Java
- JsonEmport — the import/export page's behaviour, from a script
- DateTimeUtility — formatting, parsing and timezone offsets
- LOG —
trace,debug,info,warn,errorandfatal, plusprint()while testing in the editor
Script output does not go to the Mango log, and where it goes depends on the location. Meta and scripting data source points get LOG, which writes to the point's own file, metaPoint-N.log or scripting-N.log (N is the internal id, not the XID), and only once that point's Log Level is raised from its default of None. A Script event handler gets a lowercase log binding instead, which writes to script.log beside ma.log. Looking for script output in ma.log is the most common reason people conclude their script never ran.
Performance
Meta points do not poll — the meta data source is not a polling data source, so "every poll" describes nothing. What matters is which thread runs the script:
- With Execution delay at its default of zero, a context-triggered meta script runs inline on the thread that just delivered the source point's value. A slow script there delays the source data source, not just the meta point
- Set an Execution delay and execution moves onto a scheduled task instead. This is the fix for a script that has to do something slow
- Blocking work — an HTTP call, a database query,
sleep()— belongs in a scripting data source on a cron pattern or behind an execution delay, not in a zero-delay meta point. KeepLOGat a higher level in production, since a chatty high-frequency script fills the script log
Choosing the Right Location
| Need | Location | Why |
|---|---|---|
| Derive a value from other points | Meta data source point | Built for it, and re-runs on the context event you choose |
| Pull from an external service on a schedule | Scripting data source point | Runs on its own schedule, and the script is the producer |
| React to an alarm with real logic | Script event handler | Separate callbacks for raised, acknowledged and returned-to-normal |
| Compute the value an event should write | Set point handler, Set to scripted value | Keeps the write in the handler that owns it |
| Shape or suppress an alarm email | Email handler script | Runs while the email model is built and can cancel the send |
| Share one calculation across scripts | Global scripts | Its functions are callable from every location except the Script event handler |
| Drop out-of-range readings at ingest | None — point logging properties | Discard extreme values needs no script |
| Change how a dashboard behaves | None — UI components | The page system is zero-JavaScript by design |
Verification
- Use the editor's Validate button to execute the script and see its result before saving
- Confirm the script's roles can see every point it touches — an empty result is usually a permission, not a bug
- Check the right file, not
ma.log: the point's ownmetaPoint-N.logorscripting-N.logwith its Log Level raised, orscript.logfor a Script event handler'slog(raisinglogger.script.levelif you need detail) - For a meta point, confirm the Context event type and Timer update event are what you intended; for a script handler, confirm
eventRaisedandeventInactiveboth exist and are spelled exactly
Summary
Every Mango scripting location runs on the server: meta points and scripting data source points produce values, the script, set point and email handlers respond to events, global scripts hold shared functions, and Excel reports can post-process their output. Pick by what fires the script and what it needs to reach, choose the engine and the roles deliberately, and remember the two places a script is the wrong tool — discarding bad readings at ingest, which is a point setting, and dashboard behaviour, which is what the UI components are for.