public void UpdateConfiguration()
        {
            const int labelLength = 16;
            Dictionary<string, int> signalCellIndexes = new Dictionary<string, int>();
            ConfigurationCell cell;
            SignalReference signal;
            SignalReference[] signals;
            MeasurementKey measurementKey;
            PhasorType phasorType;
            AnalogType analogType;
            char phaseType;
            string label;
            int order;
            uint scale;
            double offset;

            // Define a protocol independent configuration frame
            m_baseConfigurationFrame = new ConfigurationFrame(m_idCode, DateTime.UtcNow.Ticks, (ushort)base.FramesPerSecond);

            // Define configuration cells (i.e., PMU's that will appear in outgoing data stream)
            foreach (DataRow deviceRow in DataSource.Tables["OutputStreams"].Select(string.Format("StreamID={0}", ID)))
            {
                try
                {
                    // Create a new configuration cell
                    cell = new ConfigurationCell(m_baseConfigurationFrame, ushort.Parse(deviceRow["ID"].ToString()), deviceRow["IsVirtual"].ToNonNullString("false").ParseBoolean());

                    // The base class defaults to floating-point, polar values, derived classes can change
                    cell.PhasorDataFormat = DataFormat.FloatingPoint;
                    cell.PhasorCoordinateFormat = CoordinateFormat.Polar;
                    cell.FrequencyDataFormat = DataFormat.FloatingPoint;
                    cell.AnalogDataFormat = DataFormat.FloatingPoint;

                    cell.IDLabel = deviceRow["Acronym"].ToString().Trim();
                    cell.StationName = deviceRow["Name"].ToString().TruncateRight(cell.MaximumStationNameLength).Trim();

                    // Define all the phasors configured for this device
                    foreach (DataRow phasorRow in DataSource.Tables["OutputStreamPhasors"].Select(string.Format("DeviceID={0}", cell.IDCode), "Order"))
                    {
                        order = int.Parse(phasorRow["Order"].ToNonNullString("0"));
                        label = phasorRow["Label"].ToNonNullString("Phasor " + order).Trim().RemoveDuplicateWhiteSpace().TruncateRight(labelLength - 4);
                        phasorType = phasorRow["PhasorType"].ToNonNullString("V").Trim().ToUpper().StartsWith("V") ? PhasorType.Voltage : PhasorType.Current;
                        phaseType = phasorRow["PhaseType"].ToNonNullString("+").Trim().ToUpper()[0];
                        
                        cell.PhasorDefinitions.Add(
                            new PhasorDefinition(
                                cell,
                                GeneratePhasorLabel(label, phaseType, phasorType),
                                phasorType,
                                null));
                    }

                    // Add frequency definition
                    label = string.Format("{0} Freq", cell.IDLabel.TruncateRight(labelLength - 5)).Trim();
                    cell.FrequencyDefinition = new FrequencyDefinition(cell, label);
                    
                    // Optionally define all the analogs configured for this device
                    if (DataSource.Tables.Contains("OutputStreamAnalogs"))
                    {
                        foreach (DataRow analogRow in DataSource.Tables["OutputStreamAnalogs"].Select(string.Format("DeviceID={0}", cell.IDCode), "Order"))
                        {
                            order = int.Parse(analogRow["Order"].ToNonNullString("0"));
                            label = analogRow["Label"].ToNonNullString("Analog " + order).Trim().RemoveDuplicateWhiteSpace().TruncateRight(labelLength);
                            scale = uint.Parse(analogRow["Scale"].ToNonNullString("1"));
                            offset = double.Parse(analogRow["Offset"].ToNonNullString("0.0"));
                            analogType = analogRow["AnalogType"].ToNonNullString("SinglePointOnWave").ConvertToType<AnalogType>();

                            cell.AnalogDefinitions.Add(
                                new AnalogDefinition(
                                    cell,
                                    label,
                                    scale,
                                    offset,
                                    analogType));
                        }
                    }

                    // Optionally define all the digitals configured for this device
                    if (DataSource.Tables.Contains("OutputStreamDigitals"))
                    {
                        foreach (DataRow digitalRow in DataSource.Tables["OutputStreamDigitals"].Select(string.Format("DeviceID={0}", cell.IDCode), "Order"))
                        {
                            order = int.Parse(digitalRow["Order"].ToNonNullString("0"));
                            label = digitalRow["Label"].ToNonNullString("Digital " + order).Trim().RemoveDuplicateWhiteSpace().TruncateRight(labelLength);

                            cell.DigitalDefinitions.Add(
                                new DigitalDefinition(
                                    cell,
                                    label));
                        }
                    }

                    m_baseConfigurationFrame.Cells.Add(cell);
                }
                catch (Exception ex)
                {
                    OnProcessException(new InvalidOperationException(string.Format("Failed to define output stream device \"{0}\" due to exception: {1}", deviceRow["Acronym"].ToString().Trim(), ex.Message), ex));
                }
            }

            OnStatusMessage("Defined {0} output stream devices...", m_baseConfigurationFrame.Cells.Count);

            // Create a new signal reference dictionary indexed on measurement keys
            m_signalReferences = new Dictionary<MeasurementKey, SignalReference[]>();
            
            // Define measurement to signals cross reference dictionary
            foreach (DataRow measurementRow in DataSource.Tables["OutputStreamMeasurements"].Select(string.Format("StreamID={0}", ID)))
            {
                try
                {
                    // Create a new signal reference
                    signal = new SignalReference(measurementRow["SignalReference"].ToString());

                    // Lookup cell index by acronym - doing this work upfront will save a huge amount
                    // of work during primary measurement sorting
                    if (!signalCellIndexes.TryGetValue(signal.Acronym, out signal.CellIndex))
                    {
                        // We cache these indicies locally to speed up initialization as we'll be
                        // requesting them for the same devices over and over
                        signal.CellIndex = m_configurationFrame.Cells.IndexOfIDLabel(signal.Acronym);
                        signalCellIndexes.Add(signal.Acronym, signal.CellIndex);
                    }

                    // Define measurement key
                    measurementKey = new MeasurementKey(uint.Parse(measurementRow["PointID"].ToString()), measurementRow["Historian"].ToString());

                    // It is possible, but not as common, that a measurement will have multiple destinations
                    // within an outgoing data stream frame, hence the following
                    if (m_signalReferences.TryGetValue(measurementKey, out signals))
                    {
                        // Add a new signal to existing collection
                        List<SignalReference> signalList = new List<SignalReference>(signals);
                        signalList.Add(signal);
                        m_signalReferences[measurementKey] = signalList.ToArray();
                    }
                    else
                    {
                        // Add new signal to new collection
                        signals = new SignalReference[1];
                        signals[0] = signal;
                        m_signalReferences.Add(measurementKey, signals);
                    }
                }
                catch (Exception ex)
                {
                    OnProcessException(new InvalidOperationException(string.Format("Failed to associate measurement key to signal reference \"{0}\" due to exception: {1}", measurementRow["SignalReference"].ToString().Trim(), ex.Message), ex));
                }
            }

            // Assign action adapter input measurement keys
            InputMeasurementKeys = m_signalReferences.Keys.ToArray();

            // Create a new protocol specific configuration frame
            m_configurationFrame = CreateNewConfigurationFrame(m_baseConfigurationFrame);

            // Cache new protocol specific configuration frame
            CacheConfigurationFrame(m_configurationFrame);
        }
