Tag Processor
The Tag Processor is designed to prepare incoming data for the UMH data model. It processes messages through three configurable stages: defaults, conditional transformations, and advanced processing, all using a Node-RED style JavaScript environment.
Use the tag_processor compared to the nodered_js when you are processing tags or time series data and converting them to the UMH data model within the _historian data contract. This processor is optimized for handling structured time series data, automatically formats messages, and generates appropriate metadata.
Message Formatting Behavior
The processor automatically formats different input types into a consistent structure with a "value" field:
Simple Values (numbers, strings, booleans) Input:
42Output:
{
"value": 42
}Input:
"test string"Output:
{
"value": "test string"
}Input:
trueOutput:
Arrays (converted to JSON string representation) Input:
Output:
Objects (preserved as JSON objects) Input:
Output:
Numbers (preserved as numbers) Input:
Output:
Input:
Output:
This consistent formatting ensures that:
All messages have a "value" field
Simple types (numbers, strings, booleans) are preserved as-is
Complex types (arrays, objects) are converted to JSON string representations
Numbers are always preserved as numeric types (integers or floats)
Breaking change in v4.0.0: Arrays now serialize to JSON format
["a","b","c"]instead of space-separated format[a b c]. This preserves type information and enables array parsing in downstream processors.
Configuration
Processing Stages
Defaults
Sets initial metadata values
Runs first on every message
Must return a message object
Conditions
List of conditional transformations
Each condition has an
ifexpression and athencode blockRuns after defaults
Must return a message object
Advanced Processing
Optional final processing stage
Can modify both metadata and payload
Must return a message object
How Metadata Works
The tag processor uses a two-step process for handling metadata:
JavaScript Stage - Working with
msg.metaIn your JavaScript code (defaults, conditions, advancedProcessing), you work with the
msg.metaobject:At this stage, these are just JavaScript object properties - they're not yet actual Benthos metadata.
Conversion to Benthos Metadata
After the JavaScript processing is complete, the tag processor extracts all properties from the
msg.metaJavaScript object and converts them to actual Benthos message metadata.Final Message Structure
Important: Properties set on
msg.metabecome message metadata, not part of the payload.Metadata (accessible via message metadata):
location_path: "enterprise.site.area"data_contract: "_historian"tag_name: "temperature"virtual_path: "axis.x.position"umh_topic: "umh.v1.enterprise.site.area._historian.axis.x.position.temperature" (auto-generated)topic: "umh.v1.enterprise.site.area._historian.axis.x.position.temperature" (auto-generated, deprecated)
Payload (the actual message content):
Integration with UNS Output
The tag processor is typically used together with the uns output plugin, which is the standard way to publish data into the United Manufacturing Hub. Here's how metadata flows from tag processor to UNS:
Metadata to UNS Headers: All metadata fields set by the tag processor become UNS headers, preserving the complete context and routing information.
UMH Topic as Routing Key: The auto-generated
umh_topicmetadata becomes the UNS routing key, enabling efficient message routing and topic-based subscriptions.Payload Preservation: The structured payload (with
valueandtimestamp_ms) is published as-is to the UNS.
Complete Flow Example:
Input Message: 23.5
UNS Record Result:
UNS Topic:
umh.messages(fixed UNS topic)UNS Routing Key:
umh.v1.enterprise.site.area._historian.temperature(fromumh_topicmetadata)UNS Value:
{"value": 23.5, "timestamp_ms": 1647890123456}(structured payload)UNS Headers:
Metadata Fields
The processor uses the following metadata fields:
Required Fields:
location_path: Hierarchical location path in dot notation (e.g., "enterprise.site.area.line.workcell.plc123")data_contract: Data schema identifier (e.g., "_historian", "_analytics")tag_name: Name of the tag/variable (e.g., "temperature", "pressure")
Optional Fields:
virtual_path: Logical, non-physical grouping path in dot notation (e.g., "axis.x.position")
Generated Fields:
umh_topic: Automatically generated from the above fields in the format:Empty or undefined fields are skipped, and dots are normalized.
Message Structure
Messages in the Tag Processor follow the Node-RED style format:
Examples
Basic Defaults Processing
Input:
Output:
UMH Topic: umh.v1.enterprise.plant1.machiningArea.cnc-line.cnc5.plc123._historian.actual
OPC UA Node ID Based Processing
Input with metadata opcua_attr_nodeid: "ns=1;i=2245":
Output:
UMH Topic: umh.v1.enterprise.plant1.machiningArea.cnc-line.cnc5.plc123._historian.axis.x.position.actual
Moving Folder Structures in Virtual Path
Input messages with OPC UA tags:
Output UMH topics will be:
This example shows how to:
Match an entire folder structure using
includes("DataAccess_AnalogType")Move all matching nodes into a new virtual path prefix (
axis.x)Preserve the original folder hierarchy under the new location
Apply consistent location path for the entire folder structure
Advanced Processing with getLastPayload
getLastPayload is a function that returns the last payload of a message that was avaialble in Kafka. Remember that you will get the full payload, and might still need to extract the value you need.
This is not yet implemented, but will be available in the future.
Input:
Output:
UMH Topic: umh.v1.enterprise.site.area.line.workcell._analytics.work_order
Dropping Messages Based on Value
Input:
Output: Message is dropped (no output)
Input:
Output:
UMH Topic: umh.v1.enterprise._historian.temperature
Duplicating Messages for Different Data Contracts
Input:
Output 1 (Historian):
UMH Topic: umh.v1.enterprise.production._historian.temperature
Output 2 (custom):
UMH Topic: umh.v1.enterprise.production._custom.temperature_doubled
Processing Full MQTT Message Payload
Input:
Output:
UMH Topic: umh.v1.enterprise.area._workorder.maintenance
Setting Custom Timestamps
By default, the tag processor uses the current time. You can set custom timestamps using the timestamp_ms metadata field (Unix milliseconds or RFC3339Nano as string):
Note: In the tag_processor, the resulting payload will always include timestamp_ms and one additional key corresponding to the tag_name. If you need to fully control the resulting payload structure, consider using the nodered_js processor instead. You can set the topic and payload manually, as shown below:
Last updated

