Tutorial: Dynamic Templating

What Does This Tutorial Cover?

This tutorial will walk you through the basics of working with dynamic Templating. Templating is supported for Inputs, Instances, and Flows. Templating offers an efficient method for generating hundreds of configuration objects, with only minor variations between them. For example, if an OPC UA Server has 100 machines and the address of each machine only differs by a unique machineID, a single Input can represent all 100 machines.

When comparing dynamic Templating with static Templating, dynamic uses external values (example from a SQL table) to drive parameters into configuration components. In this tutorial, we’ll start by staging OPC UA tags with a parameter that will then associate with a dynamically Templated Instance. Our dynamic source will be a SQL input.

  • Tutorial Prerequisites
  • Tutorial Preparation
  • Tutorial Instructions
  • Tutorial Summary

Tutorial Prerequisites

  1. You have completed the initial Installation of the Intelligence Hub
  2. You have applied your Intelligence Hub license to your environment
  3. It is recommended to read the Getting Started Series before completing this tutorial exercise
  4. It is recommended to complete “Tutorial: Connections”, “Tutorial: Models and Instances” and “Tutorial: Static Templating”

Tutorial Preparation

  1. Enable Intelligence Hub MQTT broker

    • In the left-hand navigation panel, navigate to Manage, and click Settings
    • Under the MQTT Broker section enable the broker, if ports 1885 and 1886 are being utilized on your Intelligence Hub server, update to ports of your choosing, otherwise accept the defaults and click save
  2. Import the required Components

    • In the left-hand navigation panel, navigate to Manage, and click Project
    • Within the Import screen, ensure Full Project is off (otherwise your existing project will be overwritten
    • Change the Import Type to JSON and paste in the following with the Project box
{
	"productInfo": {
		"company": "HighByte",
		"product": "IntelligenceHub",
		"version": "3.2.0",
		"build": "2023.8.24.982",
		"stage": "Alpha"
	},
	"project": {
		"version": 5,
		"connections": [
			{
				"name": "Tutorial_CMMS_servicelogs",
				"uri": "jdbc.sqlserver://52.10.6.4:1433",
				"tags": [
					"Share",
					"Share2"
				],
				"writes": {
					"flattenModeledValues": false
				},
				"storeForward": {
					"enabled": false,
					"maxEntries": 100,
					"waitOnFailureInterval": {
						"duration": 1,
						"units": "Seconds"
					}
				},
				"settings": {
					"database": "serviceinfo",
					"username": "highbyte"
				}
			},
			{
				"name": "Tutorial_MQTT",
				"uri": "mqtt://0.0.0.0:1885",
				"tags": [
					"Share",
					"Share2"
				],
				"writes": {
					"flattenModeledValues": false
				},
				"storeForward": {
					"enabled": false,
					"maxEntries": 100,
					"waitOnFailureInterval": {
						"duration": 1,
						"units": "Seconds"
					}
				},
				"settings": {
					"connectionTimeoutSeconds": 10,
					"keepAliveSeconds": 60,
					"requestTimeoutMS": 5000,
					"cleanSession": true,
					"ssl": false,
					"redundantBrokers": [],
					"inputDiscovery": ""
				}
			},
			{
				"name": "Tutorial_OPC_UA",
				"uri": "opc.tcp://52.10.6.4:49320",
				"tags": [
					"Share",
					"Share2"
				],
				"writes": {
					"flattenModeledValues": false
				},
				"subscriptions": {
					"subscriptionRate": {
						"duration": 1,
						"units": "Seconds"
					}
				},
				"storeForward": {
					"enabled": false,
					"maxEntries": 100,
					"waitOnFailureInterval": {
						"duration": 1,
						"units": "Seconds"
					}
				},
				"settings": {
					"security": "None",
					"authentication": {
						"type": "Anonymous"
					},
					"connectTimeoutSeconds": 5,
					"requestTimeoutMS": 5000,
					"maxItemsPerRead": 512,
					"maxItemsPerWrite": 256,
					"certificateKeyPair": "app-certificate-private-key",
					"sessionName": ""
				}
			}
		],
		"inputs": [
			{
				"name": "Tutorial_All_Assets",
				"connection": "Tutorial_CMMS_servicelogs",
				"type": "jdbc.sqlserver",
				"qualifier": {
					"query": "select * from [dbo].[cmms_servicelogs]"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_All_Assets_CNC",
				"connection": "Tutorial_CMMS_servicelogs",
				"type": "jdbc.sqlserver",
				"qualifier": {
					"query": "select * from [dbo].[cmms_servicelogs] where [dbo].[cmms_servicelogs].[asset_type] = 'CNC'"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_AssetIDs",
				"connection": "Tutorial_CMMS_servicelogs",
				"type": "jdbc.sqlserver",
				"qualifier": {
					"query": "select  [dbo].[cmms_servicelogs].[asset_id] from [dbo].[cmms_servicelogs] where [dbo].[cmms_servicelogs].[asset_type] = 'CNC'"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Templated_Tutorial_CNC_Fanuc_Branch",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001",
					"dataType": "Auto",
					"type": "Branch",
					"maxDepth": 1,
					"cacheInterval": {
						"duration": 1,
						"units": "Hours"
					},
					"ignoreBadQuality": false,
					"browseVariableNodes": false
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_Branch",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial",
					"dataType": "Auto",
					"type": "Branch",
					"maxDepth": 1,
					"cacheInterval": {
						"duration": 1,
						"units": "Hours"
					},
					"ignoreBadQuality": false,
					"browseVariableNodes": false
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_AirPressure",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.AirPressure",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_AssetID",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.AssetID",
					"type": "Tag",
					"dataType": "String"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_AxisPositionX",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.AxisPositionX",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_AxisPositionY",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.AxisPositionY",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_AxisPositionZ",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.AxisPositionZ",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_CoolantpH",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.CoolantpH",
					"type": "Tag",
					"dataType": "Int16"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_CuttingSpeed",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.CuttingSpeed",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_FaultCode",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.FaultCode",
					"type": "Tag",
					"dataType": "Int16"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_FeedRate",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.FeedRate",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_MachineState",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.MachineState",
					"type": "Tag",
					"dataType": "Int16"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_MachineTemperature",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.MachineTemperature",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_PartProgramID",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.PartProgramID",
					"type": "Tag",
					"dataType": "String"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_PowerCurrent",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.PowerCurrent",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_PowerCurrentXAxis",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.PowerCurrentXAxis",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_PowerCurrentYAxis",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.PowerCurrentYAxis",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_PowerCurrentZAxis",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.PowerCurrentZAxis",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_ProductionCount",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.ProductionCount",
					"type": "Tag",
					"dataType": "Int16"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_RejectCount",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.RejectCount",
					"type": "Tag",
					"dataType": "Int16"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_SpindleLoad",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.SpindleLoad",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_SpindleSpeed",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.SpindleSpeed",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_SpindleTemperature",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.SpindleTemperature",
					"type": "Tag",
					"dataType": "Real32"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_StateDescription",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.StateDescription",
					"type": "Tag",
					"dataType": "String"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "Tutorial_CNC_Fanuc_1001_ToolID",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.ToolID",
					"type": "Tag",
					"dataType": "String"
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "_DynamicSource_Tutorial_CNC_Fanuc_MachineState",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.MachineState",
					"type": "Tag",
					"dataType": "Int16",
					"samplingInterval": {
						"units": "Seconds",
						"duration": 1
					}
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "_DynamicSource_Tutorial_CNC_Fanuc_PartProgramID",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.PartProgramID",
					"type": "Tag",
					"dataType": "String",
					"samplingInterval": {
						"units": "Seconds",
						"duration": 1
					}
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "_DynamicSource_Tutorial_CNC_Fanuc_RejectCount",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.RejectCount",
					"type": "Tag",
					"dataType": "Int16",
					"samplingInterval": {
						"units": "Seconds",
						"duration": 1
					}
				},
				"cacheLifetime": {
					"enabled": false
				}
			},
			{
				"name": "_DynamicSource_Tutorial_CNC_Fanuc_ToolID",
				"connection": "Tutorial_OPC_UA",
				"type": "opc.tcp",
				"qualifier": {
					"namespaceIndex": 2,
					"identifierType": "String",
					"identifier": "Tutorial.CNC_Fanuc_1001.ToolID",
					"type": "Tag",
					"dataType": "String",
					"samplingInterval": {
						"units": "Seconds",
						"duration": 1
					}
				},
				"cacheLifetime": {
					"enabled": false
				}
			}
		],
		"outputs": [
			{
				"name": "Tutorial_CNC_Output",
				"connection": "Tutorial_MQTT",
				"type": "mqtt",
				"qualifier": {
					"qos": 0,
					"namedRoot": false,
					"breakupArrays": true,
					"topic": "Tutorial/Templating/{{this.AssetID}}",
					"retained": false
				}
			},
			{
				"name": "Tutorial_CNC_Output_DynamicTemplate",
				"connection": "Tutorial_MQTT",
				"type": "mqtt",
				"qualifier": {
					"qos": 0,
					"namedRoot": false,
					"breakupArrays": true,
					"topic": "Tutorial/Templating/DynamicFlow/{{this.AssetID}}",
					"retained": false
				}
			},
			{
				"name": "Tutorial_CNC_Templated_Branch_Output",
				"connection": "Tutorial_MQTT",
				"type": "mqtt",
				"qualifier": {
					"qos": 0,
					"namedRoot": false,
					"breakupArrays": true,
					"topic": "Tutorial/Templating/TemplatedConnection/{{this.AssetID}}",
					"retained": true
				}
			},
			{
				"name": "Tutorial_CNC_Templated_Flow_Output",
				"connection": "Tutorial_MQTT",
				"type": "mqtt",
				"qualifier": {
					"qos": 0,
					"namedRoot": false,
					"breakupArrays": true,
					"topic": "Tutorial/Templating/TemplatedFlow/{{this._name}}",
					"retained": true
				}
			},
			{
				"name": "Tutorial_CNC_Templated_Instance_Output",
				"connection": "Tutorial_MQTT",
				"type": "mqtt",
				"qualifier": {
					"qos": 0,
					"namedRoot": false,
					"breakupArrays": true,
					"topic": "Tutorial/Templating/TemplatedInstance/{{this.AssetID}}",
					"retained": true
				}
			},
			{
				"name": "Tutorial_Model_Complex",
				"connection": "Tutorial_MQTT",
				"type": "mqtt",
				"qualifier": {
					"qos": 0,
					"namedRoot": false,
					"breakupArrays": false,
					"topic": "Tutorial/Model/Complex",
					"retained": false
				}
			},
			{
				"name": "Tutorial_Model_Simple",
				"connection": "Tutorial_MQTT",
				"type": "mqtt",
				"qualifier": {
					"qos": 0,
					"namedRoot": false,
					"breakupArrays": false,
					"topic": "Tutorial/Model/Simple",
					"retained": false
				}
			}
		],
		"modeling": {
			"models": [
				{
					"name": "CNC_Asset_Info",
					"tags": [
						"Share",
						"Share2"
					],
					"attributes": [
						{
							"name": "AssetID",
							"type": "String",
							"array": false,
							"required": true
						},
						{
							"name": "Temperature",
							"type": "Any",
							"array": false,
							"required": true
						},
						{
							"name": "Temperature_UOM",
							"type": "Any",
							"array": false,
							"required": false
						},
						{
							"name": "CuttingSpeed",
							"type": "Any",
							"array": false,
							"required": true
						},
						{
							"name": "PowerCurrent",
							"type": "Any",
							"array": false,
							"required": true
						},
						{
							"name": "FeedRate",
							"type": "Any",
							"array": false,
							"required": true
						},
						{
							"name": "LastServiceDate",
							"type": "Any",
							"array": false,
							"required": false
						},
						{
							"name": "LastServiceNotes",
							"type": "Any",
							"array": false,
							"required": false
						}
					]
				},
				{
					"name": "CNC_Asset_ServiceInfo",
					"tags": [
						"Share"
					],
					"attributes": [
						{
							"name": "AssetID",
							"type": "String",
							"array": false,
							"required": false
						},
						{
							"name": "LastServiceDate",
							"type": "Any",
							"array": false,
							"required": false
						},
						{
							"name": "LastServiceNotes",
							"type": "Any",
							"array": false,
							"required": false
						}
					]
				},
				{
					"name": "Enterprise_CNC_Model",
					"tags": [],
					"attributes": [
						{
							"name": "Enterprise",
							"type": "Any",
							"array": false,
							"required": false
						},
						{
							"name": "Site",
							"type": "Any",
							"array": false,
							"required": false
						},
						{
							"name": "Area",
							"type": "Any",
							"array": false,
							"required": false
						},
						{
							"name": "Line",
							"type": "Any",
							"array": false,
							"required": false
						},
						{
							"name": "Values",
							"type": "CNC_Asset_Info",
							"array": false,
							"required": false
						},
						{
							"name": "ProgramInfo",
							"type": "ProgramInfo_Model",
							"array": false,
							"required": false
						}
					]
				},
				{
					"name": "ProgramInfo_Model",
					"tags": [],
					"attributes": [
						{
							"name": "ProgramID",
							"type": "Any",
							"array": false,
							"required": false
						},
						{
							"name": "ToolID",
							"type": "Any",
							"array": false,
							"required": false
						},
						{
							"name": "MachineState",
							"type": "Any",
							"array": false,
							"required": false
						},
						{
							"name": "RejectCount",
							"type": "Any",
							"array": false,
							"required": false
						}
					]
				}
			],
			"instances": [
				{
					"name": "CNC_Asset_Info_Instance",
					"tags": [
						"Share",
						"Share2"
					],
					"model": "CNC_Asset_Info",
					"rootValueAs": "Object",
					"attributes": [
						{
							"name": "AssetID",
							"expression": "{{Connection.Tutorial_OPC_UA.Tutorial_CNC_Fanuc_1001_AssetID}}"
						},
						{
							"name": "Temperature",
							"expression": "({{Connection.Tutorial_OPC_UA.Tutorial_CNC_Fanuc_1001_MachineTemperature}}-32)*.5556"
						},
						{
							"name": "Temperature_UOM"
						},
						{
							"name": "CuttingSpeed",
							"expression": "{{Connection.Tutorial_OPC_UA.Tutorial_CNC_Fanuc_1001_CuttingSpeed}}"
						},
						{
							"name": "PowerCurrent",
							"expression": "{{Connection.Tutorial_OPC_UA.Tutorial_CNC_Fanuc_1001_PowerCurrent}}"
						},
						{
							"name": "FeedRate",
							"expression": "{{Connection.Tutorial_OPC_UA.Tutorial_CNC_Fanuc_1001_FeedRate}}"
						},
						{
							"name": "LastServiceDate",
							"expression": "{{Connection.Tutorial_CMMS_servicelogs.Tutorial_All_Assets_CNC}}[0].date"
						},
						{
							"name": "LastServiceNotes",
							"expression": "{{Connection.Tutorial_CMMS_servicelogs.Tutorial_All_Assets_CNC}}[0].notes"
						}
					]
				},
				{
					"name": "Enterprise_CNC_Model_Instance",
					"tags": [],
					"model": "Enterprise_CNC_Model",
					"rootValueAs": "Object",
					"attributes": [
						{
							"name": "Enterprise",
							"default": "Tutorial"
						},
						{
							"name": "Site",
							"default": "Site1"
						},
						{
							"name": "Area",
							"default": "Area1"
						},
						{
							"name": "Line",
							"default": "Line1"
						},
						{
							"name": "Values",
							"expression": "{{Instance.CNC_Asset_Info_Instance}}"
						},
						{
							"name": "ProgramInfo",
							"expression": "{{Instance.Enterprise_CNC_Model_Instance_ProgramInfo}}"
						}
					]
				},
				{
					"name": "Enterprise_CNC_Model_Instance_ProgramInfo",
					"tags": [],
					"model": "ProgramInfo_Model",
					"rootValueAs": "Object",
					"attributes": [
						{
							"name": "ProgramID",
							"expression": "{{Connection.Tutorial_OPC_UA.Tutorial_CNC_Fanuc_1001_PartProgramID}}"
						},
						{
							"name": "ToolID",
							"expression": "{{Connection.Tutorial_OPC_UA.Tutorial_CNC_Fanuc_1001_ToolID}}"
						},
						{
							"name": "MachineState",
							"expression": "{{Connection.Tutorial_OPC_UA.Tutorial_CNC_Fanuc_1001_MachineState}}"
						},
						{
							"name": "RejectCount",
							"expression": "{{Connection.Tutorial_OPC_UA.Tutorial_CNC_Fanuc_1001_RejectCount}}"
						}
					]
				}
			]
		},
		"flows": [],
		"conditions": [],
		"functions": [],
		"tags": [
			{
				"name": "Share"
			}
		],
		"pipelines": []
	},
	"network": {
		"groups": [],
		"hubs": []
	}
}
  1. Update the imported Connections as required

    • Navigate to Configure and click Connections, Click Tutorial_MQTT and Update the MQTT settings as required based on the prior preparation step #1

    • Navigate to Configure and click Connections, Click “Tutorial_CMMS_servicelogs”, type the following within the password field and click Save.

                          password
  1. Setup UNS Client

    • In the left-hand navigation panel, navigate to Tools and right click UNS client and open Link in New Tab
    • Enter login information
    • For Connection select Tutorial_MQTT
    • For Subscribed Topics remove the default wildcard entry # and Subscribe to Topic Tutorial/#
    • Click Add
    • Click Connect and confirm UNS client says “Connected to Tutorial_MQTT”
    • Return to the previous tab

Tutorial Instructions

  1. Review our Dynamic Templating source - this will show you where we are sourcing our Templating parameters from

    • Navigate to Connections

    • Select Tutorial_CMMS_servicelogs

    • Navigate to Inputs

    • Select Tutorial_CNC_AssetIDs

    • Review the query syntax and click Test Inputs

      • Note: we are staging an array of the asset_id values to use in our Dynamic Template, the asset_id value from our source is different from prior Tutorials (Fanuc_#### vs. #####)
  2. Stage parameters in source OPC UA inputs - Note in this step you will be updating OPC_UA input’s to have a parameter in the Identifier setting. We will NOT be enabling Templating from the Connection Layer but will drive the InputAssetID parameter set externally later in this Tutorial

    • Navigate to Connections

    • Select Tutorial_OPC_UA

    • Navigate to Inputs

    • Open _DynamicSource_Tutorial_CNC_Fanuc_MachineState

    • Within the Identifier, replace Fanuc_1001 with {{this.InputAssetID}}

      Before:
      Tutorial.CNC_Fanuc_1001.MachineState
      
      After:
      Tutorial.CNC_{{this.InputAssetID}}.MachineState
    • Click Save

    • Navigate back to the Inputs of Tutorial_OPC_UA and repeat the last step with the following Inputs:

      • _DynamicSource_Tutorial_CNC_Fanuc_PartProgramID
      • _DynamicSource_Tutorial_CNC_Fanuc_RejectCount
      • _DynamicSource_Tutorial_CNC_Fanuc_ToolID
      Before:
      Tutorial.CNC_Fanuc_1001.PartProgramID
      Tutorial.CNC_Fanuc_1001.RejectCount
      Tutorial.CNC_Fanuc_1001.ToolID
      
      
      After:
      Tutorial.CNC_{{this.InputAssetID}}.PartProgramID
      Tutorial.CNC_{{this.InputAssetID}}.RejectCount
      Tutorial.CNC_{{this.InputAssetID}}.ToolID
    • Note no data will be returned from the Test Input, this is expected

  3. Create a Dynamic Template within a new Instance

    • Navigate to Models

    • Select ProgramInfo_Model

    • Click actions, create Instance

    • From the new Instance details view, enter “ProgramInfo_Model_Instance_DynamicTemplate” as the name and click next

    • From the New Instance Model view, accept the default value and click next

    • From the new Instance attributes view, set the References panel to type Input and Connection Tutorial_OPC_UA

    • Using the References panel, map the following

      ProgramID - {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_PartProgramID}}
      ToolID - {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_ToolID}}
      MachineState -{{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_MachineState}}
      RejectCount - {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_RejectCount}}
    • Click Submit

    • Enable Use Template

    • Set type to Dynamic

    • From the References panel, set the type to Input and Connection to Tutorial_CMMS_servicelogs

    • From the References panel, map Tutorial_CNC_AssetIDs to the Template Reference field

    • Add {{this.asset_id}} as the Template name

    • Add “(InputAssetID={{this.asset_id}})” to our each of our attribute expressions after _Fanuc_TagName

      Before:
      {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_PartProgramID}}
      {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_ToolID}}
      {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_MachineState}}
      {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_RejectCount}}
      
      After:
      {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_PartProgramID(InputAssetID={{this.asset_id}})}}
      {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_ToolID(InputAssetID={{this.asset_id}})}}
      {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_MachineState(InputAssetID={{this.asset_id}})}}
      {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_RejectCount(InputAssetID={{this.asset_id}})}}
    • Click save

    • Click Test Instance and review the results