Exemple #2
0
 /// <summary>
 /// Creates a new <see cref="FrequencyDefinition"/> from specified parameters.
 /// </summary>
 /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="FrequencyDefinition"/>.</param>
 /// <param name="label">The label of this <see cref="FrequencyDefinition"/>.</param>
 public FrequencyDefinition(ConfigurationCell parent, string label)
     : base(parent, label, 1000, 100, 0.0D)
 {
 }
        private void CopyDevice(ConfigurationCell sourceDevice)
        {
            // Create a new configuration cell to hold copied information
            ConfigurationCell copiedDevice = new ConfigurationCell(m_configurationFrame, 0);

            copiedDevice.IDCode = (ushort)m_configurationFrame.Cells.Count;
            copiedDevice.StationName = "Device " + (copiedDevice.IDCode + 1);

            // Create equivalent derived phasor definitions
            foreach (PhasorDefinition sourcePhasor in sourceDevice.PhasorDefinitions)
            {
                copiedDevice.PhasorDefinitions.Add(new PhasorDefinition(copiedDevice, sourcePhasor.Label, sourcePhasor.ScalingValue, sourcePhasor.PhasorType, null));
            }

            // Create equivalent dervied frequency definition
            IFrequencyDefinition sourceFrequency = sourceDevice.FrequencyDefinition;

            if (sourceFrequency != null)
                copiedDevice.FrequencyDefinition = new FrequencyDefinition(copiedDevice, sourceFrequency.Label);

            // Create equivalent dervied analog definitions (assuming analog type = SinglePointOnWave)
            foreach (AnalogDefinition sourceAnalog in sourceDevice.AnalogDefinitions)
            {
                copiedDevice.AnalogDefinitions.Add(new AnalogDefinition(copiedDevice, sourceAnalog.Label, sourceAnalog.ScalingValue, sourceAnalog.AnalogType));
            }

            // Create equivalent dervied digital definitions
            foreach (DigitalDefinition sourceDigital in sourceDevice.DigitalDefinitions)
            {
                copiedDevice.DigitalDefinitions.Add(new DigitalDefinition(copiedDevice, sourceDigital.Label, sourceDigital.MaskValue));
            }

            // Add new copied cell to the list and select it
            m_configurationFrame.Cells.Add(copiedDevice);
            listBoxDevices.SelectedIndex = (m_configurationFrame.Cells.Count - 1);
        }
        private void buttonDeviceAdd_Click(object sender, RoutedEventArgs e)
        {
            ConfigurationCell device = new ConfigurationCell(m_configurationFrame, 0);
            device.IDCode = (ushort)m_configurationFrame.Cells.Count;
            device.StationName = "Device " + (device.IDCode + 1);

            m_configurationFrame.Cells.Add(device);
            listBoxDevices.SelectedIndex = (m_configurationFrame.Cells.Count - 1);
        }
