Skip to content

Transform DSL

A tiny, statement-based language evaluated natively against the in-memory CanonicalMachineData struct — the lowest-latency path for filters and field math.

Updated View as Markdown

The OpexFlow DSL is a tiny, statement-based language evaluated natively against the in-memory event struct. It exists for the 90% of transforms that are filters and field math, where spinning up a JS interpreter per event is pure waste.

DSL programs live inline (script_inline) or in a file (script), exactly where a JS script would. Pick the backend with backend: "dsl".

Syntax overview

A program is a list of statements, one per line. Comments start with #. There are exactly three statements:

# a complete DSL program
when metadata.temp > 80 || metadata.vib > 5.0   # keep iff true; else DROP the record
set metadata.alert = true                 # mutate a field
set status.state = "alarm"                 # ... another field
Statement Meaning
when <expr> Filter. The record is kept iff <expr> is true; otherwise it’s dropped (nothing flows to sinks). At most one when per program.
set <path> = <expr> Mutate a field. Targets: metadata.* (nested, auto-created), status.state, status.alarmCode, status.alarmMessage, machine.id, machine.name.
drop Drop the record unconditionally. Equivalent to JS return null.

If a program has no when and no drop, the (possibly mutated) record always passes through to its sinks.

Expressions & operators

Operator Description
`
== != < <= > >= Comparisons, return booleans. Numeric first, string ordering as fallback.
+ - * / Arithmetic. + also concatenates two strings.
( ) Grouping.

Literals

42   3.14             # numbers (float)
"running"            # string
true  false  null    # booleans, null

Paths

Paths read directly from CanonicalMachineData. Dotted, with numeric segments indexing arrays:

Path Reads
source Origin protocol (modbus, opcua, http, …).
machine.id / machine.name Stable machine id / display name.
status.state running | idle | alarm | offline.
status.alarmCode / status.alarmMessage Active alarm (or null).
spindle.speed / spindle.load Spindle readings (null if no spindle).
axes.<i>.position Indexed axis position (also .name, .unit).
metadata.<key>... Free-form nested JSON, where sensors like temp, vib, rpm live.

Examples

Conditional alert (filter + flag)

when metadata.temp > 80 || metadata.vib > 5.0
set metadata.alert = metadata.temp > 80 || metadata.vib > 5.0

Force alarm state on high load

when spindle.load > 90
set status.state = "alarm"
set status.alarmMessage = "spindle overload"

Unit conversion + nested metadata

set metadata.temp_f = metadata.temp_c * 9 / 5 + 32
set metadata.flags.hot = metadata.temp_c > 60

Pass only running machines

when !(status.state == "offline")

DSL cheat sheet

when expr            keep iff true
set path = expr      mutate field
drop                 drop the record
metadata.x           sensor values
status.state         run state
|| && !              boolean logic
== != > <            comparisons
+ - * /              arithmetic
# comment            one per line
"str" / true / null

Try it: live REPL

Edit the record and the program, then run. This is an in-browser evaluator of the documented DSL subset operating on the record object, no server round-trip. The interactive REPL is available in the running connector’s in-app docs; the reference behavior is fully covered by the syntax, operators, and examples above.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close