I am attempting to create a tag that will represent the change in an OPC tags value over the previous 60 seconds. I have flirted with a few ideas on how to do this, but have run into some potential issues with each version i tried.
First, I attempted to just create an expression tag that is on a much slower scan class that takes the value of the OPC tag every 60 seconds (scan class execution). That way, there would be a tag that represents the current count value (OPC tag) as well as a tag that represents its value 60 seconds ago. This tag would then have a tag change event script that would calculate the delta and write its “previousValue” to a 3rd memory tag. The issue I ran into here was that when the machine was off, or not running, the delta value would stay what it was previously (since the tag change event script would never trigger), when it ideally would change to 0.
Next, I tried to create a gateway script that could be launched from an expression tags runScript() function. Essentially, the expression tag on the 60 second scan class would pass the tag paths of the two tags it needs a delta calculation on (the OPC tag and itself [the slower 60 second scan class tag]), do a system.tag.read() on them both and then return the difference. This resulted in slightly inaccurate delta calculations when compared to the OPC tag totalized. I believe this is due to the small time difference between the scan class execution and the script running which would result in small discrepancies since the OPC tag is pretty high-speed.
A last thought I had would be to utilize the historian and every 60 seconds query the tag history and compare it to the current value. But if this is something that will be done for multiple tags in the future, a bunch of tag historian scripts executing every minute seems pretty heavy.
Does anyone have better ideas than the few I have came up with? We would really like to get an accurate, light, and simplistic solution to this. But if it does not exist then perhaps we should look at changing the way we report the counts.
You’d make an expression tag of dataset type, and use recorder() to sample the tag of interest at the desired fast rate, with the row limit set to yield sixty seconds of samples. Something like this:
There’s a bit of a visual issue remaining that I don’t plan to fix. The output of the recorder() function (and the view() function, too) is a TransientDataset, not a normal Dataset. This type of dataset serializes to zero rows. It is intended to prevent bloated project resources when datasets are part of a component. This means that recorder() output will always show zero rows in the designer, even though they really are there in the gateway. Here’s an export of a set of tags testing and demonstrating this behavior. The Recording tag shows in the tag browser with zero rows, even though it ends up with twenty rows.