Skip to content

Server-Side Script Engine

Server-side scripts run on the inSCADA server and reach every platform capability through the ins global object. This page covers the engine, sandbox, scheduling and lifecycle; individual sub-APIs have their own pages.

JDK21 replaced Nashorn with GraalJS (GraalVM JavaScript). To keep existing JDK11 scripts running unchanged, Nashorn compatibility mode is enabled (js.nashorn-compat: true). In practice this means:

  • Your existing JDK11 scripts (only var, function, ES5) run without any change.
  • You may use modern JS if you want: let / const, arrow functions, template literals, destructuring, classes, spread / rest, async / await.
  • Mixing both styles in the same script is safe.
FeatureStatus
var, function, ES5
let, const
Arrow functions (=>)
Template literals (backtick)
Destructuring
class / extends
Spread / rest (...)
async / await
eval(...)✗ (disabled by sandbox)
with (...)✗ (disabled by sandbox)

Script security is enforced through Java host access. A script may only call Java methods marked @HostAccess.Exportins.* is the surface exposed that way.

BlockedReason
Creating threadsScripts run in a shared thread pool
Direct file system accessUse ins.readFile() / ins.writeToFile() instead
Native code (JNI / JNA)
Environment variable access
Polyglot (other languages)
eval, with

System-level operations such as exec, shutdown, restart are only available through ins.* and are recorded to the project log.

LimitDefaultConfig key
Statement count100 000ins.script.maxStatementCount
Execution timeout60 secondsins.script.execution-timeout

A script that exceeds the limits is cancelled and ends with ScriptException; the error is logged, the platform is unaffected.

Objects automatically injected into the script context:

GlobalTypeDescription
insInscadaApiUnion of every sub-API the platform exposes (list below)
userCurrentUserBindingCurrent user info — id, name, roles, permissions, activeSpace, remoteAddress, spaces, menus
Custom bindingsoptionalAdditional context objects provided via a script definition’s bindings field

Nashorn’s meta globals (quit, exit, print, load, loadWithNewGlobal, $ARG, $ENV, $EXEC, $OPTIONS, $OUT, $ERR, $EXIT) are stubbed to no-op for safety — calling them does nothing.

Standalone automation jobs are defined from Development → Scripts.

TypeParametersDescription
PeriodicPeriod (ms), Offset (ms)Repeat at a fixed interval
DailyHour:MinuteEvery day at a specific time
OnceDelay (ms)One-shot execution
NoneNo automatic trigger — invoked manually via ins.executeScript() or REST
FieldDescription
NameUnique script name
CodeJavaScript source
Schedule TypePeriodic / Daily / Once / None
Period / TimeSchedule parameter
LogRecord execution logs
CompileCompiled-source cache enabled (recommended: on)
BindingsOptional extra context bindings
{
"id": 159,
"name": "Chart_ActiveReactivePower",
"projectId": 153,
"type": "None",
"log": false,
"compile": true,
"owner": "inscada",
"code": "function main() { /* ... */ } main();"
}
  1. Compilation — the code is SHA-256 hashed and written to a Caffeine cache (default 2000 entries, 60 min idle TTL). The same code is not recompiled on subsequent runs.
  2. Execution — runs on the inSCADA-script-executor-* daemon thread pool (core = CPU count, max = 8 × CPU, queue = 2048).
  3. Result — the return value is unwrapped from a GraalVM Value to a Java object — Map<String, Object> / List / primitive.
  4. Error / Timeout — if the timeout is exceeded the task is cancelled via Future.cancel(true); the error is recorded to the project log as ScriptException.

The same task in ES5 and modern JS — both are valid:

// ES5 style (compatible with JDK11 scripts)
function main() {
var active = ins.getVariableValue("ActivePower_kW");
var reactive = ins.getVariableValue("ReactivePower_kVAr");
var s = Math.sqrt(active.value * active.value + reactive.value * reactive.value);
ins.setVariableValue("ApparentPower_kVA", { value: s });
ins.writeLog("INFO", "PowerCalc", "S = " + s.toFixed(2) + " kVA");
}
main();
// Modern JS style (optional in JDK21)
function main() {
const active = ins.getVariableValue("ActivePower_kW");
const reactive = ins.getVariableValue("ReactivePower_kVAr");
const s = Math.sqrt(active.value ** 2 + reactive.value ** 2);
ins.setVariableValue("ApparentPower_kVA", { value: s });
ins.writeLog("INFO", "PowerCalc", `S = ${s.toFixed(2)} kVA`);
}
main();
ModuleShort
Variable APIRead/write variables, stats
Connection APIConnection / device / frame
Alarm APIAlarm state, fired alarm history
Trend APITrend tag management
Datasource APISQL, InfluxQL
Data Transfer APIFile-based data transfer
Notification APIMail, SMS, web notification
Script APIScript scheduling, global object
Report APIClassic + Jasper reports
Project APIProject info, location
Log APIAudit log
System APIShutdown, restart, exec
User APIUser listing
I/O Utils APIREST, ping, file, JSON
Utils APIuuid, date, bit ops, formatting
Language APIloc
Keyword APIMetadata
Console APIconsoleLog