4 Replies Latest reply on May 3, 2013 3:11 AM by hanyong

    PIValues.TimeInCondition & IPICalculation.FirstTrue


      Dear All, 




      From PI-SDK Programming Reference (v1.4.0), I found these two methods mentioned in the title marked as Not Implemented. 


      They might prove quite useful in our current development. When will they be implemented, or what are the best practises for workaround? 


      Thanks in advance! 

        • Re: PIValues.TimeInCondition & IPICalculation.FirstTrue



          I can't say when the methods will be implemented, but there are other ways to get to the same information (not necessary using other methods in PI SDK). The workaround would depend on your requirement though. For example:


          For PIValues.TimeInCondition:


          If you are using this on a set of PIValues retrieved from a single tag for a given time range, this is actually equivalent to one of the PE expressions

          • TimeEQ - Amount of time in a given time range where tag value is equal to a given value
          • TimeGT - Amount of time in a given time range where tag value is greater than to a given value
          • TimeGE - Amount of time in a given time range where tag value is greater or equal to a given value
          • TimeLE - Amount of time in a given time range where tag value is less than or equal to a given value
          • TimeLT - Amount of time in a given time range where tag value is less than to a given value

           where you specify the tag, time range and the value.


          You can always calculate the PE expression using IPICalculation.Calculate method with the appropriate parameters to get the information. 


          For IPICalculation.FirstTrue:


          I don't think there is any quick and easy workaround for this, but you can do something similar with IPICalculation.Calculate method, by calculate the expression using the method for a given time range. So you can calculate the expression in blocks of time period (like 1hr or 30m), get the timestamp of the first PIValue in the returned PIValues collection that has value True. If there is no true value, go back further in time.


          This would require some coding on your side to get it done, but it also allows you to control how this is implemented. For example you can always set a upper limit in your code how far to go back into the history before giving up.

            • Re: PIValues.TimeInCondition & IPICalculation.FirstTrue

              Hi Han Yong. Thanks a lot for your reply. I'll have the code to compose PE expressions then.

              • Re: PIValues.TimeInCondition & IPICalculation.FirstTrue

                This is unfortunately not useful in my situation:


                I need to perform a TimeInCondition (TimeGE) calculation on values retrieved from an AF attribute. Often these will be from PIPoint data references but in some cases it will be on Calculated or a Custom data reference. So I need something that will work on a PIValues object. Do you have any advice for this situation?

                  • Re: PIValues.TimeInCondition & IPICalculation.FirstTrue

                    Hi Alistair,


                    As mentioned in the previous posts in this discussion, the TimeInCondition calculation is not implemented. I am not sure what you mean by you need something that works on PIValues object. Have you implemented your own version of the calculation based on PIValues?


                    If converting the values from attributes (AFValues object) to PIValues would be helpful for you, then AFValues actually supports a AFValues.ToPIValues method that does the trick.


                    Like my suggestion in the previous post, you should get the same result using a PE expression. And in AF SDK 2.5, AFCalculation class is introduced so you can form an expression based on an attribute (instead of a PI tag) and calculate the expression. For example if I wanted to know the amount of time an attribute is greater than 50 in the last 2 hours, using AFCalculation, it will be like:

                    public static void AFCalculationTimeGT()
                        PISystems afsdk = new PISystems();
                        PISystem afserver = afsdk.DefaultPISystem;
                            AFDatabase afdb = afserver.Databases["NuGreen"];
                            AFElement elem = afdb.Elements[@"\\HANYONGE6230\NuGreen\NuGreen\Houston\Cracking Process\Equipment\B-210"];
                            AFAttribute attr = elem.Attributes["Process Feedrate"];
                            string expression = String.Format("TimeGT('{0}', '*-2d', '*', 50)", attr.Name);
                            AFValues values = AFCalculation.CalculateAtTimes(elem, expression, new AFTime[] { new AFTime("*") });
                            foreach (AFValue value in values)
                                Console.WriteLine("{0}:{1}", value.Timestamp.LocalTime, value.Value);
                        catch (Exception ex)

                    This does not working with non PI Point Data Reference Attribute though, so it wouldn't satisfy all the cases that you have stated. Apparently an expression cannot be formed using attributes that are not using PI Point Data Reference.


                    For the cases of Calculated (I guess you mean the Formula) and Custom Data Reference. I can only think of writing a function that calculates it manually after getting a list of values using AF SDK (AFAttribute.GetValues method or AFData.RecordedValues method in AF SDK 2.5)