Beispiel #1
0
        private PIPoint GetPIPoint(PIServer server, string tagName)
        {
            PIPoint point;

            PIPoint.TryFindPIPoint(server, tagName, out point);
            return(point);
        }
Beispiel #2
0
        // 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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        /// <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();
            }
        }
Beispiel #7
0
        // 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));
            }
        }
Beispiel #8
0
 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);
 }
Beispiel #9
0
        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
                        });
                    }
                }
            }
        }