Exemple #1
0
        /// <summary>
        /// Creates a new local system cache from one that was received remotely.
        /// </summary>
        /// <param name="dataSource"><see cref="DataSet"/> based data source used to interpret local measurement keys.</param>
        /// <param name="remoteCache">Deserialized remote signal index cache.</param>
        public SignalIndexCache(DataSet dataSource, SignalIndexCache remoteCache)
        {
            m_subscriberID = remoteCache.SubscriberID;

            // If active measurements are defined, interpret signal cache in context of current measurement key definitions
            if (dataSource != null && dataSource.Tables != null && dataSource.Tables.Contains("ActiveMeasurements"))
            {
                DataTable activeMeasurements = dataSource.Tables["ActiveMeasurements"];
                m_reference = new ConcurrentDictionary <ushort, Tuple <Guid, string, uint> >();

                foreach (KeyValuePair <ushort, Tuple <Guid, string, uint> > signalIndex in remoteCache.Reference)
                {
                    Guid      signalID     = signalIndex.Value.Item1;
                    DataRow[] filteredRows = activeMeasurements.Select("SignalID = '" + signalID.ToString() + "'");

                    if (filteredRows.Length > 0)
                    {
                        DataRow        row = filteredRows[0];
                        MeasurementKey key = MeasurementKey.Parse(row["ID"].ToNonNullString(MeasurementKey.Undefined.ToString()), signalID);
                        m_reference.TryAdd(signalIndex.Key, new Tuple <Guid, string, uint>(signalID, key.Source, key.ID));
                    }
                }

                m_unauthorizedSignalIDs = remoteCache.UnauthorizedSignalIDs;
            }
            else
            {
                // Just use remote signal index cache as-is if no local configuration exists
                m_reference             = remoteCache.Reference;
                m_unauthorizedSignalIDs = remoteCache.UnauthorizedSignalIDs;
            }
        }
Exemple #2
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 #3
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);
        }