Exemple #5
0
 /// <summary>
 /// Creates a new <see cref="AnalogDefinition"/> from specified parameters.
 /// </summary>
 /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="AnalogDefinition"/>.</param>
 /// <param name="label">The label of this <see cref="AnalogDefinition"/>.</param>
 /// <param name="scale">The integer scaling value of this <see cref="AnalogDefinition"/>.</param>
 /// <param name="offset">The offset of this <see cref="AnalogDefinition"/>.</param>
 /// <param name="type">The <see cref="AnalogType"/> of this <see cref="AnalogDefinition"/>.</param>
 public AnalogDefinition(ConfigurationCell parent, string label, uint scale, double offset, AnalogType type)
     : base(parent, label, scale, offset, type)
 {
 }
        /// <summary>
        /// Intializes <see cref="PhasorMeasurementMapper"/>.
        /// </summary>
        public override void Initialize()
        {
            Dictionary<string, string> settings = Settings;
            ConfigurationCell definedDevice;
            string setting, signalReference;

            // Load required mapper specific connection parameters
            m_isConcentrator = settings["isConcentrator"].ParseBoolean();
            m_accessID = ushort.Parse(settings["accessID"].ToString());
            
            // Load optional mapper specific connection parameters
            if (settings.TryGetValue("virtual", out setting))
                m_isVirtual = setting.ParseBoolean();
            else
                m_isVirtual = false;

            if (settings.TryGetValue("timeZone", out setting))
                m_timezone = TimeZoneInfo.FindSystemTimeZoneById(setting);
            else
                m_timezone = TimeZoneInfo.Utc;

            if (settings.TryGetValue("timeAdjustmentTicks", out setting))
                m_timeAdjustmentTicks = long.Parse(setting);
            else
                m_timeAdjustmentTicks = 0;

            if (settings.TryGetValue("dataLossInterval", out setting))
                m_dataStreamMonitor.Interval = double.Parse(setting) * 1000.0D;
            else
                m_dataStreamMonitor.Interval = 35000.0D;

            // Create a new phasor protocol frame parser for non-virtual connections
            if (!m_isVirtual)
            {
                MultiProtocolFrameParser frameParser = new MultiProtocolFrameParser();

                // Most of the parameters in the connection string will be for the frame parser so we provide all of them,
                // other parameters will simply be ignored
                frameParser.ConnectionString = ConnectionString;

                // For captured data simulations we will inject a simulated timestamp and auto-repeat file stream...
                if (frameParser.TransportProtocol == TransportProtocol.File)
                {
                    if (settings.TryGetValue("definedFrameRate", out setting))
                        frameParser.DefinedFrameRate = 1.0D / double.Parse(setting);
                    else
                        frameParser.DefinedFrameRate = 1.0D / 30.0D;

                    if (settings.TryGetValue("simulateTimestamp", out setting))
                        frameParser.InjectSimulatedTimestamp = setting.ParseBoolean();
                    else
                        frameParser.InjectSimulatedTimestamp = true;

                    if (settings.TryGetValue("autoRepeatFile", out setting))
                        frameParser.AutoRepeatCapturedPlayback = setting.ParseBoolean();
                    else
                        frameParser.AutoRepeatCapturedPlayback = true;
                }

                // Provide access ID to frame parser as this may be necessary to make a phasor connection
                frameParser.DeviceID = m_accessID;
                frameParser.SourceName = Name;

                // Assign reference to frame parser and attach to needed events
                this.FrameParser = frameParser;
            }

            // Load device list for this mapper connection
            m_definedDevices = new Dictionary<ushort, ConfigurationCell>();

            if (m_isConcentrator)
            {
                StringBuilder deviceStatus = new StringBuilder();
                int index = 0;

                deviceStatus.AppendLine();
                deviceStatus.AppendLine();
                deviceStatus.Append("Loading expected concentrator device list...");
                deviceStatus.AppendLine();
                deviceStatus.AppendLine();

                // Making a connection to a concentrator that can support multiple devices
                foreach (DataRow row in DataSource.Tables["ActiveConcentratorDevices"].Select(string.Format("Acronym='{0}'", Name)))
                {
                    definedDevice = new ConfigurationCell(ushort.Parse(row["AccessID"].ToString()), m_isVirtual);
                    definedDevice.IDLabel = row["Acronym"].ToString();
                    definedDevice.Tag = uint.Parse(row["ID"].ToString());
                    m_definedDevices.Add(definedDevice.IDCode, definedDevice);

                    // Create status display string for expected device
                    deviceStatus.Append("   Device ");
                    deviceStatus.Append((index++).ToString("00"));
                    deviceStatus.Append(": ");
                    deviceStatus.Append(definedDevice.IDLabel);
                    deviceStatus.Append(" (");
                    deviceStatus.Append(definedDevice.IDCode);
                    deviceStatus.Append(')');
                    deviceStatus.AppendLine();
                }

                OnStatusMessage(deviceStatus.ToString());
            }
            else
            {
                // Making a connection to a single device
                definedDevice = new ConfigurationCell(m_accessID, m_isVirtual);
                definedDevice.IDLabel = Name;
                definedDevice.Tag = ID;
                m_definedDevices.Add(definedDevice.IDCode, definedDevice);
            }

            // Load active device measurements for this mapper connection
            m_definedMeasurements = new Dictionary<string, IMeasurement>();

            foreach (DataRow row in DataSource.Tables["ActiveDeviceMeasurements"].Select(string.Format("Acronym='{0}'", Name)))
            {
                signalReference = row["SignalReference"].ToString();

                if (!string.IsNullOrEmpty(signalReference))
                {
                    try
                    {
                        m_definedMeasurements.Add(signalReference, new Measurement(
                            uint.Parse(row["PointID"].ToString()),
                            row["Historian"].ToString(),
                            signalReference,
                            double.Parse(row["Adder"].ToString()),
                            double.Parse(row["Multiplier"].ToString())));
                    }
                    catch (Exception ex)
                    {
                        OnProcessException(new InvalidOperationException(string.Format("Failed to load signal reference \"{0}\" due to exception: {1}", signalReference, ex.Message), ex));
                    }
                }
            }

            OnStatusMessage("Loaded {0} active device measurements...", m_definedMeasurements.Count);
        }