Exemple #1
0
        // Gets a measurement key based on a token which
        // may be either a signal ID or measurement key.
        private MeasurementKey GetKey(string token)
        {
            Guid signalID;

            return(Guid.TryParse(token, out signalID)
                ? MeasurementKey.LookUpBySignalID(signalID)
                : MeasurementKey.Parse(token));
        }
Exemple #2
0
 protected IMeasurement MakeMeasurement(MetaValues meta, double value)
 {
     return(new Measurement()
     {
         Metadata = MeasurementKey.LookUpBySignalID(meta.ID).Metadata,
         Timestamp = meta.Timestamp,
         Value = value,
         StateFlags = GetMeasurementStateFlags(meta.Flags)
     });
 }
Exemple #3
0
        /// <summary>
        /// Queries the signal buffer for the collection of measurements
        /// between the dates specified by the given time range.
        /// </summary>
        /// <param name="signalID">The ID of the signal to be queried.</param>
        /// <param name="startTime">The beginning of the time range to be queried.</param>
        /// <param name="endTime">The end of the time range to be queried.</param>
        /// <returns>The collection of measurements for the signal that fall between the dates in the given time range.</returns>
        public IEnumerable <IMeasurement> QuerySignalBuffer(Guid signalID, DateTime startTime, DateTime endTime)
        {
            MeasurementKey key = MeasurementKey.LookUpBySignalID(signalID);

            if (key == MeasurementKey.Undefined)
            {
                return(Enumerable.Empty <IMeasurement>());
            }

            return(QuerySignalBuffer(key, startTime, endTime));
        }
Exemple #4
0
        /// <summary>
        /// Queries the signal buffer for the measurement whose timestamp is nearest the given timestamp,
        /// but only returns the measurement if its timestamp falls within a specified tolerance around the given timestamp.
        /// </summary>
        /// <param name="signalID">The ID of the signal to be queried.</param>
        /// <param name="timestamp">The timestamp of the measurement to be queried.</param>
        /// <param name="tolerance">The tolerance that determines whether the nearest measurement is valid.</param>
        /// <returns>The measurement whose timestamp is nearest the given timestamp or null if the measurement's timestamp falls outside the given tolerance.</returns>
        public IMeasurement QuerySignalBuffer(Guid signalID, DateTime timestamp, TimeSpan tolerance)
        {
            MeasurementKey key = MeasurementKey.LookUpBySignalID(signalID);

            if (key == MeasurementKey.Undefined)
            {
                return(null);
            }

            return(QuerySignalBuffer(key, timestamp, tolerance));
        }
Exemple #5
0
        /// <summary>
        /// Initializes the adapter's settings.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary <string, string> settings = Settings;
            string setting;
            MeasurementStateFlags flags;

            if (settings.TryGetValue(nameof(Flags), out setting) && Enum.TryParse(setting, out flags))
            {
                m_flags = flags;
            }
            else
            {
                m_flags = DefaultFlags;
            }

            if (settings.TryGetValue(nameof(SupportsTemporalProcessing), out setting))
            {
                m_supportsTemporalProcessing = setting.ParseBoolean();
            }
            else
            {
                m_supportsTemporalProcessing = DefaultSupportsTemporalProcessing;
            }

            const string AlarmTable    = "Alarms";
            const string AlarmIDField  = "AssociatedMeasurementID";
            const string SignalIDField = "SignalID";

            HashSet <MeasurementKey> inputMeasurementKeys = new HashSet <MeasurementKey>(InputMeasurementKeys);

            Func <DataRow, string, MeasurementKey> getKey = (row, field) =>
                                                            MeasurementKey.LookUpBySignalID(row.ConvertField <Guid>(field));

            Dictionary <MeasurementKey, MeasurementKey> alarmToSignalLookup = DataSource.Tables[AlarmTable]
                                                                              .Select(AlarmIDField + " IS NOT NULL")
                                                                              .Select(row => new { AlarmID = getKey(row, AlarmIDField), SignalID = getKey(row, SignalIDField) })
                                                                              .Where(obj => inputMeasurementKeys.Contains(obj.AlarmID))
                                                                              .Where(obj => inputMeasurementKeys.Contains(obj.SignalID))
                                                                              .ToDictionary(obj => obj.AlarmID, obj => obj.SignalID);

            HashSet <MeasurementKey> raisedAlarms = new HashSet <MeasurementKey>(AlarmAdapter.Default?.GetRaisedAlarms()
                                                                                 .Select(alarm => alarm.AssociatedMeasurementID.GetValueOrDefault())
                                                                                 .Select(alarmID => MeasurementKey.LookUpBySignalID(alarmID)) ?? Enumerable.Empty <MeasurementKey>());

            Dictionary <MeasurementKey, bool> signalToAlarmStateLookup = alarmToSignalLookup.Values
                                                                         .ToDictionary(key => key, key => raisedAlarms.Contains(key));

            m_alarmToSignalLookup      = alarmToSignalLookup;
            m_signalToAlarmStateLookup = new ConcurrentDictionary <MeasurementKey, bool>(signalToAlarmStateLookup);
        }
Exemple #6
0
        // Converts the given row of CSV data to a single measurement.
        private IMeasurement FromCSV(string csv)
        {
            string[] split     = csv.Split(',');
            DateTime timestamp = DateTime.Parse(split[0]);
            Guid     signalID  = Guid.Parse(split[1]);
            double   value     = double.Parse(split[2]);

            return(new Measurement()
            {
                Metadata = MeasurementKey.LookUpBySignalID(signalID).Metadata,
                Timestamp = timestamp,
                Value = value
            });
        }
        private static Measurement GetMeasurement(Guid signalID)
        {
            MeasurementKey key = MeasurementKey.LookUpBySignalID(signalID);

            if (key.SignalID == Guid.Empty)
            {
                return(null);
            }

            Measurement measurement = new Measurement
            {
                Metadata = key.Metadata,
            };

            return(measurement);
        }
Exemple #8
0
        // Creates an alarm event from the given alarm and measurement.
        private IMeasurement CreateAlarmEvent(Ticks timestamp, Alarm alarm)
        {
            IMeasurement alarmEvent = new Measurement()
            {
                Timestamp = timestamp,
                Value     = (int)alarm.State
            };

            if ((object)alarm.AssociatedMeasurementID != null)
            {
                Guid alarmEventID = alarm.AssociatedMeasurementID.GetValueOrDefault();
                alarmEvent.Metadata = MeasurementKey.LookUpBySignalID(alarmEventID).Metadata;
            }

            return(alarmEvent);
        }
Exemple #9
0
        private void m_timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            List <IMeasurement> measurements = new List <IMeasurement>();
            StringBuilder       columnString = new StringBuilder();

            int timestampColumn = GetColumnIndex("Timestamp");
            int idColumn        = GetColumnIndex("SignalID");
            int valueColumn     = GetColumnIndex("Value");

            string      commandString;
            IDbCommand  command;
            IDataReader reader;

            foreach (string columnName in s_measurementColumns)
            {
                if (columnString.Length > 0)
                {
                    columnString.Append(',');
                }

                columnString.Append(columnName);
            }

            commandString       = string.Format("SELECT {0} FROM Measurement LIMIT {1},{2}", columnString, m_startingMeasurement, m_measurementsPerInput);
            command             = m_connection.CreateCommand();
            command.CommandText = commandString;

            using (reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    Ticks          timeStamp = m_fakeTimestamps ? new Ticks(DateTime.UtcNow) : new Ticks(reader.GetInt64(timestampColumn));
                    MeasurementKey key       = MeasurementKey.LookUpBySignalID(reader.GetGuid(idColumn));
                    if (key != MeasurementKey.Undefined)
                    {
                        measurements.Add(new Measurement
                        {
                            Key       = key,
                            Value     = reader.GetDouble(valueColumn),
                            Timestamp = timeStamp
                        });
                    }
                }
            }
            OnNewMeasurements(measurements);
            m_startingMeasurement += m_measurementsPerInput;
        }
Exemple #10
0
        // Gets a measurement key based on a token which
        // may be either a signal ID or measurement key.
        private MeasurementKey GetKey(string token)
        {
            Guid           signalID;
            MeasurementKey key;

            if (Guid.TryParse(token, out signalID))
            {
                // Defined using the measurement's GUID
                key = MeasurementKey.LookUpBySignalID(signalID);
            }
            else
            {
                // Defined using the measurement's key
                key = MeasurementKey.Parse(token);
            }

            return(key);
        }
        private Measurement GetMeasurement(Guid signalID)
        {
            DataRow[] rows = DataSource.Tables["ActiveMeasurements"].Select($"SignalID = '{signalID}'");

            if (!rows.Any())
            {
                return(null);
            }

            Measurement measurement = new Measurement
            {
                Key        = MeasurementKey.LookUpBySignalID(signalID),
                TagName    = rows[0]["PointTag"].ToString(),
                Adder      = Convert.ToDouble(rows[0]["Adder"]),
                Multiplier = Convert.ToDouble(rows[0]["Multiplier"])
            };

            return(measurement);
        }
