public void UpdateTest() { string path = Constants.AF_ANALYSIS_PATH; PIAnalysis analysis = instance.Get(webId, null); analysis.WebId = null; analysis.Id = null; analysis.Links = null; analysis.Path = null; analysis.AutoCreated = null; analysis.HasTemplate = null; analysis.HasNotification = null; analysis.HasTarget = null; analysis.IsConfigured = null; analysis.Description = "This is the new analysis swagger description"; analysis.IsTimeRuleDefinedByTemplate = null; instance.Update(webId, analysis); StandardPISystem.Refresh(); AFAnalysis myAnalysis = AFObject.FindObject(path) as AFAnalysis; if (analysis != null) { Assert.IsTrue(myAnalysis.Description == analysis.Description); } }
public static void ProgrammaticAnalysisRecalculation(PISystem system, AFDatabase database, AFCategory category) { // we start by generating timestamps we want to recalculate // we could get them from existing recorded values, etc... // // here we simply generate yesterdays hourly values ... var recalculationTimeStamps = new List <AFTime>(); for (int i = 0; i < 24; i++) { recalculationTimeStamps.Add(new AFTime(DateTime.Today.Subtract(TimeSpan.FromDays(1)) + TimeSpan.FromDays(i) + TimeSpan.FromSeconds(2))); } AFNamedCollectionList <AFAnalysis> analysislist; analysislist = AFAnalysis.FindAnalyses(database, null, null, null, category, null, null, AFStatus.None, AFSortField.ID, AFSortOrder.Ascending, 0, 1000); Console.WriteLine(category.Name); Console.WriteLine(analysislist.Count); foreach (var afAnalysis in analysislist) { // we recalculate results var results = Calculate(afAnalysis, recalculationTimeStamps); // we could delete values here, but I simply replce them instead // we insert our new values AFListData.UpdateValues(results, AFUpdateOption.Replace); } }
public void DeleteTest() { // TODO uncomment below to test the method and replace null with proper value instance.Delete(webId); AFAnalysis analysis = AFObject.FindObject(Constants.AF_ANALYSIS_PATH) as AFAnalysis; Assert.IsNull(analysis); DeleteSampleDatabaseForTests(); CreateSampleDatabaseForTests(); }
/// <summary> /// Run calculations for specific time stamps. /// </summary> /// inspired from: /// <see cref="https://pisquare.osisoft.com/message/28537#28537"/> /// <param name="analysis">Analysis that needs to be evaluated</param> /// <param name="times">List of times</param> /// <param name="evaluationTime">output, contains the time taken to execute all the calculations</param> /// <param name="evaluationsErrorsCount">output, contains the number of evaluations in error.</param> /// <returns></returns> public List <AFValue> Run(AFAnalysis analysis, IEnumerable <AFTime> times, out TimeSpan evaluationTime, out int evaluationsErrorsCount) { evaluationsErrorsCount = 0; var results = new List <AFValue>(); var stopwatch = Stopwatch.StartNew(); var analysisConfiguration = analysis.AnalysisRule.GetConfiguration(); var state = new AFAnalysisRuleState(analysisConfiguration); foreach (var time in times) { // Console.WriteLine("Evaluating for {0}", time); state.Reset(); state.SetExecutionTimeAndPopulateInputs(time); analysis.AnalysisRule.Run(state); if (state.EvaluationError != null) { if (_debug) { _logger.ErrorFormat("Analyse in error at time: {3:s} - {0} - at {1}, Error: {2}", analysis.Name, analysis.GetPath(), state.EvaluationError, time); } evaluationsErrorsCount += 1; } // this merges the state (results) with the configuration so its easier to loop with both... var resultSet = analysisConfiguration.ResolvedOutputs.Zip(state.Outputs, Tuple.Create); foreach (var result in resultSet) { // for more clarty, we take out our data into clearer variables AFAnalysisRuleResolvedOutput analysisRow = result.Item1; var calcRes = (AFValue)result.Item2; // we filter to get only the results that have an output attribute ( an AFValue ) if (analysisRow.Attribute != null) { // add new AF Value into the results table results.Add(new AFValue((AFAttribute)analysisRow.Attribute, calcRes.Value, calcRes.Timestamp)); } } } stopwatch.Stop(); evaluationTime = stopwatch.Elapsed; return(results); }
public void CreateSampleDatabaseForTests() { DeleteSampleDatabaseForTests(); CreateSecurityIdentities(); CreateSecurityMappings(); CreateUOMClasses(); AFDatabase db = CreateDatabase(); AFCategory analysisCategory1 = CreateCategory(db.AnalysisCategories, Constants.AF_ANALYSIS_CATEGORY_NAME, 1); AFCategory analysisCategory2 = CreateCategory(db.AnalysisCategories, Constants.AF_ANALYSIS_CATEGORY_NAME, 2); AFCategory tableCategory1 = CreateCategory(db.TableCategories, Constants.AF_TABLE_CATEGORY_NAME, 1); AFCategory tableCategory2 = CreateCategory(db.TableCategories, Constants.AF_TABLE_CATEGORY_NAME, 2); AFCategory attributeCategory1 = CreateCategory(db.AttributeCategories, Constants.AF_ATTRIBUTE_CATEGORY_NAME, 1); AFCategory attributeCategory2 = CreateCategory(db.AttributeCategories, Constants.AF_ATTRIBUTE_CATEGORY_NAME, 2); AFCategory elementCategory1 = CreateCategory(db.ElementCategories, Constants.AF_ELEMENT_CATEGORY_NAME, 1); AFCategory elementCategory2 = CreateCategory(db.ElementCategories, Constants.AF_ELEMENT_CATEGORY_NAME, 2); AFTable table = CreateTable(db); table.Categories.Add(tableCategory1); AFEnumerationSet enumSet = CreateEnumerationSet(db); AFElementTemplate elementTemplate = CreateElementTemplate(db); CreateElementFromTemplate(db, elementTemplate); AFElement el = CreateElementAndAttributes(db, elementCategory1, attributeCategory1); CreateElementForStreamSet(db); AFAnalysisTemplate analysisTemplate = CreateAnalysisTemplate(db); AFAnalysis an = CreateAnalysis(db, el, analysisCategory1, analysisCategory2); AFEventFrame ef = CreateEventFrame(db, null, elementCategory1); AFElementTemplate eventFrameTemplate = CreateEventFrameTemplate(db); AFEventFrame ef2 = CreateEventFrame(db, eventFrameTemplate, elementCategory1); db.CheckIn(); }
/// <summary> /// Adapted from Mike's example /// Mike also talks about errors and warnings in his post, you should check it. /// </summary> /// <see cref="https://pisquare.osisoft.com/message/28537#28537"/> /// <param name="analysis"></param> /// <param name="times"></param> /// <returns></returns> private static List <AFValue> Calculate(AFAnalysis analysis, IEnumerable <AFTime> times) { var results = new List <AFValue>(); var analysisConfiguration = analysis.AnalysisRule.GetConfiguration(); var state = new AFAnalysisRuleState(analysisConfiguration); foreach (var time in times) { //Console.WriteLine("Evaluating for {0}", time); state.Reset(); state.SetExecutionTimeAndPopulateInputs(time); analysis.AnalysisRule.Run(state); if (state.EvaluationError == null) { // this merges the state (results) with the configuration so its easier to loop with both... var resultSet = analysisConfiguration.ResolvedOutputs.Zip(state.Outputs, Tuple.Create); foreach (var result in resultSet) { // for more clarty, we take out our data into clearer variables AFAnalysisRuleResolvedOutput analysisRow = result.Item1; var calcRes = (AFValue)result.Item2; // we filter to get only the results that have an output attribute ( an AFValue ) if (analysisRow.Attribute != null) { // add new AF Value into the results table results.Add(new AFValue((AFAttribute)analysisRow.Attribute, calcRes.Value, calcRes.Timestamp)); } } } else { // errors occur quite frequently, for example, TagTot('attr1', 't', '*') will fail if computed at '*' = 't' // but this does not occur when the analysis is running on event base. //Console.WriteLine("An error occurred: {0}", state.EvaluationError.Message); } } return(results); }
private AFAnalysis CreateAnalysis(AFDatabase db, AFElement el, AFCategory analysisCategory1, AFCategory analysisCategory2) { AFAttribute attribute = el.Attributes["Temperature Average"]; AFAnalysis an = el.Analyses[Constants.AF_ANALYSIS_NAME]; if (an == null) { an = el.Analyses.Add(Constants.AF_ANALYSIS_NAME); an.Description = "Analysis for Washington Temeperature Average"; an.AnalysisRulePlugIn = _piSystem.AnalysisRulePlugIns["EventFrame"]; an.AnalysisRule.ConfigString = "Avg2d := TagAvg('Temperature','*-2d','*');Avg1d := TagAvg('Temperature','*-1d','*');SumAvg := Avg1d+Avg2d+2;"; an.AnalysisRule.MapVariable("SumAvg", attribute); an.TimeRulePlugIn = _piSystem.TimeRulePlugIns[Constants.AF_TIMERULE_NAME]; an.TimeRule.ConfigString = "Frequency=300"; an.SetStatus(AFStatus.Enabled); an.Categories.Add(analysisCategory1); an.Categories.Add(analysisCategory2); } return(an); }
/// <summary> /// Get the list of output attributes for an analysis. /// </summary> public static IList <AFAttribute> GetOutputs(this AFAnalysis analysis) => analysis?.AnalysisRule.GetConfiguration().GetOutputs().OfType <AFAttribute>().ToList();
public static void resetAnalysis(AFAnalysis analysis) { analysis.Description = analysis.Template.Description; analysis.ResetToTemplate(); analysis.CheckIn(); }
public AnalysisExecutor(AFAnalysis analysis) { _analysis = analysis; }
public static void StaticToAnalysisDR(PISystem myAFServ, AFElement myElement, AFAnalysis myAnalysis) { //to use later }