Exemple #4
0
        /// <summary>
        /// Initializes <see cref="FileExporter"/>.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary <string, string> settings = Settings;
            const string errorMessage            = "{0} is missing from Settings - Example: exportInterval=5; useReferenceAngle=True; referenceAngleMeasurement=DEVARCHIVE:6; companyTagPrefix=TVA; useNumericQuality=True; inputMeasurementKeys={{FILTER ActiveMeasurements WHERE Device='SHELBY' AND SignalType='FREQ'}}";
            string       setting;
            double       seconds;

            // Load required parameters
            if (!settings.TryGetValue("exportInterval", out setting) || !double.TryParse(setting, out seconds))
            {
                throw new ArgumentException(string.Format(errorMessage, "exportInterval"));
            }

            m_exportInterval      = (int)(seconds * 1000.0D);
            m_lastPublicationTime = 0;

            if (m_exportInterval <= 0)
            {
                throw new ArgumentException("exportInterval should not be 0 - Example: exportInterval=5.5");
            }

            if (InputMeasurementKeys == null || InputMeasurementKeys.Length == 0)
            {
                throw new InvalidOperationException("There are no input measurements defined. You must define \"inputMeasurementKeys\" to define which measurements to export.");
            }

            if (!settings.TryGetValue("useReferenceAngle", out setting))
            {
                throw new ArgumentException(string.Format(errorMessage, "useReferenceAngle"));
            }

            m_useReferenceAngle = setting.ParseBoolean();

            if (m_useReferenceAngle)
            {
                // Reference angle measurement has to be defined if using reference angle
                if (!settings.TryGetValue("referenceAngleMeasurement", out setting))
                {
                    throw new ArgumentException(string.Format(errorMessage, "referenceAngleMeasurement"));
                }

                m_referenceAngleKey = MeasurementKey.Parse(setting);

                // Make sure reference angle is part of input measurement keys collection
                if (!InputMeasurementKeys.Contains(m_referenceAngleKey))
                {
                    InputMeasurementKeys = InputMeasurementKeys.Concat(new[] { m_referenceAngleKey }).ToArray();
                }

                // Make sure sure reference angle key is actually an angle measurement
                SignalType signalType = InputMeasurementKeyTypes[InputMeasurementKeys.IndexOf(key => key == m_referenceAngleKey)];

                if (signalType != SignalType.IPHA && signalType != SignalType.VPHA)
                {
                    throw new InvalidOperationException(string.Format("Specified reference angle measurement key is a {0} signal, not a phase angle.", signalType.GetFormattedName()));
                }
            }

            // Load optional parameters
            if (settings.TryGetValue("companyTagPrefix", out setting))
            {
                m_companyTagPrefix = setting.ToUpper().Trim();
            }
            else
            {
                m_companyTagPrefix = null;
            }

            if (settings.TryGetValue("useNumericQuality", out setting))
            {
                m_useNumericQuality = setting.ParseBoolean();
            }
            else
            {
                m_useNumericQuality = false;
            }

            // Suffix company tag prefix with an underscore if defined
            if (!string.IsNullOrWhiteSpace(m_companyTagPrefix))
            {
                m_companyTagPrefix = m_companyTagPrefix.EnsureEnd('_');
            }

            // Define a default export location - user can override and add multiple locations in config later...
            m_dataExporter = new MultipleDestinationExporter(ConfigurationSection, m_exportInterval);
            m_dataExporter.StatusMessage    += m_dataExporter_StatusMessage;
            m_dataExporter.ProcessException += m_dataExporter_ProcessException;
            m_dataExporter.Initialize(new[] { new ExportDestination(FilePath.GetAbsolutePath(ConfigurationSection + ".txt"), false) });

            // Create new measurement tag name dictionary
            m_measurementTags = new ConcurrentDictionary <MeasurementKey, string>();
            string pointID = "undefined";

            // Lookup point tag name for input measurement in the ActiveMeasurements table
            foreach (MeasurementKey key in InputMeasurementKeys)
            {
                try
                {
                    // Get measurement key as a string
                    pointID = key.ToString();

                    // Lookup measurement key in active measurements table
                    DataRow row = DataSource.Tables["ActiveMeasurements"].Select(string.Format("ID='{0}'", pointID))[0];

                    // Remove invalid symbols that may be in tag name
                    string pointTag = row["PointTag"].ToNonNullString(pointID).Replace('-', '_').Replace(':', '_').ToUpper();

                    // Prefix point tag with company prefix if defined
                    if (!string.IsNullOrWhiteSpace(m_companyTagPrefix) && !pointTag.StartsWith(m_companyTagPrefix))
                    {
                        pointTag = m_companyTagPrefix + pointTag;
                    }

                    m_measurementTags.TryAdd(key, pointTag);
                }
                catch (ThreadAbortException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    OnProcessException(new InvalidOperationException(string.Format("Failed to lookup point tag for measurement [{0}] due to exception: {1}", pointID, ex.Message)));
                }
            }

            // We enable tracking of latest measurements so we can use these values if points are missing - since we are using
            // latest measurement tracking, we sort all incoming points even though most of them will be thrown out...
            TrackLatestMeasurements = true;
        }