Exemple #12
0
        private void HandleSendMeasurementsCommand(ClientConnection connection, byte[] buffer, int startIndex, int length)
        {
            int index = startIndex;

            if (length - index < 4)
            {
                throw new Exception("Not enough bytes in buffer to parse measurement count");
            }

            int count = BigEndian.ToInt32(buffer, index);

            index += sizeof(int);

            if (length - index < count * 36)
            {
                throw new Exception("Not enough bytes in buffer to parse all measurements");
            }

            List <IMeasurement> measurements = new List <IMeasurement>(count);

            for (int i = 0; i < count; i++)
            {
                Guid     signalID  = buffer.ToRfcGuid(index); index += 16;
                DateTime timestamp = new DateTime(BigEndian.ToInt64(buffer, index)); index += sizeof(long);
                double   value     = BigEndian.ToDouble(buffer, index); index += sizeof(double);
                MeasurementStateFlags stateFlags = (MeasurementStateFlags)BigEndian.ToInt32(buffer, index); index += sizeof(int);

                measurements.Add(new Measurement()
                {
                    Metadata   = MeasurementKey.LookUpBySignalID(signalID).Metadata,
                    Timestamp  = timestamp,
                    Value      = value,
                    StateFlags = stateFlags
                });
            }

            OnNewMeasurements(measurements);
        }
Exemple #13
0
        private void HandleDataPacketCommand(ClientConnection connection, byte[] buffer, int startIndex, int length)
        {
            try
            {
                List <IMeasurement> measurements = new List <IMeasurement>();

                int index             = startIndex;
                int payloadByteLength = BigEndian.ToInt32(buffer, index);
                index += sizeof(int);

                string dataString = connection.Encoding.GetString(buffer, index, payloadByteLength);
                ConnectionStringParser <SettingAttribute> connectionStringParser = new ConnectionStringParser <SettingAttribute>();

                foreach (string measurementString in dataString.ParseKeyValuePairs().Values)
                {
                    ECAMeasurement measurement = new ECAMeasurement();
                    connectionStringParser.ParseConnectionString(measurementString, measurement);

                    measurements.Add(new Measurement()
                    {
                        Metadata   = MeasurementKey.LookUpBySignalID(measurement.SignalID).Metadata,
                        Timestamp  = measurement.Timestamp,
                        Value      = measurement.Value,
                        StateFlags = measurement.StateFlags
                    });
                }

                OnNewMeasurements(measurements);
            }
            catch (Exception ex)
            {
                string errorMessage = $"Data packet command failed due to exception: {ex.Message}";
                OnProcessException(new Exception(errorMessage, ex));
                SendClientResponse(connection.ClientID, ServerResponse.Failed, (ServerCommand)ECAServerCommand.StatusMessage, errorMessage);
            }
        }
Exemple #14
0
        private StatisticsCollection CreateStatistics(TableOperations <MeasurementRecord> table, MeasurementKey key, Device device, int HistorianID, SignalType type)
        {
            MeasurementRecord inMeasurement = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString());
            int signaltype;

            using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
            {
                TableOperations <SignalTypeRecord> signalTypeTable = new TableOperations <SignalTypeRecord>(connection);
                signaltype = signalTypeTable.QueryRecordWhere("Acronym = {0}", "CALC").ID;
            }

            string outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:SUM";

            // Sum
            if (table.QueryRecordCountWhere("SignalReference = {0}", outputReference) < 1)
            {
                table.AddNewRecord(new MeasurementRecord
                {
                    HistorianID     = HistorianID,
                    DeviceID        = device.ID,
                    PointTag        = inMeasurement.PointTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:SUM",
                    AlternateTag    = inMeasurement.AlternateTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:SUM",
                    SignalTypeID    = signaltype,
                    SignalReference = outputReference,
                    Description     = inMeasurement.Description + " Summ of UBAL",
                    Enabled         = true,
                    CreatedOn       = DateTime.UtcNow,
                    UpdatedOn       = DateTime.UtcNow,
                    CreatedBy       = UserInfo.CurrentUserID,
                    UpdatedBy       = UserInfo.CurrentUserID,
                    SignalID        = Guid.NewGuid(),
                    Adder           = 0.0D,
                    Multiplier      = 1.0D
                });
            }

            // sqrdSum
            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:SQR";

            if (table.QueryRecordCountWhere("SignalReference = {0}", outputReference) < 1)
            {
                table.AddNewRecord(new MeasurementRecord
                {
                    HistorianID     = HistorianID,
                    DeviceID        = device.ID,
                    PointTag        = inMeasurement.PointTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:SQR",
                    AlternateTag    = inMeasurement.AlternateTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:SQR",
                    SignalTypeID    = signaltype,
                    SignalReference = outputReference,
                    Description     = inMeasurement.Description + " Summ of Sqared UBAL",
                    Enabled         = true,
                    CreatedOn       = DateTime.UtcNow,
                    UpdatedOn       = DateTime.UtcNow,
                    CreatedBy       = UserInfo.CurrentUserID,
                    UpdatedBy       = UserInfo.CurrentUserID,
                    SignalID        = Guid.NewGuid(),
                    Adder           = 0.0D,
                    Multiplier      = 1.0D
                });
            }

            // Min
            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:MIN";

            if (table.QueryRecordCountWhere("SignalReference = {0}", outputReference) < 1)
            {
                table.AddNewRecord(new MeasurementRecord
                {
                    HistorianID     = HistorianID,
                    DeviceID        = device.ID,
                    PointTag        = inMeasurement.PointTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:MIN",
                    AlternateTag    = inMeasurement.AlternateTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:MIN",
                    SignalTypeID    = signaltype,
                    SignalReference = outputReference,
                    Description     = inMeasurement.Description + " Minimum UBAL",
                    Enabled         = true,
                    CreatedOn       = DateTime.UtcNow,
                    UpdatedOn       = DateTime.UtcNow,
                    CreatedBy       = UserInfo.CurrentUserID,
                    UpdatedBy       = UserInfo.CurrentUserID,
                    SignalID        = Guid.NewGuid(),
                    Adder           = 0.0D,
                    Multiplier      = 1.0D
                });
            }

            // Max
            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:MAX";

            if (table.QueryRecordCountWhere("SignalReference = {0}", outputReference) < 1)
            {
                table.AddNewRecord(new MeasurementRecord
                {
                    HistorianID     = HistorianID,
                    DeviceID        = device.ID,
                    PointTag        = inMeasurement.PointTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:MAX",
                    AlternateTag    = inMeasurement.AlternateTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:MAX",
                    SignalTypeID    = signaltype,
                    SignalReference = outputReference,
                    Description     = inMeasurement.Description + " Maximum UBAL",
                    Enabled         = true,
                    CreatedOn       = DateTime.UtcNow,
                    UpdatedOn       = DateTime.UtcNow,
                    CreatedBy       = UserInfo.CurrentUserID,
                    UpdatedBy       = UserInfo.CurrentUserID,
                    SignalID        = Guid.NewGuid(),
                    Adder           = 0.0D,
                    Multiplier      = 1.0D
                });
            }

            // Number of Points
            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:NUM";

            if (table.QueryRecordCountWhere("SignalReference = {0}", outputReference) < 1)
            {
                table.AddNewRecord(new MeasurementRecord
                {
                    HistorianID     = HistorianID,
                    DeviceID        = device.ID,
                    PointTag        = inMeasurement.PointTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:NUM",
                    AlternateTag    = inMeasurement.AlternateTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:NUM",
                    SignalTypeID    = signaltype,
                    SignalReference = outputReference,
                    Description     = inMeasurement.Description + " Number of Points",
                    Enabled         = true,
                    CreatedOn       = DateTime.UtcNow,
                    UpdatedOn       = DateTime.UtcNow,
                    CreatedBy       = UserInfo.CurrentUserID,
                    UpdatedBy       = UserInfo.CurrentUserID,
                    SignalID        = Guid.NewGuid(),
                    Adder           = 0.0D,
                    Multiplier      = 1.0D
                });
            }

            // Number of Points above Alert
            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:ALT";

            if (table.QueryRecordCountWhere("SignalReference = {0}", outputReference) < 1)
            {
                table.AddNewRecord(new MeasurementRecord
                {
                    HistorianID     = HistorianID,
                    DeviceID        = device.ID,
                    PointTag        = inMeasurement.PointTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:ALT",
                    AlternateTag    = inMeasurement.AlternateTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:ALT",
                    SignalTypeID    = signaltype,
                    SignalReference = outputReference,
                    Description     = inMeasurement.Description + " number of Alerts",
                    Enabled         = true,
                    CreatedOn       = DateTime.UtcNow,
                    UpdatedOn       = DateTime.UtcNow,
                    CreatedBy       = UserInfo.CurrentUserID,
                    UpdatedBy       = UserInfo.CurrentUserID,
                    SignalID        = Guid.NewGuid(),
                    Adder           = 0.0D,
                    Multiplier      = 1.0D
                });
            }

            StatisticsCollection result = new StatisticsCollection();

            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:SUM";
            result.Sum      = MeasurementKey.LookUpBySignalID(table.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID);

            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:SQR";
            result.SqrD     = MeasurementKey.LookUpBySignalID(table.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID);

            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:MIN";
            result.Min      = MeasurementKey.LookUpBySignalID(table.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID);

            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:MAX";
            result.Max      = MeasurementKey.LookUpBySignalID(table.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID);

            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:NUM";
            result.Total    = MeasurementKey.LookUpBySignalID(table.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID);

            outputReference = table.QueryRecordWhere("SignalID = {0}", key.SignalID.ToString()).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL:ALT";
            result.Alert    = MeasurementKey.LookUpBySignalID(table.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID);

            result.Reset();
            return(result);
        }
