Templates for Point Messages and MQTT Topics

This guide explains how to write templates for point messages and MQTT topics in the Factry Historian system. Templates define the structure of MQTT messages and topics, enabling dynamic generation of content and paths based on specific data. This guide outlines available fields, functions, and examples for common use cases.


Overview

Templates are written using Go’s text/template syntax. Each template type has a specific context object, which determines the fields and functions available. Placeholders ({{ }}) are used to dynamically insert data.

Example: Point Message Template

1
2
3
4
5
6
{
    "Measurement": "{{(GetMeasurement .).Name}}",
    "Value": {{ toJson .Value }},
    "Timestamp": "{{ .Timestamp }}",
    "Status": "{{ .ErrorStatus }}"
}

Example: Topic Template

/devices/{{(GetCollector .).Name}}/measurements/{{ .Measurement }}

Template Types

  1. Point Message Templates:

    • Used to define the content of MQTT messages for collected data points.
  2. Measurement Topic Templates:

    • Used to define the MQTT topic structure for measurements.
  3. Asset Property Topic Templates:

    • Used to define the MQTT topic structure for asset properties.

Quick Reference

Commonly Used Fields (Point Message Templates)

  • Timestamp: The time when the point was created.
  • Value: The actual value of the measurement.
  • ErrorStatus: The status or error description for the point.
  • MeasurementUUID: The unique identifier for the measurement.

Commonly Used Functions

  • GetMeasurement .: Fetches information about the measurement.
  • GetAsset .: Fetches information about the associated asset.
  • toJson: Converts data to JSON format.

Detailed Reference

Point Message Templates

Field Description
Timestamp ISO 8601 formatted timestamp for the data point.
Value The value of the measurement.
Tags Metadata tags for the point.
ErrorStatus Error status of the point, if applicable.
MeasurementUUID UUID of the associated measurement.
AssetPropertyUUID UUID of the associated asset property, if applicable.
Available Functions
Function Description
GetMeasurement . Fetches details about the measurement.
GetAsset . Fetches details about the associated asset.
GetAssetProperty . Fetches details about the associated asset property.
GetDatabase . Fetches details about the associated database.
GetCollector . Fetches details about the associated collector.

Measurement Topic Templates

Field Description
Measurement Name of the measurement.
Database Name of the associated database.
Collector Name of the associated collector.
UUID UUID of the measurement.
Available Functions
Function Description
GetMeasurement . Fetches details about the measurement.
GetDatabase . Fetches details about the associated database.
GetCollector . Fetches details about the associated collector.

Asset Property Topic Templates

Field Description
AssetPath Path of the asset (e.g., Plant/Area/Device).
Asset Name of the associated asset.
AssetProperty Name of the associated asset property.
UUID UUID of the asset property.
Available Functions
Function Description
GetAsset . Fetches details about the asset.
GetAssetProperty . Fetches details about the asset property.
GetMeasurement . Fetches details about the associated measurement.
GetDatabase . Fetches details about the associated database.
GetCollector . Fetches details about the associated collector.

Fields in Function Return Types

GetMeasurement

Field Description
Name Name of the measurement.
Datatype Data type of the measurement.
Description Description of the measurement.
Labels Labels associated with the measurement.
Quality Quality of the measurement.
Status Status of the measurement (e.g., Active).
CollectorUUID UUID of the associated collector.
DatabaseUUID UUID of the associated database.

GetAsset

Field Description
Name Name of the asset.
AssetPath Path of the asset (e.g., Plant/Area/Device).
Description Description of the asset.
Status Current status of the asset.
ParentUUID UUID of the parent asset, if any.

GetAssetProperty

Field Description
Name Name of the asset property.
Description Description of the property.
Datatype Data type of the property (e.g., string).
AssetUUID UUID of the associated asset.
MeasurementUUID UUID of the associated measurement.

GetDatabase

Field Description
Name Name of the database.
Description Description of the database.
Status Status of the database.

GetCollector

Field Description
Name Name of the collector.
Description Description of the collector.
Status Status of the collector.
IPAddress IP address of the collector.
BuildVersion Build version of the collector.

Sprig: Extending Template Capabilities

These templates support Sprig, a library of additional functions that extend the capabilities of Go templates. With Sprig, you can perform tasks like string manipulation, mathematical calculations, and handling default values, making your templates more flexible and dynamic.

