public void PIDataPipeExample() { // Create point list containing our lab point and two known sinusoid points PIPointList pointList = new PIPointList(); pointList.Add(PIPoint.FindPIPoint(myPIServer, "sinusoid")); pointList.Add(PIPoint.FindPIPoint(myPIServer, "sinusoidu")); _eventPipe = new PIDataPipe(AFDataPipeType.Snapshot); _eventPipe.AddSignups(pointList); // Configure a timer to read the pipe every five seconds for updates Timer eventPipeTimer = new Timer(new TimerCallback(ReadPipe), null, 0, 100); // Block until user wants to exit Console.WriteLine("Press Enter to terminate"); Console.ReadLine(); // Disable timer eventPipeTimer.Dispose(); // Dispose of event pipe lock (_eventPipe) { _eventPipe.Dispose(); } }
/// <summary> /// Starts a query that will read data source values, given a set of point IDs and targets, over a time range. /// </summary> /// <param name="startTime">Start-time for query.</param> /// <param name="stopTime">Stop-time for query.</param> /// <param name="interval">Interval from Grafana request.</param> /// <param name="decimate">Flag that determines if data should be decimated over provided time range.</param> /// <param name="targetMap">Set of IDs with associated targets to query.</param> /// <returns>Queried data source data in terms of value and time.</returns> protected override IEnumerable <DataSourceValue> QueryDataSourceValues(DateTime startTime, DateTime stopTime, string interval, bool decimate, Dictionary <ulong, string> targetMap) { Dictionary <int, ulong> idMap = new Dictionary <int, ulong>(); PIPointList points = new PIPointList(); foreach (KeyValuePair <ulong, string> target in targetMap) { ulong metadataID = target.Key; string pointTag = target.Value; if (!MetadataIDToPIPoint.TryGetValue(metadataID, out PIPoint point)) { if (TryFindPIPoint(Connection, Metadata, GetPITagName(pointTag, PrefixRemoveCount), out point)) { MetadataIDToPIPoint[metadataID] = point; } } if ((object)point != null) { points.Add(point); idMap[point.ID] = metadataID; } } // Start data read from historian using (IEnumerator <AFValue> dataReader = ReadData(startTime, stopTime, points).GetEnumerator()) { while (dataReader.MoveNext()) { AFValue currentPoint = dataReader.Current; if (currentPoint == null) { continue; } yield return(new DataSourceValue { Target = targetMap[idMap[currentPoint.PIPoint.ID]], Time = (currentPoint.Timestamp.UtcTime.Ticks - m_baseTicks) / (double)Ticks.PerMillisecond, Value = Convert.ToDouble(currentPoint.Value), Flags = ConvertStatusFlags(currentPoint.Status) }); } } }
// 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)); } }
// 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)); } }