Exemple #15
0
        /// <summary>
        /// Initializes this <see cref="MetricImporter"/>.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary <string, string> settings = Settings;
            string setting;

            // Load optional parameters

            if (settings.TryGetValue("importPath", out setting))
            {
                m_importPath = setting;
            }
            else
            {
                throw new InvalidOperationException("No import path was specified for EPRI metric importer - this is a required setting.");
            }

            if (settings.TryGetValue("inputInterval", out setting))
            {
                m_inputInterval = double.Parse(setting);
            }

            if (settings.TryGetValue("measurementsPerInterval", out setting))
            {
                m_measurementsPerInterval = int.Parse(setting);
            }

            if (settings.TryGetValue("simulateTimestamp", out setting))
            {
                m_simulateTimestamp = setting.ParseBoolean();
            }

            if (settings.TryGetValue("timestampFormat", out setting))
            {
                m_timestampFormat = setting;
            }

            if (settings.TryGetValue("skipRows", out setting))
            {
                int.TryParse(setting, out m_skipRows);
            }

            if (m_skipRows < 0)
            {
                m_skipRows = 0;
            }

            settings.TryGetValue("useHighResolutionInputTimer", out setting);

            if (string.IsNullOrEmpty(setting))
            {
                setting = "false";
            }

            UseHighResolutionInputTimer = setting.ParseBoolean();

            if (!UseHighResolutionInputTimer)
            {
                m_looseTimer = new System.Timers.Timer();
            }

            // Load column mappings:
            if (settings.TryGetValue("columnMappings", out setting))
            {
                Dictionary <int, string> columnMappings = new Dictionary <int, string>();
                int index;

                foreach (KeyValuePair <string, string> mapping in setting.ParseKeyValuePairs())
                {
                    if (int.TryParse(mapping.Key, out index))
                    {
                        columnMappings[index] = mapping.Value;
                    }
                }

                if (!m_simulateTimestamp && !columnMappings.Values.Contains("Timestamp", StringComparer.OrdinalIgnoreCase))
                {
                    throw new InvalidOperationException("One of the column mappings must be defined as a \"Timestamp\": e.g., columnMappings={1=Timestamp; 2=PPA:12; 3=PPA13}.");
                }

                // In transverse mode, maximum measurements per interval is set to maximum columns in input file
                m_measurementsPerInterval = columnMappings.Keys.Max();

                // Auto-assign output measurements based on column mappings
                OutputMeasurements = columnMappings.Where(kvp => string.Compare(kvp.Value, "Timestamp", true) != 0).Select(kvp =>
                {
                    string measurementID     = kvp.Value;
                    IMeasurement measurement = new Measurement();
                    MeasurementKey key;
                    Guid id;

                    if (Guid.TryParse(measurementID, out id))
                    {
                        measurement.Key = MeasurementKey.LookUpBySignalID(id);
                    }
                    else if (MeasurementKey.TryParse(measurementID, out key))
                    {
                        measurement.Key = key;
                    }

                    if (measurement.ID != Guid.Empty)
                    {
                        try
                        {
                            DataRow[] filteredRows = DataSource.Tables["ActiveMeasurements"].Select(string.Format("SignalID = '{0}'", measurement.ID));

                            if (filteredRows.Length > 0)
                            {
                                DataRow row = filteredRows[0];

                                // Assign other attributes
                                measurement.TagName    = row["PointTag"].ToNonNullString();
                                measurement.Multiplier = double.Parse(row["Multiplier"].ToString());
                                measurement.Adder      = double.Parse(row["Adder"].ToString());
                            }
                        }
                        catch
                        {
                            // Failure to lookup extra metadata is not catastrophic
                        }

                        // Associate measurement with column index
                        m_columnMappings[kvp.Key] = measurement;
                    }

                    return(measurement);
                }).ToArray();

                int timestampColumn = columnMappings.First(kvp => string.Compare(kvp.Value, "Timestamp", true) == 0).Key;

                // Reserve a column mapping for timestamp value
                IMeasurement timestampMeasurement = new Measurement()
                {
                    TagName = "Timestamp"
                };

                m_columnMappings[timestampColumn] = timestampMeasurement;
            }

            // Override input interval based on temporal processing interval if it's not set to default
            if (ProcessingInterval > -1)
            {
                m_inputInterval = ProcessingInterval == 0 ? 1 : ProcessingInterval;
            }

            if ((object)m_looseTimer != null)
            {
                m_looseTimer.Interval  = m_inputInterval;
                m_looseTimer.AutoReset = true;
                m_looseTimer.Elapsed  += m_looseTimer_Elapsed;
            }

            m_fileSystemWatcher          = new FileSystemWatcher(m_importPath, "EPRI-VS-Metrics-*.csv");
            m_fileSystemWatcher.Created += m_fileSystemWatcher_Created;
            m_fileSystemWatcher.Renamed += m_fileSystemWatcher_Renamed;
        }
Exemple #16
0
 /// <summary>
 /// Gets the minimum amount of time that data should be retained in the
 /// signal buffer for the signal identified by the given signal ID.
 /// </summary>
 /// <param name="signalID">The ID of the signal.</param>
 /// <returns>The retention time of the signal.</returns>
 public TimeSpan GetMinimumRetentionTime(Guid signalID)
 {
     return(GetMinimumRetentionTime(MeasurementKey.LookUpBySignalID(signalID)));
 }
Exemple #17
0
 /// <summary>
 /// Sets the minimum retention time of the signal identified by the given signal ID.
 /// </summary>
 /// <param name="signalID">The ID of the signal.</param>
 /// <param name="retentionTime">The minimum retention time of the signal.</param>
 public void SetMinimumRetentionTime(Guid signalID, TimeSpan retentionTime)
 {
     SetMinimumRetentionTime(MeasurementKey.LookUpBySignalID(signalID), retentionTime);
 }
