/// <summary> /// Reads Data From the Historian and returns condensed DataPoints. /// </summary> /// <param name="start">Starttime.</param> /// <param name="end">EndTime.</param> /// <param name="measurements">Measurements to be read.</param> /// <param name="threshold">Threshhold used to determine number of alerts.</param> /// <param name="cancelationToken">Cancleation Token for the operation.</param> /// <param name="progress"> Progress Tracker <see cref="IProgress{T}"/>.</param> public IEnumerable <CondensedDataPoint> ReadCondensed(DateTime start, DateTime end, IEnumerable <ActiveMeasurement> measurements, double threshold, CancellationToken cancelationToken, IProgress <ulong> progress) { // Enumerate measurements once ActiveMeasurement[] activeMeasurements = measurements.ToArray(); List <CondensedDataPoint> result = new List <CondensedDataPoint>(activeMeasurements.Length); SnapServer server = GetServer(m_instance)?.Host; // start by separating all framerates foreach (int frameRate in activeMeasurements.Select(item => item.FramesPerSecond.GetValueOrDefault()).Distinct()) { ulong[] pointIDs = activeMeasurements.Where(item => item.FramesPerSecond == frameRate).Select(item => item.PointID).ToArray(); Dictionary <ulong, CondensedDataPoint> frameRateResult = new Dictionary <ulong, CondensedDataPoint>(); foreach (ulong key in pointIDs) { frameRateResult.Add(key, CondensedDataPoint.EmptyPoint(key)); if (cancelationToken.IsCancellationRequested) { return(result); } } using (ReportHistorianReader reader = new ReportHistorianReader(server, m_instance, start, end, frameRate, pointIDs)) { DataPoint point = new DataPoint(); // this.mProgress.Report(this.m_prevProgress); // Scan to first record if (!reader.ReadNext(point)) { throw new InvalidOperationException("No data for specified time range in openHistorian connection!"); } ulong currentTimeStamp = point.Timestamp; while (reader.ReadNext(point)) { if (currentTimeStamp < point.Timestamp) { progress.Report(point.Timestamp); } if (cancelationToken.IsCancellationRequested) { return(result); } if (!float.IsNaN(point.ValueAsSingle)) { if (frameRateResult.TryGetValue(point.PointID, out CondensedDataPoint dataPoint) && dataPoint != null) { if (point.ValueAsSingle > dataPoint.Max) { dataPoint.Max = point.ValueAsSingle; } if (point.ValueAsSingle < dataPoint.Min) { dataPoint.Min = point.ValueAsSingle; } dataPoint.Sum += point.ValueAsSingle; dataPoint.SqrSum += point.ValueAsSingle * point.ValueAsSingle; dataPoint.TotalPoints++; if (point.ValueAsSingle > threshold) { dataPoint.Alert++; } } } currentTimeStamp = point.Timestamp; } } result.AddRange(frameRateResult.Where(item => item.Value.TotalPoints > 0).Select(item => { item.Value.PointID = item.Key; return(item.Value); })); if (cancelationToken.IsCancellationRequested) { return(result); } } return(result); }
/// <summary> /// Updates the Report Data Source. /// </summary> /// <param name="startDate">Start date of the Report.</param> /// <param name="endDate">End date of the Report.</param> /// <param name="reportType"> Type of Report <see cref="ReportType"/>.</param> /// /// <param name="reportCriteria"> Criteria to create Report <see cref="ReportCriteria"/>.</param> /// <param name="numberOfRecords">Number of records included 0 for all records.</param> /// <param name="dataContext">DataContext from which the available reportingParameters are pulled <see cref="DataContext"/>.</param> public void UpdateReportSource(DateTime startDate, DateTime endDate, ReportCriteria reportCriteria, ReportType reportType, int numberOfRecords, DataContext dataContext) { m_endTime = endDate; m_percentComplete = 0; m_totalTime = (endDate - startDate).TotalSeconds; if (m_writing) { m_cancellation.Cancel(); } m_writing = true; CancellationToken token = m_cancellation.Token; new Thread(() => { try { string sourceFile = $"{FilePath.GetAbsolutePath("")}{Path.DirectorySeparatorChar}ReportTemplate.db"; m_databaseFile = $"{ConfigurationCachePath}{Path.DirectorySeparatorChar}{ConnectionID}.db"; File.Copy(sourceFile, m_databaseFile, true); string filterString = ""; if (reportType == ReportType.SNR) { filterString = "%-SNR"; } else if (reportType == ReportType.Unbalance_I) { filterString = "%-IUBAL"; } else if (reportType == ReportType.Unbalance_V) { filterString = "%-VUBAL"; } // Get AlertThreshold CategorizedSettingsElementCollection reportSettings = ConfigurationFile.Current.Settings["reportSettings"]; double threshold = 0; if (reportType == ReportType.SNR) { reportSettings.Add("DefaultSNRThreshold", "4.0", "Default SNR Alert threshold."); threshold = reportSettings["DefaultSNRThreshold"].ValueAs(threshold); } else if (reportType == ReportType.Unbalance_V) { reportSettings.Add("VUnbalanceThreshold", "4.0", "Voltage Unbalance Alert threshold."); threshold = reportSettings["VUnbalanceThreshold"].ValueAs(threshold); } else if (reportType == ReportType.Unbalance_I) { reportSettings.Add("IUnbalanceThreshold", "4.0", "Current Unbalance Alert threshold."); threshold = reportSettings["IUnbalanceThreshold"].ValueAs(threshold); } if (token.IsCancellationRequested) { m_writing = false; return; } List <ReportMeasurements> reportingMeasurements = GetFromStats(dataContext, startDate, endDate, reportType, token); if (token.IsCancellationRequested) { m_writing = false; return; } if (!reportingMeasurements.Any()) { TableOperations <ActiveMeasurement> tableOperations = new TableOperations <ActiveMeasurement>(dataContext.Connection); tableOperations.RootQueryRestriction[0] = $"{GetSelectedInstanceName()}:%"; List <ActiveMeasurement> activeMeasuremnts = tableOperations.QueryRecordsWhere("PointTag LIKE {0}", filterString).ToList(); reportingMeasurements = activeMeasuremnts.Select(point => new ReportMeasurements(point)).ToList(); // Pull Data From the Open Historian if (token.IsCancellationRequested) { m_writing = false; return; } Progress <ulong> progress = new Progress <ulong>(UpdatePercentage); List <CondensedDataPoint> historiandata = m_historianOperations.ReadCondensed(startDate, endDate, activeMeasuremnts, threshold, token, progress).ToList(); if (token.IsCancellationRequested) { m_writing = false; return; } //remove any that don't have data reportingMeasurements = reportingMeasurements.Where(item => historiandata.Select(point => point.PointID).Contains(item.PointID)).ToList(); // Deal with the not-aggregated signals reportingMeasurements = reportingMeasurements.Select(item => { CondensedDataPoint data = historiandata.Find(point => point.PointID == item.PointID); item.Max = data.Max; item.Min = data.Min; item.Mean = data.Sum / data.TotalPoints; item.NumberOfAlarms = data.Alert; item.PercentAlarms = data.Alert * 100.0D / data.TotalPoints; item.StandardDeviation = Math.Sqrt((data.SqrSum - 2 * data.Sum * item.Mean + data.TotalPoints * item.Mean * item.Mean) / data.TotalPoints); item.TimeInAlarm = item.PercentAlarms * (endDate - startDate).TotalSeconds / 100.0D; //Fix Alarm Numbers for SNR if (reportType == ReportType.SNR) { item.NumberOfAlarms = data.TotalPoints - item.NumberOfAlarms; item.PercentAlarms = 100 - item.PercentAlarms; item.TimeInAlarm = item.PercentAlarms * (endDate - startDate).TotalSeconds / 100.0D; } return(item); } ).ToList(); } if (reportCriteria == ReportCriteria.Mean) { reportingMeasurements = reportingMeasurements.OrderByDescending(item => item.Mean).ToList(); } if (reportCriteria == ReportCriteria.AlertTime) { reportingMeasurements = reportingMeasurements.OrderByDescending(item => item.TimeInAlarm).ToList(); } if (reportCriteria == ReportCriteria.Maximum) { reportingMeasurements = reportingMeasurements.OrderByDescending(item => item.Max).ToList(); } string connectionString = $"Data Source={m_databaseFile}; Version=3; Foreign Keys=True; FailIfMissing=True"; string dataProviderString = "AssemblyName={System.Data.SQLite, Version=1.0.109.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139}; ConnectionType=System.Data.SQLite.SQLiteConnection; AdapterType=System.Data.SQLite.SQLiteDataAdapter"; // Make this a single Transaction for speed purpose using (TransactionScope scope = new TransactionScope()) { m_connection = new AdoDataConnection(connectionString, dataProviderString); // Remove Points that are all NaN reportingMeasurements = reportingMeasurements.Where(item => { return(!(double.IsNaN(item.Mean))); }).ToList(); if (numberOfRecords == 0) { numberOfRecords = reportingMeasurements.Count; } // Create Original Point Tag and Fix Alarm Counters for SNR reportingMeasurements = reportingMeasurements.Select(item => { if (reportType == ReportType.SNR) { item.PointTag = item.PointTag.Remove(item.PointTag.Length - 4); } else { item.PointTag = item.PointTag.Remove(item.PointTag.Length - 5); } return(item); }).ToList(); if (token.IsCancellationRequested) { m_writing = false; return; } TableOperations <ReportMeasurements> reportMeasurements = new TableOperations <ReportMeasurements>(m_connection); for (int i = 0; i < Math.Min(numberOfRecords, reportingMeasurements.Count); i++) { reportMeasurements.AddNewRecord(reportingMeasurements[i]); } scope.Complete(); } m_writing = false; m_percentComplete = 100.0; } catch (Exception e) { LogException(e); } m_writing = false; m_percentComplete = 100.0; }) { IsBackground = true, }.Start(); }