Creating Asset-Based Analytics Programmatically (Rollup and Event Frame Generation)

Blog Post created by dng on Jun 10, 2015

When Asset-Based Analytics was first released with PI Asset Framework 2014 last year, Marcos wrote an excellent blog post about how to programmatically interact with expression analyses. Over the course of the year, we have seen some interests in accessing, editing or creating analyses programmatically.


Before we start, I would like to stress that the creation and maintenance of AF analyses is best accomplished by using the Analyses Management plug-in in PI System Explorer. You can find detailed information in our user guides for Asset-Based Analytics. In addition, we strongly encourage the use of analysis templates, which take advantage of the AF hierarchy and is a much more efficient way to create analyses. Every element derived from an element template automatically acquires analyses from its analysis templates.


In some scenario, you might want to make bulk edits to attribute names, time rules, or exporting analysis configuration into another application. In this blog post, I will add a few code snippets on:

  • Accessing and creating rollup analyses
  • Changing natural and periodic time rules
  • Viewing, editing and creating event frame generation analyses


The following is tested with PI AF SDK 2.6.2.



Rollup Analyses


Unlike expression analyses which store the equation/expression in the config string of the analysis rule:


   Figure 1: Expression analysis


AnalysisRule.ConfigString gives Average := (‘Temperature’ + ‘Temperature2’)/2


Rollup analyses store the configurations in variable mappings:

     Figure 2: Rollup analysis


AnalysisRule.VariableMapping gives SearchCriteria||Elements[@Name=*]|Attributes[@Name=Level];Sum||Level_Rollup;


In fact, the ConfigString is configuration specific to the AnalysisRule, while the VariableMapping is PI AF SDK infrastructure that is common to all AnalysisRules. The reason Rollup doesn't have any config string is that the analysis it performs is fixed, it's just a matter of "wiring up" the inputs/outputs to attributes.



To programmatically create a roll-up analysis (one that is identical to Figure 2), we can create a new analysis with the analysis rule plug in type of "RollUp" and set the variable mapping according to the format observed above. E.g.


//Add rollup analysis with name "Rollup_Calc"
AFAnalysis rollupAnalysis = tanks.Analyses.Add("Rollup_Calc");

// Define analysis rule plug-in
rollupAnalysis.AnalysisRulePlugIn = myAF.AnalysisRulePlugIns["Rollup"];

// Define the variable mappings
AFAttribute rollupLevel = tanks.Attributes["Level_Rollup"];
string rollupSearch = "Elements[@Name=*]|Attributes[@Name=Level]";
rollupAnalysis.AnalysisRule.MapVariable("Sum", rollupLevel);

/* An alternative way to define the variable mappings using the AFVariableMap object. It provides a richer object model for examining and updating the variable mapping configuration.
AFVariableMap rollupVarMap = rollupAnalysis.AnalysisRule.VariableMap;
AFVariableMappingData rollupSearchMap = new AFVariableMappingData(rollupSearch);
AFVariableMappingData rollupLevelMap = new AFVariableMappingData(rollupLevel);
rollupVarMap.SetMapping("SearchCriteria", rollupSearchMap);
rollupVarMap.SetMapping("Sum", rollupLevelMap);

// Define periodic time rule with frequency of 5 minutes
rollupAnalysis.TimeRulePlugIn = myAF.TimeRulePlugIns["Periodic"];
rollupAnalysis.TimeRule.ConfigString = "Frequency=300";

// Enable and check in newly created analysis



Natural and Periodic Time Rules


In the above example, we have created a periodic time rule such that the analysis runs every 5 minutes. Let's examine how we can change it to a natural time rule.


The structures for periodic and natural time rule differ slightly:

Time rule plug inPeriodicNaturalNatural
Time rule config stringFrequency=300;Offset=10(null)"attribute1";"attribute2"
CommentsFrequency and offset are represented in seconds (offset is optional)Analysis triggered on any inputTriggered on one or more input attribute


For the above rollup analysis (Figure 2), if we would like to change from periodic to natural time rule (and trigger on any input):


AFAnalysis rollupAnalysis = tanks.Analyses["Rollup_Calc"];
rollupAnalysis.TimeRulePlugIn = myAF.TimeRulePlugIns["Natural"];



Event Frame Generation Analyses


Before attempting to programmatically construct an Event Frame Generation analysis, let’s first inspect the analysis rule structure by looking at an existing event frame analysis.

   Figure 3: Event Frame Generation analysis


To inspect the analysis, the easiest way would be to look at the exported XML file for the element where the analysis rule belongs to:


            <ConfigString>StartTrigger:= 'Temperature' &gt; 200;</ConfigString>



Alternatively, we can look at the Analysis.AnalysisRule in Visual Studio:



From both, we can see the following:

  • The analysis rule plug in type is "EventFrame"
  • The config string for the analysis rule is of the format:
    • EFTGUID=<GUID of event frame template>;EFTNAME=<name of event frame template>
  • The start trigger (end trigger) and time true are stored as child analysis rules within the event frame analysis rule
    • Start trigger:
      • Plug in type: PerformanceEquation
      • Config string format: StartTrigger:= <equation>;
    • Time true:
      • Plug in type: TimeTrue
      • Config string format: TimeTrueValue=<value>


With these information, we can create our Event Frame Generation Analysis programmatically. The configuration of this analysis is identical to the one shown in Figure 3.


// Obtaining the event frame template
AFElementTemplate efTemplate = myDB.ElementTemplates["EFTemplate"];

// Add event frame generation analysis with the name "EF_Calc"
AFAnalysis efAnalysis = tanks.Analyses.Add("EF_Calc");

// Define analysis rule plug in and build config string
efAnalysis.AnalysisRulePlugIn = myAF.AnalysisRulePlugIns["EventFrame"];
efAnalysis.AnalysisRule.ConfigString = String.Format("EFTGUID={0};EFTNAME={1}", efTemplate.UniqueID, efTemplate.Name);

// Define plug in type and config string for child analysis rules
AFAnalysisRule triggerRule = efAnalysis.AnalysisRule.AnalysisRules.Add(myAF.AnalysisRulePlugIns["PerformanceEquation"]);
triggerRule.ConfigString = "StartTrigger:= 'Temperature' > 200;";
AFAnalysisRule timeTrueRule = efAnalysis.AnalysisRule.AnalysisRules.Add(myAF.AnalysisRulePlugIns["TimeTrue"]);
timeTrueRule.ConfigString = "TimeTrueValue=0";
// Define natural time rule to trigger at any input
efAnalysis.TimeRulePlugIn = myAF.TimeRulePlugIns["Natural"];





At the very least, I hope this blog post can give you a glimpse into the configuration of rollup and event frame generation analyses. Feedback and comments are always welcomed!



EDIT (6/11/2015): Courtesy of David Moler and Mike Zboray, I have edited the blog post to incorporate their comments. Please keep the comments coming!