Exemple #18
0
        // Attempt to read the next record
        private bool ReadNextRecord(long currentTime)
        {
            try
            {
                List <IMeasurement> newMeasurements = new List <IMeasurement>();
                long     fileTime        = 0;
                int      timestampColumn = 0;
                string[] fields          = m_inStream.ReadLine().ToNonNullString().Split(',');

                if (m_inStream.EndOfStream || fields.Length < m_columns.Count)
                {
                    return(false);
                }

                // Read time from Timestamp column in transverse mode
                if (m_transverse)
                {
                    if (m_simulateTimestamp)
                    {
                        fileTime = currentTime;
                    }
                    else
                    {
                        timestampColumn = m_columnMappings.First(kvp => string.Compare(kvp.Value.TagName, "Timestamp", StringComparison.OrdinalIgnoreCase) == 0).Key;
                        fileTime        = long.Parse(fields[timestampColumn]);
                    }
                }

                for (int i = 0; i < m_measurementsPerInterval; i++)
                {
                    IMeasurement measurement;

                    if (m_transverse)
                    {
                        // No measurement will be defined for timestamp column
                        if (i == timestampColumn)
                        {
                            continue;
                        }

                        if (m_columnMappings.TryGetValue(i, out measurement))
                        {
                            measurement       = Measurement.Clone(measurement);
                            measurement.Value = double.Parse(fields[i]);
                        }
                        else
                        {
                            measurement          = new Measurement();
                            measurement.Metadata = MeasurementKey.Undefined.Metadata;
                            measurement.Value    = double.NaN;
                        }

                        if (m_simulateTimestamp)
                        {
                            measurement.Timestamp = currentTime;
                        }
                        else if (m_columns.ContainsKey("Timestamp"))
                        {
                            measurement.Timestamp = fileTime;
                        }
                    }
                    else
                    {
                        measurement = new Measurement();

                        if (m_columns.ContainsKey("Signal ID"))
                        {
                            Guid measurementID = new Guid(fields[m_columns["Signal ID"]]);

                            if (m_columns.ContainsKey("Measurement Key"))
                            {
                                measurement.Metadata = MeasurementKey.LookUpOrCreate(measurementID, fields[m_columns["Measurement Key"]]).Metadata;
                            }
                            else
                            {
                                measurement.Metadata = MeasurementKey.LookUpBySignalID(measurementID).Metadata;
                            }
                        }
                        else if (m_columns.ContainsKey("Measurement Key"))
                        {
                            measurement.Metadata = MeasurementKey.Parse(fields[m_columns["Measurement Key"]]).Metadata;
                        }

                        if (m_simulateTimestamp)
                        {
                            measurement.Timestamp = currentTime;
                        }
                        else if (m_columns.ContainsKey("Timestamp"))
                        {
                            measurement.Timestamp = long.Parse(fields[m_columns["Timestamp"]]);
                        }

                        if (m_columns.ContainsKey("Value"))
                        {
                            measurement.Value = double.Parse(fields[m_columns["Value"]]);
                        }
                    }

                    newMeasurements.Add(measurement);
                }

                OnNewMeasurements(newMeasurements);
            }
            catch (Exception ex)
            {
                OnProcessException(MessageLevel.Warning, ex);
            }

            return(true);
        }
        /// <summary>
        /// Loads configuration from the database and configures adapter to run with that configuration
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            HashSet <IMeasurement> outputMeasurements = new HashSet <IMeasurement>();

            m_configuredCalculations        = new List <PowerCalculation>();
            m_averageCalculationsPerFrame   = new RunningAverage();
            m_averageCalculationTime        = new RunningAverage();
            m_averageTotalCalculationTime   = new RunningAverage();
            m_lastActivePowerCalculations   = new ConcurrentQueue <IMeasurement>();
            m_lastReactivePowerCalculations = new ConcurrentQueue <IMeasurement>();
            m_lastApparentPowerCalculations = new ConcurrentQueue <IMeasurement>();

            string query = "SELECT " +
                           //            1                   2                     3                   4                     5
                           "ID, CircuitDescription, VoltageAngleSignalID, VoltageMagSignalID, CurrentAngleSignalID, CurrentMagSignalID, " +
                           //         6                        7                            8
                           "ActivePowerOutputSignalID, ReactivePowerOutputSignalID, ApparentPowerOutputSignalID FROM PowerCalculation " +
                           "WHERE NodeId = {0} AND Enabled <> 0 ";

            using (AdoDataConnection database = new AdoDataConnection("systemSettings"))
                using (IDataReader rdr = database.ExecuteReader(query, ConfigurationFile.Current.Settings["systemSettings"]["NodeID"].ValueAs <Guid>()))
                {
                    while (rdr.Read())
                    {
                        m_configuredCalculations.Add(new PowerCalculation
                        {
                            PowerCalculationID             = rdr.GetInt32(0),
                            CircuitDescription             = rdr.GetString(1),
                            VoltageAngleSignalID           = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[2].ToString())),
                            VoltageMagnitudeSignalID       = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[3].ToString())),
                            CurrentAngleSignalID           = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[4].ToString())),
                            CurrentMagnitudeSignalID       = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[5].ToString())),
                            ActivePowerOutputMeasurement   = AddOutputMeasurement(Guid.Parse(rdr[6].ToString()), outputMeasurements),
                            ReactivePowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[7].ToString()), outputMeasurements),
                            ApparentPowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[8].ToString()), outputMeasurements)
                        });
                    }
                }

            if (m_configuredCalculations.Any())
            {
                InputMeasurementKeys = m_configuredCalculations.SelectMany(pc => new[] { pc.CurrentAngleSignalID, pc.CurrentMagnitudeSignalID, pc.VoltageAngleSignalID, pc.VoltageMagnitudeSignalID }).ToArray();
            }
            else
            {
                throw new InvalidOperationException("Skipped initialization of power calculator: no defined power calculations...");
            }

            if (outputMeasurements.Any())
            {
                OutputMeasurements = outputMeasurements.ToArray();
            }

            Dictionary <string, string> settings = Settings;
            string setting;

            if (settings.TryGetValue("AlwaysProduceResult", out setting))
            {
                AlwaysProduceResult = setting.ParseBoolean();
            }

            if (settings.TryGetValue("ApplySqrt3Adjustment", out setting))
            {
                ApplySqrt3Adjustment = setting.ParseBoolean();
            }

            if (settings.TryGetValue("RemoveSqrt3Adjustment", out setting))
            {
                RemoveSqrt3Adjustment = setting.ParseBoolean();
            }

            if (settings.TryGetValue("EnableTemporalProcessing", out setting))
            {
                EnableTemporalProcessing = setting.ParseBoolean();
            }
        }
