Appearance
Scripts and Workflows Together
Last updated
Scripts and workflows can call each other. A common split: the workflow is the readable outline (trigger, conditions, who gets told), and a script does the part a node cannot — building a JSON body, writing a data table row, talking to a TCP device that needs a CR/LF.
Calling a workflow from a script
Workflows are found by numeric id or by name (not case-sensitive).
| Call | What it does |
|---|---|
await workflows.run(target, params) | Runs the workflow, waits, returns { executionId, status, error } |
workflows.trigger(target, params) | Starts it and returns at once |
workflows.find(name) | Id, or null |
workflows.list() | [{ id, name, enabled }] |
workflows.status(target) | { id, name, enabled, lastStatus, lastRunAt } or null |
await workflows.enable(target) / disable(target) / setEnabled(target, bool) | Turns its triggers on or off |
javascript
const result = await workflows.run('Press fault notification', {
press: 'Press 2',
faultCode: tags.read('Press2', 'FaultCode'), // device name, tag path
});
if (result.status !== 'completed') {
log('Notification workflow failed: ' + result.error);
}In the workflow, {{press}} and {{faultCode}} are available, and {{trigger}} is script.
Messages between scripts and workflows
messages.send(name, payload) reaches every script with the Message Handler trigger and every workflow with the Message Received trigger for that name, and returns how many it reached. A Send Message node does the same from a workflow. Unlike workflows.run, the sender doesn't name a workflow — whoever listens for the name gets it, on this appliance or on a paired appliance.
await messages.sendRequest(name, payload) gets one answer: the first listening script's return value or, when no script listens, the first listening workflow's Reply node. See Message Received and Send Message and Reply.
Calling a script from a workflow
Use the Run Script node. The script's context contains:
| Key | Value |
|---|---|
context.trigger | workflow |
context.workflowId | The calling workflow's id |
context.depth | Nesting level |
context.<name> | Every variable of the run, and each parameter |
context.params | Just the parameters (and the run's variables), as an object |
context.timestamp | When the script started, ISO text |
The workflow continues from Out if the script completes and Error if it throws or times out. The script's return value is not passed back. To return data, write a local tag in the script and read it with Read Tag afterwards:
javascript
// Script "Insert scrap row", run from a workflow with parameters line, reason, count
await db.insert('scrap_log', {
line: Number(context.params.line),
reason: context.params.reason,
qty: Number(context.params.count),
});
tags.write('Scrap/LastInsertOk', true); // local tagdb.insert writes a data table row and tags.write writes a tag on the Local Tags device; see Script API Reference for the full list.
Nesting
Calls can chain: workflow → script → workflow → … up to 5 levels, counted across both kinds. The sixth level fails with Maximum workflow nesting depth reached (5), which stops accidental cycles. Messages are counted the same way: five messages in a row that start each other's runs, and the sixth is refused.