You want to make sure that both tag A and B's retrieval mode is "By Time" and "Interpolated". This way whenever you ask for a value at a certain time in your calculations, an interpolated value is returned; i.e. there is no need to match the timestamp exactly.
To have an average of a tag over time you can choose "By Time Range" as the retrieval mode and then pick "Average". This option will calculate the average according to the time each value persisted. In other words different sample values will have different weights in the average depending on the time period they lasted.
Hope this answers your question. For more detailed information you can check with AF documentation and search for "Configuring the PI point data reference".
Regarding tag C, it seems that I can only get a value from it when tag B has a value. Not sure why it is working like that, because tag A doesn't have a value at that same second.
With respect to this last point that you are asking here, can you tell us a bit more about what tools you are using to calculate the value of tag C? You mentioned about AF and AFSDK, are you defining C as a AF Attribute with Formula Data Reference and getting the value from C using AF SDK?
Or are you using Performance Equation to perform the calculation with PI tags A and B and storing the result in tag C?
Thanks for the answers, guys!
Han, tag C contains the following formula:
so I believe that makes C an AF tag attribute.
I am getting the values using a GetValues() call in C# code. I have tried setting tag A and B's 'By Time' retrieval method as Interpolated, but that hasn't seemed to fix the problem.
I have tried making the call using 0 for number of values, or specifying a number, but that hasn't had an effect either.
Strangely, I haven't found a Af SDK method to get an attirubute value by time range, e.g. get an average, either, which would be a decent part of the solution.
The GetValues call on C, with "0" for the number of Values, will return a value at each point in time over the time range where either A or B has a value in the archive. For each calculation, the value it uses for A and B if a value does not exist at that exact point in time will depend on their PI Point "step" point attributes and how the data has been archived into PI. In the case where the point is stepped, then the previous value is used. In the case where the point is not stepped, then the value is interpolated from the two values that surround the point. The interpolation takes into account the offset from both times. In essesnce, for non-stepped points, this is a "time weighted" average between the two points in time.
However, it should be noted that if the value of B changes infrequently, the behavior of the interpolation of B can be affected by how the data is collected by the interface of B. If the interface sends the non-changing value of B frequently, then B will not actually be a gradual change from its two values which are 30 minutes apart, but rather, a sharp change at the time the interface reported the change. If the interface does not send the value often, then the interpolation will be more gradual, but it should be noted that values calculated after the last value sent by the interface have nothing to interpolate against until that value arrives.
The call with "NumValues=0" will most accurately reflect your data stored in PI. You could also make an interpolated call (give me a value every minute). The mechanism to do this is to pass a negative numvalues parameter to GetValues() - yes, this is goofy. So, passing -25 over a 1 day time period will return one hour increments over the one day time range). The calculation at each value works the same - the value for the input tag is interpolated, unless it is a stepped tag.
First, using the negative number for number of values is very helpful! Great!
Using zero for the number of values is what I am doing currently, and it doesn't interpolate. I'll post again when I can concisely list my findings.