Exemple #20
0
        /// <summary>
        /// Initializes <see cref="UnBalancedCalculation"/>.
        /// </summary>
        public override void Initialize()
        {
            new ConnectionStringParser <CalculatedMesaurementAttribute>().ParseConnectionString(ConnectionString, this);

            base.Initialize();

            m_threePhaseComponent = new List <ThreePhaseSet>();
            m_statisticsMapping   = new Dictionary <Guid, StatisticsCollection>();
            m_saveStats           = SaveAggregates;

            CategorizedSettingsElementCollection reportSettings = ConfigurationFile.Current.Settings["reportSettings"];

            reportSettings.Add("IUnbalanceThreshold", "4.0", "Current Unbalance Alert threshold.");
            reportSettings.Add("VUnbalanceThreshold", "4.0", "Voltage Unbalance Alert threshold.");
            double i_threshold = reportSettings["IUnbalanceThreshold"].ValueAs(1.0D);
            double v_threshold = reportSettings["VUnbalanceThreshold"].ValueAs(1.0D);

            List <Guid> processed = new List <Guid>();

            using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
            {
                TableOperations <MeasurementRecord> measurementTable      = new TableOperations <MeasurementRecord>(connection);
                TableOperations <ActiveMeasurement> activeMeasurmentTable = new TableOperations <ActiveMeasurement>(connection);

                TableOperations <Device>           deviceTable = new TableOperations <Device>(connection);
                TableOperations <SignalTypeRecord> signalTable = new TableOperations <SignalTypeRecord>(connection);

                Device device      = deviceTable.QueryRecordWhere("Acronym = {0}", ResultDeviceName);
                int    historianID = Convert.ToInt32(connection.ExecuteScalar("SELECT ID FROM Historian WHERE Acronym = {0}", new object[] { HistorianInstance }));

                // Take Care of the Device
                if (InputMeasurementKeys.Length < 1)
                {
                    return;
                }

                m_nodeID = deviceTable.QueryRecordWhere("Id={0}", measurementTable.QueryRecordWhere("SignalID = {0}", InputMeasurementKeys[0].SignalID).DeviceID).NodeID;

                if (device == null)
                {
                    device = CreateDefaultDevice(deviceTable);
                    OnStatusMessage(MessageLevel.Warning, $"Default Device for Output Measurments not found. Created Device {device.Acronym}");
                }


                if (MappingFilePath != "")
                {
                    // Read Mapping File
                    using (StreamReader reader = new StreamReader(FilePath.GetAbsolutePath(MappingFilePath)))
                    {
                        string line;
                        int    index = -1;


                        while ((line = reader.ReadLine()) != null)
                        {
                            index++;
                            List <string> pointTags = line.Split(',').Select(item => item.Trim()).ToList();

                            List <MeasurementKey> availableInputs = new List <MeasurementKey>(3);

                            if (pointTags.Count != 3)
                            {
                                OnStatusMessage(MessageLevel.Warning, $"Skipping Line {index} in mapping file.");
                                continue;
                            }

                            OnStatusMessage(MessageLevel.Info, $"PointTag of Measurment 1 is: {pointTags[0]}");
                            OnStatusMessage(MessageLevel.Info, $"PointTag of Measurment 1 is: {pointTags[0]}");
                            OnStatusMessage(MessageLevel.Info, $"PointTag of Measurment 1 is: {pointTags[0]}");

                            // check if measurments are in inputmeasurments
                            availableInputs.Add(InputMeasurementKeys.FirstOrDefault(item => item.SignalID == GetSignalID(pointTags[0], activeMeasurmentTable)));
                            availableInputs.Add(InputMeasurementKeys.FirstOrDefault(item => item.SignalID == GetSignalID(pointTags[1], activeMeasurmentTable)));
                            availableInputs.Add(InputMeasurementKeys.FirstOrDefault(item => item.SignalID == GetSignalID(pointTags[2], activeMeasurmentTable)));

                            if (availableInputs[0] == null || availableInputs[1] == null || availableInputs[2] == null)
                            {
                                OnStatusMessage(MessageLevel.Warning, $"Skipping Line {index} in mapping file. PointTag not found");
                                continue;
                            }

                            SignalType type = GetSignalType(availableInputs[0], new TableOperations <ActiveMeasurement>(connection));

                            MeasurementKey neg = availableInputs.FirstOrDefault(item =>
                                                                                SearchNegative(item, new TableOperations <ActiveMeasurement>(connection)) &&
                                                                                GetSignalType(item, new TableOperations <ActiveMeasurement>(connection)) == type);
                            MeasurementKey pos = availableInputs.FirstOrDefault(item =>
                                                                                SearchPositive(item, new TableOperations <ActiveMeasurement>(connection)) &&
                                                                                GetSignalType(item, new TableOperations <ActiveMeasurement>(connection)) == type);
                            MeasurementKey zero = availableInputs.FirstOrDefault(item =>
                                                                                 SearchZero(item, new TableOperations <ActiveMeasurement>(connection)) &&
                                                                                 GetSignalType(item, new TableOperations <ActiveMeasurement>(connection)) == type
                                                                                 );

                            if (neg != null && zero != null && pos != null)
                            {
                                MeasurementKey unBalance;
                                string         outputReference = measurementTable.QueryRecordWhere("SignalID = {0}", pos.SignalID).SignalReference + "-" + (type == SignalType.IPHM? "I" : "V") + "UBAL";

                                if (measurementTable.QueryRecordCountWhere("SignalReference = {0}", outputReference) > 0)
                                {
                                    // Measurement Exists
                                    unBalance = MeasurementKey.LookUpBySignalID(measurementTable.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID);
                                }
                                else
                                {
                                    // Add Measurment to Database and make a statement
                                    MeasurementRecord inMeasurement = measurementTable.QueryRecordWhere("SignalID = {0}", pos.SignalID);

                                    MeasurementRecord outMeasurement = new MeasurementRecord
                                    {
                                        HistorianID     = historianID,
                                        DeviceID        = device.ID,
                                        PointTag        = inMeasurement.PointTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL",
                                        AlternateTag    = inMeasurement.AlternateTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL",
                                        SignalTypeID    = signalTable.QueryRecordWhere("Acronym = {0}", "CALC").ID,
                                        SignalReference = outputReference,
                                        Description     = GetDescription(pos, new TableOperations <ActiveMeasurement>(connection)) + " UnBalanced",
                                        Enabled         = true,
                                        CreatedOn       = DateTime.UtcNow,
                                        UpdatedOn       = DateTime.UtcNow,
                                        CreatedBy       = UserInfo.CurrentUserID,
                                        UpdatedBy       = UserInfo.CurrentUserID,
                                        SignalID        = Guid.NewGuid(),
                                        Adder           = 0.0D,
                                        Multiplier      = 1.0D
                                    };

                                    measurementTable.AddNewRecord(outMeasurement);
                                    unBalance = MeasurementKey.LookUpBySignalID(measurementTable.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID);

                                    OnStatusMessage(MessageLevel.Warning, $"Output measurment {outputReference} not found. Creating measurement");
                                }

                                double threshold = InputMeasurementKeyTypes[InputMeasurementKeys.IndexOf(item => item == availableInputs[0])] == SignalType.IPHM ? i_threshold : v_threshold;

                                m_threePhaseComponent.Add(new ThreePhaseSet(pos, zero, neg, unBalance, threshold));

                                if (m_saveStats)
                                {
                                    m_statisticsMapping.Add(pos.SignalID, CreateStatistics(measurementTable, pos, device, historianID, type));
                                }
                            }
                            else
                            {
                                OnStatusMessage(MessageLevel.Warning, $"Skipping Line {index} in mapping file. Did not find pos. neg. and zero seq.");
                            }
                        }
                    }
                }
                else
                {
                    foreach (MeasurementKey key in InputMeasurementKeys)
                    {
                        if (processed.Contains(key.SignalID))
                        {
                            continue;
                        }

                        // ensure only magnitudes are being used
                        if (!(GetSignalType(key, new TableOperations <ActiveMeasurement>(connection)) == SignalType.IPHM ||
                              GetSignalType(key, new TableOperations <ActiveMeasurement>(connection)) == SignalType.VPHM))
                        {
                            continue;
                        }



                        bool isNeg  = SearchNegative(key, new TableOperations <ActiveMeasurement>(connection));
                        bool isPos  = SearchPositive(key, new TableOperations <ActiveMeasurement>(connection));
                        bool isZero = SearchZero(key, new TableOperations <ActiveMeasurement>(connection));

                        if (!(isNeg || isPos || isZero))
                        {
                            continue;
                        }

                        string description = GetDescription(key, new TableOperations <ActiveMeasurement>(connection));

                        // Check to make sure can actually deal with this
                        if (description == string.Empty)
                        {
                            OnStatusMessage(MessageLevel.Warning, "Failed to apply automatic Line bundling to " + key.SignalID);
                            continue;
                        }

                        //Make sure only correct Type (V vs I) makes it here....
                        SignalType type = GetSignalType(key, new TableOperations <ActiveMeasurement>(connection));

                        MeasurementKey neg = InputMeasurementKeys.FirstOrDefault(item =>
                                                                                 GetDescription(item, new TableOperations <ActiveMeasurement>(connection)) == description &&
                                                                                 SearchNegative(item, new TableOperations <ActiveMeasurement>(connection)) &&
                                                                                 GetSignalType(item, new TableOperations <ActiveMeasurement>(connection)) == type);
                        MeasurementKey pos = InputMeasurementKeys.FirstOrDefault(item =>
                                                                                 GetDescription(item, new TableOperations <ActiveMeasurement>(connection)) == description &&
                                                                                 SearchPositive(item, new TableOperations <ActiveMeasurement>(connection)) &&
                                                                                 GetSignalType(item, new TableOperations <ActiveMeasurement>(connection)) == type);
                        MeasurementKey zero = InputMeasurementKeys.FirstOrDefault(item =>
                                                                                  GetDescription(item, new TableOperations <ActiveMeasurement>(connection)) == description &&
                                                                                  SearchZero(item, new TableOperations <ActiveMeasurement>(connection)) &&
                                                                                  GetSignalType(item, new TableOperations <ActiveMeasurement>(connection)) == type
                                                                                  );

                        if (neg != null && zero != null && pos != null)
                        {
                            MeasurementKey unBalance;
                            string         outputReference = measurementTable.QueryRecordWhere("SignalID = {0}", pos.SignalID).SignalReference + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL";

                            if (measurementTable.QueryRecordCountWhere("SignalReference = {0}", outputReference) > 0)
                            {
                                // Measurement Exists
                                unBalance = MeasurementKey.LookUpBySignalID(measurementTable.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID);
                            }
                            else
                            {
                                // Add Measurment to Database and make a statement
                                MeasurementRecord inMeasurement = measurementTable.QueryRecordWhere("SignalID = {0}", pos.SignalID);

                                MeasurementRecord outMeasurement = new MeasurementRecord
                                {
                                    HistorianID     = historianID,
                                    DeviceID        = device.ID,
                                    PointTag        = inMeasurement.PointTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL",
                                    AlternateTag    = inMeasurement.AlternateTag + "-" + (type == SignalType.IPHM ? "I" : "V") + "UBAL",
                                    SignalTypeID    = signalTable.QueryRecordWhere("Acronym = {0}", "CALC").ID,
                                    SignalReference = outputReference,
                                    Description     = GetDescription(pos, new TableOperations <ActiveMeasurement>(connection)) + " UnBalanced",
                                    Enabled         = true,
                                    CreatedOn       = DateTime.UtcNow,
                                    UpdatedOn       = DateTime.UtcNow,
                                    CreatedBy       = UserInfo.CurrentUserID,
                                    UpdatedBy       = UserInfo.CurrentUserID,
                                    SignalID        = Guid.NewGuid(),
                                    Adder           = 0.0D,
                                    Multiplier      = 1.0D
                                };

                                measurementTable.AddNewRecord(outMeasurement);
                                unBalance = MeasurementKey.LookUpBySignalID(measurementTable.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID);

                                OnStatusMessage(MessageLevel.Warning, $"Output measurment {outputReference} not found. Creating measurement");
                            }

                            double threshold = InputMeasurementKeyTypes[InputMeasurementKeys.IndexOf(item => item == key)] == SignalType.IPHM ? i_threshold : v_threshold;

                            m_threePhaseComponent.Add(new ThreePhaseSet(pos, zero, neg, unBalance, threshold));

                            processed.Add(pos.SignalID);
                            processed.Add(neg.SignalID);
                            processed.Add(zero.SignalID);

                            if (m_saveStats)
                            {
                                m_statisticsMapping.Add(pos.SignalID, CreateStatistics(measurementTable, pos, device, historianID, type));
                            }
                        }

                        else
                        {
                            if (pos != null)
                            {
                                processed.Add(pos.SignalID);
                            }

                            if (neg != null)
                            {
                                processed.Add(neg.SignalID);
                            }

                            if (zero != null)
                            {
                                processed.Add(zero.SignalID);
                            }
                        }
                    }
                }

                if (m_threePhaseComponent.Count == 0)
                {
                    OnStatusMessage(MessageLevel.Error, "No case with all 3 sequences was found");
                }
            }
        }
