Tag transforms facilitate powerful analytics, that are not easily possible with measures and events alone. Tag transforms also extend measures and events to give us data points in real-time about the value of a measure or event.
First, let's look at the options that Tag Transforms provide for Tags.
"Tag" Tag Transforms
By default, a tag retrieves all available data points from a data source for the period it is evaluated. This is referred to as time-series data. When multiple tags are used in a calculated tag, each tag's data points are evaluated in a wide query format - from period start to period end, each time one of the tag values changes, a new row is created with the timestamp of the change and the value for each tag at that timestamp. A tag's value is presumed unchanged from the previous timestamp (unless it is the tag whose value changed, of course).
Range
But what if we wanted to determine the slope, or instantaneous rate of change, of a process variable? In this case, we need to know the tag value at the period start, and we also need to know the previous value before the period starts. In this case, Flow provides a "Range" Tag Transform, where one can configure the number of seconds (the Offset) for which values for the Source tag must be retrieved. Every time Flow processes the Source Tag, it will also return all the values before "now" for the offset number of seconds. These values are returned as an array of values in the tag. One can then use a calculation to evaluate the instantaneous rate of change.
In the example below, a Tank Level Tag is transformed using a Range tag transform, which returns the last 30 seconds of level data.
This tag is then passed into a calculated tag, which calculates the rate of change of level (i.e. the slope) by using the values of the last 2 data points from the range tag transform, as well as the duration between those points. Remember that the range tag transform returns an array of values, so you have to use the specific points that you are interested in.
The calculated "slope" tag is then plotted against the tank level tag - see how the slope is correctly evaluated: it is negative when the tank is emptying, positive when the tank is filling, and zero when there is no change in the tank level.
One can loop through the points in a user defined function by passing the Tag Proxy object to your function and looping through the Points array on the object:
The entire Tag Proxy can then be passed to the function.
Offset
Another type of tag transform is the "Offset" transform. This allows one to fetch a single Source tag value from the offset number of seconds ago. Let's say that, instead of the instantaneous rate of change of a process value, we're only interested in the rate of change evaluated every 15 seconds. In this case, we could use an Offset transform with the Offset configured to 15. Of course, we could use the Range transform with an offset of 15 and then select the first value from the array. But this would then require an additional calculated tag to select that first value.
In the image below, the source tag represents the number of seconds that have elapsed each minute. Using an Offset tag transform, with the Offset set to 5 seconds, note how the value returned is the seconds value from 5 seconds ago.
Latch
The last type of "tag" tag transform is a "Latch" transform. This is used when we want to reference a tag's value when a specific condition occurs. This could be when an Event is triggered, or at the start of a specific calendar interval.
In the example below, a tag representing the hours elapsed in the day is used as the source of a latch tag transform. The latch "trigger" is a calendar, with the interval configured as Day(s). The purpose of this is to latch the hour value at the start of the day. As expected, the value returned is 5, since this calendar day starts at 05:00 UTC.
"Measure" Tag Transforms
Measures generate values every time their interval type time period completes. For example, a daily measure generates a value at the end of each day. Sometimes, we may want to use measure values within a tag calculation. To do this, we need to apply a "measure" tag transform to a measure, which returns the appropriate measure values for the high-resolution tag periods.
Measure Value & Quality
For example, let's say we have a monthly measure for the Peak Electricity Usage Demand target. Being a monthly measure, the value can change at most once a month. Also, we can only use this measure as it is in other monthly measures. But what if we wanted to compare the instantaneous Electricity Usage, which we have a tag for, with the monthly target, and if exceeded the target, we wanted to trigger an event?
With a "measure" tag transform, we can use the monthly measure as a Source to the transform and return the Value of the target value for each timestamp for which we have an instantaneous Electricity Usage value.
Another option is to return the measure's Quality.
Measure Limit Exception
One more measure tag transform is to get the limit exceptions of a measure into a tag. Perhaps you want to trigger an event when a minutely measure has a limit exception. One example of this is where you have a minutely measure that evaluates the change in level in a tank (using the Delta retrieval aggregation type). According to your process, the tank should not fill or empty faster than 200l a minute. So you configure a limit on the measure and set the High and Low limit values to 200. But you also want to trigger an event named "Fill Control" whenever this happens. In this case, you would use a tag transform to get any exceptions from the minutely measure into a tag, and then use that tag as a trigger for the Fill Control event.
A measure tag transform that is used to evaluate "Any" limit exceptions will return a value of 0 if there is no exception during a time period, +1 if there is a high-value exception, and -1 if there is a low-value exception.
"Event" Tag Transforms
At times, we may want to use the status of an event when evaluating other conditions. Perhaps we have an event that must not be triggered if another event is active. For example, we may have an event named "Water Push" which is active when we are priming a vessel for product transfer. At the same time, we are monitoring the vessel level for large changes using an event named "Fill Control" as described above. But we don't want Fill Control to trigger if the Water Push event is active.
A longwinded way to do this is to reuse all the conditions that trigger Water Push and invert their logic in the Fill Control. A better way is to use an event tag transform which returns a value that represents whether Water Push is active or not.
In the example below, two event tag transforms have been used: one to monitor the change in state of the Mixer 1 Batch event, and the other to monitor the Filler 1 Stop event. A calculated tag is used to evaluate whether both equipment have stopped.
Previewing this calculated tag along with both the Mixer 1 Batch and Filler 1 Stop events, you can see that this tag does indeed tell us when both equipment have stopped.