Complete Examples
Each example below is a complete, working adapter script. The transform adapter examples read data items from a parent adapter; the direct connectivity examples read a machine protocol. See Declaring Inputs for the difference.
| Example | Adapter type | Demonstrates |
|---|---|---|
| Extract operation from a program comment | Transform | declare-keys, pattern-match |
| Passthrough with filtering | Transform | mtconnect-passthrough, deny-keys |
| Overriding execution state | Transform | Replacing a parent data item |
| Part counter with execution state | EtherNet/IP | rising-edge, count, state |
| Modbus temperature monitoring | Modbus | Register scaling, multi-level conditions |
| OPC-UA with a calculated OEE component | OPC-UA | Derived performance and quality metrics |
Transform Adapter Examples
Extract Operation from a Program Comment
Pulls data from a parent FANUC FOCAS adapter and extracts the operation number from the program comment.
Parent adapter: FANUC FOCAS, collecting a program_comment such as O1234(OP10-ROUGH-MILL)
Transform adapter: outputs OP10-ROUGH-MILL as the operation data item
version: 2
# INPUT: Pull data items from parent FOCAS adapter
declare-keys:
- program_comment
# TRANSFORMATION: Extract operation from program comment using regex
variables:
operation:
- source: program_comment
- pattern-match:
pattern: /\(([^)]+)\)/
group: 1
# OUTPUT: Send extracted operation to MachineMetrics
data-items:
- operation
How it works:
- The parent FOCAS adapter collects
program_commentfrom the CNC controller. - The transform adapter declares it needs
program_commentviadeclare-keys. - The regex
/\(([^)]+)\)/matches text inside parentheses. group: 1extracts the captured group — the text between the parentheses.- The result is output as the
operationdata item.
Example transformations:
| Input | Output |
|---|---|
O1234(OP10-ROUGH-MILL) | OP10-ROUGH-MILL |
O5678(OP20-FINISH) | OP20-FINISH |
O9999(INSPECTION) | INSPECTION |
Passthrough with Filtering
Uses mtconnect-passthrough to pass all parent FOCAS data through, while adding transformed data items and filtering out internal ones.
Scenario: the parent FOCAS adapter provides 50+ data items. We want to pass all of them through unchanged, extract the operation and part number from the program comment, and block internal debug flags from reaching MachineMetrics.
version: 2
# Pass all parent FOCAS data through automatically
mtconnect-passthrough: true
# Pull specific items for transformation
declare-keys:
- program_comment
# Block these items from parent adapter
deny-keys:
- debug_mode
- internal_flag
- raw_alarm_buffer
# Transform program comment into structured data
variables:
# Extract operation: O1234(OP10-ROUGH) → OP10-ROUGH
operation:
- source: program_comment
- pattern-match:
pattern: /\(([^)]+)\)/
group: 1
# Extract part number: O1234(OP10-ROUGH) → 1234
part_number:
- source: program_comment
- pattern-match:
pattern: /O(\d+)/
group: 1
# Output transformed data items
data-items:
- operation
- part_number
Result: all 50+ FOCAS data items (spindle_speed, tool_number, execution, and so on) pass through, the new operation and part_number items are added, and the three items in deny-keys are filtered out.
Overriding Execution State
Use this pattern when the execution status reported by a parent adapter does not reflect what is actually happening on the machine. A machine may report ACTIVE even when an alarm means no real production is occurring. Declaring the parent execution as a key and redefining it through a variables state machine lets you override the status with logic that reflects the true machine state.
Scenario: the parent adapter reports pexecution, but alarm code 4773 indicates the machine is not truly running even when the status reads ACTIVE. The system.level field catches fault conditions.
version: 2
declare-keys:
- system
- pexecution
deny-keys:
- pexecution
variables:
modified-execution:
- state:
- ACTIVE: pexecution == "ACTIVE" and system.code != 4773
- FAULT: system.level == "FAULT"
- INTERRUPTED: true
data-items:
- modified-execution
How it works:
declare-keyspullssystemandpexecutionfrom the parent adapter.deny-keysblocks the originalpexecutionfrom passing through — the modified version replaces it.- The
modified-executionvariable re-evaluates execution state:ACTIVEonly when the parent reportsACTIVEand alarm 4773 is not active,FAULTwhen the system level indicates a fault, andINTERRUPTEDas the default fallback. modified-executionis output in place of the original execution data item.
When to use this pattern:
- The machine reports
ACTIVEduring alarms or non-production states, inflating utilization - A specific alarm code should suppress or change the reported execution state
- The system fault level needs to be reflected in execution rather than reported separately
- You need to reconcile execution state across multiple signals for a more accurate picture
Direct Connectivity Examples
Part Counter with Execution State
A direct connectivity adapter using EtherNet/IP.
version: 2
# Input - EtherNet/IP
slot: 1
scan-interval: 0.25
tags:
mode_auto: Module10.ModeAuto
cycle_complete: Module10.CycleComplete
fault_ind: Module10.FaultInd
spindle_on: Module10.SpindleRunning
# Transformation
variables:
execution:
- state:
- ACTIVE: mode_auto and spindle_on and fault_ind == 0
- INTERRUPTED: fault_ind > 0
- READY: true
part-count:
- source: cycle_complete
- rising-edge
- count
# Output
data-items:
- execution
- part-count
- spindle_on
conditions:
machine-fault:
message: Machine is in fault state
value:
FAULT: fault_ind > 0
If this double-counts parts, the cycle-complete signal is likely producing more than one rising edge per cycle — add debounce ahead of count.
Modbus Temperature Monitoring
version: 2
# Input - Modbus
unit-id: 1
byte-order: big
registers:
temp-raw:
address: 40001
type: int16
setpoint:
address: 40002
type: int16
# Transformation
variables:
temperature:
- source: temp-raw / 10 # Scale raw value
temp-status:
- state:
- HIGH: temperature > setpoint + 10
- LOW: temperature < setpoint - 10
- NORMAL: true
# Output
data-items:
- temperature
- setpoint
- temp-status
conditions:
temp-alarm:
- code: over-temp
message: Temperature exceeds setpoint by more than 10 degrees
value:
FAULT: temperature > setpoint + 10
- code: under-temp
message: Temperature below setpoint by more than 10 degrees
value:
WARNING: temperature < setpoint - 10
OPC-UA with a Calculated OEE Component
version: 2
# Input - OPC-UA
tags:
actual-speed: ns=2;s=Spindle.ActualSpeed
rated-speed: ns=2;s=Spindle.RatedSpeed
good-parts: ns=2;s=Production.GoodParts
total-parts: ns=2;s=Production.TotalParts
# Transformation
variables:
performance:
- source: (actual-speed / rated-speed) * 100
- expression: min(this, 100) # Cap at 100%
quality:
- source: total-parts > 0 ? (good-parts / total-parts) * 100 : 0
# Output
data-items:
- actual-speed
- performance
- quality
- good-parts
- total-parts
The total-parts > 0 ? ... : 0 guard avoids a divide-by-zero before the first part of a run completes.
Related
- Generating Scripts with AI — have Max write a script like these from a description
- Troubleshooting — what to check when a script does not behave as expected
- Operations — every available transform operation