Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Prerequisites

Familiarity with creating event scripts and tag trees in Designer

Installation of Cirrus Link Modules at v4.0.10 or greater and familiarity with configuring the modules

  • Distributor
  • Transmission
  • Engine

Abstract

Tag Latching is used for synchronizing events at an Ignition Gateway running MQTT Engine when using tag change scripts.

If tag change events are occurring very quickly (many times per second) this can lead to synchronization problems in tag change scripts and the use of trigger and latch tags can be used resolve this. Another scenario for rapidly changing tags is when the Edge Node is flushing large volumes of historical data and MQTT Engine is configured to write these historical events directly to the tag. 

In this tutorial we will show how to use trigger and tag latches to synchronize events.

System Setup - Transmission

In the MQTT Transmission module, create a Transmitter pointing to the default Tag Provider with Edge Nodes as the Tag Path:Image Modified

System Setup - Designer

In Designer, create a file structure under the default tag provider as shown below and confirm that the data tags are reported in MQTT engine:

Now to simulate change events at the Edge (MQTT Transmission), we will add the following Gateway Event Timer script with a delay of 1,000ms which will write the same value to both Data1 and Data2 tags once per second. (Scripts to use/copy can be found here)


We will also add a Gateway Tag Change script for that compares the Data1 and Data2 tags at MQTT Engine to verify they are the same using [MQTT Engine]Edge Nodes/G1/E1/D1/Data1 as our trigger tag. (Scripts to use/copy can be found here)


Note

Make sure to save your project in Designer for these changes to take effect.


Now when we look the the Logs in Ignition, we can see the following output as expected showing Data1 and Data2 have the same value.


The problem arises when MQTT Engine is calling 'update tag' on both Data1 and Data2 very quickly (many times a second). This can lead to synchronization problems in our tag change script because by the time the script is reading Data2, MQTT Engine has already written a new value to it and we end up with an erroneous output.

To simulate this scenario, let's edit the Gateway Timer Script and set the delay to only 5ms

Now when we look the the Logs in Ignition, we can see the following output showing that the values are out of synchronization.  


Configuring Tag Latching

When this happens, we can use tag latching to synchronize MQTT Engine with the tag change script.

The configuration for Tag Latching is available under MQTT Engine General tab > Advanced Settings with the following properties:

  • Enable Tag Latching
    • Whether or not to enable Tag latching to synchronize MQTT Tag updates with events in Ignition.
  • Latch Timeout

    • The amount of time in milliseconds MQTT Engine will to wait for a tag latch to be released before does it on its own.
  • Latch Tags

    • A semicolon separated list comma separated list of Trigger Tag and Latch Tag pairs.
    • A 'Trigger Tag' is a 'real tag' that you would normally use in a standard Transaction Group or Tag Change Script as a trigger.
    • The 'Latch Tag' is a tag that will be created in the [MQTT Engine]Engine Info/Latches folder. Each latch tag will be set to true when MQTT Engine calls updateTag for that given trigger tag. Then MQTT Engine waits until the timeout or until the latch tag gets set back to false by a script, transaction group, etc - which ever comes first. The latch tag is what should be used by scripts or transaction groups and must be set back to false at the end of the operation to allow MQTT Engine to continue processing incoming Sparkplug messages.
    • The 'Latch Tags' must be of the form:
      • Group ID/Edge Node ID/Device ID/Trigger Tag,Group ID/Edge Node ID/Device ID/Latch Tag for example:
      • G1/E1/D1/Trigger Tag 1,G1/E1/D1/Latch Tag 1
    • You can also have longer folder paths on any trigger tag or latch tag.  For example:
      • G1/E1/D1/my/longer/tag/path/Trigger Tag 1,G1/E1/D1/my/longer/path/Latch Tag 1
    • If you want to specify two or more latches, separate them with a semicolon:
      • G1/E1/D1/Trigger Tag 1,G1/E1/D1/Latch Tag 1;G1/E1/D1/Trigger Tag 2,G1/E1/D1/Latch Tag 2
    • You can also specify multiple trigger tags for any given latch.  Just create two or more entries that each point to the same latch tag:
      • G1/E1/D1/Trigger Tag 1,G1/E1/D1/Latch Tag 1;G1/E1/D1/Trigger Tag 2,G1/E1/D1/Latch Tag 1
    • You can specify as many as trigger and latch tags as you want.

Edit the configuration as shown below to set the Latch Tags field as 'G1/E1/D1/Data1,G1/E1/D1/Latch'. 

Note
Note we are using Data1 as the trigger tag since that is the 'trigger' for our existing tag change script.


With this set, MQTT Engine will now set a new tag '[MQTT Engine]Engine Info/Latches/G1/E1/D1/Latch' to true every time the trigger tag changes. 

Warning

It is the responsibility of the script, transaction group, or external application to reset the latch tag to allow MQTT Engine to continue processing data normally. If this is not done MQTT Engine will stop processing incoming change events until the 'Latch Timeout' elapses. 

It should also be noted that this does have a performance impact on MQTT Engine. Because we must synchronize the processing of incoming events MQTT Engine will not process these events as quickly. From the time MQTT Engine sets the latch and the script releases it, MQTT Engine pauses all processing of tag change events.


So for this example, the tag change script is modified as follows to release the latch at the end of the script. (Scripts to use/copy can be found here)

Now with this setup, we can see the output is correct as shown below. Note all of this output came from within the same second.

Anchor
GatewayScripts
GatewayScripts
Gateway Event Scripts

Code Block
languagepy
titleGateway Timer Script
value = system.tag.read("[default]Edge Nodes/G1/E1/D1/Data1").value
value += 1
if value > 500:
  value = 0
 
system.tag.writeSynchronous("[default]Edge Nodes/G1/E1/D1/Data2", value, 30)
system.tag.writeSynchronous("[default]Edge Nodes/G1/E1/D1/Data1", value, 30)


Code Block
languagepy
titleGateway Tag Change Script
#add logger
logger = system.util.logger("com.cirruslink.test.MQTTEngine.latching")

dataOneValue = newValue.getValue()
dataTwoValue = system.tag.read("[MQTT Engine]Edge Nodes/G1/E1/D1/Data2").value
logger.info("Values: " + str(dataOneValue) + " => " + str(dataTwoValue))


Code Block
languagepy
titleGateway Tag Change Script with Latching
#add logger
logger = system.util.logger("com.cirruslink.test.MQTTEngine.latching")

dataOneValue = newValue.getValue()
dataTwoValue = system.tag.read("[MQTT Engine]Edge Nodes/G1/E1/D1/Data2").value
logger.info("Values: " + str(dataOneValue) + " => " + str(dataTwoValue))

# Free the latch
system.tag.writeSynchronous("[MQTT Engine]Engine Info/Latches/G1/E1/D1/Latch", False, 45)





Additional Resources