Exemple #21
0
        /// <summary>
        /// Initializes this <see cref="FileImporter"/>.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary <string, string> settings = Settings;
            string setting;

            // Load optional parameters

            if (settings.TryGetValue("importPath", out setting))
            {
                m_importPath = setting;
            }
            else
            {
                throw new InvalidOperationException("No import path was specified for EPRI file importer - this is a required setting.");
            }

            if (settings.TryGetValue("inputInterval", out setting))
            {
                m_inputInterval = double.Parse(setting);
            }

            if (settings.TryGetValue("measurementsPerInterval", out setting))
            {
                m_measurementsPerInterval = int.Parse(setting);
            }

            if (settings.TryGetValue("simulateTimestamp", out setting))
            {
                m_simulateTimestamp = setting.ParseBoolean();
            }

            if (settings.TryGetValue("timestampFormat", out setting))
            {
                m_timestampFormat = setting;
            }

            if (settings.TryGetValue("skipRows", out setting))
            {
                int.TryParse(setting, out m_skipRows);
            }

            if (m_skipRows < 0)
            {
                m_skipRows = 0;
            }

            settings.TryGetValue("useHighResolutionInputTimer", out setting);

            if (string.IsNullOrEmpty(setting))
            {
                setting = "false";
            }

            UseHighResolutionInputTimer = setting.ParseBoolean();

            if (!UseHighResolutionInputTimer)
            {
                m_looseTimer = new Timer();
            }

            // Load column mappings:
            if (settings.TryGetValue("columnMappings", out setting))
            {
                Dictionary <int, string> columnMappings = new Dictionary <int, string>();
                int index;

                foreach (KeyValuePair <string, string> mapping in setting.ParseKeyValuePairs())
                {
                    if (int.TryParse(mapping.Key, out index))
                    {
                        columnMappings[index] = mapping.Value;
                    }
                }

                if (!m_simulateTimestamp && !columnMappings.Values.Contains("Timestamp", StringComparer.OrdinalIgnoreCase))
                {
                    throw new InvalidOperationException("One of the column mappings must be defined as a \"Timestamp\": e.g., columnMappings={0=Timestamp; 1=PPA:12; 2=PPA13}.");
                }

                // In transverse mode, maximum measurements per interval is set to maximum columns in input file
                m_measurementsPerInterval = columnMappings.Keys.Max();

                // Auto-assign output measurements based on column mappings
                OutputMeasurements = columnMappings.Where(kvp => string.Compare(kvp.Value, "Timestamp", StringComparison.OrdinalIgnoreCase) != 0).Select(kvp =>
                {
                    string measurementID     = kvp.Value;
                    IMeasurement measurement = new Measurement();
                    MeasurementKey key;
                    Guid id;

                    if (Guid.TryParse(measurementID, out id))
                    {
                        key = MeasurementKey.LookUpBySignalID(id);
                    }
                    else
                    {
                        MeasurementKey.TryParse(measurementID, out key);
                    }

                    if (key.SignalID != Guid.Empty)
                    {
                        measurement.Metadata = key.Metadata;

                        // Associate measurement with column index
                        m_columnMappings[kvp.Key] = measurement;
                    }

                    return(measurement);
                }).ToArray();

                int timestampColumn = columnMappings.First(kvp => string.Compare(kvp.Value, "Timestamp", StringComparison.OrdinalIgnoreCase) == 0).Key;

                // Reserve a column mapping for timestamp value
                IMeasurement timestampMeasurement = new Measurement
                {
                    Metadata = new MeasurementMetadata(null, "Timestamp", 0, 1, null)
                };

                m_columnMappings[timestampColumn] = timestampMeasurement;
            }

            // Override input interval based on temporal processing interval if it's not set to default
            if (ProcessingInterval > -1)
            {
                m_inputInterval = ProcessingInterval == 0 ? 1 : ProcessingInterval;
            }

            if ((object)m_looseTimer != null)
            {
                m_looseTimer.Interval  = m_inputInterval;
                m_looseTimer.AutoReset = true;
                m_looseTimer.Elapsed  += m_looseTimer_Elapsed;
            }

            m_fileSystemWatcher          = new SafeFileWatcher(m_importPath, "EPRI-VS-Output-*.csv");
            m_fileSystemWatcher.Created += m_fileSystemWatcher_Created;
            m_fileSystemWatcher.Renamed += m_fileSystemWatcher_Renamed;
        }