Exemple #5
0
        /// <summary>
        /// Initializes <see cref="FileExporter"/>.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary <string, string> settings = Settings;
            const string errorMessage            = "{0} is missing from Settings - Example: exportInterval=5; modelIdentifier=Goslin; referenceAngleMeasurement=DEVARCHIVE:6; inputMeasurementKeys={{FILTER ActiveMeasurements WHERE Device='SHELBY' AND SignalType='FREQ'}}";
            string       setting;
            double       seconds;

            // Load required parameters
            if (!settings.TryGetValue("exportInterval", out setting) || !double.TryParse(setting, out seconds))
            {
                throw new ArgumentException(string.Format(errorMessage, "exportInterval"));
            }

            if (!settings.TryGetValue("fileExportPath", out m_fileExportPath))
            {
                m_fileExportPath = FilePath.GetAbsolutePath("");
            }

            m_exportInterval = (int)(seconds * 1000.0D);

            if (m_exportInterval <= 0)
            {
                throw new ArgumentException("exportInterval should not be 0 - Example: exportInterval=5.5");
            }

            if ((object)InputMeasurementKeys == null || InputMeasurementKeys.Length == 0)
            {
                throw new InvalidOperationException("There are no input measurements defined. You must define \"inputMeasurementKeys\" to define which measurements to export.");
            }

            // Reference angle measurement has to be defined if using reference angle
            if (!settings.TryGetValue("referenceAngleMeasurement", out setting))
            {
                throw new ArgumentException(string.Format(errorMessage, "referenceAngleMeasurement"));
            }

            m_referenceAngleKey = MeasurementKey.Parse(setting);

            // Make sure reference angle is first angle of input measurement keys collection
            InputMeasurementKeys = (new[] { m_referenceAngleKey }).Concat(InputMeasurementKeys).ToArray();

            // Make sure sure reference angle key is actually an angle measurement
            SignalType signalType = InputMeasurementKeyTypes[InputMeasurementKeys.IndexOf(key => key == m_referenceAngleKey)];

            if (signalType != SignalType.IPHA && signalType != SignalType.VPHA)
            {
                throw new InvalidOperationException(string.Format("Specified reference angle measurement key is a {0} signal, not a phase angle.", signalType.GetFormattedName()));
            }

            Comments = settings.TryGetValue("comments", out setting) ? setting : "Comment section---";

            if (!settings.TryGetValue("modelIdentifier", out setting))
            {
                throw new ArgumentException(string.Format(errorMessage, "modelIdentifier"));
            }

            ModelIdentifier = setting;

            // We enable tracking of latest measurements so we can use these values if points are missing - since we are using
            // latest measurement tracking, we sort all incoming points even though most of them will be thrown out...
            TrackLatestMeasurements = true;

            //// Create a new dictionary of base voltages
            //m_baseVoltages = new Dictionary<MeasurementKey, double>();

            StringBuilder header = new StringBuilder();

            //MeasurementKey voltageMagnitudeKey;
            //double baseKV;

            // Write header row
            header.Append("TimeStamp");

            DataTable measurements   = DataSource.Tables["ActiveMeasurements"];
            int       tieLines       = 0;
            bool      referenceAdded = false;

            for (int i = 0; i < InputMeasurementKeys.Length; i++)
            {
                // Lookup measurement key in active measurements table
                DataRow row        = measurements.Select(string.Format("ID='{0}'", InputMeasurementKeys[i]))[0];
                string  deviceName = row["Device"].ToNonNullString("UNDEFINED").ToUpper().Trim();

                if (!referenceAdded && InputMeasurementKeys[i] == m_referenceAngleKey)
                {
                    header.AppendFormat(",Ref. Angle of {0}", deviceName);
                    referenceAdded = true;
                }
                else
                {
                    switch (InputMeasurementKeyTypes[i])
                    {
                    case SignalType.VPHM:
                        header.AppendFormat(",{0} |V|", deviceName);
                        tieLines++;

                        //voltageMagnitudeKey = InputMeasurementKeys[i];

                        //if (settings.TryGetValue(voltageMagnitudeKey + "BaseKV", out setting) && double.TryParse(setting, out baseKV))
                        //{
                        //    m_baseVoltages.Add(voltageMagnitudeKey, baseKV * SI.Kilo);
                        //}
                        //else
                        //{
                        //    int baseKVCode;

                        //    // Second check if base KV can be inferred from device name suffixed KV index
                        //    if (int.TryParse(deviceName[deviceName.Length - 1].ToString(), out baseKVCode) && baseKVCode > 1 && baseKVCode < BaseKVs.Length)
                        //    {
                        //        m_baseVoltages.Add(voltageMagnitudeKey, BaseKVs[baseKVCode]);
                        //    }
                        //    else
                        //    {
                        //        OnStatusMessage("WARNING: Did not find a valid base KV setting for voltage magnitude {0}, assumed 500KV", voltageMagnitudeKey.ToString());
                        //        m_baseVoltages.Add(voltageMagnitudeKey, 500.0D * SI.Kilo);
                        //    }
                        //}
                        break;

                    case SignalType.VPHA:
                        header.AppendFormat(",{0} Voltage Angle", deviceName);
                        break;

                    case SignalType.IPHM:
                        header.AppendFormat(",{0} |I|", deviceName);
                        break;

                    case SignalType.IPHA:
                        header.AppendFormat(",{0} Current Angle", deviceName);
                        break;

                    default:
                        header.AppendFormat(",{0} ??", deviceName);
                        break;
                    }
                }
            }

            string row5 = header.ToString();

            header = new StringBuilder();

            // Add row 1
            header.AppendFormat("Comments: {0}\r\n", Comments);

            // Add row 2
            header.AppendFormat("Model Identifier: {0}\r\n", ModelIdentifier);

            // Add row 3
            header.Append("Datapoints,Tielines,TimeStep");

            if (InputMeasurementKeys.Length - 3 > 0)
            {
                header.Append(new string(',', InputMeasurementKeys.Length - 3));
            }

            header.AppendLine();

            // Add row 4
            header.AppendFormat("{0},{1},{2}", RowCountMarker, tieLines, 1.0D / FramesPerSecond);
            header.AppendLine();

            // Add row 5
            header.AppendLine(row5);

            // Cache header for each file export
            m_header = header.ToString();
        }
Exemple #6
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);
        }