Is their a way to retrieve the value of the last successful calculation?
To get the previous archive value and timestamp of a tag you can use the two methods PrevVal and PrevEvent.
PrevEvent([TimeStamp]) as PITime
And here are how you would use them:
TempVar = Sinusoid.PrevVal("1-1-01 1am")
TempVar = Cdm158.PrevEvent(Now-0.1).LocalDate
Set TempVar = Cdm158.PrevEvent
If you need the last snapshot value then you would need to set take care of that programmatically. As you know, due to compression, the last snapshot value could be different from the last archive value. To simplify the discussion, let us assume that we would like to get the last snapshot value of the PI tag SINUSOID. SINUSOID should be defined as an input tag (or as both input tag and output tag) since the snapshot value for an output tag is never retrieved. The scheduling type needs to be set to Natural and the trigger tags include SINUSOID.
Within the ACE Module, we define a module-level variable (say LastSnapshotValue) and initialize it with the current snapshot value (e.g., LastSnapshotValue = SINUSOID.Value). When SINUSOID receives a new snapshot event, it would trigger a calculation. Then LastSnapshotValue is truly the last snapshot value and should be reset to the current snapshot value before leaving the calculation so that it would be available for the next calculation.
Let me specify better. In the event that the calculation fails I would like to reset the value to its previous good value on the next execution. Is there some easy way to find this?
I am assuming that you already know that a calculation has gone wrong and you would like to know how to recapture the latest good value to assign it to your output tag. In that case, you can use one of the above methods to get the job done.
Depending on what you would like to use as the "last good value" you can choose either method: PrevVal to us ethe archive value and using a module-level storage variable to use the latest calculation value (snapshot).
Does it answer your question?
But if the calculation has failed won't the snapshot value be "Calc Failed"? And if the code that resets the value to the previous good value doesn't get called until the executation after the calc actually failed won't the previous value also be "Calc Failed"?
If the whole ACE calculation is in trouble and can't function properly you would obviously need an external mechanism (with respect to PI ACE) to reset the value.
But if your question is related to something inside your ACE calculation you can check the values of the tags using IsGood(). Using the module-level storage variable you can always store only good values and use that to reload your output point.
Perhaps one easy way to accomplish this would be to specify the "Bad Value Substitution" for your output tags as "Previous Value". When a calculation fails, i.e. the output value is not set during execution, ACE by default writes "Calc Failed" to the PI Server. However, if you specify "Bad Value Substitution" ACE would write the output value accordingly.
From the ACE user manual:
Bad Value Substitution determines what to do when a tag value is bad. A tag value is considered bad if it equals a system digital state. A value outside of its range is not considered as bad. For numeric points, its options are:
Previous Value: The bad value is substituted by a previously good value. Only the last ten archival values are searched to find a good value. If a good value cannot be found, then no action is taken.
Hope this helps.
I don't know the nature/complexity of your calculations, but if they fail because of some external function/library being called, then an option might be to enclose the bulk of your code in a try..catch statement, where the catch block would set the result to the previous value.
Is there any reason you can't simply save the last good calculation result in a static variable?
What Noah refers to is described in the PI ACE CBT (found here vcampus.osisoft.com/.../default.aspx ) as "Module-Level Vaiables in VB" in chapter 10.0.5 - these variables are not reinitalized for every calculation, they are only reset when reseting the context.
Retrieving data ...