For a complete list of available Sprig functions and their usage, refer to the official documentation: Sprig Functions Documentation .


Performance Considerations for Templates

Efficient templates are crucial for maintaining system performance, especially when working with dynamic data in high-throughput environments. Keep the following in mind while creating templates:

  1. Simplify Template Logic:

    • Avoid overly complex or deeply nested expressions that can slow down rendering.
  2. Use Default Values:

    • Handle missing data gracefully with defaults to prevent errors and reduce processing overhead.
  3. Minimize Function Overhead:

    • Reuse computed values within the template by assigning them to variables using with, range or directly.

By following these guidelines, you can ensure your templates are both powerful and optimized for performance.


Example Templates

Point Message Template

Basic message with measurement name and value:

1
2
3
4
5
{
    "Measurement": "{{(GetMeasurement .).Name}}",
    "Value": {{ toJson .Value }},
    "Timestamp": "{{ .Timestamp }}"
}

Include detailed information about the measurement, - is used to remove whitespace:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
    {{- $measurement := GetMeasurement . -}}
    "Measurement": {
        "Name": "{{ $measurement.Name }}",
        "Datatype": "{{ $measurement.Datatype }}",
        "Status": "{{ $measurement.Status }}"
    },
    "Value": {{ toJson .Value }},
    "Timestamp": "{{ .Timestamp }}"
}

Include the name and path of the associated asset:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
    {{- $asset := GetAsset . -}}
    "Asset": {
        "Name": "{{ $asset.Name }}",
        "Path": "{{ $asset.AssetPath }}"
    },
    "Measurement": "{{(GetMeasurement .).Name}}",
    "Value": {{ toJson .Value }},
    "Timestamp": "{{ .Timestamp }}"
}

A detailed message that combines information from the point, measurement, and associated asset property:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
    {{- $measurement := GetMeasurement . -}}
    {{- $assetProperty := GetAssetProperty . -}}
    {{- $asset := GetAsset . -}}
    "Measurement": {
        "Name": "{{$measurement.Name}}",
        "Datatype": "{{$measurement.Datatype}}",
        "Labels": {{ toJson $measurement.Labels }},
        "Status": "{{$measurement.Status }}"
    },
    "Value": {{ toJson .Value }},
    "Timestamp": "{{ .Timestamp }}",
    "Error": "{{ .ErrorStatus }}",
    "Tags": {{ toJson .Tags }},
    "AssetProperty": {
        "Name": "{{$assetProperty.Name}}",
        "Description": "{{$assetProperty.Description}}"
    },
    "Asset": {
        "Name": "{{$asset.Name}}",
        "Path": "{{$asset.AssetPath}}"
    }
}

Add a category field based on the value range, making sure the numbers are compared as floats:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
    "Measurement": "{{ (GetMeasurement .).Name }}",
    "Value": {{ toJson .Value }},
    "Timestamp": "{{ .Timestamp }}",
    "Category": "{{-
        if lt (float .Value) 10.0 -}}
            Low
        {{- else if and (ge (float .Value) 10.0) (lt (float .Value) 50.0) -}}
            Medium
        {{- else -}}
            High
        {{- end -}}"
}

Include custom labels for the measurement:

1
2
3
4
5
6
7
8
9
{
    {{- $measurement := GetMeasurement . -}}
    "Measurement": "{{ $measurement.Name }}",
    "Labels": [{{- range $index, $label := $measurement.Labels -}}
        "{{ $label }}"{{ if lt (add1 $index) (len $measurement.Labels) }}, {{ end }}
    {{- end -}}],
    "Value": {{ toJson .Value }},
    "Timestamp": "{{ .Timestamp }}"
}

Show asset data if it’s available

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
    {{- with GetAsset . }}
    "Asset": {
        "Name": "{{.Name}}",
        "Path": "{{.AssetPath}}"
    },
    {{- else }}
    "Asset": null,
    {{- end }}
    "Measurement": "{{(GetMeasurement .).Name}}",
    "Value": {{ toJson .Value }},
    "Timestamp": "{{ .Timestamp }}"
}

Measurement Topic Template

/measurements/{{ .Measurement }}/databases/{{ .Database }}/collectors/{{ .Collector }}

Asset Property Topic Template

/assets/{{ .Asset }}/properties/{{ .AssetProperty }}/path/{{ .AssetPath }}