Exemple #22
0
 private static MeasurementKey GetTargetFromGuid(string guidID) => MeasurementKey.LookUpBySignalID(Guid.Parse(guidID));
        /// <summary>
        /// Loads configuration from the database and configures adapter to run with that configuration
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            HashSet <IMeasurement> outputMeasurements = new HashSet <IMeasurement>();

            m_configuredCalculations        = new List <PowerCalculation>();
            m_adjustmentStrategies          = new Dictionary <MeasurementKey, VoltageAdjustmentStrategy>();
            m_averageCalculationsPerFrame   = new RunningAverage();
            m_averageCalculationTime        = new RunningAverage();
            m_averageTotalCalculationTime   = new RunningAverage();
            m_lastActivePowerCalculations   = new ConcurrentQueue <IMeasurement>();
            m_lastReactivePowerCalculations = new ConcurrentQueue <IMeasurement>();
            m_lastApparentPowerCalculations = new ConcurrentQueue <IMeasurement>();

            if (!Settings.TryGetValue(nameof(TableName), out string tableName))
            {
                tableName = DefaultTableName;
            }

            string query = "SELECT " +
                           // 0          1                    2                     3                   4                     5
                           "ID, CircuitDescription, VoltageAngleSignalID, VoltageMagSignalID, CurrentAngleSignalID, CurrentMagSignalID, " +
                           //            6                          7                            8
                           "ActivePowerOutputSignalID, ReactivePowerOutputSignalID, ApparentPowerOutputSignalID FROM " + tableName + " " +
                           "WHERE NodeId = {0} AND Enabled <> 0 ";

            using (AdoDataConnection database = new AdoDataConnection("systemSettings"))
                using (IDataReader rdr = database.ExecuteReader(query, ConfigurationFile.Current.Settings["systemSettings"]["NodeID"].ValueAs <Guid>()))
                {
                    while (rdr.Read())
                    {
                        m_configuredCalculations.Add(new PowerCalculation
                        {
                            PowerCalculationID             = rdr.GetInt32(0),
                            CircuitDescription             = rdr.GetString(1),
                            VoltageAngleMeasurementKey     = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[2].ToString())),
                            VoltageMagnitudeMeasurementKey = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[3].ToString())),
                            CurrentAngleMeasurementKey     = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[4].ToString())),
                            CurrentMagnitudeMeasurementKey = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[5].ToString())),
                            ActivePowerOutputMeasurement   = AddOutputMeasurement(Guid.Parse(rdr[6].ToString()), outputMeasurements),
                            ReactivePowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[7].ToString()), outputMeasurements),
                            ApparentPowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[8].ToString()), outputMeasurements)
                        });
                    }
                }

            if (m_configuredCalculations.Any())
            {
                InputMeasurementKeys = m_configuredCalculations.SelectMany(pc => new[] { pc.CurrentAngleMeasurementKey, pc.CurrentMagnitudeMeasurementKey, pc.VoltageAngleMeasurementKey, pc.VoltageMagnitudeMeasurementKey }).ToArray();
            }
            else
            {
                throw new InvalidOperationException("Skipped initialization of power calculator: no defined power calculations...");
            }

            if (outputMeasurements.Any())
            {
                OutputMeasurements = outputMeasurements.ToArray();
            }

            Dictionary <string, string> settings = Settings;

            if (settings.TryGetValue(nameof(AlwaysProduceResult), out string setting))
            {
                AlwaysProduceResult = setting.ParseBoolean();
            }

            if (settings.TryGetValue(nameof(AdjustmentStrategy), out setting) && Enum.TryParse(setting, out VoltageAdjustmentStrategy adjustmentStrategy))
            {
                AdjustmentStrategy = adjustmentStrategy;
            }

            if (settings.TryGetValue(nameof(EnableTemporalProcessing), out setting))
            {
                EnableTemporalProcessing = setting.ParseBoolean();
            }

            // Define per power calculation line adjustment strategies
            foreach (PowerCalculation powerCalculation in m_configuredCalculations)
            {
                if (powerCalculation.VoltageMagnitudeMeasurementKey is null || string.IsNullOrWhiteSpace(powerCalculation.CircuitDescription))
                {
                    continue;
                }

                try
                {
                    Dictionary <string, string> circuitSettings = powerCalculation.CircuitDescription.ParseKeyValuePairs();

                    if (circuitSettings.TryGetValue(nameof(AdjustmentStrategy), out setting) && Enum.TryParse(setting, out adjustmentStrategy))
                    {
                        m_adjustmentStrategies[powerCalculation.VoltageMagnitudeMeasurementKey] = adjustmentStrategy;
                    }
                }
                catch (Exception ex)
                {
                    OnStatusMessage(MessageLevel.Warning, $"Failed to parse settings from circuit description \"{powerCalculation.CircuitDescription}\": {ex.Message}");
                }
            }
        }
Exemple #24
0
        /// <summary>
        /// Initializes <see cref="ActionAdapterBase"/>.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary <string, string> settings = Settings;
            string            alternateDatabaseConnection;
            AdoDataConnection connection = null;

            try
            {
                // Load optional parameters
                if (settings.TryGetValue("AlternateDatabaseConnection", out alternateDatabaseConnection) && !string.IsNullOrEmpty(alternateDatabaseConnection))
                {
                    string connectionString, dataProviderString;
                    settings = alternateDatabaseConnection.ParseKeyValuePairs();
                    settings.TryGetValue("ConnectionString", out connectionString);
                    settings.TryGetValue("DataProviderString", out dataProviderString);

                    if (!string.IsNullOrEmpty(connectionString) && !string.IsNullOrEmpty(dataProviderString))
                    {
                        connection = new AdoDataConnection(connectionString, dataProviderString);
                    }
                }

                // Fall back on current openPDC database if alternate connection was not provided
                if ((object)connection == null)
                {
                    connection = new AdoDataConnection("systemSettings");
                }

                // This example assumes stored procedure returns a table with a column named ID that is a Guid, each row representing an input measurement
                MeasurementKey[] inputKeys = connection.RetrieveData("GetMyInputsProc @param1 @param2", "param1Value", "param2Value").Rows.OfType <DataRow>()
                                             .Select(row => MeasurementKey.LookUpBySignalID(Guid.Parse(row["ID"].ToString()))).ToArray();

                // Lookup signal types for defined input measurements
                SignalType[] inputTypes = inputKeys.Select(key => LookupSignalType(key)).ToArray();

                // Segregate inputs into voltage and current phasor measurements
                MeasurementKey[] voltageAngles     = inputKeys.Where((key, index) => inputTypes[index] == SignalType.VPHA).ToArray();
                MeasurementKey[] voltageMagnitudes = inputKeys.Where((key, index) => inputTypes[index] == SignalType.VPHM).ToArray();
                MeasurementKey[] currentAngles     = inputKeys.Where((key, index) => inputTypes[index] == SignalType.IPHA).ToArray();
                MeasurementKey[] currentMagnitudes = inputKeys.Where((key, index) => inputTypes[index] == SignalType.IPHM).ToArray();

                // Validate input measurement types have quartic alignment
                if (voltageAngles.Length != currentAngles.Length || voltageAngles.Length != voltageMagnitudes.Length || currentAngles.Length != currentMagnitudes.Length)
                {
                    throw new InvalidOperationException("A different number of voltage and current phasor input measurement keys were supplied - the current and voltage phasors inputs must be supplied in pairs to represent a line measurement set, i.e., one set of voltage phasor input measurements must be supplied for each current phasor input measurement in a consecutive sequence (e.g., VA1;VM1;IA1;IM1;  VA2;VM2;IA2;IM2; ... VAn;VMn;IAn;IMn)");
                }

                // Reduce inputs to validated set of source measurements
                InputMeasurementKeys = voltageAngles.Concat(voltageMagnitudes).Concat(currentAngles).Concat(currentMagnitudes).Distinct().ToArray();

                // Store phasor pairs as line measurements
                PhasorMeasurements voltageMeasurements, currentMeasurements;
                m_lineMeasurements = new LineMeasurements[voltageAngles.Length];

                // Needed values for a line consist of measurements for voltage phasors and current phasors
                for (int i = 0; i < m_lineMeasurements.Length; i++)
                {
                    voltageMeasurements   = new PhasorMeasurements(voltageAngles[i], voltageMagnitudes[i]);
                    currentMeasurements   = new PhasorMeasurements(currentAngles[i], currentMagnitudes[i]);
                    m_lineMeasurements[i] = new LineMeasurements(voltageMeasurements, currentMeasurements);
                }

                // Define output measurements as defined in stored procedure
                OutputMeasurements = connection.RetrieveData("GetMyOutputsProc @param1 @param2", "param1Value", "param2Value").Rows.OfType <DataRow>()
                                     .Select(row => new Measurement()
                {
                    Key = MeasurementKey.LookUpBySignalID(Guid.Parse(row["ID"].ToString()))
                }).ToArray();
            }
            finally
            {
                if ((object)connection != null)
                {
                    connection.Dispose();
                }
            }
        }