To recap, what we just configured was a Dynamic Template configuration. We utilized the asset_id column from our Tutorial_CMMS_servicelogs connection, and dynamically passed this into the instance and ultimately to the OPC UA tag connection. This also is a lesson on dynamically passing parameters from object to object. This works because our source OPC UA tags have {{this.InputAssetID}} configured within the identifier.

  1. Review the Output target

    • Navigate to Connections
    • Select Tutorial_MQTT
    • Navigate to Outputs
    • Select Tutorial_CNC_Templated_Flow_Output and review the configuration
    • Take note we having a dynamic reference of {{this._name}} within our topic - this will utilize the internal attribute _name as our breakup topic
  2. Create a new Flow - note in order to build a practical example of a Templated Flow, we will be using Flow Event mode and OnChange publish mode to monitor a templated event source

    • Navigate to Instances
    • Select ProgramInfo_Model_Instance_DynamicTemplate
    • Click actions, create Flow
    • From the New Flow details screen, accept the defaults and click next
    • From the New Flow sources & targets screen, set the Reference panel type to Output
    • In the Reference panel set Connections to Tutorial_MQTT
    • From the Reference panel, map Tutorial_CNC_Templated_Flow_Output to the target
    • Click next
    • From the New Flow settings screen, set the type to Event
    • Set the Mode to On Change
    • Using the Reference panel, set type to Input and Connection to Tutorial_OPC_UA
    • Map {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_MachineState}} to the expression field
    • Leave the enabled flag off as we still need to Template our new Flow
    • Click submit
  3. Template the new Flow

    • Within the new Flow, Enable Use Template

    • Set type to Dynamic

    • From the References panel, set the type to Input and Connection to Tutorial_CMMS_servicelogs

    • From the References panel, map Tutorial_CNC_AssetIDs to the Template Reference field

    • Add {{this.asset_id}} as the Template name

    • Within the Setting’s expression add “(InputAssetID={{this.asset_id}})” to the end of the expression after _MachineState

      Before:
      {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_MachineState}}
      
      After:
      {{Connection.Tutorial_OPC_UA._DynamicSource_Tutorial_CNC_Fanuc_MachineState(InputAssetID={{this.asset_id}})}}
    • Within the Sources panel, click the pencil icon next to your Instance source

    • Add “(asset_id={{this.asset_id}})” after _DynamicTemplate

      Before
      {{Instance.ProgramInfo_Model_Instance_DynamicTemplate}}
      After
      {{Instance.ProgramInfo_Model_Instance_DynamicTemplate(asset_id={{this.asset_id}})}}
    • Click enable

    • Click save and review the results in the UNS Client

Take note we just configured a Flow that is dynamically passing static template parameters (asset_id) to two separate objects. The first object was to the source Instance to link the Flow parameters with the Instance dynamic parameters. The second object was to the Flow event source OPC UA tag to control the flow execution. As you can see in your UNS client, we are only seeing Fanuc_1002 and Fanuc_1003 as the event values are changing. Fanuc_1001 has a simulated MachineState that is NOT changing.

Tutorial Summary

This tutorial covered how to utilize templating within Intelligence Hub components to assist in scaling successful use cases from one configuration object to many. Templating can happen within Inputs, Instances and Flows. We covered how to connect multiple templated objects together to ensure consistency with our use cases.