private PIPoint GetPIPoint(PIServer server, string tagName) { PIPoint point; PIPoint.TryFindPIPoint(server, tagName, out point); return(point); }
// Try to find PI Point, if no point found, return False and a null PI Point, else return true and the PI Point private (bool, PIPoint) GetPIPoint(string piPointName, string category = "") { PIPoint OutputPIPoint; string pointName = piPointName + category; bool result = PIPoint.TryFindPIPoint(_SitePI, pointName, out OutputPIPoint); return(result, OutputPIPoint); }
public bool TryGetTimeSeries(string name, out AFAttribute timeseries) { if (!PIPoint.TryFindPIPoint(server, name, out PIPoint point)) { timeseries = null; return(false); } timeseries = new AFAttribute(point); return(true); }
/// <summary> /// Removes the PI Point from the PI Server (Data Archive) if it exists. /// </summary> /// <param name="pointName">The name of the PI Point to remove.</param> /// <param name="output">The output logger used for writing messages.</param> public void RemovePIPointIfExists(string pointName, ITestOutputHelper output) { Contract.Requires(output != null); if (PIPoint.TryFindPIPoint(PIServer, pointName, out _)) { output.WriteLine($"PI Point [{pointName}] found. Removing it from [{PIServer.Name}]."); PIServer.DeletePIPoint(pointName); } else { output.WriteLine($"PI Point [{pointName}] not found. Cannot remove it from [{PIServer.Name}]."); } }
private async Task _RetrieveAndBackfillAsync(string HDAPIPointName) { // await for the _throttler to give a worker to the task. The worker is released in ReportAndRelease method await _throttler.WaitAsync(); string message; // Try find HDA PI Point, if it cant be found, Report Error, Progress and Release throttler. PIPoint HDAPIPoint; if (!PIPoint.TryFindPIPoint(_SitePI, HDAPIPointName, out HDAPIPoint)) { message = string.Format("HDA PI Point {0} not found", HDAPIPointName); ReportAndRelease(message); return; } // Try find DA PI Point, if it cant be found, Report Error, Progress and Release throttler. string DAPIPointName = _GetDAPIPointName(HDAPIPointName); PIPoint DAPIPoint; if (!PIPoint.TryFindPIPoint(_SitePI, DAPIPointName, out DAPIPoint)) { message = string.Format("DA PI Point {0} not found", DAPIPointName); ReportAndRelease(message); return; } // Retrieve Recorded Values within backfill time range var retrieveDataTask = HDAPIPoint.RecordedValuesAsync(_backfillRange, AFBoundaryType.Inside, null, false); // Backfill retrieved data from HDA PI Point into the DA PI Point var backfillResult = await DAPIPoint.ReplaceValuesAsync(_backfillRange, await retrieveDataTask, AFBufferOption.Buffer); // if backfillResult != null, backfill failed; else if backfillResult = null, it succeeds if (backfillResult != null) { message = string.Format("Backfill from {0} to {1} failed", HDAPIPointName, DAPIPointName); ReportAndRelease(message); return; } else { ReportAndRelease(); } return; }
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(); } }
// Kick start read process for historian private void StartDataReader(object state) { try { if (SupportsTemporalProcessing) { if ((object)RequestedOutputMeasurementKeys != null) { OnStatusMessage(MessageLevel.Info, $"Replaying for requested output keys: {RequestedOutputMeasurementKeys.Length:N0} defined measurements"); } else { OnStatusMessage(MessageLevel.Warning, "No measurements have been requested for playback - make sure \"; connectOnDemand=true\" is defined in the connection string for the reader."); } } MeasurementKey[] requestedKeys = SupportsTemporalProcessing ? RequestedOutputMeasurementKeys : OutputMeasurements.MeasurementKeys().ToArray(); if (Enabled && (object)m_connection != null && (object)requestedKeys != null && requestedKeys.Length > 0) { HashSet <string> tagList = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var query = from row in DataSource.Tables["ActiveMeasurements"].AsEnumerable() from key in requestedKeys where row["ID"].ToString() == key.ToString() select new { Key = key, AlternateTag = row["AlternateTag"].ToString(), PointTag = row["PointTag"].ToString() }; string tagName; m_points = new PIPointList(); PIPoint point; foreach (var result in query) { tagName = result.PointTag; if (!string.IsNullOrWhiteSpace(result.AlternateTag)) { tagName = result.AlternateTag; } if (tagList.Add(tagName) && PIPoint.TryFindPIPoint(m_connection.Server, tagName, out point)) { m_tagKeyMap[point.ID] = result.Key; m_points.Add(point); } } m_publicationTime = 0; // Start data read from historian lock (m_readTimer) { m_startTime = base.StartTimeConstraint <DateTime.MinValue?DateTime.MinValue : base.StartTimeConstraint> DateTime.MaxValue ? DateTime.MaxValue : base.StartTimeConstraint; m_stopTime = base.StopTimeConstraint <DateTime.MinValue?DateTime.MinValue : base.StopTimeConstraint> DateTime.MaxValue ? DateTime.MaxValue : base.StopTimeConstraint; m_dataReader = ReadData(m_startTime, m_stopTime).GetEnumerator(); m_readTimer.Enabled = m_dataReader.MoveNext(); if (m_readTimer.Enabled) { OnStatusMessage(MessageLevel.Info, "Starting historical data read..."); } else { OnStatusMessage(MessageLevel.Info, "No historical data was available to read for given time frame."); OnProcessingComplete(); } } } else { m_readTimer.Enabled = false; OnStatusMessage(MessageLevel.Info, "No measurement keys have been requested for reading, historian reader is idle."); OnProcessingComplete(); } } catch (Exception ex) { OnProcessException(MessageLevel.Warning, new InvalidOperationException($"Could not start historical data read due to exception: {ex.Message}", ex)); } }
private static bool TryFindPIPoint(PIConnection connection, string pointTag, string alternateTag, out PIPoint point) { return PIPoint.TryFindPIPoint(connection.Server, string.IsNullOrWhiteSpace(alternateTag) ? pointTag : alternateTag, out point); }
public void OMFTest() { // Use ticks as a unique id mask to avoid naming collisions with other PI Points var idTicks = $"{DateTime.UtcNow.Ticks}"; string typeId = $"TankMeasurement{idTicks}"; string containerId = $"Tank1Measurements{idTicks}"; PISystem omfAFServer = null; AFDatabase omfDatabase = null; PIServer omfPIServer = null; List <PIPoint> omfPIPoints = null; AFElementTemplate omfTypeAsTemplate = null; var jsonType = @"[ { ""id"": """ + typeId + @""", ""version"": ""1.0.0.0"", ""type"": ""object"", ""classification"": ""dynamic"", ""properties"": { ""Time"": { ""format"": ""date-time"", ""type"": ""string"", ""isindex"": true }, ""Pressure"": { ""type"": ""number"", ""name"": ""Tank Pressure"" }, ""Temperature"": { ""type"": ""number"", ""name"": ""Tank Temperature"" } } } ]"; var jsonContainer = @"[{ ""id"": """ + containerId + @""", ""typeid"": """ + typeId + @""", ""typeVersion"": ""1.0.0.0"", ""indexes"": [""Pressure""] }]"; var jsonData = @"[{ ""containerid"": """ + containerId + @""", ""values"": [{ ""Time"": ""2017-01-11T22:24:23.430Z"", ""Pressure"": 11.5, ""Temperature"": 101 }] }]"; var coll = new NameValueCollection { { "messagetype", "type" }, { "messageformat", "json" }, { "omfversion", "1.1" }, { "action", "create" }, }; try { // Create the type object var omfUrl = $"{Fixture.HomePageUrl}/omf"; Fixture.Client.Headers.Add(coll); Output.WriteLine($"Create OMF type through Web API using Url [{omfUrl}] and JSON [{jsonType}]."); var createTypeResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonType)); Assert.True(createTypeResponse["OperationId"] != null, $"OperationId not returned in OMF response."); // Create a container for the created type Fixture.Client.Headers["messagetype"] = "container"; Output.WriteLine($"Create OMF container through Web API using Url [{omfUrl}] and JSON [{jsonContainer}]."); var createContainerResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonContainer)); Assert.True(createContainerResponse["OperationId"] != null, "OperationId not returned in OMF response."); // Add data to the container Fixture.Client.Headers["messagetype"] = "data"; Output.WriteLine($"Add data to the OMF container through Web API using Url [{omfUrl}] and JSON [{jsonData}]."); var createDataResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonData)); Assert.True(createDataResponse["OperationId"] != null, "OperationId not returned in OMF response."); // Verify objects were created correctly in AF and PI var instanceConfigUrl = $"{Fixture.HomePageUrl}/system/instanceconfiguration"; var config = JObject.Parse(Fixture.Client.DownloadString(instanceConfigUrl)); Output.WriteLine($"Verify OMF objects were create in AF and PI through Web API using Url [{instanceConfigUrl}]."); omfAFServer = new PISystems()[(string)config["OmfAssetServerName"]]; omfDatabase = omfAFServer.Databases[(string)config["OmfAssetDatabaseName"]]; omfPIServer = PIServers.GetPIServers()[(string)config["OmfDataArchiveName"]]; if (omfPIServer.ConnectionInfo == null) { omfPIServer.Connect(); } var typeInAF = omfDatabase.ElementTemplates[typeId]; Assert.True(typeInAF != null, $"The OMF Type [{typeId}] should exist as an ElementTemplate in [{omfDatabase}] on [{omfAFServer}]."); var pointFound = PIPoint.TryFindPIPoint(omfPIServer, $"{containerId}.Pressure", out var piPointPressure); Assert.True(pointFound, $"PI Point [{containerId}.Pressure] not found in [{omfPIServer.Name}]."); Assert.True(piPointPressure.CurrentValue().ValueAsSingle() == 11.5, $"Value for PI Point [{containerId}.Pressure] incorrect. Expected: [11.5], Actual: [{piPointPressure.CurrentValue().ValueAsSingle()}]."); pointFound = PIPoint.TryFindPIPoint(omfPIServer, $"{containerId}.Temperature", out var piPointTemperature); Assert.True(pointFound, $"PI Point [{containerId}.Temperature] not found in [{omfPIServer.Name}]."); Assert.True(piPointTemperature.CurrentValue().ValueAsInt32() == 101, $"Value for PI Point [{containerId}.Temperature] incorrect. Expected: [101], Actual: [{piPointTemperature.CurrentValue().ValueAsInt32()}]."); // Delete the data Output.WriteLine("Delete OMF data."); Fixture.Client.Headers["action"] = "delete"; var deleteDataResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonData)); Assert.True(deleteDataResponse["OperationId"] != null, "OperationId not returned in OMF response."); // Delete the container Fixture.Client.Headers["messagetype"] = "container"; var deleteContainerResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonContainer)); Assert.True(deleteContainerResponse["OperationId"] != null, "OperationId not returned in OMF response."); // Delete the type Fixture.Client.Headers["messagetype"] = "type"; var deleteTypeResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonType)); Assert.True(deleteTypeResponse["OperationId"] != null, "OperationId not returned in OMF response."); // Verify objects were deleted. Remove objects that were not deleted before Assert to ensure cleanup omfPIPoints = PIPoint.FindPIPoints(omfPIServer, $"{containerId}*", null, null).ToList(); omfDatabase.ElementTemplates.Refresh(); omfTypeAsTemplate = omfDatabase.ElementTemplates[typeId]; Assert.True(omfPIPoints.Count == 0, "PIPoints were not deleted by the DELETE CONTAINER request to OMF."); Assert.True(omfTypeAsTemplate == null, $"The OMF Type [{typeId}] was not deleted by the DELETE TYPE request to OMF."); } catch (WebException ex) { var httpResponse = (HttpWebResponse)ex.Response; var statusCode = string.Empty; if (httpResponse.StatusCode != HttpStatusCode.OK && httpResponse.StatusCode != HttpStatusCode.Accepted && httpResponse.StatusCode != HttpStatusCode.NoContent) { statusCode = $"{httpResponse.StatusCode}: {httpResponse.StatusDescription}"; } // For troubleshooting error response codes returned by PI Web API using (var reader = new StreamReader(ex.Response.GetResponseStream())) { var response = JObject.Parse(reader.ReadToEnd())["Messages"]?[0]["Events"]?[0]["Message"]?.ToString(); if (!string.IsNullOrEmpty(response)) { Assert.True(false, $"Error returned from OMF: {response}. {statusCode}."); } else { throw; } } } finally { // Clean up any existing OMF objects if not deleted by OMF if (omfPIServer != null) { if (omfPIServer.ConnectionInfo == null) { omfPIServer.Connect(); } omfPIPoints = PIPoint.FindPIPoints(omfPIServer, $"{containerId}*", null, null).ToList(); bool pointsDeleted = omfPIPoints.Count == 0; if (!pointsDeleted) { omfPIServer.DeletePIPoints(omfPIPoints.Select(p => p.Name).ToList()); } } if (omfAFServer != null && omfDatabase != null) { omfTypeAsTemplate = omfDatabase.ElementTemplates[typeId]; bool typeDeleted = omfTypeAsTemplate == null; if (!typeDeleted) { AFElementTemplate.DeleteElementTemplates(omfAFServer, new List <Guid> { omfTypeAsTemplate.ID }); } } } }