/// <summary> /// Calculates MW, MVAR and MVA then publishes those measurements /// </summary> /// <param name="frame">Input values for calculation</param> /// <param name="index">Index of frame within second.</param> protected override void PublishFrame(IFrame frame, int index) { ConcurrentDictionary<MeasurementKey, IMeasurement> measurements = frame.Measurements; Ticks totalCalculationTime = DateTime.UtcNow.Ticks; Ticks lastCalculationTime = DateTime.UtcNow.Ticks; List<IMeasurement> outputMeasurements = new List<IMeasurement>(); IMeasurement measurement; int calculations = 0; foreach (PowerCalculation powerCalculation in m_configuredCalculations) { double activePower = double.NaN, reactivePower = double.NaN, apparentPower = double.NaN; try { double voltageMagnitude = 0.0D, voltageAngle = 0.0D, currentMagnitude = 0.0D, currentAngle = 0.0D; bool allValuesReceived = false; lastCalculationTime = DateTime.UtcNow.Ticks; if (measurements.TryGetValue(powerCalculation.VoltageMagnitudeSignalID, out measurement) && measurement.ValueQualityIsGood()) { voltageMagnitude = measurement.AdjustedValue; if (ApplySqrt3Adjustment) voltageMagnitude *= SqrtOf3; if (RemoveSqrt3Adjustment) voltageMagnitude /= SqrtOf3; if (measurements.TryGetValue(powerCalculation.VoltageAngleSignalID, out measurement) && measurement.ValueQualityIsGood()) { voltageAngle = measurement.AdjustedValue; if (measurements.TryGetValue(powerCalculation.CurrentMagnitudeSignalID, out measurement) && measurement.ValueQualityIsGood()) { currentMagnitude = measurement.AdjustedValue; if (measurements.TryGetValue(powerCalculation.CurrentAngleSignalID, out measurement) && measurement.ValueQualityIsGood()) { currentAngle = measurement.AdjustedValue; allValuesReceived = true; } } } } if (allValuesReceived) { // Calculate power (P), reactive power (Q) and apparent power (|S|) Phasor voltage = new Phasor(PhasorType.Voltage, Angle.FromDegrees(voltageAngle), voltageMagnitude); Phasor current = new Phasor(PhasorType.Current, Angle.FromDegrees(currentAngle), currentMagnitude); activePower = Phasor.CalculateActivePower(voltage, current) / SI.Mega; reactivePower = Phasor.CalculateReactivePower(voltage, current) / SI.Mega; apparentPower = Phasor.CalculateApparentPower(voltage, current) / SI.Mega; } } catch (Exception ex) { OnProcessException(ex); } finally { if ((object)powerCalculation.ActivePowerOutputMeasurement != null) { Measurement activePowerMeasurement = Measurement.Clone(powerCalculation.ActivePowerOutputMeasurement, activePower, frame.Timestamp); if (AlwaysProduceResult || !double.IsNaN(activePowerMeasurement.Value)) { outputMeasurements.Add(activePowerMeasurement); calculations++; m_lastActivePowerCalculations.Enqueue(activePowerMeasurement); while (m_lastActivePowerCalculations.Count > ValuesToTrack) m_lastActivePowerCalculations.TryDequeue(out measurement); } } if ((object)powerCalculation.ReactivePowerOutputMeasurement != null) { Measurement reactivePowerMeasurement = Measurement.Clone(powerCalculation.ReactivePowerOutputMeasurement, reactivePower, frame.Timestamp); if (AlwaysProduceResult || !double.IsNaN(reactivePowerMeasurement.Value)) { outputMeasurements.Add(reactivePowerMeasurement); calculations++; m_lastReactivePowerCalculations.Enqueue(reactivePowerMeasurement); while (m_lastReactivePowerCalculations.Count > ValuesToTrack) m_lastReactivePowerCalculations.TryDequeue(out measurement); } } if ((object)powerCalculation.ApparentPowerOutputMeasurement != null) { Measurement apparentPowerMeasurement = Measurement.Clone(powerCalculation.ApparentPowerOutputMeasurement, apparentPower, frame.Timestamp); if (AlwaysProduceResult || !double.IsNaN(apparentPowerMeasurement.Value)) { outputMeasurements.Add(apparentPowerMeasurement); calculations++; m_lastApparentPowerCalculations.Enqueue(apparentPowerMeasurement); while (m_lastApparentPowerCalculations.Count > ValuesToTrack) m_lastApparentPowerCalculations.TryDequeue(out measurement); } } m_averageCalculationTime.AddValue((DateTime.UtcNow.Ticks - lastCalculationTime).ToMilliseconds()); } } m_lastTotalCalculationTime = (DateTime.UtcNow.Ticks - totalCalculationTime).ToMilliseconds(); m_averageTotalCalculationTime.AddValue(m_lastTotalCalculationTime); m_lastTotalCalculations = calculations; m_averageCalculationsPerFrame.AddValue(calculations); OnNewMeasurements(outputMeasurements); }
public Ship() { velocity = new Vector2(); state = ShipState.Normal; dead = false; // total looks like about 160 energy = MAX_ENERGY; shield = 40.0f; // create the particles that will be used // when the ship does hyperspace or explodes particles = new List<Particle>(); for( int i = 0; i < 100; i++ ) { particles.Add( new Particle( this ) ); } // initialize the phasor phasor = new Phasor( this ); }
/// <summary> /// Gets the reporting Measurment List from Aggregate Channels if available. /// </summary> /// <returns> List of ReportMeasurements to be added to Report.</returns> /// <param name="start">Start date of the Report.</param> /// <param name="end">End date of the Report.</param> /// <param name="type"> Type of Report <see cref="ReportType"/>.</param> /// <param name="criteria"> Criteria for sorting this Report <see cref="ReportCriteria"/></param> /// <param name="numberRecords"> Number of Records that are being obtained. </param> /// <param name="cancelationToken"> Cancleation Token for the historian read operation.</param> /// <param name="dataContext">DataContext from which the available reportingParameters are pulled <see cref="DataContext"/>.</param> private List <ReportMeasurements> GetFromStats(DataContext dataContext, DateTime start, DateTime end, ReportType type, ReportCriteria criteria, int numberRecords, CancellationToken cancelationToken) { List <ReportMeasurements> result = new List <ReportMeasurements>(); // For now lump I and V together since we have to change all of this logic anyway to get away from SignalID back to Point Tags eventually // and get away from SQLLite files - waiting for ritchies comments before implementing that // Also using SignalID for everything this will be adjusted once I figured out how to combine the 2 SQL DB string idCollumn = (type == ReportType.SNR? "SignalID" : "PositivePhaseSignalID"); string sortCollumn = "Max"; string typerestriction = $" AND SignalType = '{(type == ReportType.Unbalance_I? "I" : "V")}'"; switch (criteria) { case (ReportCriteria.Maximum): sortCollumn = "Max"; break; case (ReportCriteria.Mean): sortCollumn = "Mean"; break; case (ReportCriteria.StandardDev): sortCollumn = "StandardDeviation"; break; case (ReportCriteria.TimeInAlarm): sortCollumn = "PercentAlarms"; break; } string sqlQuery = $@"SELECT TOP {numberRecords} {idCollumn} AS ID, {idCollumn} AS SignalID, {idCollumn} AS PointTag, {idCollumn} AS SignalReference, (SUM(SUM)/SUM(Count)) AS Mean, MAX(Maximum) AS Max, Min(Minimum) AS Min, SQRT((1/CAST(SUM(COUNT) AS Float))*(SUM(SquaredSum)-2*SUM(Sum)*Sum(Sum)/CAST(SUM(Count) AS Float)+SUM(Sum)*Sum(Sum)/SUM(Count))) AS StandardDeviation, SUM(AlarmCount) AS NumberOfAlarms, (CAST(SUM(AlarmActiveCount)AS float)/CAST(SUM(Count) AS Float)) as PercentAlarms FROM {(type == ReportType.SNR? "SNRSummary" : "UnbalanceSummary")} WHERE Date >= '{start.ToString("yyyy-MM-dd")}' AND Date <= '{end.ToString("yyyy-MM-dd")}'{(type == ReportType.SNR? "" : typerestriction)} GROUP BY {idCollumn} ORDER BY {sortCollumn}"; DataTable reportTbl; using (AdoDataConnection connection = new AdoDataConnection(ReportSettingsCategory)) reportTbl = connection.RetrieveData(sqlQuery); using (AdoDataConnection connection = new AdoDataConnection("Systemsettings")) { TableOperations <ActiveMeasurement> activeMeasurementTbl = new TableOperations <ActiveMeasurement>(connection); TableOperations <Phasor> phasorTbl = new TableOperations <Phasor>(connection); int i = 0; foreach (DataRow row in reportTbl.Rows) { UpdatePercentage(i, numberRecords); i++; Guid signalID = row.Field <Guid>("SignalID"); ActiveMeasurement sourceMeasurement = activeMeasurementTbl.QueryRecordWhere("SignalID = {0}", signalID); if (sourceMeasurement == null) { continue; } Phasor phasor = phasorTbl.QueryRecordWhere("ID = {0}", sourceMeasurement.PhasorID); result.Add(new ReportMeasurements() { SignalID = signalID, PointTag = (((phasor != null) && (type != ReportType.SNR))? phasor.Label : sourceMeasurement.PointTag), SignalReference = sourceMeasurement.SignalReference, SignalType = sourceMeasurement.SignalType, DeviceName = sourceMeasurement.Device, Mean = row.Field <double>("Mean"), Max = row.Field <double>("Max"), Min = row.Field <double>("Min"), StandardDeviation = row.Field <double>("StandardDeviation"), AlarmCount = row.Field <int>("NumberOfAlarms"), PercentInAlarm = row.Field <double>("PercentAlarms") * 100.0D, }); } } return(result); }
void SavePhasor(Phasor phasor, bool isNew) { m_client.SavePhasorAsync(phasor, isNew); }
static int Main() { int row = 0; try { // Handle command line arguments Arguments args = new Arguments(Environment.CommandLine, true); bool skipFirstRow; int successes = 0, failures = 0; // First ordered argument is source CSV file name, it is required if (args.Count < RequiredArgumentCount) { throw new ArgumentException($"Expected {RequiredArgumentCount:N0} argument, received {args.Count:N0}."); } // Check for switch based arguments if (!args.TryGetValue("sourceApp", out string sourceApp)) // Source GPA application, defaults to "SIEGate" { sourceApp = DefaultSourceApp; } if (!args.TryGetValue("outputName", out string outputName)) // Target IEEE C37.118 output stream name, defaults to "IMPORTEDSTREAM" { outputName = DefaultOutputName; } if (args.TryGetValue("skipFirstRow", out string setting)) // Setting to skip first row of import file, default to true { skipFirstRow = setting.ParseBoolean(); } else { skipFirstRow = true; } // Make sure output name is upper case, this is an acronym for the output adapter in the target system outputName = outputName.ToUpperInvariant(); // Make provided files name are relative to run path if not other path was provided string sourceFileName = FilePath.GetAbsolutePath(args["OrderedArg1"]); #if DEBUG string configFile = "C:\\Program Files\\openPDC\\openPDC.exe.config"; #else string configFile = FilePath.GetAbsolutePath($"{sourceApp}.exe.config"); #endif if (!File.Exists(configFile)) { configFile = FilePath.GetAbsolutePath($"..\\{sourceApp}.exe.config"); // Fail if source config file cannot be found if (!File.Exists(configFile)) { throw new FileNotFoundException($"Config file for {sourceApp} application \"{configFile}\" was not found. Checked this folder and parent folder."); } } // Load needed database settings from target config file XDocument serviceConfig = XDocument.Load(configFile); nodeID = Guid.Parse(serviceConfig .Descendants("systemSettings") .SelectMany(systemSettings => systemSettings.Elements("add")) .Where(element => "NodeID".Equals((string)element.Attribute("name"), StringComparison.OrdinalIgnoreCase)) .Select(element => (string)element.Attribute("value")) .FirstOrDefault()); string connectionString = serviceConfig .Descendants("systemSettings") .SelectMany(systemSettings => systemSettings.Elements("add")) .Where(element => "ConnectionString".Equals((string)element.Attribute("name"), StringComparison.OrdinalIgnoreCase)) .Select(element => (string)element.Attribute("value")) .FirstOrDefault(); string dataProviderString = serviceConfig .Descendants("systemSettings") .SelectMany(systemSettings => systemSettings.Elements("add")) .Where(element => "DataProviderString".Equals((string)element.Attribute("name"), StringComparison.OrdinalIgnoreCase)) .Select(element => (string)element.Attribute("value")) .FirstOrDefault(); // Open database schema and input CSV file using (AdoDataConnection connection = new AdoDataConnection(connectionString, dataProviderString)) using (StreamReader reader = File.OpenText(sourceFileName)) { // Configuration database tracks user changes for CIP reasons, use current user for ID currentUserID = UserInfo.CurrentUserID ?? DefaultUserID; // Setup database table operations for OutputStream table - this allows model, i.e., class instance representing record, based CRUD operations TableOperations <OutputStream> outputStreamTable = new TableOperations <OutputStream>(connection); // See if target output stream already exists OutputStream outputStream = outputStreamTable.QueryRecordWhere("NodeID = {0} AND Acronym = {1}", nodeID, outputName); if (outputStream == null) { // Setup a new output stream using default settings (user can adjust later as needed) outputStream = new OutputStream { NodeID = nodeID, Acronym = outputName, Name = outputName, ConnectionString = "RoundToNearestTimestamp=True; addPhaseLabelSuffix=false;", DataChannel = "port=-1; clients=localhost:4712; interface=0.0.0.0", AutoPublishConfigFrame = true, AutoStartDataChannel = true, NominalFrequency = 60, FramesPerSecond = 30, LagTime = 5.0D, LeadTime = 5.0D, AllowSortsByArrival = true, TimeResolution = 330000, AllowPreemptivePublishing = true, PerformTimeReasonabilityCheck = true, DownsamplingMethod = "LastReceived", DataFormat = "FloatingPoint", CoordinateFormat = "Polar", CurrentScalingValue = 2423, VoltageScalingValue = 2725785, AnalogScalingValue = 1373291, DigitalMaskValue = -65536, Enabled = true, CreatedOn = DateTime.UtcNow, CreatedBy = currentUserID, UpdatedOn = DateTime.UtcNow, UpdatedBy = currentUserID }; outputStreamTable.AddNewRecord(outputStream); outputStream = outputStreamTable.QueryRecordWhere("NodeID = {0} AND Acronym = {1}", nodeID, outputName); if (outputStream == null) { throw new InvalidOperationException($"Failed to lookup OutputStream record with Acronym of \"{outputName}\"."); } } else { // If record already exists, just track updates by user with timestamp outputStream.UpdatedOn = DateTime.UtcNow; outputStream.UpdatedBy = currentUserID; outputStreamTable.UpdateRecord(outputStream); } // Setup database table operations for other needed tables TableOperations <Device> deviceTable = new TableOperations <Device>(connection); TableOperations <Measurement> measurementTable = new TableOperations <Measurement>(connection); TableOperations <Phasor> phasorTable = new TableOperations <Phasor>(connection); TableOperations <OutputStreamDevice> outputStreamDeviceTable = new TableOperations <OutputStreamDevice>(connection); TableOperations <OutputStreamMeasurement> outputStreamMeasurementTable = new TableOperations <OutputStreamMeasurement>(connection); TableOperations <OutputStreamDevicePhasor> outputStreamDevicePhasorTable = new TableOperations <OutputStreamDevicePhasor>(connection); Device device = null; OutputStreamDevice outputStreamDevice = null; string line, lastDeviceName = null; int deviceIndex = 0, phasorIndex = 0; // Loop through each line in CSV input file while ((line = reader.ReadLine()) != null) { row++; if (skipFirstRow) { skipFirstRow = false; continue; } string[] columns = line.Split(','); if (columns.Length < 6) { Console.WriteLine($"Not enough columns in CSV file at row {row} - expected 6, encountered {columns.Length}, skipped row."); continue; } // Read columns of data from current row string sourceDeviceName = columns[0].ToUpperInvariant().Trim(); string destDeviceName = columns[1].ToUpperInvariant().Trim(); string sourcePhasorName = columns[2].ToUpperInvariant().Trim(); string destPhasorName = columns[3].ToUpperInvariant().Trim(); ushort idCode = ushort.Parse(columns[4].Trim()); string description = columns[5].Trim(); if (!sourceDeviceName.Equals(lastDeviceName, StringComparison.InvariantCultureIgnoreCase)) { lastDeviceName = sourceDeviceName; deviceIndex++; phasorIndex = 0; // Lookup existing source device device = deviceTable.QueryRecordWhere("Acronym = {0}", sourceDeviceName); if (device == null) { Console.WriteLine($"Failed to find source device \"{sourceDeviceName}\" - cannot create new output stream device for \"{destDeviceName}\"."); failures++; continue; } Console.WriteLine($"Mapping source device \"{sourceDeviceName}\" to output stream device \"{destDeviceName}\"..."); // Setup a new output stream device outputStreamDevice = outputStreamDeviceTable.QueryRecordWhere("NodeID = {0} AND AdapterID = {1} AND Acronym = {2}", nodeID, outputStream.ID, destDeviceName); if (outputStreamDevice == null) { outputStreamDevice = new OutputStreamDevice { NodeID = nodeID, AdapterID = outputStream.ID, IDCode = idCode > 0 ? idCode : deviceIndex, Acronym = destDeviceName, Name = destDeviceName.ToTitleCase(), Enabled = true, CreatedOn = DateTime.UtcNow, CreatedBy = currentUserID, UpdatedOn = DateTime.UtcNow, UpdatedBy = currentUserID }; outputStreamDeviceTable.AddNewRecord(outputStreamDevice); outputStreamDevice = outputStreamDeviceTable.QueryRecordWhere("NodeID = {0} AND AdapterID = {1} AND Acronym = {2}", nodeID, outputStream.ID, destDeviceName); if (outputStreamDevice == null) { throw new InvalidOperationException($"Failed to lookup OutputStreamDevice record with Acronym of \"{destDeviceName}\"."); } } else { // TODO: Could augment existing record, current logic just skips existing to account for possible input file errors outputStreamDevice.IDCode = idCode > 0 ? idCode : deviceIndex; outputStreamDevice.UpdatedOn = DateTime.UtcNow; outputStreamDevice.UpdatedBy = currentUserID; outputStreamDeviceTable.UpdateRecord(outputStreamDevice); } // Validate base output stream measurements exist foreach (string signalType in new[] { "SF", "FQ", "DF" }) // Status flags, frequency and dF/dT (delta frequency over delta time, i.e., rate of change of frequency) { AddOutputStreamMeasurement(measurementTable, outputStreamMeasurementTable, outputStream.ID, $"{device.Acronym}-{signalType}", $"{destDeviceName}-{signalType}"); } } if (device == null) { failures++; continue; } // 123456789012345678901234567890 Console.WriteLine($" Adding phasors for \"{$"{destPhasorName} - {description}".TrimWithEllipsisEnd(70)}\""); // Lookup existing device phasor record Phasor phasor = phasorTable.QueryRecordWhere("DeviceID = {0} AND Label = {1}", device.ID, sourcePhasorName); phasorIndex++; if (phasor == null) { Console.WriteLine($"Failed to lookup Phasor record with Label of \"{sourcePhasorName}\""); failures++; } else { // Setup a new output stream device phasor OutputStreamDevicePhasor outputStreamDevicePhasor = outputStreamDevicePhasorTable.QueryRecordWhere("NodeID = {0} AND OutputStreamDeviceID = {1} AND Label = {2}", nodeID, outputStreamDevice.ID, destPhasorName); if (outputStreamDevicePhasor == null) { outputStreamDevicePhasor = new OutputStreamDevicePhasor { NodeID = nodeID, OutputStreamDeviceID = outputStreamDevice.ID, Label = destPhasorName, Type = phasor.Type, Phase = phasor.Phase, LoadOrder = phasorIndex, CreatedOn = DateTime.UtcNow, CreatedBy = currentUserID, UpdatedOn = DateTime.UtcNow, UpdatedBy = currentUserID }; outputStreamDevicePhasorTable.AddNewRecord(outputStreamDevicePhasor); outputStreamDevicePhasor = outputStreamDevicePhasorTable.QueryRecordWhere("NodeID = {0} AND OutputStreamDeviceID = {1} AND Label = {2}", nodeID, outputStreamDevice.ID, destPhasorName); if (outputStreamDevicePhasor == null) { throw new InvalidOperationException($"Failed to lookup OutputStreamDevicePhasor record with Label of \"{destPhasorName}\"."); } } else { // TODO: Could augment existing record, current logic just skips existing to account for possible input file errors outputStreamDevicePhasor.UpdatedOn = DateTime.UtcNow; outputStreamDevicePhasor.UpdatedBy = currentUserID; outputStreamDevicePhasorTable.UpdateRecord(outputStreamDevicePhasor); } // Define output stream phasor measurements AddOutputStreamMeasurement(measurementTable, outputStreamMeasurementTable, outputStream.ID, $"{device.Acronym}-PA{phasor.SourceIndex}", $"{destDeviceName}-PA{phasorIndex}"); AddOutputStreamMeasurement(measurementTable, outputStreamMeasurementTable, outputStream.ID, $"{device.Acronym}-PM{phasor.SourceIndex}", $"{destDeviceName}-PM{phasorIndex}"); successes++; } } } Console.WriteLine(); Console.WriteLine($"{successes:N0} successful phasor imports."); Console.WriteLine($"{failures:N0} failed phasor imports."); #if DEBUG Console.ReadKey(); #endif return(0); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine($"Import halted at row {row}!"); Console.Error.WriteLine($"Load Exception: {ex.Message}"); return(1); } }
/// <summary> /// Calculates MW, MVAR and MVA then publishes those measurements /// </summary> /// <param name="frame">Input values for calculation</param> /// <param name="index">Index of frame within second.</param> protected override void PublishFrame(IFrame frame, int index) { ConcurrentDictionary <MeasurementKey, IMeasurement> measurements = frame.Measurements; Ticks totalCalculationTime = DateTime.UtcNow.Ticks; Ticks lastCalculationTime = DateTime.UtcNow.Ticks; List <IMeasurement> outputMeasurements = new List <IMeasurement>(); IMeasurement measurement; int calculations = 0; foreach (PowerCalculation powerCalculation in m_configuredCalculations) { double activePower = double.NaN, reactivePower = double.NaN, apparentPower = double.NaN; try { double voltageMagnitude = 0.0D, voltageAngle = 0.0D, currentMagnitude = 0.0D, currentAngle = 0.0D; bool allValuesReceivedWithGoodQuality = false; lastCalculationTime = DateTime.UtcNow.Ticks; if (measurements.TryGetValue(powerCalculation.VoltageMagnitudeMeasurementKey, out measurement) && measurement.ValueQualityIsGood()) { voltageMagnitude = measurement.AdjustedValue; if (!m_adjustmentStrategies.TryGetValue(powerCalculation.VoltageMagnitudeMeasurementKey, out VoltageAdjustmentStrategy adjustmentStrategy)) { adjustmentStrategy = AdjustmentStrategy; } switch (adjustmentStrategy) { case VoltageAdjustmentStrategy.LineToNeutral: voltageMagnitude *= 3; break; case VoltageAdjustmentStrategy.LineToLine: voltageMagnitude *= SqrtOf3; break; } if (measurements.TryGetValue(powerCalculation.VoltageAngleMeasurementKey, out measurement) && measurement.ValueQualityIsGood()) { voltageAngle = measurement.AdjustedValue; if (measurements.TryGetValue(powerCalculation.CurrentMagnitudeMeasurementKey, out measurement) && measurement.ValueQualityIsGood()) { currentMagnitude = measurement.AdjustedValue; if (measurements.TryGetValue(powerCalculation.CurrentAngleMeasurementKey, out measurement) && measurement.ValueQualityIsGood()) { currentAngle = measurement.AdjustedValue; allValuesReceivedWithGoodQuality = true; } } } } if (allValuesReceivedWithGoodQuality) { // Calculate power (P), reactive power (Q) and apparent power (|S|) Phasor voltage = new Phasor(PhasorType.Voltage, Angle.FromDegrees(voltageAngle), voltageMagnitude); Phasor current = new Phasor(PhasorType.Current, Angle.FromDegrees(currentAngle), currentMagnitude); activePower = Phasor.CalculateActivePower(voltage, current) / SI.Mega; reactivePower = Phasor.CalculateReactivePower(voltage, current) / SI.Mega; apparentPower = Phasor.CalculateApparentPower(voltage, current) / SI.Mega; } } catch (Exception ex) { OnProcessException(MessageLevel.Warning, ex); } finally { if ((object)powerCalculation.ActivePowerOutputMeasurement != null) { Measurement activePowerMeasurement = Measurement.Clone(powerCalculation.ActivePowerOutputMeasurement, activePower, frame.Timestamp); if (AlwaysProduceResult || !double.IsNaN(activePowerMeasurement.Value)) { outputMeasurements.Add(activePowerMeasurement); calculations++; m_lastActivePowerCalculations.Enqueue(activePowerMeasurement); while (m_lastActivePowerCalculations.Count > ValuesToTrack) { m_lastActivePowerCalculations.TryDequeue(out measurement); } } } if ((object)powerCalculation.ReactivePowerOutputMeasurement != null) { Measurement reactivePowerMeasurement = Measurement.Clone(powerCalculation.ReactivePowerOutputMeasurement, reactivePower, frame.Timestamp); if (AlwaysProduceResult || !double.IsNaN(reactivePowerMeasurement.Value)) { outputMeasurements.Add(reactivePowerMeasurement); calculations++; m_lastReactivePowerCalculations.Enqueue(reactivePowerMeasurement); while (m_lastReactivePowerCalculations.Count > ValuesToTrack) { m_lastReactivePowerCalculations.TryDequeue(out measurement); } } } if ((object)powerCalculation.ApparentPowerOutputMeasurement != null) { Measurement apparentPowerMeasurement = Measurement.Clone(powerCalculation.ApparentPowerOutputMeasurement, apparentPower, frame.Timestamp); if (AlwaysProduceResult || !double.IsNaN(apparentPowerMeasurement.Value)) { outputMeasurements.Add(apparentPowerMeasurement); calculations++; m_lastApparentPowerCalculations.Enqueue(apparentPowerMeasurement); while (m_lastApparentPowerCalculations.Count > ValuesToTrack) { m_lastApparentPowerCalculations.TryDequeue(out measurement); } } } m_averageCalculationTime.AddValue((DateTime.UtcNow.Ticks - lastCalculationTime).ToMilliseconds()); } } m_lastTotalCalculationTime = (DateTime.UtcNow.Ticks - totalCalculationTime).ToMilliseconds(); m_averageTotalCalculationTime.AddValue(m_lastTotalCalculationTime); m_lastTotalCalculations = calculations; m_averageCalculationsPerFrame.AddValue(calculations); OnNewMeasurements(outputMeasurements); }
void SavePhasor(Phasor phasor, bool isNew) { SystemMessages sm; DataConnection connection = new DataConnection(); ; try { string result = CommonFunctions.SavePhasor(connection, phasor, isNew); //ClearForm(); sm = new SystemMessages(new Message() { UserMessage = result, SystemMessage = string.Empty, UserMessageType = MessageType.Success }, ButtonType.OkOnly); sm.Owner = Window.GetWindow(this); sm.WindowStartupLocation = WindowStartupLocation.CenterOwner; sm.ShowPopup(); GetPhasors(); GetPhasorList(); //make this newly added or updated item as default selected. So user can click initialize right away. ListBoxPhasorList.SelectedItem = ((List <Phasor>)ListBoxPhasorList.ItemsSource).Find(c => c.Label == phasor.Label); //Update Metadata in the openPDC Service. try { Device device = CommonFunctions.GetDeviceByDeviceID(connection, phasor.DeviceID); WindowsServiceClient serviceClient = ((App)Application.Current).ServiceClient; if (serviceClient != null && serviceClient.Helper.RemotingClient.CurrentState == TVA.Communication.ClientState.Connected) { if (device.HistorianID != null) { string runtimeID = CommonFunctions.GetRuntimeID(connection, "Historian", (int)device.HistorianID); CommonFunctions.SendCommandToWindowsService(serviceClient, "Invoke " + runtimeID + " RefreshMetadata"); } if (device.Enabled) //if device is enabled then send initialize command otherwise send reloadconfig command. { if (device.ParentID == null) { CommonFunctions.SendCommandToWindowsService(serviceClient, "Initialize " + CommonFunctions.GetRuntimeID(connection, "Device", device.ID)); } else { CommonFunctions.SendCommandToWindowsService(serviceClient, "Initialize " + CommonFunctions.GetRuntimeID(connection, "Device", (int)device.ParentID)); } } else { CommonFunctions.SendCommandToWindowsService(serviceClient, "ReloadConfig"); //we do this to make sure all statistical measurements are in the system. } CommonFunctions.SendCommandToWindowsService(serviceClient, "RefreshRoutes"); } else { sm = new SystemMessages(new openPDCManager.Utilities.Message() { UserMessage = "Failed to Perform Configuration Changes", SystemMessage = "Application is disconnected from the openPDC Service.", UserMessageType = openPDCManager.Utilities.MessageType.Information }, ButtonType.OkOnly); sm.Owner = Window.GetWindow(this); sm.WindowStartupLocation = WindowStartupLocation.CenterOwner; sm.ShowPopup(); } } catch (Exception ex) { sm = new SystemMessages(new openPDCManager.Utilities.Message() { UserMessage = "Failed to Perform Configuration Changes", SystemMessage = ex.Message, UserMessageType = openPDCManager.Utilities.MessageType.Information }, ButtonType.OkOnly); sm.Owner = Window.GetWindow(this); sm.WindowStartupLocation = WindowStartupLocation.CenterOwner; sm.ShowPopup(); CommonFunctions.LogException(null, "SavePhasor.RefreshMetadata", ex); } } catch (Exception ex) { CommonFunctions.LogException(connection, "WPF.SavePhasor", ex); sm = new SystemMessages(new Message() { UserMessage = "Failed to Save Phasor Information", SystemMessage = ex.Message, UserMessageType = MessageType.Error }, ButtonType.OkOnly); sm.Owner = Window.GetWindow(this); sm.WindowStartupLocation = WindowStartupLocation.CenterOwner; sm.ShowPopup(); } finally { if (connection != null) { connection.Dispose(); } } }
/// <summary> /// Default data processing entry point for <see cref="Algorithm"/>. /// </summary> /// <param name="timestamp">Timestamp of <paramref name="dataBlock"/>.</param> /// <param name="dataBlock">Points values read at current timestamp.</param> public void Execute(DateTime timestamp, DataPoint[] raw_dataBlock, int lineNumber) { DataPoint[] dataBlock = raw_dataBlock; if (m_rawDataSet.TimeStamps[0].Year == 1969) { m_rawDataSet.TimeStamps[0] = timestamp; } else { m_rawDataSet.TimeStamps.Add(timestamp); } // Check dataBlock completeness if (dataBlock.Count() < (lineNumber * 8)) { for (int idx0 = 0; idx0 < (lineNumber * 8 - 1); idx0++) { if (idx0 >= (dataBlock.Count() - 1)) { DataPoint[] TempDataBlock = new DataPoint[dataBlock.Count() + 1]; for (int idx1 = 0; idx1 < dataBlock.Count(); idx1++) { TempDataBlock[idx1] = dataBlock[idx1]; } int idx2 = dataBlock.Count() - 1; DataPoint TempPoint = new DataPoint(); TempPoint.PointID = dataBlock[idx2].PointID + 1; TempPoint.Timestamp = dataBlock[idx2].Timestamp; TempPoint.Value = 0; TempPoint.Flags = dataBlock[idx2].Flags; TempDataBlock[dataBlock.Count()] = TempPoint; TempDataBlock[dataBlock.Count()] = TempPoint; dataBlock = TempDataBlock; } else { if ((dataBlock[idx0 + 1].PointID != (dataBlock[idx0].PointID + 1))) { DataPoint TempPoint = new DataPoint(); TempPoint.PointID = dataBlock[idx0].PointID + 1; TempPoint.Timestamp = dataBlock[idx0].Timestamp; TempPoint.Value = 0; TempPoint.Flags = dataBlock[idx0].Flags; dataBlock = InsertPoint(dataBlock, TempPoint, (idx0 + 1), lineNumber); } } } //dataBlock = TempDataBlock; } int AssignValueCount = 0; Measurement_set CurrentFrameMeasurementSet = new Measurement_set(); do { Phasor FromBusVTemp = new Phasor(); Phasor FromBusITemp = new Phasor(); Phasor ToBusVTemp = new Phasor(); Phasor ToBusITemp = new Phasor(); VI_data FromBusVITemp = new VI_data(); VI_data ToBusVITemp = new VI_data(); Line_data CurrentLineDataTemp = new Line_data(); FromBusVTemp.Magnitude = dataBlock[AssignValueCount].ValueAsSingle; AssignValueCount += 1; FromBusVTemp.Angle = dataBlock[AssignValueCount].ValueAsSingle; AssignValueCount += 1; FromBusVITemp.Voltage = FromBusVTemp; FromBusITemp.Magnitude = dataBlock[AssignValueCount].ValueAsSingle; AssignValueCount += 1; FromBusITemp.Angle = dataBlock[AssignValueCount].ValueAsSingle; AssignValueCount += 1; FromBusVITemp.Current = FromBusITemp; ToBusVTemp.Magnitude = dataBlock[AssignValueCount].ValueAsSingle; AssignValueCount += 1; ToBusVTemp.Angle = dataBlock[AssignValueCount].ValueAsSingle; AssignValueCount += 1; ToBusVITemp.Voltage = ToBusVTemp; ToBusITemp.Magnitude = dataBlock[AssignValueCount].ValueAsSingle; AssignValueCount += 1; ToBusITemp.Angle = dataBlock[AssignValueCount].ValueAsSingle; AssignValueCount += 1; ToBusVITemp.Current = ToBusITemp; CurrentLineDataTemp.From_bus = FromBusVITemp; CurrentLineDataTemp.To_bus = ToBusVITemp; if (CurrentFrameMeasurementSet.Measurements[0].From_bus == null) { CurrentFrameMeasurementSet.Measurements[0] = CurrentLineDataTemp; } else { CurrentFrameMeasurementSet.Measurements.Add(CurrentLineDataTemp); } } while (AssignValueCount < (dataBlock.Count() - 7)); if (m_rawDataSet.RawDataSet[0].Measurements[0].From_bus == null) { m_rawDataSet.RawDataSet[0] = CurrentFrameMeasurementSet; } else { m_rawDataSet.RawDataSet.Add(CurrentFrameMeasurementSet); } m_processedDataBlocks++; //string message = $"Analyzed {m_processedDataBlocks:N0} timestamps so far.{Environment.NewLine}"; //Console.WriteLine(message); }