private static void Main(string[] args) { PIServer server = new PIServers().DefaultPIServer; server.Connect(); List <PIPoint> points = PIPoint.FindPIPoints(server, "testSinusoid_*").ToList(); if (points.Count == 0) { server.CreatePIPoints(Enumerable.Range(1, 6000).Select(x => "testSinusoid_" + x), new Dictionary <String, Object>() { { "compressing", 0 } }); points = PIPoint.FindPIPoints(server, "testSinusoid_*").ToList(); } Console.WriteLine("Found {0} points", points.Count); TimeSpan chunkSize = new TimeSpan(5, 0, 0); for (DateTime start = new DateTime(2017, 1, 1); start < new DateTime(2018, 1, 1); start = start.Add(chunkSize)) { Console.WriteLine("Writing chunk starting at: " + start); List <AFValue> values = getSinusoidData(start, start.Add(chunkSize), new TimeSpan(0, 0, 15)); Parallel.ForEach(points, point => { point.UpdateValues(values, AFUpdateOption.Replace); }); } server.Disconnect(); }
/// <summary> /// Starts threads and timers to poll the PI server for data /// </summary> /// <param name="state">Filter string which will get the desired points from PI</param> private void StartGettingData(object state) { try { string tagFilter = state.ToString(); m_points = new PIPointList(PIPoint.FindPIPoints(m_connection.Server, tagFilter, true)); m_dataThread = new Thread(QueryData); m_dataThread.IsBackground = true; m_dataThread.Start(); m_publishTimer = new System.Timers.Timer(); m_publishTimer.Interval = ProcessingInterval > 0 ? ProcessingInterval : 33; m_publishTimer.Elapsed += m_publishTimer_Tick; m_publishTimer.Start(); } catch (ThreadAbortException) { throw; } catch (Exception e) { OnProcessException(e); } }
/// <summary> /// This method deletes the data stored in specified tags of the PI Data Archive /// To delete data, it is required to first read the values that you want to delete, and then /// Call the update values method with the AFUpdateOption.Remove option /// <remarks> /// </remarks> /// </summary> private void DeleteData() { try { ValidateParameters(); piConnectionMgr = new PiConnectionMgr(Server); piConnectionMgr.Connect(); PIServer server = piConnectionMgr.GetPiServer(); var timer = Stopwatch.StartNew(); // Gets the tags and creates a point list with the tags, to prepare for bulk read call var points = PIPoint.FindPIPoints(server, TagList); var pointList = new PIPointList(points); Logger.InfoFormat("Initialized PI Points for deletion: {0}", string.Join(", ", points.Select(p => p.Name))); // converts strings to AFTime objects this will throw an error if invalid var startTime = new AFTime(StartTime); var endTime = new AFTime(EndTime); if (startTime > endTime) { throw new PIDeleteUtilInvalidParameterException("Start Time must be smaller than End Time"); } // defines the data eraser task that will work in parallel as the data querying task dataEraser = new DataProcessor(EraseData); var eraseTask = Task.Run(() => dataEraser.Run()); // splits iterates the period, over foreach (var period in Library.Helpers.EachNDay(startTime, endTime, Days)) { Logger.InfoFormat("Getting tags information for period {0} to {1} ({2} Days chunk)", startTime, endTime, Days); // makes the first data call var data = pointList.RecordedValues(period, AFBoundaryType.Inside, null, false, new PIPagingConfiguration(PIPageType.TagCount, 100)); Logger.InfoFormat("Adding the data to the queue for deletion. ({0} to {1})", startTime, endTime); // we push this data into the data processor queue so we can continue to query for the rest of the data. dataEraser.DataQueue.Add(data); } dataEraser.DataQueue.CompleteAdding(); // // this will tell the data eraser that no more data will be added and allow it to complete eraseTask.Wait(); // waiting for the data processor to complete Logger.InfoFormat( "Deletion process completed in {0} seconds. With {1} events deleted (assuming there was no errors).", Math.Round(timer.Elapsed.TotalSeconds, 0), dataEraser.TotalEventProcessed); } catch (Exception ex) { Logger.Error(ex); } }
/// <summary> /// Deletes the PI Points matching the name filter. /// </summary> /// <param name="nameFilter">Name filter to use when deleting PI Points.</param> /// <param name="output">The output logger used for writing messages.</param> public void DeletePIPoints(string nameFilter, ITestOutputHelper output) { Contract.Requires(output != null); var pointList = new List <PIPoint>(); pointList.AddRange(PIPoint.FindPIPoints(PIServer, nameFilter)); if (pointList.Count <= 0) { output.WriteLine($"Did not find any PI Points to delete with name filter [{nameFilter}]."); } else { output.WriteLine($"PI Points with name filter [{nameFilter}] found. Removing from [{PIServer.Name}]."); } // Process PI Points in pages int i = 0; foreach (IList <PIPoint> pointGroup in pointList.GroupBy(name => i++ / PointPageSize).Select(g => g.ToList())) { AFErrors <string> errors = PIServer.DeletePIPoints(pointGroup.Select(pt => pt.Name)); if (errors != null) { throw errors.Errors.First().Value; } } }
public void Run() { PIServers piServers = new PIServers(); PIServer piServer = piServers["<PISERVER>"]; IList <PIPoint> points = PIPoint.FindPIPoints(piServer, new[] { "sample_floatpoint", "sample_digitalpoint" }); PIPoint floatingPIPoint = points[0]; PIPoint digitalPIPoint = points[1]; AFEnumerationSet digSet = piServer.StateSets["Modes"]; IList <AFValue> valuesToWrite = new List <AFValue>(); for (int i = 0; i < 10; i++) { AFTime time = new AFTime(new DateTime(2015, 1, 1, i, 0, 0, DateTimeKind.Local)); AFValue afValueFloat = new AFValue(i, time); // Associate the AFValue to a PI Point so we know where to write to. afValueFloat.PIPoint = floatingPIPoint; AFEnumerationValue digSetValue = i % 2 == 0 ? digSet["Auto"] : digSet["Manual"]; AFValue afValueDigital = new AFValue(digSetValue, time); afValueDigital.PIPoint = digitalPIPoint; valuesToWrite.Add(afValueFloat); valuesToWrite.Add(afValueDigital); } // Perform a bulk write. Use a single local call to PI Buffer Subsystem if possible. // Otherwise, make a single call to the PI Data Archive. // We use no compression just so we can check all the values are written. piServer.UpdateValues(valuesToWrite, AFUpdateOption.InsertNoCompression, AFBufferOption.BufferIfPossible); }
public IEnumerable <PIPoint> Search(string query) { var queries = PIPointQuery.ParseQuery(_server, query); var points = PIPoint.FindPIPoints(_server, queries); return(points); }
public void ConnectToPIDataArchive() { piServer.Connect(); IEnumerable <PIPoint> allPIPoints = PIPoint.FindPIPoints(piServer, "CityBikes*"); allPIPointNames = allPIPoints.Select(p => p.Name).ToList(); }
public void ArchiveQueryTest(string pointMask, string startTime, string endTime, double minValue, double maxValue) { var now = AFTime.Now; var st = new AFTime(startTime, now); var et = new AFTime(endTime, now); Output.WriteLine($"Start to execute PI Data Archive queries on PI Points matching [{pointMask}] " + $"between [{st}] and [{et}]."); IList <IEnumerable <PIPointQuery> > queries = PIPointQuery.ParseQuery(Fixture.PIServer, pointMask); IEnumerable <PIPoint> pointList = PIPoint.FindPIPoints(Fixture.PIServer, queries).ToList(); IDictionary <string, AFValues> events = Fixture.ReadPIEvents(pointList, st, et); // Verify all event values are in the expected range foreach (var ptvaluespair in events) { foreach (var val in ptvaluespair.Value.Where(val => val.IsGood)) { var convertedValue = Convert.ToDouble(val.Value, CultureInfo.InvariantCulture); Assert.True(convertedValue >= minValue && convertedValue <= maxValue, $"[{ptvaluespair.Key}] has a value [{val.Value}] outside of expected data range of " + $"[{minValue} ~ {maxValue}]"); } } Output.WriteLine($"Found {events.Sum(kvp => kvp.Value.Count)} PI events."); }
private PIPoint GetPIPoint(PIServer server, Guid signalID, out string cachedTagName) { PIPoint point = null; // See if cached mapping exists between guid and tag name - tag name lookups are faster than GetPoints query if (m_tagMap.TryGetValue(signalID, out cachedTagName)) { point = GetPIPoint(server, cachedTagName); } if ((object)point == null) { // Point was not previously cached, lookup tag using signal ID stored in extended description field IEnumerable <PIPoint> points = PIPoint.FindPIPoints(server, string.Format("EXDESC='{0}'", signalID), false, new[] { PICommonPointAttributes.ExtendedDescriptor }); point = points.FirstOrDefault(); if ((object)point != null) { cachedTagName = point.Name; } } return(point); }
private void MonitorPITags() { DataPipeHandler archiveDataPipeHandler = null; DataPipeHandler snapshotDataPipeHandler = null; try { if (string.IsNullOrEmpty(PIServerName)) { throw new PIServerNotFoundException(); } else { PIServer piserver; var piConnectionManager = PiConnectionMgr.ConnectAndGetServer(PIServerName, out piserver); // get the tag we want to monitor var pointList = PIPoint.FindPIPoints(piserver, TagList).ToList(); // event pipe for archive modifications var archive = AFDataPipeType.Archive; archiveDataPipeHandler = new DataPipeHandler(new PIConsoleDataObserver(archive), archive); archiveDataPipeHandler.AddSignupsWithInitEvents(pointList); // event pipe for snpshot modifications var snapshot = AFDataPipeType.Snapshot; snapshotDataPipeHandler = new DataPipeHandler(new PIConsoleDataObserver(snapshot), snapshot); snapshotDataPipeHandler.AddSignupsWithInitEvents(pointList); // archive data pipe is for demonstrative use // you may only need the snapshot in your application, this depends on your use case archiveDataPipeHandler.StartListening(TimeSpan.FromSeconds(Interval)); snapshotDataPipeHandler.StartListening(TimeSpan.FromSeconds(Interval)); Logger.InfoFormat("Listening for data changes started. Checking every {0}s", Interval); } } catch (Exception ex) { Logger.Error(ex); } finally { // here the method will wait until _terminateRequest.Set() before terminating _terminateRequest.WaitOne(); // in case you don't know this is called null propagation // its equivalent to if x!=null x.Dispose() archiveDataPipeHandler?.Dispose(); snapshotDataPipeHandler?.Dispose(); } }
public void PIPointSearchTest() { PIServer piServer = PIFixture.PIServer; int numberOfPointsToCreate = 10; var pointPrefix = "PIPointSearchTest_Point"; try { // Create PI Points Output.WriteLine($"Creating PI Points with prefix [{pointPrefix}]."); var points = PIFixture.CreatePIPoints($"{pointPrefix}#", numberOfPointsToCreate); // Assign range of values to defined tags for (int i = 0; i < points.Count(); i++) { points.ElementAt(i).UpdateValue(new AFValue(Math.Pow(-1, i + 1), null), 0); // Set the Step attribute of half of the PI Points to true and half to false points.ElementAt(i).SetAttribute(PICommonPointAttributes.Step, Convert.ToBoolean(1 * ((i + 1) % 2))); points.ElementAt(i).SaveAttributes(); } // Search PI Points with queries var searchQuery = $"Name:'{pointPrefix}*' value:>0"; Output.WriteLine($"Searching for PI Points with query [{searchQuery}]."); var parsedQuery = PIPointQuery.ParseQuery(piServer, searchQuery); var searchPointsCount = PIPoint.FindPIPoints(piServer, parsedQuery).Count(); AssertEventually.True( () => PIPoint.FindPIPoints(piServer, parsedQuery).Count() == (numberOfPointsToCreate / 2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(0.5), $"The PI Points count do not match. Expected: {numberOfPointsToCreate / 2}, Actual: {searchPointsCount}."); searchQuery = $"Name:'{pointPrefix}*'"; Output.WriteLine($"Searching for PI Points with query [{searchQuery}]."); parsedQuery = PIPointQuery.ParseQuery(piServer, searchQuery); searchPointsCount = PIPoint.FindPIPoints(piServer, parsedQuery).Count(); AssertEventually.True( () => PIPoint.FindPIPoints(piServer, parsedQuery).Count() == numberOfPointsToCreate, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(0.5), $"The PI Points count do not match. Expected: {numberOfPointsToCreate}, Actual: {searchPointsCount}."); searchQuery = $"Name:'{pointPrefix}*' step:=0"; Output.WriteLine($"Searching for PI Points with query [{searchQuery}]."); parsedQuery = PIPointQuery.ParseQuery(piServer, searchQuery); searchPointsCount = PIPoint.FindPIPoints(piServer, parsedQuery).Count(); AssertEventually.True( () => PIPoint.FindPIPoints(piServer, parsedQuery).Count() == (numberOfPointsToCreate / 2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(0.5), $"The PI Points count do not match. Expected: {numberOfPointsToCreate / 2}, Actual: {searchPointsCount}."); } finally { PIFixture.DeletePIPoints("PIPointSearchTest_Point*", Output); } }
public void PointSearchTest(string query, int expectedCount) { Output.WriteLine($"Search for PI Points using the query [{query}]. Expect to find {expectedCount} PI Points."); IList <IEnumerable <PIPointQuery> > queries = PIPointQuery.ParseQuery(Fixture.PIServer, query); IEnumerable <PIPoint> pointList = PIPoint.FindPIPoints(Fixture.PIServer, queries).ToList(); int actualCount = pointList.Count(); Assert.True(actualCount == expectedCount, $"Query [{query}] resulted in {actualCount} PI Points, expected {expectedCount}."); }
public PIPointsProvider(string query, PIServer server) { var queries = PIPointQuery.ParseQuery(server, query); if (queries == null || queries.Count < 1) { throw new Exception("The query passed was invalid, it would not find any PI Point"); } Points = PIPoint.FindPIPoints(server, queries); }
// Tag level public static void WriteTags(PIServer piServer, string outputFile) { using (StreamWriter outputStreamWriter = new StreamWriter(outputFile)) { foreach (PIPoint tag in PIPoint.FindPIPoints(piServer, "*")) { string path = tag.GetPath(); //Console.WriteLine(path); outputStreamWriter.WriteLine(path); } } }
public List <string> GetPIPoints() { PIPointList myPointList = new PIPointList(PIPoint.FindPIPoints(_pi, "*")); List <string> piPointList = new List <string> { }; foreach (PIPoint point in myPointList) { piPointList.Add(point.Name); } return(piPointList); }
public bool ValidateTagNames(string[] piPoints) { try { IList <PIPoint> piPointList = PIPoint.FindPIPoints(piServer, piPoints); pointList = new PIPointList(piPointList); return(true); } catch { return(false); } }
public static AFListResults <PIPoint, AFValue> ReadValuesFromPi(string[] tagnam) { IList <PIPoint> points = PIPoint.FindPIPoints(piServer, tagnam); // Create an PIPointList object in order to make the bulk call later. PIPointList pointList = new PIPointList(points); if (pointList == null) { return(null); } // MAKE A BULK CALL TO THE PI DATA ARCHIVE return(pointList.CurrentValue()); // Requires AF SDK 2.7+ }
public void SineWaveEventsTest() { string query = $"name:{PIFixture.SineWavePointNameMask} AND PointSource:{PIFixture.TestPIPointSource}"; Output.WriteLine($"Start to verify the SineWave wave pattern in PI Points matching [{query}] in the past one day."); IList <IEnumerable <PIPointQuery> > queries = PIPointQuery.ParseQuery(Fixture.PIServer, query); IEnumerable <PIPoint> pointList = PIPoint.FindPIPoints(Fixture.PIServer, queries).ToList(); IDictionary <string, AFValues> sineEvents = Fixture.ReadPIEvents(pointList, new AFTime("*-1d"), AFTime.Now); int totalCheckedEventCount = 0; foreach (KeyValuePair <string, AFValues> kvp in sineEvents) { // Use Distinct() in case there are duplicate archived events var timedEvents = kvp.Value.Distinct().ToDictionary(val => val.Timestamp.LocalTime, val => val.ValueAsDouble()); // Start for the oldest event and check events one by one foreach (KeyValuePair <DateTime, double> evt in timedEvents) { var timestampAfterAHalfWave = evt.Key.AddSeconds(PIFixture.SineWaveLengthInHours * 1800); var timestampAfterOneWave = evt.Key.AddSeconds(PIFixture.SineWaveLengthInHours * 3600); if (timedEvents.ContainsKey(timestampAfterAHalfWave) && timedEvents.ContainsKey(timestampAfterOneWave)) { // Based on the SineWave pattern, the current value should be equal to -1 * the value // after a half wave and the value after a full wave. Assert.True( Math.Abs(evt.Value - (-1 * timedEvents[timestampAfterAHalfWave])) < PIFixture.Epsilon, $"Found events in [{kvp.Key}] at [{evt.Key}] and [{timestampAfterAHalfWave}] not matching the SineWave pattern."); Assert.True( Math.Abs(evt.Value - timedEvents[timestampAfterOneWave]) < PIFixture.Epsilon, $"Found events in [{kvp.Key}] at [{evt.Key}] and [{timestampAfterOneWave}] not matching the SineWave pattern."); totalCheckedEventCount++; } else { // If the data set does not contain a key of timestampAfterOneWave, it means we have reached the end of set. break; } } } Output.WriteLine($"Successfully verified a total of {totalCheckedEventCount} SineWave values in {sineEvents.Count} PI Points."); }
private void btnTagsAnalyse_Click(object sender, EventArgs e) { btnConnect_Click(null, null); PIServer srv = (new PIServers()).DefaultPIServer; var pts = PIPoint.FindPIPoints(srv, "*"); var tmRange = new AFTimeRange(new AFTime("-70d"), new AFTime("*")); // 31+31+8 var writer = new StreamWriter("d:\\stats.csv"); writer.WriteLine("tag;zero;span;min;max"); int i = 0; foreach (var pt in pts) { i += 1; if (pt.PointType == PIPointType.Float16 || pt.PointType == PIPointType.Float32 || pt.PointType == PIPointType.Float64) { pt.LoadAttributes(PICommonPointAttributes.Zero, PICommonPointAttributes.Span); float zero = (float)pt.GetAttribute(PICommonPointAttributes.Zero); float span = (float)pt.GetAttribute(PICommonPointAttributes.Span); var sums = pt.Summary(tmRange, AFSummaryTypes.Minimum | AFSummaryTypes.Maximum, AFCalculationBasis.EventWeighted, AFTimestampCalculation.MostRecentTime); try { double min = (double)sums[AFSummaryTypes.Minimum].Value; double max = (double)sums[AFSummaryTypes.Maximum].Value; if (min < zero || max > zero + span) { writer.WriteLine(pt.Name + ";" + zero + ";" + span + ";" + min + ";" + max); } } catch (Exception) { } } Text = i.ToString(); System.Windows.Forms.Application.DoEvents(); } writer.Flush(); writer.Close(); }
public override void Run() { try { PiConnectionHelper piConnectionHelper = new PiConnectionHelper(Server); piConnectionHelper.Connect(); PIServer pi = piConnectionHelper.GetPiServer(); List <PIPoint> points = PIPoint.FindPIPoints(pi, NameFilter, SourceFilter).ToList(); Logger.InfoFormat("{0} Tags Found", points.Count()); Logger.Info(string.Join(",", points.Select(p => p.Name))); } catch (Exception ex) { Logger.Error(ex); } }
public void PIPointsTest() { PIServer piServer = PIFixture.PIServer; int count = 10; var pointPrefix = "PIPointsTest_Point"; try { // Create PI Point and verify Output.WriteLine($"Creating PI Points with prefix [{pointPrefix}] with default attributes and verifying."); var points = PIFixture.CreatePIPoints($"{pointPrefix}#", count); var returnedPoints = PIPoint.FindPIPoints(piServer, $"{pointPrefix}*"); Assert.True(returnedPoints.Count() == count, $"Expected to find {count} PI Points on Data Archive [{piServer}], actually found {returnedPoints.Count()}."); var timestamp = new AFTime("*-10m"); // Set Value of PI Points Output.WriteLine("Updating PI Points with new values."); for (int i = 0; i < returnedPoints.Count(); i++) { returnedPoints.ElementAt(i).UpdateValue(new AFValue(i, timestamp), AFUpdateOption.NoReplace); } // Check for updated values Output.WriteLine("Checking PI Points were updated with new values."); for (int i = 0; i < count; i++) { AssertEventually.Equals(returnedPoints.ElementAt(i).CurrentValue(), new AFValue(Convert.ToSingle(i), timestamp.ToPIPrecision())); } // Delete PI Points and verify Output.WriteLine("Deleting PI Points that were created and verifying."); PIFixture.DeletePIPoints($"{pointPrefix}*", Output); returnedPoints = PIPoint.FindPIPoints(piServer, $"{pointPrefix}*"); Assert.True(returnedPoints.Count() == 0, $"Expected to find no PI Points with prefix [{pointPrefix}], but {returnedPoints.Count()} were found."); } finally { PIFixture.DeletePIPoints($"{pointPrefix}*", Output); } }
public void Run() { PIServers piServers = new PIServers(); PIServer piServer = piServers["<PISERVER>"]; // Use PICommonPointAttributes so we don't have to remember the strings for point attributes. PIPointQuery compressionFilter = new PIPointQuery { AttributeName = PICommonPointAttributes.Compressing, AttributeValue = "1", Operator = AFSearchOperator.Equal }; PIPointQuery nameFilter = new PIPointQuery { AttributeName = PICommonPointAttributes.PointSource, AttributeValue = "R", Operator = AFSearchOperator.Equal }; IEnumerable <string> attributesToLoad = new[] { PICommonPointAttributes.Compressing, PICommonPointAttributes.Descriptor, PICommonPointAttributes.PointSource, PICommonPointAttributes.Span, PICommonPointAttributes.Zero }; IEnumerable <PIPoint> points = PIPoint.FindPIPoints(piServer, new[] { compressionFilter, nameFilter }, attributesToLoad); foreach (PIPoint pt in points) { Console.WriteLine("Name: {0}", pt.GetAttribute(PICommonPointAttributes.Tag)); Console.WriteLine("Compressing: {0}", pt.GetAttribute(PICommonPointAttributes.Compressing)); Console.WriteLine("Descriptor: {0}", pt.GetAttribute(PICommonPointAttributes.Descriptor)); Console.WriteLine("PointSource: {0}", pt.GetAttribute(PICommonPointAttributes.PointSource)); Console.WriteLine("Span: {0}", pt.GetAttribute(PICommonPointAttributes.Span)); Console.WriteLine("Zero: {0}", pt.GetAttribute(PICommonPointAttributes.Zero)); Console.WriteLine(); } }
public void GetPIData(string piDataArchiveName, string piPointName1, string piPointName2, string piPointName3, string startTime, string endTime, string interval) { IEnumerable <string> piPointNames = new List <string> { piPointName1, piPointName2, piPointName3 }; PIServer piServer = new PIServers()[piDataArchiveName]; if (piServer == null) { return; } IList <PIPoint> points = PIPoint.FindPIPoints(piServer, piPointNames); PIPointList pointList = new PIPointList(points); AFTimeRange timeRange = new AFTimeRange(new AFTime(startTime), new AFTime(endTime)); AFTimeSpan timeSpan; bool result = AFTimeSpan.TryParse(interval, out timeSpan); if (result == false) { AFTimeSpan.TryParse("1h", out timeSpan); } IEnumerable <AFValues> valuesList = pointList.InterpolatedValues(timeRange, timeSpan, string.Empty, false, new PIPagingConfiguration(PIPageType.TagCount, 100)); foreach (AFValues values in valuesList) { if (values.PIPoint.Name == piPointName1) { values1 = values.Where(m => m.ValueTypeCode == TypeCode.Single || m.ValueTypeCode == TypeCode.Double).Select(m => m.ValueAsDouble()).ToArray(); } else if (values.PIPoint.Name == piPointName2) { values2 = values.Where(m => m.ValueTypeCode == TypeCode.Single || m.ValueTypeCode == TypeCode.Double).Select(m => m.ValueAsDouble()).ToArray(); } else if (values.PIPoint.Name == piPointName3) { values3 = values.Where(m => m.ValueTypeCode == TypeCode.Single || m.ValueTypeCode == TypeCode.Double).Select(m => m.ValueAsDouble()).ToArray(); } } }
//PIPoints /// <summary> /// Accesses the PIServer to get the PIPoints that are available. /// </summary> /// <param name="sys"> The current PISystem</param> /// <param name="serv"> The current PIServer</param> /// <returns></returns> public List <PIPoint> getPIPoints(PISystem sys, PIServer serv) { mainForm.Status("Getting PIPoints..."); currentSystem = sys; currentPIServer = serv; List <PIPoint> list; try { List <string> query = new List <string>() { "*" }; list = (List <PIPoint>)PIPoint.FindPIPoints(serv, query, null); return(list); } catch { mainForm.Status("ERROR: Unable to attach to " + serv.Name); return(null); } }
public override void Run() { try { PiConnectionMgr piConnectionMgr = new PiConnectionMgr(Server); piConnectionMgr.Connect(); PIServer pi = piConnectionMgr.GetPiServer(); PIPointList pointList = new PIPointList(PIPoint.FindPIPoints(pi, TagMask)); AFListResults <PIPoint, AFValue> values = pointList.CurrentValue(); foreach (AFValue val in values) { Logger.InfoFormat("The current value for PI Point {0} is : {1} - {2}", val.PIPoint, val.Timestamp, val.Value); } } catch (Exception ex) { Logger.Error(ex); } }
public void Run() { PIServers piServers = new PIServers(); PIServer piServer = piServers["<PISERVER>"]; IList <PIPoint> points = PIPoint.FindPIPoints(piServer, new[] { "sinusoid", "sinusoidu", "cdt158", "cdm158" }); // Create an PIPointList object in order to make the bulk call later. PIPointList pointList = new PIPointList(points); if (pointList == null) { return; } // MAKE A BULK CALL TO THE PI DATA ARCHIVE AFListResults <PIPoint, AFValue> values = pointList.CurrentValue(); // Requires AF SDK 2.7+ foreach (AFValue val in values) { Console.WriteLine("Point: {0}, Timestamp: {1}, Value: {2}", val.PIPoint, val.Timestamp, val.Value.ToString()); } }
/// <summary> /// Create any non-existing PI points based on a list of point definitions on a given PI Data Archive /// </summary> /// <param name="targetPI"></param> /// <param name="pointDefinitions"></param> private static void CreatePIPoints(PIServer targetPI, IDictionary <string, IDictionary <string, object> > pointDefinitions) { IEnumerable <string> pointNames = pointDefinitions.Keys; // See what points exist var resolvedPoints = new HashSet <string>(PIPoint.FindPIPoints(targetPI, pointNames) .Select(pt => pt.Name)); // Filter out existing points var pointsToCreate = pointDefinitions .Where(p => !resolvedPoints.Contains(p.Key)) .ToDictionary(p => p.Key, p => p.Value); // Create any points with default PI point attributes IEnumerable <string> pointsWithDefaultAttributes = pointsToCreate .Where(p => p.Value == null) .Select(p => p.Key) .ToList(); var results = targetPI.CreatePIPoints(pointsWithDefaultAttributes); if (results.Errors.Count > 0) { throw new AggregateException(results.Errors.Values); } // Create other PI points foreach (var pt in pointsWithDefaultAttributes) { pointsToCreate.Remove(pt); } results = targetPI.CreatePIPoints(pointsToCreate); if (results.Errors.Count > 0) { throw new AggregateException(results.Errors.Values); } }
public static void Run(PIServer piserver) { //Constructs a new PIDataPipe to signup for events on a list of PIPoint objects PIDataPipe piDP_A = new PIDataPipe(AFDataPipeType.TimeSeries); try { //List of PIPoints var ptListNames = new List <string> { "sinusoid", "CDT158", "CDT158Testt" }; var ptList = PIPoint.FindPIPoints(piserver, ptListNames.AsEnumerable()); //Find Tags Available in the DataArchive foreach (var val in ptListNames) { if ((PIPoint.TryFindPIPoint(piserver, val, out PIPoint point) == false)) { Console.WriteLine("Tag Has been DELETED: {0}", val.ToString()); } } Console.ReadLine(); //PIDataPipe1 //Moved below line above try block //PIDataPipe piDP_A = new PIDataPipe(AFDataPipeType.TimeSeries); //Take Returns a specified number of contiguous elements from the start of a sequence. var errPIa = piDP_A.AddSignups(ptList.Take(2).ToList()); var observerpiA = new Pipe_Observer("observerpiA"); // registering an Iobserver for ADDataPipeEvent with the PIDataPipe. All the AFDataPipeEvents received by the data pipe will // be sent to the IObserver. piDP_A.Subscribe(observerpiA); //using 3 minutes time to gracefully exiting and showing how dispose is working in finally block DateTime start = DateTime.Now; while (true && DateTime.Now.Subtract(start).Minutes < 3) { bool hasMorePiA; //Get updates.... Trigger retrival of new events var PIa = piDP_A.GetObserverEvents(100, out hasMorePiA); // out hasMorePiA - Indicates whether there could be more events in the pipe. hasMorePiA is set to true whenever the number of result // events reach maxEventCountPerServer for any one PI Data Archive within the pipe. if (hasMorePiA == true) { Console.WriteLine("the number of result events reach maxEventCountPerServer for any one PI Data Archive within the pipe"); } // while (hasMorePiA) ; } } catch (Exception ex) { Logs Err = new Logs(); Err.MyLogFile(ex); Console.WriteLine("An Error has occured for details please check the Log File:'" + ex.Message + "'"); Console.ReadLine(); } finally { //close – which will terminate the data pipes connection to the PI Servers associated with the monitored PI Point Object //Dispose - which will terminate the data pipes connection to the PI Servers associated with the monitored PI Point Object. //This method also releases the resources used by the PIDataPipe piDP_A.Close(); piDP_A.Dispose(); } }
private static IList <PIPoint> GetPIPoints(PIServer dataArchive, IEnumerable <string> tagNames, IEnumerable <string> attributeNames = null) { return(PIPoint.FindPIPoints(dataArchive, tagNames, attributeNames)); }
static int Main(string[] args) { var options = new Options(); var errors = new List <Error>(); var result = Parser.Default.ParseArguments <Options>(args); result.WithParsed(opts => options = opts).WithNotParsed(errs => errors = errs.ToList()); if (errors.Any()) { foreach (var error in errors) { Console.WriteLine(error.Tag); } return(1); } NameValueCollection appSettings = ConfigurationManager.AppSettings; string accountId = appSettings["accountId"]; string namespaceId = appSettings["namespaceId"]; string clusterAddress = appSettings["address"]; string ingressServiceUrl = clusterAddress + @"/api/omf"; // Use a client secret, retrieved from the OSIsoft Cloud Services portal for your account, to // create a SecurityHandler used to authenticate this app. string resource = appSettings["resource"]; string clientId = appSettings["clientId"]; string clientSecret = appSettings["clientSecret"]; var securityHandler = new SdsSecurityHandler(resource, accountId, clientId, clientSecret); // Create a client to manage OSIsoft Cloud Services Ingress resources. using (var managementClient = new IngressManagementClient(clusterAddress, accountId, securityHandler)) { // Connect to a PI server and select PI points for which to move data to OCS. var piServerName = appSettings["PIDataArchive"]; var piServer = new PIServers()[piServerName]; var points = PIPoint.FindPIPoints(piServer, options.TagMask).ToList(); if (!points.Any()) { Console.WriteLine($"No PI points found matching the tagMask query!"); return(1); } // Create OCS data ingress objects. string publisherName = appSettings["publisherName"]; string topicName = appSettings["topicName"]; string subscriptionName = appSettings["subscriptionName"]; Console.WriteLine("Setting up OSIsoft Cloud Services OMF ingress objects."); string publisherId = managementClient.GetOrCreatePublisherAsync(publisherName).GetAwaiter().GetResult(); string producerToken = managementClient.GetOrCreateToken(publisherId).GetAwaiter().GetResult(); string topicId = managementClient.GetOrCreateTopic(topicName, publisherId).GetAwaiter().GetResult(); string subscriptionId = managementClient.GetOrCreateSubscription(subscriptionName, topicId, namespaceId).GetAwaiter().GetResult(); // Each PI point type will be written to an OSIsoft Cloud Services(OCS) SDSStream. // The structure of each stream is defined by an OCS SDSType. We create this SDSType // by posting an OSIsoft Message Format(OMF) type message to OCS. // PI point value types need to translate to OCS SDSTypes. We create a limited number // of SDSTypes in OCS and then map PI point value types to those SDSTypes. // A mapping between PI point value types and the Ids of the SDSType that represents // them in OCS is shown below. Dictionary <OmfTypeCode, string> typeIdsByOmfType = new Dictionary <OmfTypeCode, string>(); typeIdsByOmfType.Add(OmfTypeCode.Number, "numberValueAndTimestamp"); typeIdsByOmfType.Add(OmfTypeCode.Integer, "integerValueAndTimestamp"); typeIdsByOmfType.Add(OmfTypeCode.String, "stringValueAndTimestamp"); typeIdsByOmfType.Add(OmfTypeCode.Time, "timeValueAndTimestamp"); typeIdsByOmfType.Add(OmfTypeCode.ByteArray, "byteArrayValueAndTimestamp"); using (var client = new IngressClient(ingressServiceUrl, producerToken) { UseCompression = true }) { // Create and send OMF Type messages. Console.WriteLine("Creating basic types in OCS to represent the format of PI points."); List <OmfType> types = GetOmfTypes(typeIdsByOmfType); var omfTypeMessageContent = new OmfTypeMessageContent() { Types = types }; client.SendMessageAsync(omfTypeMessageContent.ToByteArray(), MessageType.Type, MessageAction.Create).GetAwaiter().GetResult(); // Generate containers for each of the point with the correct OMF message type. List <OmfContainer> containers = GetOmfContainers(points, typeIdsByOmfType); if (options.WriteMode == Options.DataWriteMode.clearExistingData) { // Deleting the OMF container deletes the underlying SDSStream and its data. Console.WriteLine("Deleting OMF containers corresponding to the selected PI points that existed before the sample was run."); var omfContainerMessageContent = new OmfContainerMessageContent() { Containers = containers }; client.SendMessageAsync(omfContainerMessageContent.ToByteArray(), MessageType.Container, MessageAction.Delete).GetAwaiter().GetResult(); } Console.WriteLine("Creating corresponding containers for the PI points whose data will be written to OCS."); // OSIsoft Cloud Services' OMF Ingress sets a size limit on the request accepted by its external endpoint. We may need to split, or chunk, // containers into multiple OMF messages sent to the endpoint. for (int chunkStartIndex = 0; chunkStartIndex < containers.Count; chunkStartIndex += MaxChunkSize) { int numberOfContainersToSendInThisChunk = Math.Min(containers.Count - chunkStartIndex, MaxChunkSize); var containersToSendInThisChunk = containers.GetRange(chunkStartIndex, numberOfContainersToSendInThisChunk).ToList(); var omfContainerMessageContent = new OmfContainerMessageContent() { Containers = containersToSendInThisChunk }; client.SendMessageAsync(omfContainerMessageContent.ToByteArray(), MessageType.Container, MessageAction.Create).GetAwaiter().GetResult(); } // Write data from each PI point to a SDSStream. foreach (PIPoint point in points) { Console.WriteLine($"Writing PI point data for point {point.Name} to OCS."); string containerId = GetContainerId(point); AFValues values = point.RecordedValues(new AFTimeRange(options.StartTime, options.EndTime), AFBoundaryType.Inside, null, true); // OSIsoft Cloud Services' OMF Ingress sets a size limit on the request accepted by its external endpoint. We may need to split, or chunk, // events into multiple OMF messages sent to the endpoint. for (int chunkStartIndex = 0; chunkStartIndex < values.Count; chunkStartIndex += MaxChunkSize) { int numberOfEventsToReadForThisChunk = Math.Min(values.Count - chunkStartIndex, MaxChunkSize); // If there are multiple events at a single timestamp for the PI point, the most recently added event will be written to OCS. List <AFValue> distinctValuesInChunk = values.GetRange(chunkStartIndex, numberOfEventsToReadForThisChunk).GroupBy(value => value.Timestamp).Select(valuesAtTimestamp => valuesAtTimestamp.Last()).ToList(); List <PIData> piDataEvents = GetPIData(distinctValuesInChunk, ToOmfTypeCode(point.PointType)); OmfDataMessageContent omfDataMessageContent = new OmfDataMessageContent(containerId, piDataEvents); Console.WriteLine($"Sending PI point data from index {distinctValuesInChunk.First().Timestamp} to index {distinctValuesInChunk.Last().Timestamp} to OCS ({distinctValuesInChunk.Count} values)."); client.SendMessageAsync(omfDataMessageContent.ToByteArray(), MessageType.Data, MessageAction.Create).GetAwaiter().GetResult(); } } } // Delete OCS data ingress objects. if (options.DeleteIngressObjects) { Console.WriteLine($"Deleting subscription with Id {subscriptionId}."); managementClient.DeleteSubscription(subscriptionId).GetAwaiter().GetResult(); Console.WriteLine($"Deleting topic with Id {topicId}."); managementClient.DeleteTopicAsync(topicId).GetAwaiter().GetResult(); Console.WriteLine($"Deleting publisher with Id {publisherId}."); managementClient.DeletePublisherAsync(publisherId).GetAwaiter().GetResult(); } } return(0); }