/// <summary> /// If it is a new search, the elements that fit the criteria are collected and the first is selected. /// Else it iterates through the collection of elements and expands to the node. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void bSearchElements_Click(object sender, EventArgs e) { currentTreeSearchTimes++; if (currentTreeSearch == tbElementSearchName.Text) { if (currentSearchResults.Count == 0) //No search results { Status("Couldn't find Element Name"); return; } else if (currentTreeSearchTimes < currentSearchResults.Count) // iterate through. { findTreeNode(afTreeViewElements.Nodes[0], currentSearchResults[currentTreeSearchTimes]); } else //restart iteration through. { currentTreeSearchTimes = 0; findTreeNode(afTreeViewElements.Nodes[0], currentSearchResults[currentTreeSearchTimes]); } } else //Load Search Results { currentTreeSearchTimes = 0; currentTreeSearch = tbElementSearchName.Text; AFDatabase afdb = control.getAFDatabase(); currentSearchResults = AFElement.FindElements(afdb, null, "*" + tbElementSearchName.Text + "*", AFSearchField.Name, true, AFSortField.Name, AFSortOrder.Ascending, Int32.MaxValue); if (currentSearchResults.Count > 0) { findTreeNode(afTreeViewElements.Nodes[0], currentSearchResults[currentTreeSearchTimes]); } } }
public void Run() { PISystems piSystems = new PISystems(); PISystem piSystem = piSystems["<AFSERVER>"]; AFDatabase afDatabase = piSystem.Databases["NuGreen"]; const int pageSize = 1000; int startIndex = 0; int totalCount; do { // Find a collection of elements instantiated from the Boiler tempplate. // Only the Elements' header information (Name, Description, Template, Type, etc.) // are loaded from the AF Server by this call. AFNamedCollection <AFElement> elements = AFElement.FindElements( database: afDatabase, searchRoot: null, query: "Boiler", field: AFSearchField.Template, searchFullHierarchy: true, sortField: AFSortField.Name, sortOrder: AFSortOrder.Ascending, startIndex: startIndex, maxCount: pageSize, totalCount: out totalCount); if (elements == null) { break; } // This call goes to the AF Server to fully load the found elements in one call, // so further AF Server calls can be avoided. AFElement.LoadElements(elements); // Now we can use the elements without having to make any additional server calls. // In the example below, accessing the Attributes collection would have // caused an additional call per element if we had not called LoadElements previously. Console.WriteLine("Found {0} Elements.", elements.Count); foreach (AFElement item in elements) { Console.WriteLine(" Element {0} has {1} Attributes", item.Name, item.Attributes.Count); } startIndex += pageSize; } while (startIndex < totalCount); }
public void Run() { PISystems piSystems = new PISystems(); PISystem piSystem = piSystems["<AFSERVER>"]; AFDatabase afDatabase = piSystem.Databases["NuGreen"]; const int pageSize = 1000; int startIndex = 0; int totalCount; do { // Find a collection of elements instantiated from the Boiler tempplate. // Only the Elements' header information (Name, Description, Template, Type, etc.) // are loaded from the AF Server by this call. AFNamedCollection <AFElement> elements = AFElement.FindElements( database: afDatabase, searchRoot: null, query: "Boiler", field: AFSearchField.Template, searchFullHierarchy: true, sortField: AFSortField.Name, sortOrder: AFSortOrder.Ascending, startIndex: startIndex, maxCount: pageSize, totalCount: out totalCount); if (elements == null) { break; } // Because we are just retrieving the element's name, no additional calls // to the AF Server are made. Console.WriteLine("Found {0} Elements.", elements.Count); foreach (AFElement item in elements) { Console.WriteLine(" Element name is {0}.", item.Name); } startIndex += pageSize; } while (startIndex < totalCount); }
private List <string> FindChildElementTemplates() { List <string> _templateNames = new List <string>(); try { if (dataReference.Attribute != null) { AFElement element = (AFElement)dataReference.Attribute.Element; AFNamedCollectionList <AFElement> childElements = AFElement.FindElements(element.Database, element, "*", AFSearchField.Name, false, AFSortField.Name, AFSortOrder.Ascending, 1000000); if (childElements != null && childElements.Count > 0) { foreach (AFElement childElement in childElements) { if (!(_templateNames.Contains(childElement.Template.Name))) { _templateNames.Add(childElement.Template.Name); } } } } if (dataReference.Template != null) { foreach (AFElementTemplate template in dataReference.Database.ElementTemplates) { _templateNames.Add(template.Name); } } _templateNames.Sort(); return(_templateNames); } catch { return(null); } }
public void Run() { PISystems piSystems = new PISystems(); PISystem piSystem = piSystems["<AFSERVER>"]; AFDatabase afDatabase = piSystem.Databases["NuGreen"]; AFElementTemplate boilerTemplate = afDatabase.ElementTemplates["Boiler"]; const int pageSize = 1000; int startIndex = 0; int totalCount; do { // Find a collection of elements instantiated from the Boiler tempplate. // Only the Elements' header information (Name, Description, Template, Type, etc.) // are loaded from the AF Server by this call. AFNamedCollection <AFElement> elements = AFElement.FindElements( database: afDatabase, searchRoot: null, query: "Boiler", field: AFSearchField.Template, searchFullHierarchy: true, sortField: AFSortField.Name, sortOrder: AFSortOrder.Ascending, startIndex: startIndex, maxCount: pageSize, totalCount: out totalCount); if (elements == null) { break; } // Partially load the element by retrieving information only for the Water Flow attribute. AFElement.LoadAttributes(elements, new[] { boilerTemplate.AttributeTemplates["Water Flow"] }); Console.WriteLine("Found {0} Elements.", elements.Count); AFAttributeList attrList = new AFAttributeList(); // Because we are retrieving the Water Flow attribute which was previously loaded, // no additional server calls are made. // If LoadAttributes had not been called previously, then a server call would have been made for each element // in the loop below. foreach (AFElement item in elements) { attrList.Add(item.Attributes["Water Flow"]); } AFValues values = attrList.GetValue(); Console.WriteLine(" Water Flow values"); foreach (AFValue val in values) { Console.WriteLine(" Element: {0}, Timestamp: {1}, Value: {2}", val.Attribute.Element, val.Timestamp, val.Value.ToString()); } startIndex += pageSize; } while (startIndex < totalCount); }
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); } }
public static void GetACIOutput(Service unit, string ViewerFilePath) { PISystems piSystems = new PISystems(); PISystem piSystem; AFDatabase database; string error = ""; string error1 = ""; Outputs objOutputUnit = null; CurrentOutputAtGivenLoadStep resCurrentOutputs = null; IdealOutputAtGivenTorque resIdealOtpsAt90T = null, resIdealOtpsAt95T = null, resIdealOtpsAt100T = null; IList <PIPoint> lstPiPointForUnit = null; AFNamedCollectionList <AFElement> AllElements = new AFNamedCollectionList <AFElement>(); AFValue floatingValue = null; AFElement Model = new AFElement(); AFAttribute ErrorArrayCode = null; try { piSystem = piSystems["WINOSIT3D01"]; database = piSystem.Databases["DCPDev"]; if (File.Exists(ViewerFilePath)) { // Trace.Write(unit.UnitName + " :"); Trace.WriteLine(ViewerFilePath); var objERCM = objERCMKernal; objERCM.Reset(); objERCM.eRCMViewerFilename = ViewerFilePath; AciModelInputs objAciInput = new AciModelInputs(unit); if (objERCM.SuccessfulFileLoad) { if (!string.IsNullOrEmpty(objAciInput.ErrorMsg)) { Trace.TraceError("Valid Input data not available for " + unit.UnitName + " at" + DateTime.Now); return; } objOutputUnit = GetACIOutputObjectForUnit(unit.UnitName, unit.ServiceName); if (objAciInput.Rpm < 100) { error1 = " RPM is less than 100. Model wouold not run for " + unit.ServiceName + " " + unit.UnitName; Console.WriteLine(error1); AllElements = AFElement.FindElements(database, null, null, AFSearchField.Name, true, AFSortField.Name, AFSortOrder.Ascending, 1000000000); foreach (AFElement ele in AllElements) { if (ele.Name.Equals(unit.UnitName) && ((ele.Parent != null && ele.Parent.Name.Equals(unit.ServiceName)) || (ele.Parent.Parent != null && ele.Parent.Parent.Name.Equals(unit.ServiceName)))) { Model = ele.Elements["Model"]; ErrorArrayCode = Model.Attributes["ACI Error Array Code"]; floatingValue = new AFValue(error1); ErrorArrayCode.Data.UpdateValue(floatingValue, AFUpdateOption.NoReplace, AFBufferOption.DoNotBuffer); } } return; } objERCM.CurrentLoadStep = unit.LoadStep; resCurrentOutputs = GetCurrentOutputAtGivenLoadStep(unit.LoadStep, objAciInput, objERCM); resIdealOtpsAt90T = GetIdealOutputAtGivenTorque(unit.LoadStep, 90, objAciInput, objERCM); resIdealOtpsAt95T = GetIdealOutputAtGivenTorque(unit.LoadStep, 95, objAciInput, objERCM); resIdealOtpsAt100T = GetIdealOutputAtGivenTorque(unit.LoadStep, 100, objAciInput, objERCM); objERCM.TorqueLimit = 100; objERCM.CurrentLoadStep = unit.LoadStep; objERCM.ChangeOpCondition(objAciInput.PsG, objAciInput.PdG, objAciInput.Rpm, objAciInput.Ts1, objAciInput.Ts2, objAciInput.Ts3, objAciInput.Ts4, objAciInput.Ts5, objAciInput.Ts6); string ACIInputValues = "PsG:" + objAciInput.PsG + " PdG:" + objAciInput.PdG + " Rpm:" + objAciInput.Rpm + " Ts1:" + objAciInput.Ts1 + " Ts2:" + objAciInput.Ts2 + " Ts3:" + objAciInput.Ts3 + " Ts4:" + objAciInput.Ts4 + " Ts5:" + objAciInput.Ts5 + " Ts6:" + objAciInput.Ts6; Trace.TraceInformation(ACIInputValues); //Max Allowed Dischage Pressure var MaxAllowedPd = objERCM.CalcMaxAllowedPd(objAciInput.PsG, objAciInput.Rpm, objAciInput.Ts1, objAciInput.Ts2, objAciInput.Ts3, objAciInput.Ts4, objAciInput.Ts5, objAciInput.Ts6, unit.LoadStep); objERCM.ErrorArray(objERCM.CurrentLoadStep); error = objERCM.FullEnglishErrors(objERCM.ErrorArray(objERCM.CurrentLoadStep), 0); if (error != string.Empty) { Trace.TraceInformation(ACIInputValues); Trace.TraceError(error); } error = error + error1; string CurrentTorq = objERCM.CurrentTorque.ToString(); //Output Result //objOutputUnit = GetACIOutputObjectForUnit(unit.UnitName, unit.ServiceName);//at here Error Occurs!!! //Assign Value to tags lstPiPointForUnit = GetOutputTagList(objOutputUnit); //Update in PI Server // var result = SaveOutputDataInPi(objUnit, lstPiPointForUnit, objERCM); objOutputUnit.MaxAllowedDischargePressure.Value = MaxAllowedPd; //Current Operating Outputs objOutputUnit.LoadStep.Current.Value = resCurrentOutputs.CurrentLoadStep; objOutputUnit.LoadStep.CurrentDetails.Value = resCurrentOutputs.CurrentLoadStepDetail; objOutputUnit.LoadPrediction.Current.Value = resCurrentOutputs.CurrentLoad; objOutputUnit.FlowPrediction.Current.Value = resCurrentOutputs.CurrentFlow; objOutputUnit.FuelRate.Current.Value = resCurrentOutputs.CurrentFuelRate; //Ideal Outputs at 90% Torque objOutputUnit.IdealFlow90T.Value = resIdealOtpsAt90T.IdealFlowAtGivenTorque; objOutputUnit.IdealFuelRate90T.Value = resIdealOtpsAt90T.IdealFuelRateAtGivenTorque; objOutputUnit.IdealLoad90T.Value = resIdealOtpsAt90T.IdealLoadAtGivenTorque; objOutputUnit.IdealLoadStep90T.Value = resIdealOtpsAt90T.IdealLoadStepAtGivenTorque; objOutputUnit.IdealLoadStepDetail90T.Value = resIdealOtpsAt90T.IdealLoadStepDetailAtGivenTorque; //Ideal Outputs at 95% Torque objOutputUnit.IdealFlow95T.Value = resIdealOtpsAt95T.IdealFlowAtGivenTorque; objOutputUnit.IdealFuelRate95T.Value = resIdealOtpsAt95T.IdealFuelRateAtGivenTorque; objOutputUnit.IdealLoad95T.Value = resIdealOtpsAt95T.IdealLoadAtGivenTorque; objOutputUnit.IdealLoadStep95T.Value = resIdealOtpsAt95T.IdealLoadStepAtGivenTorque; objOutputUnit.IdealLoadStepDetail95T.Value = resIdealOtpsAt95T.IdealLoadStepDetailAtGivenTorque; //Ideal Outputs at 100% Torque objOutputUnit.LoadStep.Ideal.Value = resIdealOtpsAt100T.IdealLoadStepAtGivenTorque; objOutputUnit.LoadStep.IdealDetails.Value = resIdealOtpsAt100T.IdealLoadStepDetailAtGivenTorque; objOutputUnit.LoadPrediction.Ideal.Value = resIdealOtpsAt100T.IdealLoadAtGivenTorque; objOutputUnit.FlowPrediction.Ideal.Value = resIdealOtpsAt100T.IdealFlowAtGivenTorque; objOutputUnit.FuelRate.Ideal.Value = resIdealOtpsAt100T.IdealFuelRateAtGivenTorque; if (resCurrentOutputs.CurrentFlow < resIdealOtpsAt100T.IdealFlowAtGivenTorque || resCurrentOutputs.CurrentLoad < resIdealOtpsAt100T.IdealLoadAtGivenTorque) { Console.WriteLine("Current load & Flow lower than ideal."); string message = string.Format("Service Name:{0}, Unit Name:{1},Current Load:{2},Ideal Load:{3}, Current Flow:{4}, Ideal Flow: {5}", unit.ServiceName, unit.UnitName, resCurrentOutputs.CurrentLoad, resIdealOtpsAt100T.IdealLoadAtGivenTorque, resCurrentOutputs.CurrentFlow, resIdealOtpsAt100T.IdealFlowAtGivenTorque); Trace.WriteLine(message); //Ideal Outputs at 90% Torque objOutputUnit.IdealFlow90T.Value = "No Data"; objOutputUnit.IdealFuelRate90T.Value = "No Data"; objOutputUnit.IdealLoad90T.Value = "No Data"; objOutputUnit.IdealLoadStep90T.Value = "No Data"; objOutputUnit.IdealLoadStepDetail90T.Value = "No Data"; //Ideal Outputs at 95% Torque objOutputUnit.IdealFlow95T.Value = "No Data"; objOutputUnit.IdealFuelRate95T.Value = "No Data"; objOutputUnit.IdealLoad95T.Value = "No Data"; objOutputUnit.IdealLoadStep95T.Value = "No Data"; objOutputUnit.IdealLoadStepDetail95T.Value = "No Data"; objOutputUnit.LoadStep.Ideal.Value = "No Data"; objOutputUnit.LoadStep.IdealDetails.Value = "No Data"; objOutputUnit.LoadPrediction.Ideal.Value = "No Data"; objOutputUnit.FlowPrediction.Ideal.Value = "No Data"; objOutputUnit.FuelRate.Ideal.Value = "No Data"; } objOutputUnit.ErrorCode.Value = error; SaveOutputDataInPi(objOutputUnit, lstPiPointForUnit, objERCM, unit); } else { Trace.WriteLine("Failed to load in Viewer file!"); } } else { Trace.WriteLine("File doesn't exist at " + ViewerFilePath); return; } } catch (Exception ex) { Console.WriteLine(ex.Message); Trace.WriteLine(ex.StackTrace); } }