Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
    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);
        }
Esempio n. 4
0
 void SavePhasor(Phasor phasor, bool isNew)
 {
     m_client.SavePhasorAsync(phasor, isNew);
 }
Esempio n. 5
0
        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);
            }
        }
Esempio n. 6
0
        /// <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);
        }
Esempio n. 7
0
 void SavePhasor(Phasor phasor, bool isNew)
 {
     m_client.SavePhasorAsync(phasor, isNew);
 }
Esempio n. 8
0
        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();
                }
            }
        }
Esempio n. 9
0
        /// <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);
        }