Exemple #25
0
        // Per partition consumer read handler
        private void ProcessPartitionMessages(object state)
        {
            int partition = (int)state;

            try
            {
                Dictionary <uint, MeasurementKey> idTable         = new Dictionary <uint, MeasurementKey>();
                ConsumerOptions           options                 = new ConsumerOptions(Topic, m_router);
                LongSynchronizedOperation cacheLastConsumerOffset = null;
                OffsetPosition            consumerCursor          = new OffsetPosition {
                    PartitionId = partition, Offset = 0
                };
                long lastUpdateTime          = 0;
                long lastMetadataUpdateCount = 0;
                long lastMeasurementTime     = 0;

                options.PartitionWhitelist.Add(partition);
                options.Log = new TimeSeriesLogger((message, parameters) => OnStatusMessage($"P[{partition}]: " + message, parameters), OnProcessException);

                // Handle consumer offset tracking, i.e., adapter will start reading messages where it left off from last run
                if (TrackConsumerOffset)
                {
                    // Parse path/filename.ext into constituent parts
                    string[] fileParts = new string[3];

                    fileParts[0] = FilePath.GetDirectoryName(ConsumerOffsetFileName);               // 0: path/
                    fileParts[1] = FilePath.GetFileNameWithoutExtension(ConsumerOffsetFileName);    // 1: filename
                    fileParts[2] = FilePath.GetExtension(ConsumerOffsetFileName);                   // 2: .ext

                    // Include partition index as part of consumer offset cache file name
                    string fileName = $"{fileParts[0]}{fileParts[1]}-P{partition}{fileParts[2]}";

                    if (File.Exists(fileName))
                    {
                        try
                        {
                            // Read last consumer offset
                            consumerCursor.Offset = long.Parse(File.ReadAllText(fileName));
                        }
                        catch (Exception ex)
                        {
                            OnProcessException(new InvalidOperationException($"Failed to read last consumer offset from \"{fileName}\": {ex.Message}", ex));
                        }
                    }

                    cacheLastConsumerOffset = new LongSynchronizedOperation(() =>
                    {
                        // Do not write file any more often than defined consumer offset cache interval
                        int restTime = (int)(Ticks.FromSeconds(ConsumerOffsetCacheInterval) - (DateTime.UtcNow.Ticks - lastUpdateTime)).ToMilliseconds();

                        if (restTime > 0)
                        {
                            Thread.Sleep(restTime);
                        }

                        lastUpdateTime = DateTime.UtcNow.Ticks;

                        // Write current consumer offset
                        File.WriteAllText(fileName, consumerCursor.Offset.ToString());
                    },
                                                                            ex => OnProcessException(new InvalidOperationException($"Failed to cache current consumer offset to \"{fileName}\": {ex.Message}", ex)))
                    {
                        IsBackground = true
                    };
                }

                using (Consumer consumer = new Consumer(options, new OffsetPosition(partition, consumerCursor.Offset)))
                {
                    lock (m_consumers)
                        m_consumers.Add(new WeakReference <Consumer>(consumer));

                    foreach (Message message in consumer.Consume())
                    {
                        if ((object)m_metadata == null)
                        {
                            continue;
                        }

                        uint         id;
                        byte         metadataVersion;
                        IMeasurement measurement = message.KafkaDeserialize(out id, out metadataVersion);

                        // Kick-off a refresh for new metadata if message version numbers change
                        if (m_lastMetadataVersion != metadataVersion)
                        {
                            m_lastMetadataVersion = metadataVersion;
                            m_updateMetadata.RunOnceAsync();
                        }

                        // Clear all undefined items in dictionary when metadata gets updated
                        if (lastMetadataUpdateCount < m_metadataUpdateCount)
                        {
                            lastMetadataUpdateCount = m_metadataUpdateCount;
                            foreach (uint undefinedID in idTable.Where(item => item.Value.SignalID == Guid.Empty).Select(item => item.Key).ToArray())
                            {
                                idTable.Remove(undefinedID);
                            }
                        }

                        // Get associated measurement key, or look it up in metadata table
                        measurement.Key = idTable.GetOrAdd(id, lookupID => MeasurementKey.LookUpBySignalID(m_metadata?.Records?.FirstOrDefault(record => record.ID == lookupID)?.ParseSignalID() ?? Guid.Empty));

                        // Only publish measurements with associated metadata and are assigned to this adapter
                        if (measurement.Key != MeasurementKey.Undefined && ((object)m_outputMeasurementKeys == null || m_outputMeasurementKeys.Contains(measurement.Key)))
                        {
                            OnNewMeasurements(new[] { measurement });
                        }

                        // Cache last consumer offset
                        consumerCursor.Offset = message.Offset;

                        if ((object)cacheLastConsumerOffset != null)
                        {
                            cacheLastConsumerOffset.RunOnceAsync();
                        }

                        if (ReadDelay > -1)
                        {
                            // As a group of measurements transition from timestamp to another, inject configured read delay
                            if (lastMeasurementTime != measurement.Timestamp)
                            {
                                Thread.Sleep(ReadDelay);
                            }

                            lastMeasurementTime = measurement.Timestamp;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                OnProcessException(new InvalidOperationException($"Exception while reading Kafka messages for topic \"{Topic}\" P[{partition}]: {ex.Message}", ex));
            }
        }
Exemple #26
0
        /// <summary>
        /// Initializes <see cref="SNRComputation"/>.
        /// </summary>
        public override void Initialize()
        {
            new ConnectionStringParser <CalculatedMesaurementAttribute>().ParseConnectionString(ConnectionString, this);

            base.Initialize();

            // Figure Output Measurement Keys
            m_dataWindow        = new Dictionary <Guid, List <double> >();
            m_refWindow         = new List <double>();
            m_outputMapping     = new Dictionary <Guid, MeasurementKey>();
            m_statisticsMapping = new Dictionary <Guid, StatisticsCollection>();
            m_saveStats         = SaveAggregates;

            if (ReportingInterval % (double)WindowLength != 0.0D)
            {
                ReportingInterval = WindowLength * (ReportingInterval / WindowLength);
                OnStatusMessage(MessageLevel.Warning, $"Adjusting Reporting Interval to every {ReportingInterval} frames.");
            }

            CategorizedSettingsElementCollection reportSettings = ConfigurationFile.Current.Settings["reportSettings"];

            reportSettings.Add("DefaultSNRThreshold", "4.0", "Default SNR Alert threshold.");
            m_threshold = reportSettings["DefaultSNRThreshold"].ValueAs(m_threshold);

            using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
            {
                TableOperations <MeasurementRecord> measurementTable = new TableOperations <MeasurementRecord>(connection);
                TableOperations <Device>            deviceTable      = new TableOperations <Device>(connection);
                TableOperations <SignalTypeRecord>  signalTable      = new TableOperations <SignalTypeRecord>(connection);

                Device device      = deviceTable.QueryRecordWhere("Acronym = {0}", ResultDeviceName);
                int    historianID = Convert.ToInt32(connection.ExecuteScalar("SELECT ID FROM Historian WHERE Acronym = {0}", new object[] { HistorianInstance }));

                if (!InputMeasurementKeys.Any())
                {
                    return;
                }

                m_nodeID = deviceTable.QueryRecordWhere("Id={0}", measurementTable.QueryRecordWhere("SignalID = {0}", InputMeasurementKeys[0].SignalID).DeviceID).NodeID;

                if (device == null)
                {
                    device = CreateDefaultDevice(deviceTable);
                    OnStatusMessage(MessageLevel.Warning, $"Default Device for Output Measurments not found. Created Device {device.Acronym}");
                }

                foreach (MeasurementKey key in InputMeasurementKeys)
                {
                    m_dataWindow.Add(key.SignalID, new List <double>());

                    string outputReference = measurementTable.QueryRecordWhere("SignalID = {0}", key.SignalID).SignalReference + "-SNR";

                    if (measurementTable.QueryRecordCountWhere("SignalReference = {0}", outputReference) > 0)
                    {
                        // Measurement Exists
                        m_outputMapping.Add(key.SignalID, MeasurementKey.LookUpBySignalID(measurementTable.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID));
                    }
                    else
                    {
                        // Add Measurment to Database and make a statement
                        MeasurementRecord inMeasurement = measurementTable.QueryRecordWhere("SignalID = {0}", key.SignalID);

                        MeasurementRecord outMeasurement = new MeasurementRecord
                        {
                            HistorianID     = historianID,
                            DeviceID        = device.ID,
                            PointTag        = inMeasurement.PointTag + "-SNR",
                            AlternateTag    = inMeasurement.AlternateTag + "-SNR",
                            SignalTypeID    = signalTable.QueryRecordWhere("Acronym = {0}", "CALC").ID,
                            SignalReference = outputReference,
                            Description     = inMeasurement.Description + " SNR",
                            Enabled         = true,
                            CreatedOn       = DateTime.UtcNow,
                            UpdatedOn       = DateTime.UtcNow,
                            CreatedBy       = UserInfo.CurrentUserID,
                            UpdatedBy       = UserInfo.CurrentUserID,
                            SignalID        = Guid.NewGuid(),
                            Adder           = 0.0D,
                            Multiplier      = 1.0D
                        };

                        measurementTable.AddNewRecord(outMeasurement);

                        m_outputMapping.Add(key.SignalID, MeasurementKey.LookUpBySignalID(
                                                measurementTable.QueryRecordWhere("SignalReference = {0}", outputReference).SignalID));

                        OnStatusMessage(MessageLevel.Warning, $"Output measurment {outputReference} not found. Creating measurement");
                    }

                    if (m_saveStats)
                    {
                        m_statisticsMapping.Add(key.SignalID, CreateStatistics(measurementTable, key, device, historianID));
                    }
                }

                if (Reference == null)
                {
                    OnStatusMessage(MessageLevel.Warning, "No Reference Angle Specified");

                    int refIndex = InputMeasurementKeyTypes.IndexOf(item => item == SignalType.IPHA || item == SignalType.VPHA);

                    if (refIndex > -1)
                    {
                        Reference = InputMeasurementKeys[refIndex];
                    }
                }

                if (Reference != null)
                {
                    if (!InputMeasurementKeys.Contains(Reference))
                    {
                        InputMeasurementKeys.AddRange(new[] { Reference });
                    }
                }
            }
        }