Beispiel #1
0
        public bool ReadNextHistorianBlock(out DataPoint[] points)
        {
            try
            {
                CurrentTimestamp = new DateTime((long)m_dataPoint.Timestamp);
                ulong currentTimestamp = m_dataPoint.Timestamp;

                int  timeComparison;
                bool readSuccess = true;

                // Create a new data block for current timestamp and load first/prior point
                m_dataBlock.Clear();
                m_dataBlock[m_dataPoint.PointID] = m_dataPoint.Clone();

                // Load remaining data for current timestamp
                do
                {
                    // Scan to next record
                    if (!m_historianClient.ReadNext(m_dataPoint))
                    {
                        readSuccess = false;
                        break;
                    }

                    timeComparison = DataPoint.CompareTimestamps(m_dataPoint.Timestamp, currentTimestamp, m_settings.FrameRate);

                    if (timeComparison == 0)
                    {
                        m_dataBlock[m_dataPoint.PointID] = m_dataPoint.Clone();
                    }
                }while (timeComparison == 0);

                // Finished with data read
                if (!readSuccess)
                {
                    ShowMessage(">>> End of data in range encountered...");
                    return(false);
                }

                return(true);
            }
            catch (Exception ex)
            {
                ShowMessage($"!!! Failure during historian read: {ex.Message}");
                Log.Publish(MessageLevel.Error, "HistorianDataRead", "Failed while reading data from the historian", exception: ex);
                return(false);
            }
            finally
            {
                PercentComplete = (int)((1.0D - (new Ticks(m_endTime.Ticks - (long)m_dataPoint.Timestamp).ToSeconds() / m_timeRange)) * 100.0D);
                points          = m_dataBlock.Values.ToArray();
            }
        }
