10 Replies Latest reply on Nov 2, 2011 4:38 PM by Mike.Mander

    AF Data Reference output




      I have built a data reference that calculates an average value of a PI Tag over a period defined by other attributes in the element. The calculation seems to work and produces a result. 


      However the problem is that I would like to plot this value on a PI Trend, when I currently plot it, I get a straight line on the trend at the current calculated value. I think it must be something to do with the time I am passing back with the new value. I have used the AFTime.Now but this seems to be current time rather than the query time. 


      Is there anything I can try?





        • Re: AF Data Reference output

          Hi Mike,


          A few questions to get a better understanding of what you are trying to achieve and what you have done so far:

          • Do you want your custom AF Data Reference to return just a single value for a given period?
          • Which method(s) have you implemented?

          If you want the period of your PI trend to be used as an input to your AF DataReference and you want a single value to be returned by it, you will want to provide an implementation of method 

          Public Overridable Function GetValue ( _
               context As Object, _
               timeContext As Object, _
               inputAttributes As AFAttributeList, _
               inputValues As AFValues _
          ) As AFValue

          Here is a description of the timeContext parameter, from the AFSDK Reference


          AFSDK Reference

          Type: System.Object
          The time context. If the context is null reference (Nothing in Visual Basic), then the most recent value is returned. If the context is an AFTime object, then the value at the specified time is returned. If the context is an AFTimeRange object, then the value for the specified time range is returned.


          In your implementation, you need thus to check if the type of the passed timeContext is an AFTimeRange. If it is, then you need to make the method return an AFValue with an start time matching the start time of the passed timeContext.


          Let us know if this helps and makes sense in your use case.

            • Re: AF Data Reference output
              Rick Davin

              To trend the attribute, you will also need to implement the GetValues method, in which case the timeContext is an AFTimeRange, and (hopefully) multiple values across the time range will be returned by your data reference.


              One thing to add to Daniel's remark about the GetValue method regarding when the timeContext is an AFTimeRange: since GetValue will return a single value then the typical time used is usually from AFTimeRange.EndTime.



                • Re: AF Data Reference output
                  Rick Davin

                  More to the point as a reply to my own comment on GetValue.  While you may invoke a call to GetValue using an AFTime, I'm not sure that your implementation of GetValue will actually ever receive an AFTime.  If a time is specified by the GetValue call, what is actually passed to your method is an AFTimeRange with the EndTime being that specified time as an AFTime object.

                  • Re: AF Data Reference output

                    There are generally two styles of Data References:


                    1) Calculation Based (like Formula).  For these, as long as you implement GetInputs, you do not need to implement GetValues - the base implementation will work - (however you do need to tell the AFSDK that you support GetValues in the SupportedMethods property)


                    2) Data Based (like PI Point).  For these, you must implement GetValues.  Please see the documentation on GetValues as there are several behaviors you must account for (Interpolated Values, Recorded Values, and Plot Values).


                    From your description, it is not 100% clear which of these two implementations is appropriate - its a little of both.  If the input attributes which define the timestamp's are absolute times AND if they are also historized (ie defined by a Time Tag), then it may be possible to use method 1, depending on the exact timerange calc behavior you are expecting.  Otherwise, you will need to implement method 2.  Note that since you are doing an average over time range defined by other attributes, the implementation for GetValues could be complex.


                    Note that trend's can easily be configured to cover large amounts of time (1 year).  You need to consider the impact your Data Reference will have to client applications in these cases when implementing an algorithm for GetValues.

                      • Re: AF Data Reference output

                        Thanks for all your replies, (I only work on this for half the week so have only got back to it today).


                        I will try to set a little context and see if what I am trying to implement is feasible.


                        I would like to create an AF Data Reference that essentially acts as a data pre-processing function. Similar to an ACE calculation that I have built before that outputs the values to a PI tag. However we are hoping that the "on the fly" calculation functionality of AF will remove the need for extraneous tags.


                        The Data Pre-Processing that we have initially decided to try to test the concept is data averaging. Taking an input tag that contains noisy data and performing an hourly average on a regular basis (say 5 minutes) so that the result data is a smoothed version of the input data (when seen on a trend), however the result will not necessarily be only visualised but also used in further calculations/alarms etc.


                        The configuration for the calculation will be stored as attributes, ie average period (hours), average interval (-1).


                        In the current Data Reference I have used the GetValue function, I pull in and check the attributes for, input tag, average period and average interval. I then generate a start and end time object as UTC seconds and get the PI Point. Then I ask for the PiPoint.Data.Summary astAverage between the start and end times. The output then returns the resultant value to another attribute as AFValue(dblOutput, AFTime.Now)


                        I understand that this may not give me the result I need yet, but it was just something thrown together to get me started.


                        Where I want to go from here is to understand how I make the calculation perform the calculation on the regular basis on the data, ie not scheduled to run constantly like an ACE calc, but whenever the data is requested, return a set of values over whatever TimeRange I am looking at that is calculated every say 5 minutes. This is similar in principle to the PIPoint average that you can set as an attribute, looking at an input tag. However I want to develop other pre-processing functions later that arent available as standard so this is just a precursor to get my knowledge up.


                        I hope this helps in understanding what I am trying to do, I will read and try and understand and implement your suggestions to see if they help me solve the problem, but if you have any more advice based on what I have said then it would be very welcome,





                          • Re: AF Data Reference output

                            I will caution you on writing a custom data reference for this function - Data References need to be as performant as possible - in particular - the Data Reference needs to be able to produce data for a trend of the value over long periods of time in a relatively short period of time without also placing unnecessary strain on the network and PI Server.  The PI Point Data Reference shipped with AF does allow for summaries, and will trend them, but differs from your proposal in that it does not provide a moving average or custom filtering, as you are requesting.  Both of these requirements will add complexity and performance cost to the implementation.  


                            In my opinion, your best option is to not use a Data Reference, but instead have the extra tag that contains the smoothed data.  What are your reasons for not wanting a tag?  


                            If you still prefer the Data Reference, you must implement the GetValues call (GetValue alone will not suffice).  Note that there is not a direct moving average call you can make against a PI Server over a time range.  But there are two solutions you could employ:


                            1) Get all the recorded values over the requested time range in one call, and compute the averages yourself.  This will be one RPC to the server, but with potentially lots of data returned, and you have to write all the code to do the time-weighted averaging and whatever additional filtering/calculations you need.  Additionally, the GetValues call itself has 3 modes (recorded values, "plot values", and interpolated values - see the AFSDK for details).  These modes will require different algorithms.  


                            2)  Use PISDK's IPICalculation to create a PE on the fly which inside has an "TagAvg" over the previous hour.  This will be server side execution and thus will perform much better of long periods of time - but will also be resource intensive on your PI Server.  This solution provides limited mechanisms to inject your own logic on the average.


                            In either case, if you are using other attributes within your data reference that could also be coming from PI, make sure you implement GetInputs() in your Data Reference and use the values the AFSDK provides, rather than retrieving the values within your own code.  This allows the AFSDK to bundle calls to PI Server, when relevant, which makes for much more efficient retrieval of data.

                              • Re: AF Data Reference output



                                Chris Manhard

                                In my opinion, your best option is to not use a Data Reference, but instead have the extra tag that contains the smoothed data. What are your reasons for not wanting a tag?


                                I thought I would jump in here with a comment. There are times when a separate tag isn't appropriate. As an example you need an average of the power/feed while the equipment is running over an arbitrary (user selected) time range. This is next to impossible to do with the out the box functionality in AF, it would be nice if AF would support similar functionality to the DataLink filter functions.




                                We've implemented a custom DR to do a similar calculation using your second method; using IPICalculation.




                                As a side note using an extra tag isn’t an issue for people like me (EA customer) but could be an issue for others who don’t have that luxury.



                                  • Re: AF Data Reference output

                                    I agree that there are times when an extra tag is not appropriate - as you state - having the ability to change the time range/algorithm/filter on the fly is certainly a valid one.  Tags for which data which arrives late, for example, via manual entry, also makes the extra tag more problematic.  While I realize there are costs to an extra tag (and often organizational permission issues), I wanted to make sure to illustrate the cost (implementation and performance) of not creating a tag.  


                                    Regarding filtering in AF configured summary tags - this is an outstanding feature request in AF that is still on the list for the next release of AF (AF 2012).  A complication to filtering in the Data Referemce is that a user would expect the filter to be defined in terms of the element, and not the underlying PI Tags.  However, the filter evaluation is a PI Server feature, which is unaware of the AF asset context.

                                      • Re: AF Data Reference output

                                        Thanks Chris,


                                        I agree with you regarding the extra tags; this is an engineering decision to balance the flexibility with the performance.


                                        Chris Manhard

                                        A complication to filtering in the Data Reference is that a user would expect the filter to be defined in terms of the element, and not the underlying PI Tags. However, the filter evaluation is a PI Server feature, which is unaware of the AF asset context.


                                        This is a good example why the AF analytics are so sorely needed (my hobby horse like some else’s SSB).


                                        Now back to Mike Mander's original problem. Did you come right with your Data Reference?



                                          • Re: AF Data Reference output

                                            Thanks for your recommendations Chris, 


                                            I was wondering if there were going to be any implications of building the Data Reference like this. I have built it now and got it working with the Get Values function. And like you say, when I set a trend to a long period then it certainly takes a while to get the data back. I will try using the other suggestions that you gave and run some tests on which are the quickest and which (if any) are sufficient for a user. 


                                            As to the reason that we are choosing this method instead of using a tag, I suppose it's just to see if it can be done. I have previously done this using ACE and a separate tag and that was quick and efficient and did the job, however there was no scope for changing your mind. If the average period that you wanted wasn't relevant any more you could change but it would only show in the values from that point forward. So users of the values would have to know that before a previous date the average was different. If we decide that after all the investigation that the way we did it before was better, we haven't really lost out because hopefully we will have learned a lot more about what AF can do and see if any of the functionality that we built before in ACE or PE's or other applications can be done more effectively in AF. Its the first time that I have been able to have a proper play with AF and the AFSDK. 


                                            And yes I agree Michael, the AF Analytics are a much needed addition. Do we have any idea when the AF 2012 is coming out? 2012 is probably a good guess but anything more definite yet?