16 Replies Latest reply on May 20, 2015 8:33 PM by jorgewong

    Is there are a PI SDK function to force a tag recalculation?

    jfarrera

      I need to recalculate some tags , but the source tag value being changed is the last one usually, so to make the recalc I must chage the value , then create an auxiliary event in the current time to force the out orf order change for the tag recalculation and then delete the auxiliary event.  Im using vba in Excel to do this, so if there are a PI SDK funtion to make the recalculation directly for a tag just giving the start and end time period would be great.

       

      Regards

       

      Julio Farrera - CEMEX - EA

        • Re: Is there are a PI SDK function to force a tag recalculation?
          Ahmad Fattahi

          Julio,

           

          Would you explain some more what you exactly mean by "recalculate some tags"? What kind of PI tags are they and how are they configured (PE/Totalizer/PI ACE)?

            • Re: Is there are a PI SDK function to force a tag recalculation?
              jfarrera

              Hi Ahmad,

               

              What I mean is that I have some calculated tags (PE) that must be recalculated when their input tags change, but Pi recalc just take the "out of order" changes to trigger an event. So a workarround that we implemented to trigger that change when the value that changes is the last one (snapshot) is: change the values of the input tag, then create a new value at present time (*) to make the change "out of order" and then erase the value, but instead of that We would like to make the recalculation using a direct command if it exists in SDK.

                • Re: Is there are a PI SDK function to force a tag recalculation?
                  Ahmad Fattahi

                  Normally when an event goes into archive it should trigger an event and hence "the last event in the archive" as you put it should automatically trigger a PE calculation. If that is not happening automatically I would suggest you contact Tech Support to troubleshoot that.

                   

                  However, without knowing too much about your set up, I can think of the following options and resources. Please see this KB Article that explains and exemplifies using PE recalculations. Also, please take a look at the "PI Server Applications User Guide" under the "PI Performance Equations Recalculator" chapter. Under the "Start Recalculator Manually" section there are examples showing how you can recalculate a PE at a certain time or over a specific time window. Does that sound helpful to the problem?

                    • Re: Is there are a PI SDK function to force a tag recalculation?
                      jfarrera

                      This manually recalculation is the one that Im trying to do with SDK , to avoid to interact with DOS commands. This is being done with an Excel Macro.

                        • Re: Is there are a PI SDK function to force a tag recalculation?
                          Ahmad Fattahi

                          Have you checked the Calculate method in the PI SDK IPICalculation interface? It takes a number of parameters including start and end times and expression (among other things). Hope it helps.

                            • Re: Is there are a PI SDK function to force a tag recalculation?
                              dtakara

                              This is some sample code to illustrate the use of the method Ahmad mentioned:

                               
                              ' recalculates values of a Performance Equation tag
                              ' using the Calculate method of the IPICalculation interface
                              ' at the timestamps of the archived events of the tags involved
                              ' in the PE tag calculation expression
                              
                              Dim svr As Server
                              Dim myPIPoint As PIPoint
                              Dim myPointAttribute As PointAttribute
                              Dim myIPICalculation As IPICalculation
                              Dim calculationExpression As String
                              Dim myPointValues As PIValues
                              
                              ' define PI Server
                              Set svr = PISDK.Servers("MYPISERVER")
                              ' set the PIPoint corresponding to the PE tag whose values will be recalculated
                              Set myPIPoint = svr.PIPoints.Item("MyCalcTag1")
                              ' get PointAttribute "exdesc"
                              Set myPointAttribute = myPIPoint.PointAttributes.Item("exdesc")
                              ' exdesc attribute of any valid PE tag contains the calculation expression
                              calculationExpression = myPointAttribute.Value
                              ' set the IPICalculation object
                              Set myIPICalculation = svr
                              ' run calculationExpress for timestamps of recorded values of tags involved in the calculation expression
                              Set myPointValues = myIPICalculation.Calculate("t", "*", calculationExpression, stRecordedValues, "")
                              ' overwrite the values of the PE tag
                              myPIPoint.Data.UpdateValues myPointValues, dmReplaceDuplicates
                              ' cleanup
                              Set svr = Nothing
                              Set myPIPoint = Nothing
                              Set myPointAttribute = Nothing
                              Set myIPICalculation = Nothing
                              Set myPointValues = Nothing
                              

                              @Julio: You may want to adapt and try this example, to see if it fits in your need.

                                • Re: Is there are a PI SDK function to force a tag recalculation?
                                  jorgewong

                                  I'm trying to do a similar thing but with C# and the PI AF SDK.  I seem to be having issues however when it gets to the calculation function and doesn't recognize the pi point.  Here is my sample code below.  I'm testing using the Test-PE-OSI tag which has an extended descriptor of 'sinudoid'*2.  When it gets to the CalculateAtIntervals call it fails with: Unrecognized variable 'sinusoid' in expression.

                                   

                                   

                                   

                                   

                                  public static String TagRecalculate(string tagname, string startTime, string endTime)

                                   

                                  String  result = null;

                                   

                                  //find tag

                                   

                                  PIPoint myPIPoint = GetPIPoint(tagname, PICommonPointAttributes.ExtendedDescriptor);

                                   

                                  if (myPIPoint != null)

                                   

                                  //search for exdesc pointattribute

                                   

                                  string calculationExpression = myPIPoint.GetAttribute(PICommonPointAttributes.ExtendedDescriptor).ToString();

                                  AFTimeRange myTimeRange = new AFTimeRange();

                                  myTimeRange.StartTime = new AFTime(DateTime.UtcNow.AddHours(-1));

                                  myTimeRange.EndTime = AFTime.Now;

                                   

                                  //get values based on recalc with that expression

                                  AFValues values = AFCalculation.CalculateAtIntervals(myPIPoint, calculationExpression, myTimeRange, AFTimeSpan.Parse("1 hour"));

                                   

                                  //write values back to PE tag and replace if any exist


                                   

                                  myPIPoint.UpdateValues(values, AFUpdateOption.Replace, AFBufferOption.DoNotBuffer);

                                   

                                   

                                  }

                                  //need to set values list here for recalc

                                   

                                  return result;

                                  }

                      • Re: Is there are a PI SDK function to force a tag recalculation?
                        jorgewong

                        Looks like the problem with that was I was using myPIPOint where I should have had myPIServer as the first input to the CalculateAtInterval.  Its still not just replacing the existing archives values that I have.  Its creating new values in the archive.  Any clues on what I might need to do?

                        • Re: Is there are a PI SDK function to force a tag recalculation?
                          jorgewong

                          Its creating new values at a new timestamp in the archives.  For the one above it creates two.  One at the current time and one, an hour back.  I think I am giving the wrong parameters or using the wrong AFCalculcation.  I want to be able to replace all the existing given a time range that I define.  I don't want new values to be created.  Does that make sense?

                          • Re: Is there are a PI SDK function to force a tag recalculation?
                            jorgewong

                            I just tried to do something like the following:

                             

                             

                            AFValues values = AFCalculation.CalculateAtRecordedValues(myPIServer, calculationExpression, myTimeRange);

                             

                            //write values back to PE tag and replace if any exist

                            AFErrors<AFValue> errorsWithBuffer = myPIPoint.UpdateValues(values, AFUpdateOption.ReplaceOnly, AFBufferOption.DoNotBuffer);

                             

                             

                            but its not working as there are no current recorded values for that time.  I get this error in the PI logs:

                             

                             

                            PIarcmgr::addevent failed, mode: 3 ptid: 88196 recid: 1400713 status: [-11075] Target event for replacement not found in record

                             

                            I'm using the tag: Test-PE-OSI which is basically sinusoid*2

                            • Re: Is there are a PI SDK function to force a tag recalculation?
                              jorgewong

                              I think I'm just not explaining what I need properly.  What I need to do is search for existing archives values for a performance equation tag and do a recalculation for any of those archive values for the time range that I pass in.  I think the problem is that the calculation expression is running for the right time range but the values that it gives back don't line up with what is in the archives.  Does that make sense?

                                • Re: Is there are a PI SDK function to force a tag recalculation?
                                  bshang

                                  Can you provide the PE expression and also the archived events for the input tags to the PE and also the output tag? I believe what might be occurring is that there is more than one input tag in the PE, the PE is being triggered by just one of them, but CalculateAtRecordedValues() will "time-synchronize" the output (i.e. generate results at timestamps of a set representing the union of all the input tags' timestamps)

                                   

                                  For example, if input tag 1 has timestamps

                                  00:00, 01:00, 02:00

                                   

                                  and input tag 2 has timestamps

                                  00:30, 01:30, 02:30

                                   

                                  and if the PE is triggered by input tag 1, then the output tag will have events at 00:00, 01:00, 02:00.

                                   

                                  However, the output AFValues from CalculateAtRecordedValues will have timestamps at 00:00, 00:30, etc.

                                   

                                  The recalculation will also not match if the PE was periodically scheduled (even intervals) while the recalculation here is looking at the recorded values timestamps (intervals could be irregular).

                                   

                                  If you can provide the info above, it would be very helpful. It may also be worthwhile to print out the returned AFValues and check its timestamps with the existing ones of the input and output tags.

                                • Re: Is there are a PI SDK function to force a tag recalculation?
                                  jorgewong

                                  I took a look at my PE tag and I think I had it setup incorrectly.  I fixed my PE tag to point to a tag that I setup and it seems to only replace existing archives values now if I do the "replaceOnly" option below.  Thanks for helping clarify things. I was only using one input tag for my PE but I think the compression settings on the previous tag I used was throwing things off.  Here is what I'm now using.  I will test some more but I think we are good now.

                                   

                                                  //get values based on recalc with that expression

                                                  AFValues values = AFCalculation.CalculateAtRecordedValues(myPIServer, calculationExpression, myTimeRange);

                                   

                                                  //write values back to PE tag and replace if any exist

                                                  AFErrors<AFValue> errorsWithBuffer = myPIPoint.UpdateValues(values, AFUpdateOption.ReplaceOnly);