Beispiel #2
0
        // Internal Functions

        private void ReadArchive(object state)
        {
            try
            {
                double    timeRange           = (m_settings.EndTime - m_settings.StartTime).TotalSeconds;
                long      receivedPoints      = 0;
                long      processedDataBlocks = 0;
                long      duplicatePoints     = 0;
                Ticks     operationTime;
                Ticks     operationStartTime;
                DataPoint point          = new DataPoint();
                DateTime  firstTimestamp = new DateTime(0L);
                DateTime  lastTimestamp  = new DateTime(0L);

                using (Algorithm algorithm = new Algorithm())
                {
                    algorithm.ShowMessage     = ShowUpdateMessage;
                    algorithm.MessageInterval = m_settings.MessageInterval;
                    algorithm.StartTime       = m_settings.StartTime;
                    algorithm.EndTime         = m_settings.EndTime;
                    algorithm.FrameRate       = m_settings.FrameRate;
                    algorithm.TimeRange       = timeRange;
                    algorithm.Log             = m_log;

                    // Load historian meta-data
                    ShowUpdateMessage(">>> Loading source connection metadata...");

                    operationStartTime = DateTime.UtcNow.Ticks;
                    algorithm.Metadata = MetadataRecord.Query(m_settings.HostAddress, m_settings.MetadataPort, m_settings.MetadataTimeout);
                    operationTime      = DateTime.UtcNow.Ticks - operationStartTime;

                    ShowUpdateMessage("*** Metadata Load Complete ***");
                    ShowUpdateMessage($"Total metadata load time {operationTime.ToElapsedTimeString(3)}...");

                    ShowUpdateMessage(">>> Processing filter expression for metadata...");

                    operationStartTime = DateTime.UtcNow.Ticks;
                    MeasurementKey[] inputKeys   = AdapterBase.ParseInputMeasurementKeys(MetadataRecord.Metadata, false, textBoxPointList.Text, "MeasurementDetail");
                    List <ulong>     pointIDList = inputKeys.Select(key => (ulong)key.ID).ToList();
                    operationTime = DateTime.UtcNow.Ticks - operationStartTime;

                    // Allow algorithm to augment (or even replace) point ID list as provided by user
                    algorithm.AugmentPointIDList(pointIDList);

                    ShowUpdateMessage($">>> Historian read will be for {pointIDList.Count:N0} points based on provided meta-data expression and algorithm augmentation.");

                    // Reduce metadata to filtered point list
                    ShowUpdateMessage($">>> Reducing metadata to the {pointIDList.Count:N0} defined points...");

                    List <MetadataRecord> records = new List <MetadataRecord>();

                    foreach (ulong pointID in pointIDList)
                    {
                        MetadataRecord record = algorithm.Metadata.FirstOrDefault(metadata => metadata.PointID == pointID);

                        if ((object)record != null)
                        {
                            records.Add(record);
                        }
                    }

                    algorithm.Metadata = records;

                    ShowUpdateMessage("*** Filter Expression Processing Complete ***");
                    ShowUpdateMessage($"Total filter expression processing time {operationTime.ToElapsedTimeString(3)}...");

                    ShowUpdateMessage(">>> Initializing algorithm...");
                    algorithm.Initialize();

                    ShowUpdateMessage(">>> Starting archive read...");

                    // Start historian data read
                    operationStartTime = DateTime.UtcNow.Ticks;

                    using (SnapDBClient historianClient = new SnapDBClient(m_settings.HostAddress, m_settings.DataPort, m_settings.InstanceName, m_settings.StartTime, m_settings.EndTime, m_settings.FrameRate, pointIDList))
                    {
                        // Scan to first record
                        if (!historianClient.ReadNext(point))
                        {
                            throw new InvalidOperationException("No data for specified time range in openHistorian connection!");
                        }

                        ulong currentTimestamp;
                        receivedPoints++;

                        while (!m_formClosing)
                        {
                            int  timeComparison;
                            bool readSuccess = true;

                            // Create a new data block for current timestamp and load first/prior point
                            Dictionary <ulong, DataPoint> dataBlock = new Dictionary <ulong, DataPoint>
                            {
                                [point.PointID] = point.Clone()
                            };

                            currentTimestamp = point.Timestamp;

                            // Load remaining data for current timestamp
                            do
                            {
                                // Scan to next record
                                if (!historianClient.ReadNext(point))
                                {
                                    readSuccess = false;
                                    break;
                                }

                                receivedPoints++;
                                timeComparison = DataPoint.CompareTimestamps(point.Timestamp, currentTimestamp, m_settings.FrameRate);

                                if (timeComparison == 0)
                                {
                                    // Timestamps are compared based on configured frame rate - if archived data rate is
                                    // higher than configured frame rate, then data block will contain only latest values
                                    if (dataBlock.ContainsKey(point.PointID))
                                    {
                                        duplicatePoints++;
                                    }

                                    dataBlock[point.PointID] = point.Clone();
                                }
                            }while (timeComparison == 0);

                            // Finished with data read
                            if (!readSuccess)
                            {
                                ShowUpdateMessage(">>> End of data in range encountered...");
                                break;
                            }

                            if (++processedDataBlocks % m_settings.MessageInterval == 0)
                            {
                                ShowUpdateMessage($"{Environment.NewLine}{receivedPoints:N0} points{(duplicatePoints > 0 ? $", which included {duplicatePoints:N0} duplicates," : "")} read so far averaging {receivedPoints / (DateTime.UtcNow.Ticks - operationStartTime).ToSeconds():N0} points per second.");
                                UpdateProgressBar((int)((1.0D - new Ticks(m_settings.EndTime.Ticks - (long)point.Timestamp).ToSeconds() / timeRange) * 100.0D));
                            }

                            try
                            {
                                lastTimestamp = new DateTime((long)currentTimestamp);

                                if (firstTimestamp.Ticks == 0L)
                                {
                                    firstTimestamp = lastTimestamp;
                                }

                                // Analyze data block
                                algorithm.Execute(lastTimestamp, dataBlock.Values.ToArray());
                            }
                            catch (Exception ex)
                            {
                                ShowUpdateMessage($"ERROR: Algorithm exception: {ex.Message}");
                                m_log.Publish(MessageLevel.Error, "AlgorithmError", "Failed while processing data from the historian", exception: ex);
                            }
                        }

                        operationTime = DateTime.UtcNow.Ticks - operationStartTime;

                        if (m_formClosing)
                        {
                            ShowUpdateMessage("*** Historian Read Canceled ***");
                            UpdateProgressBar(0);
                        }
                        else
                        {
                            ShowUpdateMessage("*** Historian Read Complete ***");
                            UpdateProgressBar(100);
                        }

                        algorithm.Complete();

                        // Show some operational statistics
                        long   expectedPoints   = (long)(timeRange * m_settings.FrameRate * algorithm.Metadata.Count);
                        double dataCompleteness = Math.Round(receivedPoints / (double)expectedPoints * 100000.0D) / 1000.0D;

                        string overallSummary =
                            $"Total processing time {operationTime.ToElapsedTimeString(3)} at {receivedPoints / operationTime.ToSeconds():N0} points per second.{Environment.NewLine}" +
                            $"{Environment.NewLine}" +
                            $"           Meta-data points: {algorithm.Metadata.Count}{Environment.NewLine}" +
                            $"          Time-span covered: {timeRange:N0} seconds: {Ticks.FromSeconds(timeRange).ToElapsedTimeString(2)}{Environment.NewLine}" +
                            $"       Processed timestamps: {processedDataBlocks:N0}{Environment.NewLine}" +
                            $"            Expected points: {expectedPoints:N0} @ {m_settings.FrameRate:N0} samples per second{Environment.NewLine}" +
                            $"            Received points: {receivedPoints:N0}{Environment.NewLine}" +
                            $"           Duplicate points: {duplicatePoints:N0}{Environment.NewLine}" +
                            $"          Data completeness: {dataCompleteness:N3}%{Environment.NewLine}" +
                            $"  First timestamp with data: {firstTimestamp:yyyy-MM-dd HH:mm:ss.fff}{Environment.NewLine}" +
                            $"   Last timestamp with data: {lastTimestamp:yyyy-MM-dd HH:mm:ss.fff}{Environment.NewLine}";

                        ShowUpdateMessage(overallSummary);
                    }
                }
            }
            catch (Exception ex)
            {
                ShowUpdateMessage($"!!! Failure during historian read: {ex.Message}");
                m_log.Publish(MessageLevel.Error, "HistorianDataRead", "Failed while reading data from the historian", exception: ex);
            }
            finally
            {
                SetGoButtonEnabledState(true);
            }
        }