static void Main(string[] args) { var db = new PISystems().DefaultPISystem.Databases.DefaultDatabase; var analyses = new AFAnalysisSearch(db, null, "*"); foreach (var analysis in analyses.FindAnalyses()) analysis.SetStatus(AFStatus.Disabled); }
static void Main(string[] args) { PISystems myPISystems = new PISystems(); PISystem myPISystem = myPISystems.DefaultPISystem; if (myPISystem == null) { throw new InvalidOperationException("Default PISystem was not found."); } AFDatabase myDB = myPISystem.Databases["PE"]; if (myDB == null) { throw new InvalidOperationException("Database was not found."); } AFElement element = myDB.Elements["El"]; int count; using (var search = new AFAnalysisSearch(myDB, "MyAnalysisSearch", string.Format(@"Target:'{0}'", element.GetPath()))) { search.CacheTimeout = TimeSpan.FromMinutes(10); count = search.GetTotalCount(); Console.WriteLine("Found {0} Analyses", count); foreach (var item in search.FindObjects(fullLoad: true)) { Console.Write("Analysis Name = {0},", item.Name); Console.Write("Analysis Description = {0},", item.Description); Console.Write("Analysis Target = {0}", item.Target); Console.WriteLine(); } } }
public static int sleepTimePerAnalysis = 1 * 100; // in milliseconds static void Main(string[] args) { var af = new PISystems().DefaultPISystem; var db = af.Databases.DefaultDatabase; var service = af.AnalysisService; StreamReader file = new StreamReader("c:\\kit\\utilities.txt"); string line; while ((line = file.ReadLine()) != null) { Console.WriteLine(line); var search = new AFAnalysisSearch(db, null, line); IEnumerable <AFAnalysis> analyses = search.FindAnalyses(); Console.WriteLine($"Found: {analyses.Count()} analyses."); // start all found analyses foreach (var analysis in analyses) { analysis.SetStatus(AFStatus.Enabled); } // status does not return information in this version var status = service.QueueCalculation(analyses, timeRange, AFAnalysisService.CalculationMode.DeleteExistingData); Thread.Sleep(sleepTimePerAnalysis * analyses.Count()); } file.Close(); }
/// <summary> /// Removes the analysis from the AF Database if it exists. /// </summary> /// <param name="name">The name of the analysis to remove.</param> /// <param name="output">The output logger used for writing messages.</param> public void RemoveAnalysisIfExists(string name, ITestOutputHelper output) { Contract.Requires(output != null); AFAnalysis preCheckAnalysis; using (var search = new AFAnalysisSearch(AFDatabase, string.Empty, $"Name:'{name}'")) { var coll = new AFNamedCollectionList <AFAnalysis>(search.FindObjects()); preCheckAnalysis = coll[name]; } if (preCheckAnalysis != null) { output.WriteLine($"Analysis [{preCheckAnalysis}] exists, delete it."); preCheckAnalysis.Delete(); preCheckAnalysis.CheckIn(); } else { output.WriteLine($"Analysis [{name}] does not exist, can not be deleted."); } }
static void Main(string[] args) { //define variables string user_path = null; string user_serv = null; string user_db = null; string user_analysisfilter = null; string user_mode = null; PIServer aPIServer = null; PISystems aSystems = new PISystems(); PISystem aSystem = null; AFAnalysisService aAnalysisService = null; AFDatabase aDatabase = null; List <AFElement> foundElements = new List <AFElement>(); List <AFAnalysis> foundAnalyses = new List <AFAnalysis>(); IEnumerable <AFAnalysis> elemAnalyses = null; AFTimeRange backfillPeriod = new AFTimeRange(); AFAnalysisService.CalculationMode mode = AFAnalysisService.CalculationMode.FillDataGaps; String reason = null; Object response = null; String help_message = "This utility backfills/recalculates analyses. Generic syntax: " + "\n\tAnalysisBackfill.exe \\\\AFServer\\AFDatabase\\pathToElement\\AFElement AnalysisNameFilter StartTime EndTime Mode" + "\n This utility supports two modes: backfill and recalc. Backfill will fill in data gaps only. Recalc will replace all values. Examples:" + "\n\tAnalysisBackfill.exe \\\\AF1\\TestDB\\Plant1\\Pump1 FlowRate_*Avg '*-10d' '*' recalc" + "\n\tAnalysisBackfill.exe \\\\AF1\\TestDB\\Plant1\\Pump1 *Rollup '*-10d' '*' backfill"; //bad input handling & help if (args.Length < 5 || args.Contains("?")) { Console.WriteLine(help_message); Environment.Exit(0); } try { //parse inputs and connect user_path = args[0]; var inputs = user_path.Split('\\'); user_serv = inputs[2]; user_db = inputs[3]; //connect AFSystemHelper.Connect(user_serv, user_db); aSystem = aSystems[user_serv]; aDatabase = aSystem.Databases[user_db]; aAnalysisService = aSystem.AnalysisService; /* check versions. need to write this. * aSystem.ServerVersion * aSystems.Version * aPIServer.ServerVersion */ //find AFElements //will eventually include element search filter as well if (inputs.Length == 4) { //all elements in database foundElements = AFElement.FindElements(aDatabase, null, null, AFSearchField.Name, true, AFSortField.Name, AFSortOrder.Ascending, 1000).ToList(); } else { //single element var prelength = user_serv.Length + user_db.Length; var path1 = user_path.Substring(prelength + 4, user_path.Length - prelength - 4); foundElements.Add((AFElement)AFObject.FindObject(path1, aDatabase)); } //other inputs user_analysisfilter = args[1]; AFTime backfillStartTime = new AFTime(args[2].Trim('\'')); AFTime backfillEndTime = new AFTime(args[3].Trim('\'')); backfillPeriod = new AFTimeRange(backfillStartTime, backfillEndTime); //user_mode user_mode = args[4]; switch (user_mode.ToLower()) { case "recalc": mode = AFAnalysisService.CalculationMode.DeleteExistingData; break; case "backfill": mode = AFAnalysisService.CalculationMode.FillDataGaps; break; default: Console.WriteLine("Invalid mode specified. Supported modes: backfill, recalc"); Environment.Exit(0); break; } Console.WriteLine("Requested backfills/recalculations:"); foreach (AFElement elem_n in foundElements) { //find analyses String analysisfilter = "Target:=\"" + elem_n.GetPath(aDatabase) + "\" Name:=\"" + user_analysisfilter + "\""; AFAnalysisSearch analysisSearch = new AFAnalysisSearch(aDatabase, "analysisSearch", AFAnalysisSearch.ParseQuery(analysisfilter)); elemAnalyses = analysisSearch.FindAnalyses(0, true).ToList(); //print details to user Console.WriteLine("\tElement: " + elem_n.GetPath().ToString() + "\n\tAnalyses (" + elemAnalyses.Count() + "):"); if (elemAnalyses.Count() == 0) { Console.WriteLine("\t\tNo analyses on this AF Element match the analysis filter."); } else { foundAnalyses.AddRange(elemAnalyses); foreach (var analysis_n in elemAnalyses) { Console.WriteLine("\t\t{0}, {1}, Outputs:{2}", analysis_n.Name, analysis_n.AnalysisRule.Name, analysis_n.AnalysisRule.GetOutputs().Count); } } /* to check for dependent analyses * foreach (var analysis_n in foundAnalyses) * { * * } */ } Console.WriteLine("\nTime range: " + backfillPeriod.ToString() + ", " + "{0}d {1}h {2}m {3}s." , backfillPeriod.Span.Days, backfillPeriod.Span.Hours, backfillPeriod.Span.Minutes, backfillPeriod.Span.Seconds); Console.WriteLine("Mode: " + user_mode + "=" + mode.ToString()); //implement wait time Console.WriteLine("\nA total of {0} analyses will be queued for processing in 10 seconds. Press Ctrl+C to cancel.", foundAnalyses.Count); DateTime beginWait = DateTime.Now; while (!Console.KeyAvailable && DateTime.Now.Subtract(beginWait).TotalSeconds < 10) { Console.Write("."); Thread.Sleep(250); } //no status check Console.WriteLine("\n\nAll analyses have been queued.\nThere is no status check after the backfill/recalculate is queued (until AF 2.9.0). Please verify by using other means.", foundAnalyses.Count); //queue analyses for backfill/recalc foreach (var analysis_n in foundAnalyses) { response = aAnalysisService.QueueCalculation(new List <AFAnalysis> { analysis_n }, backfillPeriod, mode); /* no status check info * in AF 2.9, QueueCalculation will allow for true status checking. In AF 2.8.5, it is not possible to check. * Documentation (https://techsupport.osisoft.com/Documentation/PI-AF-SDK/html/M_OSIsoft_AF_Analysis_AFAnalysisService_ToString.htm) states: * This method queues the list of analyses on the analysis service to be calculated. * The operation is asynchronous and returning of the method does not indicate that queued analyses were calculated. * The status can be queried in the upcoming releases using the returned handle. */ //Might be able to add a few check mechanisms using AFAnalysis.GetResolvedOutputs and the number of values in AFTimeRange } } catch (Exception ex) { Console.WriteLine("Error returned: " + ex.Message); Environment.Exit(0); } }