Example #1
0
        // Static Methods

        /// <summary>
        /// Creates a new IEEE C37.118 <see cref="ConfigurationFrame2"/> based on provided protocol independent <paramref name="baseConfigurationFrame"/>.
        /// </summary>
        /// <param name="baseConfigurationFrame">Protocol independent <see cref="GSF.PhasorProtocols.Anonymous.ConfigurationFrame"/>.</param>
        /// <param name="timeBase">Timebase to use for fraction second resolution.</param>
        /// <param name="nominalFrequency">The nominal <see cref="LineFrequency"/> to use for the new <see cref="ConfigurationFrame2"/></param>.
        /// <returns>A new IEEE C37.118 <see cref="ConfigurationFrame2"/>.</returns>
        public static ConfigurationFrame2 CreateConfigurationFrame(ConfigurationFrame baseConfigurationFrame, uint timeBase, LineFrequency nominalFrequency)
        {
            // Create a new IEEE C37.118 configuration frame 2 using base configuration
            ConfigurationFrame2 configurationFrame = new ConfigurationFrame2(timeBase, baseConfigurationFrame.IDCode, DateTime.UtcNow.Ticks, baseConfigurationFrame.FrameRate);

            foreach (GSF.PhasorProtocols.Anonymous.ConfigurationCell baseCell in baseConfigurationFrame.Cells)
            {
                // Create a new IEEE C37.118 configuration cell (i.e., a PMU configuration)
                ConfigurationCell newCell = new ConfigurationCell(configurationFrame, baseCell.IDCode, nominalFrequency)
                {
                    // Update other cell level attributes
                    StationName            = baseCell.StationName,
                    IDLabel                = baseCell.IDLabel,
                    PhasorDataFormat       = baseCell.PhasorDataFormat,
                    PhasorCoordinateFormat = baseCell.PhasorCoordinateFormat,
                    FrequencyDataFormat    = baseCell.FrequencyDataFormat,
                    AnalogDataFormat       = baseCell.AnalogDataFormat
                };

                // Add phasor definitions
                foreach (IPhasorDefinition phasorDefinition in baseCell.PhasorDefinitions)
                {
                    newCell.PhasorDefinitions.Add(new PhasorDefinition(newCell, phasorDefinition.Label, phasorDefinition.ScalingValue, phasorDefinition.Offset, phasorDefinition.PhasorType, null));
                }

                // Add frequency definition
                newCell.FrequencyDefinition = new FrequencyDefinition(newCell, baseCell.FrequencyDefinition.Label);

                // Add analog definitions
                foreach (IAnalogDefinition analogDefinition in baseCell.AnalogDefinitions)
                {
                    newCell.AnalogDefinitions.Add(new AnalogDefinition(newCell, analogDefinition.Label, analogDefinition.ScalingValue, analogDefinition.Offset, analogDefinition.AnalogType));
                }

                // Add digital definitions
                foreach (IDigitalDefinition digitalDefinition in baseCell.DigitalDefinitions)
                {
                    // Attempt to derive user defined mask value if available
                    DigitalDefinition anonymousDigitalDefinition = digitalDefinition as DigitalDefinition;

                    uint maskValue = anonymousDigitalDefinition?.MaskValue ?? 0U;

                    newCell.DigitalDefinitions.Add(new GSF.PhasorProtocols.IEEEC37_118.DigitalDefinition(newCell, digitalDefinition.Label, maskValue.LowWord(), maskValue.HighWord()));
                }

                // Add new PMU configuration (cell) to protocol specific configuration frame
                configurationFrame.Cells.Add(newCell);
            }

            return(configurationFrame);
        }
        public bool TryFindTargetConfigurationFrame(System.Guid signalID, out ConfigurationFrame targetFrame)
        {
            guid_t tempsignalID = Common.ParseGuid(signalID.ToByteArray(), true);

            targetFrame = new ConfigurationFrame();
            {
                bool ret = CommonPINVOKE.SubscriberInstanceBase_TryFindTargetConfigurationFrame(swigCPtr, guid_t.getCPtr(tempsignalID), ConfigurationFrame.getCPtr(targetFrame));
                if (CommonPINVOKE.SWIGPendingException.Pending)
                {
                    throw CommonPINVOKE.SWIGPendingException.Retrieve();
                }
                return(ret);
            }
        }
Example #3
0
        /// <summary>
        /// Creates a new IEC 61850-90-5 specific <see cref="DataFrame"/> for the given <paramref name="timestamp"/>.
        /// </summary>
        /// <param name="timestamp">Timestamp for new <see cref="IFrame"/> in <see cref="Ticks"/>.</param>
        /// <param name="configurationFrame">Associated <see cref="ConfigurationFrame"/> for the new <see cref="DataFrame"/>.</param>
        /// <param name="msvID">MSVID to use for <see cref="DataFrame"/>.</param>
        /// <param name="asduCount">ASDU count.</param>
        /// <param name="asduImages">Concentrator's ASDU image cache.</param>
        /// <param name="configurationRevision">Configuration revision.</param>
        /// <returns>New IEC 61850-90-5 <see cref="DataFrame"/> at given <paramref name="timestamp"/>.</returns>
        public static DataFrame CreateDataFrame(Ticks timestamp, ConfigurationFrame configurationFrame, string msvID, int asduCount, byte[][] asduImages, uint configurationRevision)
        {
            // We create a new IEC 61850-90-5 data frame based on current configuration frame
            DataFrame dataFrame = new DataFrame(timestamp, configurationFrame, msvID, asduCount, asduImages, configurationRevision);

            foreach (ConfigurationCell configurationCell in configurationFrame.Cells)
            {
                // Create a new IEC 61850-90-5 data cell (i.e., a PMU entry for this frame)
                DataCell dataCell = new DataCell(dataFrame, configurationCell, true);

                // Add data cell to the frame
                dataFrame.Cells.Add(dataCell);
            }

            return(dataFrame);
        }
Example #4
0
        private static void SaveDeviceRecords(ImportParameters importParams, ConfigurationCell configCell, Device device)
        {
            ConfigurationFrame            configFrame      = importParams.TargetConfigFrame;
            AdoDataConnection             connection       = importParams.Connection;
            TableOperations <Measurement> measurementTable = new(connection);

            // Add frequency
            SaveFixedMeasurement(importParams, s_deviceSignalTypes["FREQ"], device, measurementTable);

            // Add dF/dt
            SaveFixedMeasurement(importParams, s_deviceSignalTypes["DFDT"], device, measurementTable);

            // Add status flags
            SaveFixedMeasurement(importParams, s_deviceSignalTypes["FLAG"], device, measurementTable);

            // Add analogs
            SignalType analogSignalType = s_deviceSignalTypes["ALOG"];

            for (int i = 0; i < configCell.AnalogDefinitions.Count; i++)
            {
                if (configCell.AnalogDefinitions[i] is not AnalogDefinition analogDefinition)
                {
                    continue;
                }

                int    index = i + 1;
                string oldSignalReference = $"{device.OldAcronym}-{analogSignalType.Suffix}{index}";
                string newSignalReference = $"{device.Acronym}-{analogSignalType.Suffix}{index}";

                // Query existing measurement record for specified signal reference - function will create a new blank measurement record if one does not exist
                Measurement measurement = measurementTable.QueryMeasurement(oldSignalReference);
                string      pointTag    = importParams.CreateIndexedPointTag(device.Acronym, analogSignalType.Acronym, index);

                measurement.DeviceID        = device.ID;
                measurement.HistorianID     = configFrame.HistorianID;
                measurement.PointTag        = pointTag;
                measurement.AlternateTag    = analogDefinition.Label;
                measurement.Description     = $"{device.Acronym} Analog Value {index} {analogDefinition.AnalogType}: {analogDefinition.Label}{(string.IsNullOrWhiteSpace(analogDefinition.Description) ? "" : $" - {analogDefinition.Description}")}";
                measurement.SignalReference = newSignalReference;
                measurement.SignalTypeID    = analogSignalType.ID;
                measurement.Internal        = true;
                measurement.Enabled         = true;

                measurementTable.AddNewOrUpdateMeasurement(measurement);
            }
Example #5
0
        /// <summary>
        /// Creates a new BPA PDCstream specific <see cref="DataFrame"/> for the given <paramref name="timestamp"/>.
        /// </summary>
        /// <param name="timestamp">Timestamp for new <see cref="IFrame"/> in <see cref="Ticks"/>.</param>
        /// <param name="configurationFrame">Associated <see cref="ConfigurationFrame"/> for the new <see cref="DataFrame"/>.</param>
        /// <returns>New IEEE C37.118 <see cref="DataFrame"/> at given <paramref name="timestamp"/>.</returns>
        public static DataFrame CreateDataFrame(Ticks timestamp, ConfigurationFrame configurationFrame)
        {
            // We create a new BPA PDCstream data frame based on current configuration frame
            ushort sampleNumber = (ushort)((timestamp.DistanceBeyondSecond() + 1.0D) / (double)configurationFrame.TicksPerFrame);

            DataFrame dataFrame = new DataFrame(timestamp, configurationFrame, 1, sampleNumber);

            foreach (ConfigurationCell configurationCell in configurationFrame.Cells)
            {
                // Create a new BPA PDCstream data cell (i.e., a PMU entry for this frame)
                DataCell dataCell = new DataCell(dataFrame, configurationCell, true);

                // Add data cell to the frame
                dataFrame.Cells.Add(dataCell);
            }

            return(dataFrame);
        }
Example #6
0
        private static void UpdatePMUDevices(ImportParameters importParams, Device parentDevice)
        {
            ConfigurationFrame configFrame = importParams.TargetConfigFrame;

            foreach (IConfigurationCell cell in configFrame.Cells)
            {
                if (cell is ConfigurationCell configCell)
                {
                    if (configCell.Delete)
                    {
                        DeletePMUDevice(importParams, configCell, parentDevice);
                    }
                    else
                    {
                        SavePMUDevice(importParams, configCell, parentDevice);
                    }
                }
            }
        }
Example #7
0
        /// <summary>
        /// Creates a new IEEE C37.118 specific <see cref="IConfigurationFrame"/> based on provided protocol independent <paramref name="baseConfigurationFrame"/>.
        /// </summary>
        /// <param name="baseConfigurationFrame">Protocol independent <see cref="GSF.PhasorProtocols.Anonymous.ConfigurationFrame"/>.</param>
        /// <returns>A new IEEE C37.118 specific <see cref="IConfigurationFrame"/>.</returns>
        protected override IConfigurationFrame CreateNewConfigurationFrame(ConfigurationFrame baseConfigurationFrame)
        {
            // Create a new IEEE C37.118 configuration frame 2 using base configuration
            ConfigurationFrame2 configurationFrame = CreateConfigurationFrame(baseConfigurationFrame, m_timeBase, base.NominalFrequency);

            // After system has started any subsequent changes in configuration get indicated in the outgoing data stream
            bool configurationChanged = (object)m_configurationFrame != null;

            // Cache new IEEE C7.118 for later use
            Interlocked.Exchange(ref m_configurationFrame, configurationFrame);

            if (configurationChanged)
            {
                // Start adding configuration changed notification flag to data cells
                m_configurationChanged  = true;
                m_notificationStartTime = DateTime.UtcNow.Ticks;
            }

            return(configurationFrame);
        }
Example #8
0
        /// <summary>
        /// Creates a new IEC 61850-90-5 specific <see cref="IConfigurationFrame"/> based on provided protocol independent <paramref name="baseConfigurationFrame"/>.
        /// </summary>
        /// <param name="baseConfigurationFrame">Protocol independent <see cref="GSF.PhasorProtocols.Anonymous.ConfigurationFrame"/>.</param>
        /// <returns>A new IEC 61850-90-5 specific <see cref="IConfigurationFrame"/>.</returns>
        /// <remarks>
        /// This operation provides a common IEEE C37.118 style frame for IEC 61850-90-5 implementations
        /// that may not otherwise support native IEC 61850 configuration queries.
        /// </remarks>
        protected override IConfigurationFrame CreateNewConfigurationFrame(GSF.PhasorProtocols.Anonymous.ConfigurationFrame baseConfigurationFrame)
        {
            // Create a new IEC 61850-90-5 configuration frame 2 using base configuration
            ConfigurationFrame configurationFrame = CreateConfigurationFrame(baseConfigurationFrame, TimeBase, NominalFrequency);

            // After system has started any subsequent changes in configuration get indicated in the outgoing data stream
            bool configurationChanged = m_configurationFrame != null;

            // Cache new configuration frame for later use
            Interlocked.Exchange(ref m_configurationFrame, configurationFrame);
            m_configurationRevision++;

            if (configurationChanged)
            {
                // Start adding configuration changed notification flag to data cells
                m_configurationChanged  = true;
                m_notificationStartTime = DateTime.UtcNow.Ticks;
            }

            return(configurationFrame);
        }
Example #9
0
        public ConfigurationFrame LoadConfigurationFrame(string sourceData)
        {
            IConfigurationFrame sourceFrame = GetConfigurationFrame(sourceData, out string connectionString);

            if (sourceFrame is ConfigurationErrorFrame)
            {
                return(new ConfigurationFrame());
            }

            // Create a new simple concrete configuration frame for JSON serialization converted from equivalent configuration information
            int protocolID = 0, deviceID = 0, phasorID = -1; // Start phasor ID's at less than -1 since associated voltage == -1 is reserved as unselected

            if (!string.IsNullOrWhiteSpace(connectionString))
            {
                Dictionary <string, string> settings = connectionString.ParseKeyValuePairs();
                protocolID = GetProtocolID(settings["phasorProtocol"]);
            }

            ConfigurationFrame derivedFrame = new ConfigurationFrame
            {
                IDCode           = sourceFrame.IDCode,
                FrameRate        = sourceFrame.FrameRate,
                ConnectionString = connectionString,
                ProtocolID       = protocolID
            };

            foreach (IConfigurationCell sourceCell in sourceFrame.Cells)
            {
                // Create new derived configuration cell
                ConfigurationCell derivedCell = new ConfigurationCell
                {
                    ID          = --deviceID, // Provide a negative index so any database lookup will return null
                    ParentID    = null,
                    IDCode      = sourceCell.IDCode,
                    StationName = sourceCell.StationName,
                    IDLabel     = sourceCell.IDLabel
                };

                // Create equivalent derived frequency definition
                IFrequencyDefinition sourceFrequency = sourceCell.FrequencyDefinition;

                if (sourceFrequency != null)
                {
                    derivedCell.FrequencyDefinition = new FrequencyDefinition {
                        Label = sourceFrequency.Label
                    }
                }
                ;

                int sourceIndex = 0;

                // Create equivalent derived phasor definitions
                foreach (IPhasorDefinition sourcePhasor in sourceCell.PhasorDefinitions)
                {
                    derivedCell.PhasorDefinitions.Add(new PhasorDefinition {
                        ID = --phasorID, Label = sourcePhasor.Label, PhasorType = sourcePhasor.PhasorType.ToString(), SourceIndex = ++sourceIndex
                    });
                }

                // Create equivalent derived analog definitions (assuming analog type = SinglePointOnWave)
                foreach (IAnalogDefinition sourceAnalog in sourceCell.AnalogDefinitions)
                {
                    derivedCell.AnalogDefinitions.Add(new AnalogDefinition {
                        Label = sourceAnalog.Label, AnalogType = sourceAnalog.AnalogType.ToString()
                    });
                }

                // Create equivalent derived digital definitions
                foreach (IDigitalDefinition sourceDigital in sourceCell.DigitalDefinitions)
                {
                    derivedCell.DigitalDefinitions.Add(new DigitalDefinition {
                        Label = sourceDigital.Label
                    });
                }

                // Add cell to frame
                derivedFrame.Cells.Add(derivedCell);
            }

            derivedFrame.IsConcentrator = derivedFrame.Cells.Count > 1;

            return(derivedFrame);
        }
Example #10
0
        public static bool TryGetMeasurementMetdataFromConfigurationFrame(System.Guid signalID, ConfigurationFrame sourceFrame, out MeasurementMetadata measurementMetadata)
        {
            guid_t tempsignalID = Common.ParseGuid(signalID.ToByteArray(), true);

            measurementMetadata = new MeasurementMetadata();
            {
                bool ret = CommonPINVOKE.SubscriberInstanceBase_TryGetMeasurementMetdataFromConfigurationFrame(guid_t.getCPtr(tempsignalID), ConfigurationFrame.getCPtr(sourceFrame), MeasurementMetadata.getCPtr(measurementMetadata));
                if (CommonPINVOKE.SWIGPendingException.Pending)
                {
                    throw CommonPINVOKE.SWIGPendingException.Retrieve();
                }
                return(ret);
            }
        }
Example #11
0
        public ConfigurationFrame ExtractConfigurationFrame(int deviceID)
        {
            Device device = QueryDeviceByID(deviceID);

            if (device.ID == 0)
            {
                return(new ConfigurationFrame());
            }

            ConfigurationFrame derivedFrame = new ConfigurationFrame
            {
                IDCode           = (ushort)device.AccessID,
                StationName      = device.Name,
                IDLabel          = device.Acronym,
                ConnectionString = device.ConnectionString,
                ProtocolID       = device.ProtocolID ?? IeeeC37_118ProtocolID
            };

            if ((device.FramesPerSecond ?? 0) > 0)
            {
                derivedFrame.FrameRate = (ushort)device.FramesPerSecond.GetValueOrDefault();
            }

            if (device.ParentID == null)
            {
                IEnumerable <Device> devices = QueryChildDevices(deviceID);

                foreach (Device childDevice in devices)
                {
                    // Create new configuration cell
                    ConfigurationCell derivedCell = new ConfigurationCell
                    {
                        ID          = childDevice.ID,
                        ParentID    = device.ID,
                        IDCode      = (ushort)childDevice.AccessID,
                        StationName = childDevice.Name,
                        IDLabel     = childDevice.Acronym
                    };

                    derivedCell.FrequencyDefinition = new FrequencyDefinition {
                        Label = "Frequency"
                    };

                    // Extract phasor definitions
                    foreach (Phasor phasor in QueryPhasorsForDevice(childDevice.ID))
                    {
                        derivedCell.PhasorDefinitions.Add(new PhasorDefinition {
                            ID = phasor.ID, Label = phasor.Label, PhasorType = phasor.Type == 'V' ? "Voltage" : "Current", Phase = phasor.Phase.ToString(), DestinationPhasorID = phasor.DestinationPhasorID, NominalVoltage = phasor.BaseKV, SourceIndex = phasor.SourceIndex
                        });
                    }

                    // Add cell to frame
                    derivedFrame.Cells.Add(derivedCell);
                }

                if (derivedFrame.Cells.Count > 0)
                {
                    derivedFrame.IsConcentrator = true;
                }
                else
                {
                    // This is a directly connected device
                    derivedFrame.IsConcentrator = false;

                    ConfigurationCell derivedCell = new ConfigurationCell
                    {
                        ID          = device.ID,
                        ParentID    = null,
                        IDCode      = derivedFrame.IDCode,
                        StationName = device.Name,
                        IDLabel     = device.Acronym
                    };

                    derivedCell.FrequencyDefinition = new FrequencyDefinition {
                        Label = "Frequency"
                    };

                    // Extract phasor definitions
                    foreach (Phasor phasor in QueryPhasorsForDevice(device.ID))
                    {
                        derivedCell.PhasorDefinitions.Add(new PhasorDefinition {
                            ID = phasor.ID, Label = phasor.Label, PhasorType = phasor.Type == 'V' ? "Voltage" : "Current", Phase = phasor.Phase.ToString(), DestinationPhasorID = phasor.DestinationPhasorID, NominalVoltage = phasor.BaseKV, SourceIndex = phasor.SourceIndex
                        });
                    }

                    // Add cell to frame
                    derivedFrame.Cells.Add(derivedCell);
                }
            }
            else
            {
                derivedFrame.IsConcentrator = true;

                // Create new configuration cell
                ConfigurationCell derivedCell = new ConfigurationCell
                {
                    ID          = device.ID,
                    ParentID    = null,
                    IDCode      = (ushort)device.AccessID,
                    StationName = device.Name,
                    IDLabel     = device.Acronym
                };

                derivedCell.FrequencyDefinition = new FrequencyDefinition {
                    Label = "Frequency"
                };

                // Extract phasor definitions
                foreach (Phasor phasor in QueryPhasorsForDevice(device.ID))
                {
                    derivedCell.PhasorDefinitions.Add(new PhasorDefinition {
                        ID = phasor.ID, Label = phasor.Label, PhasorType = phasor.Type == 'V' ? "Voltage" : "Current", Phase = phasor.Phase.ToString(), DestinationPhasorID = phasor.DestinationPhasorID, NominalVoltage = phasor.BaseKV, SourceIndex = phasor.SourceIndex
                    });
                }

                // Add cell to frame
                derivedFrame.Cells.Add(derivedCell);
            }

            return(derivedFrame);
        }
Example #12
0
 public bool TryGetConfigurationFrame(string deviceAcronym, out ConfigurationFrame configurationFrame)
 {
     configurationFrame = new ConfigurationFrame();
     {
         bool ret = CommonPINVOKE.SubscriberInstanceBase_TryGetConfigurationFrame(swigCPtr, deviceAcronym, ConfigurationFrame.getCPtr(configurationFrame));
         if (CommonPINVOKE.SWIGPendingException.Pending)
         {
             throw CommonPINVOKE.SWIGPendingException.Retrieve();
         }
         return(ret);
     }
 }
Example #13
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ConfigurationFrame obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
Example #14
0
        public ConfigurationFrame LoadConfigurationFrame(string sourceData)
        {
            string connectionString = "";

            IConfigurationFrame GetConfigurationFrame()
            {
                try
                {
                    ConnectionSettings connectionSettings;
                    SoapFormatter      formatter = new SoapFormatter
                    {
                        AssemblyFormat = FormatterAssemblyStyle.Simple,
                        TypeFormat     = FormatterTypeStyle.TypesWhenNeeded,
                        Binder         = Serialization.LegacyBinder
                    };

                    using (MemoryStream source = new MemoryStream(Encoding.UTF8.GetBytes(sourceData)))
                        connectionSettings = formatter.Deserialize(source) as ConnectionSettings;

                    if ((object)connectionSettings != null)
                    {
                        connectionString = connectionSettings.ConnectionString;

                        Dictionary <string, string> connectionStringKeyValues = connectionString.ParseKeyValuePairs();

                        connectionString = "transportProtocol=" + connectionSettings.TransportProtocol + ";" + connectionStringKeyValues.JoinKeyValuePairs();

                        if ((object)connectionSettings.ConnectionParameters != null)
                        {
                            switch (connectionSettings.PhasorProtocol)
                            {
                            case PhasorProtocol.BPAPDCstream:
                                GSF.PhasorProtocols.BPAPDCstream.ConnectionParameters bpaParameters = connectionSettings.ConnectionParameters as GSF.PhasorProtocols.BPAPDCstream.ConnectionParameters;
                                if ((object)bpaParameters != null)
                                {
                                    connectionString += "; iniFileName=" + bpaParameters.ConfigurationFileName + "; refreshConfigFileOnChange=" + bpaParameters.RefreshConfigurationFileOnChange + "; parseWordCountFromByte=" + bpaParameters.ParseWordCountFromByte;
                                }
                                break;

                            case PhasorProtocol.FNET:
                                GSF.PhasorProtocols.FNET.ConnectionParameters fnetParameters = connectionSettings.ConnectionParameters as GSF.PhasorProtocols.FNET.ConnectionParameters;
                                if ((object)fnetParameters != null)
                                {
                                    connectionString += "; timeOffset=" + fnetParameters.TimeOffset + "; stationName=" + fnetParameters.StationName + "; frameRate=" + fnetParameters.FrameRate + "; nominalFrequency=" + (int)fnetParameters.NominalFrequency;
                                }
                                break;

                            case PhasorProtocol.SelFastMessage:
                                GSF.PhasorProtocols.SelFastMessage.ConnectionParameters selParameters = connectionSettings.ConnectionParameters as GSF.PhasorProtocols.SelFastMessage.ConnectionParameters;
                                if ((object)selParameters != null)
                                {
                                    connectionString += "; messagePeriod=" + selParameters.MessagePeriod;
                                }
                                break;

                            case PhasorProtocol.IEC61850_90_5:
                                GSF.PhasorProtocols.IEC61850_90_5.ConnectionParameters iecParameters = connectionSettings.ConnectionParameters as GSF.PhasorProtocols.IEC61850_90_5.ConnectionParameters;
                                if ((object)iecParameters != null)
                                {
                                    connectionString += "; useETRConfiguration=" + iecParameters.UseETRConfiguration + "; guessConfiguration=" + iecParameters.GuessConfiguration + "; parseRedundantASDUs=" + iecParameters.ParseRedundantASDUs + "; ignoreSignatureValidationFailures=" + iecParameters.IgnoreSignatureValidationFailures + "; ignoreSampleSizeValidationFailures=" + iecParameters.IgnoreSampleSizeValidationFailures;
                                }
                                break;

                            case PhasorProtocol.Macrodyne:
                                GSF.PhasorProtocols.Macrodyne.ConnectionParameters macrodyneParameters = connectionSettings.ConnectionParameters as GSF.PhasorProtocols.Macrodyne.ConnectionParameters;
                                if ((object)macrodyneParameters != null)
                                {
                                    connectionString += "; protocolVersion=" + macrodyneParameters.ProtocolVersion + "; iniFileName=" + macrodyneParameters.ConfigurationFileName + "; refreshConfigFileOnChange=" + macrodyneParameters.RefreshConfigurationFileOnChange + "; deviceLabel=" + macrodyneParameters.DeviceLabel;
                                }
                                break;
                            }
                        }

                        connectionString += "; accessID=" + connectionSettings.PmuID;
                        connectionString += "; phasorProtocol=" + connectionSettings.PhasorProtocol;

                        using (CommonPhasorServices phasorServices = new CommonPhasorServices())
                        {
                            phasorServices.StatusMessage    += (sender, e) => LogStatusMessage(e.Argument.Replace("**", ""));
                            phasorServices.ProcessException += (sender, e) => LogException(e.Argument);
                            return(phasorServices.RequestDeviceConfiguration(connectionString));
                        }
                    }

                    using (MemoryStream source = new MemoryStream(Encoding.UTF8.GetBytes(sourceData)))
                        return(formatter.Deserialize(source) as IConfigurationFrame);
                }
                catch
                {
                    return(new ConfigurationErrorFrame());
                }
            }

            IConfigurationFrame sourceFrame = GetConfigurationFrame();

            if (sourceFrame is ConfigurationErrorFrame)
            {
                return(new ConfigurationFrame());
            }

            ConfigurationFrame derivedFrame;

            // Create a new simple concrete configuration frame for JSON serialization converted from equivalent configuration information
            int protocolID = 0, deviceID = 0, phasorID = -1; // Start phasor ID's at less than -1 since associated voltage == -1 is reserved as unselected

            if (!string.IsNullOrWhiteSpace(connectionString))
            {
                Dictionary <string, string> settings = connectionString.ParseKeyValuePairs();
                protocolID = GetProtocolID(settings["phasorProtocol"]);
            }

            derivedFrame = new ConfigurationFrame
            {
                IDCode           = sourceFrame.IDCode,
                FrameRate        = sourceFrame.FrameRate,
                ConnectionString = connectionString,
                ProtocolID       = protocolID
            };

            foreach (IConfigurationCell sourceCell in sourceFrame.Cells)
            {
                // Create new derived configuration cell
                ConfigurationCell derivedCell = new ConfigurationCell
                {
                    ID          = --deviceID, // Provide a negative index so any database lookup will return null
                    ParentID    = null,
                    IDCode      = sourceCell.IDCode,
                    StationName = sourceCell.StationName,
                    IDLabel     = sourceCell.IDLabel
                };

                // Create equivalent derived frequency definition
                IFrequencyDefinition sourceFrequency = sourceCell.FrequencyDefinition;

                if (sourceFrequency != null)
                {
                    derivedCell.FrequencyDefinition = new FrequencyDefinition {
                        Label = sourceFrequency.Label
                    }
                }
                ;

                int sourceIndex = 0;

                // Create equivalent derived phasor definitions
                foreach (IPhasorDefinition sourcePhasor in sourceCell.PhasorDefinitions)
                {
                    derivedCell.PhasorDefinitions.Add(new PhasorDefinition {
                        ID = --phasorID, Label = sourcePhasor.Label, PhasorType = sourcePhasor.PhasorType.ToString(), SourceIndex = ++sourceIndex
                    });
                }

                // Create equivalent derived analog definitions (assuming analog type = SinglePointOnWave)
                foreach (IAnalogDefinition sourceAnalog in sourceCell.AnalogDefinitions)
                {
                    derivedCell.AnalogDefinitions.Add(new AnalogDefinition {
                        Label = sourceAnalog.Label, AnalogType = sourceAnalog.AnalogType.ToString()
                    });
                }

                // Create equivalent derived digital definitions
                foreach (IDigitalDefinition sourceDigital in sourceCell.DigitalDefinitions)
                {
                    derivedCell.DigitalDefinitions.Add(new DigitalDefinition {
                        Label = sourceDigital.Label
                    });
                }

                // Add cell to frame
                derivedFrame.Cells.Add(derivedCell);
            }

            derivedFrame.IsConcentrator = derivedFrame.Cells.Count > 1;

            return(derivedFrame);
        }
Example #15
0
 /// <summary>
 /// Creates a new <see cref="ConfigurationCell"/> from specified parameters.
 /// </summary>
 /// <param name="parent">The reference to parent <see cref="ConfigurationFrame"/> of this <see cref="ConfigurationCell"/>.</param>
 /// <param name="idCode">The numeric ID code for this <see cref="ConfigurationCell"/>.</param>
 /// <param name="nominalFrequency">The nominal <see cref="LineFrequency"/> of the <see cref="FrequencyDefinition"/> of this <see cref="ConfigurationCell"/>.</param>
 public ConfigurationCell(ConfigurationFrame parent, ushort idCode, LineFrequency nominalFrequency)
     : this(parent)
 {
     IDCode = idCode;
     NominalFrequency = nominalFrequency;
 }
Example #16
0
        /// <summary>
        /// Creates a new BPA PDCstream specific <see cref="IConfigurationFrame"/> based on provided protocol independent <paramref name="baseConfigurationFrame"/>.
        /// </summary>
        /// <param name="baseConfigurationFrame">Protocol independent <see cref="GSF.PhasorProtocols.Anonymous.ConfigurationFrame"/>.</param>
        /// <returns>A new BPA PDCstream specific <see cref="IConfigurationFrame"/>.</returns>
        protected override IConfigurationFrame CreateNewConfigurationFrame(GSF.PhasorProtocols.Anonymous.ConfigurationFrame baseConfigurationFrame)
        {
            int count = 0;

            // Fix ID labels to use BPA PDCstream 4 character label
            foreach (GSF.PhasorProtocols.Anonymous.ConfigurationCell baseCell in baseConfigurationFrame.Cells)
            {
                baseCell.StationName = baseCell.IDLabel.TruncateLeft(baseCell.MaximumStationNameLength);
                baseCell.IDLabel     = DataSource.Tables["OutputStreamDevices"].Select($"IDCode={baseCell.IDCode}")[0]["BpaAcronym"].ToNonNullString(baseCell.IDLabel).TruncateLeft(4);

                // If no ID label was provided, we default to first 4 characters of station name
                if (string.IsNullOrEmpty(baseCell.IDLabel))
                {
                    string stationName = baseCell.StationName;
                    string pmuID       = count.ToString();

                    if (string.IsNullOrEmpty(stationName))
                    {
                        stationName = "PMU";
                    }

                    baseCell.IDLabel = stationName.Substring(0, 4 - pmuID.Length).ToUpper() + pmuID;
                }

                count++;
            }

            // Create a default INI file if one doesn't exist
            if (!File.Exists(IniFileName))
            {
                using (StreamWriter iniFile = File.CreateText(IniFileName))
                {
                    iniFile.Write(GSF.PhasorProtocols.BPAPDCstream.ConfigurationFrame.GetIniFileImage(baseConfigurationFrame));
                }
            }

            // Create a new BPA PDCstream configuration frame using base configuration
            ConfigurationFrame configurationFrame = new ConfigurationFrame(DateTime.UtcNow.Ticks, IniFileName, 1, RevisionNumber.Revision2, StreamType.Compact);

            foreach (GSF.PhasorProtocols.Anonymous.ConfigurationCell baseCell in baseConfigurationFrame.Cells)
            {
                // Create a new BPA PDCstream configuration cell (i.e., a PMU configuration)
                ConfigurationCell newCell = new ConfigurationCell(configurationFrame, baseCell.IDCode, NominalFrequency)
                {
                    // Update other cell level attributes
                    StationName            = baseCell.StationName,
                    IDLabel                = baseCell.IDLabel,
                    PhasorDataFormat       = DataFormat.FixedInteger,
                    PhasorCoordinateFormat = CoordinateFormat.Rectangular,
                    FrequencyDataFormat    = DataFormat.FixedInteger,
                    AnalogDataFormat       = DataFormat.FixedInteger
                };

                // Add phasor definitions
                foreach (IPhasorDefinition phasorDefinition in baseCell.PhasorDefinitions)
                {
                    newCell.PhasorDefinitions.Add(new PhasorDefinition(newCell, phasorDefinition.Label, phasorDefinition.ScalingValue, phasorDefinition.Offset, phasorDefinition.PhasorType, null));
                }

                // Add frequency definition
                newCell.FrequencyDefinition = new FrequencyDefinition(newCell, baseCell.FrequencyDefinition.Label);

                // Add analog definitions
                foreach (IAnalogDefinition analogDefinition in baseCell.AnalogDefinitions)
                {
                    newCell.AnalogDefinitions.Add(new AnalogDefinition(newCell, analogDefinition.Label, analogDefinition.ScalingValue, analogDefinition.Offset, analogDefinition.AnalogType));
                }

                // Add digital definitions
                foreach (IDigitalDefinition digitalDefinition in baseCell.DigitalDefinitions)
                {
                    newCell.DigitalDefinitions.Add(new DigitalDefinition(newCell, digitalDefinition.Label));
                }

                // Add new PMU configuration (cell) to protocol specific configuration frame
                configurationFrame.Cells.Add(newCell);
            }

            // Setup new configuration cells with their proper INI file settings
            configurationFrame.Refresh(true);

            // Cache new BPA PDCstream for later use
            Interlocked.Exchange(ref m_configurationFrame, configurationFrame);

            return(configurationFrame);
        }
Example #17
0
        public static ConfigurationFrame Parse(string configFile, ShowMessageFunc showMessage)
        {
            XDocument config = XDocument.Load(configFile);

            // Load all "SettingsGroup" elements
            XElement[] settingsGroups = config.Descendants("SettingsGroup").ToArray();

            // Load nominal frequency from "Globals" setting group
            string nominalFrequencySetting = settingsGroups
                                             .WhereAttribute("Type").Is("Globals")
                                             .Descendants("Setting")
                                             .WhereAttribute("Name").Is("Frequency")
                                             .GetValue(DefaultLineFrequency);

            LineFrequency nominalFrequency = nominalFrequencySetting.Equals("50") ?
                                             LineFrequency.Hz50 :
                                             LineFrequency.Hz60;

            // Get server gateway instances
            XElement[] serverGatewayInstances = settingsGroups
                                                .WhereAttribute("Type").Is("ServerGateway")
                                                .Descendants("Instance")
                                                .WhereAttribute("Type").Is("Server")
                                                .ToArray();

            if (serverGatewayInstances.Length == 0)
            {
                throw new NullReferenceException($"No server gateway instances where defined in \"{Path.GetFileName(configFile)}\".");
            }

            int enabledInstanceCount = serverGatewayInstances
                                       .Count(elem => elem.Descendants("Setting")
                                              .WhereAttribute("Name").Is("Enabled")
                                              .GetValue(false));

            XElement serverGatewayInstance = null;

            if (enabledInstanceCount == 0)
            {
                if (showMessage($"No enabled server gateway instances where found in \"{Path.GetFileName(configFile)}\", do you want to load a disabled instance?", "No Enabled Server Gateways Found", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
                {
                    throw new NullReferenceException("Failed to load an enabled server gateway instance.");
                }

                serverGatewayInstance = serverGatewayInstances.FirstOrDefault();
            }
            else
            {
                if (enabledInstanceCount > 1 && showMessage($"Found {enabledInstanceCount:N0} enabled server gateway instances in \"{Path.GetFileName(configFile)}\", do you want to load first enabled instance?", "Multiple Enabled Server Gateways Found", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
                {
                    throw new NullReferenceException("Failed to load an enabled server gateway instance.");
                }

                serverGatewayInstance = serverGatewayInstances
                                        .FirstOrDefault(elem => elem.Descendants("Setting")
                                                        .WhereAttribute("Name").Is("Enabled")
                                                        .GetValue(false));
            }

            if (serverGatewayInstance is null)
            {
                throw new NullReferenceException("Failed to load any server gateway instance.");
            }

            // Load all "Setting" elements from server gateway instance
            XElement[] serverGatewaySettings = serverGatewayInstance
                                               .Descendants("Setting")
                                               .ToArray();

            // Load server name setting
            string serverName = Path.GetFileNameWithoutExtension(configFile).GetCleanAcronym();

            // Load ID code setting
            ushort idCode = serverGatewaySettings
                            .WhereAttribute("Name").Is("ID")
                            .GetValue(DefaultIDCode);

            // Load frame rate setting
            ushort frameRate = serverGatewaySettings
                               .WhereAttribute("Name").Is("DataRate")
                               .GetValue(DefaultFrameRate);

            // With an ID code, frame rate and server name, there's enough info to create a config frame
            ConfigurationFrame configFrame = new ConfigurationFrame(idCode, frameRate, serverName);

            // Load all output PMUs
            IEnumerable <XElement> pmus = serverGatewaySettings
                                          .WhereAttribute("Name").Is("OutputTags")
                                          .Descendants("PMU");

            foreach (XElement pmu in pmus)
            {
                string name = pmu.Attribute("Name")?.Value;

                if (string.IsNullOrWhiteSpace(name))
                {
                    continue;
                }

                if (!ushort.TryParse(pmu.Attribute("ID")?.Value, out idCode))
                {
                    continue;
                }

                // With a name and an ID code, there's enough info to create a config cell representing the PMU
                ConfigurationCell configCell = new ConfigurationCell(configFrame, name, idCode)
                {
                    NominalFrequency = nominalFrequency,
                };

                // Load all PMU tags
                XElement[] tags = pmu.Descendants("Tag").ToArray();

                // Load all phasor tags
                IEnumerable <XElement> phasors = tags
                                                 .WhereAttribute("Type").Is("Phasor");

                foreach (XElement phasor in phasors)
                {
                    name = phasor.Attribute("Name")?.Value;

                    if (string.IsNullOrWhiteSpace(name))
                    {
                        continue;
                    }

                    string description = phasor.Attribute("Description")?.Value;

                    string quantityType = phasor.Attribute("QuantityType")?.Value ?? DefaultPhasorType;

                    PhasorType phasorType = quantityType.Equals("Current") ?
                                            PhasorType.Current :
                                            PhasorType.Voltage;

                    string phaseSetting = phasor.Attribute("Phase")?.Value.Trim();

                    if (string.IsNullOrWhiteSpace(phaseSetting))
                    {
                        phaseSetting = GuessPhase(phasor.Attribute("OriginalName")?.Value ?? name);
                    }

                    char phase = string.IsNullOrWhiteSpace(phaseSetting) ? DefaultPhase : TranslatePhase(phaseSetting[0]);

                    if (string.IsNullOrWhiteSpace(description))
                    {
                        description = $"{configCell.StationName} phase {phase} {phasorType.ToString().ToLowerInvariant()} phasor";
                    }

                    configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, name, description, phasorType, phase));
                }

                // Load all analog tags
                IEnumerable <XElement> analogs = tags
                                                 .WhereAttribute("Type").Is("Analog");

                foreach (XElement analog in analogs)
                {
                    name = analog.Attribute("Name")?.Value;

                    if (string.IsNullOrWhiteSpace(name))
                    {
                        continue;
                    }

                    string description = analog.Attribute("Description")?.Value;

                    if (string.IsNullOrWhiteSpace(description))
                    {
                        description = $"{configCell.StationName} {name} analog value";
                    }

                    configCell.AnalogDefinitions.Add(new AnalogDefinition(configCell, name, description));
                }

                // Load all digital tags
                IEnumerable <XElement> digitals = tags
                                                  .WhereAttribute("Type").Is("Digital");

                foreach (XElement digital in digitals)
                {
                    name = digital.Attribute("Name")?.Value;

                    if (string.IsNullOrWhiteSpace(name))
                    {
                        continue;
                    }

                    string description = digital.Attribute("Description")?.Value;

                    if (string.IsNullOrWhiteSpace(description))
                    {
                        description = $"{configCell.StationName} {name} digital value";
                    }

                    configCell.DigitalDefinitions.Add(new DigitalDefinition(configCell, name, description));
                }

                configFrame.Cells.Add(configCell);
            }

            // Get connection details configured for SEL PDC
            string transportProtocol = serverGatewaySettings
                                       .WhereAttribute("Name").Is("TransportProtocol")
                                       .GetValue(DefaultTransportProtocol)
                                       .ToUpperInvariant();

            configFrame.TransportProtocol = transportProtocol;

            ushort commandPort = serverGatewaySettings
                                 .WhereAttribute("Name").Is("CommandPort")
                                 .GetValue(DefaultCommandPort);

            ushort dataPort = serverGatewaySettings
                              .WhereAttribute("Name").Is("DataPort")
                              .GetValue(DefaultDataPort);

            ushort port = serverGatewaySettings
                          .WhereAttribute("Name").Is("Port")
                          .GetValue(DefaultPort);

            bool multicastEnabled = serverGatewaySettings
                                    .WhereAttribute("Name").Is("MulticastEnabled")
                                    .GetValue(DefaultMulticastEnabled);

            string multicastGroup = serverGatewaySettings
                                    .WhereAttribute("Name").Is("MulticastGroup")
                                    .GetValue(DefaultMulticastGroup);

            // Setup MultiProtocolFrameParser style connection string
            Dictionary <string, string> getTcpSettings(bool commandChannel = false)
            {
                // Use of simple "protocol" key in commandChannel and separation of
                // server/port keys are required to create a proper "PmuConnection"
                // file that can be successfully parsed by the PMU Connection Tester
                return(new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase)
                {
                    [commandChannel ? "protocol": nameof(TransportProtocol)] = nameof(TransportProtocol.Tcp),
                    ["server"] = IPAddressToken,
                    ["port"] = commandChannel ? $"{commandPort}" : $"{port}",
                    ["isListener"] = "false",
                    ["interface"] = "0.0.0.0"
                });
            }

            Dictionary <string, string> settings = configFrame.Settings;

            settings[nameof(PhasorProtocol)] = nameof(PhasorProtocol.IEEEC37_118V1);

            if (transportProtocol == "TCP")
            {
                foreach (KeyValuePair <string, string> pair in getTcpSettings())
                {
                    settings[pair.Key] = pair.Value;
                }
            }
            else if (transportProtocol.StartsWith("UDP"))
            {
                settings[nameof(TransportProtocol)] = nameof(TransportProtocol.Udp);
                settings["localPort"] = $"{dataPort}";
                settings["interface"] = "0.0.0.0";

                switch (transportProtocol)
                {
                case "UDP_T":
                case "UDP_U":
                    settings["commandChannel"] = getTcpSettings(true).JoinKeyValuePairs();
                    break;
                }

                if (multicastEnabled)
                {
                    settings["server"]     = multicastGroup;
                    settings["remotePort"] = $"{commandPort}";
                }
            }
            else
            {
                settings["error"] = "No valid connection protocol detected";
            }

            // Save device IP configuration
            Dictionary <string, string> deviceIPs = configFrame.DeviceIPs;

            // Load "NetworkSettingsGroup" element from settings group
            XElement networkSettingsGroup = settingsGroups
                                            .WhereAttribute("Type").Is("NetworkSettingsGroup")
                                            .FirstOrDefault();

            if (networkSettingsGroup is null)
            {
                deviceIPs["loopback"] = "127.0.0.1";
            }
            else
            {
                string gatewayIP = networkSettingsGroup
                                   .Descendants("Setting")
                                   .WhereAttribute("Name").Is("Gateway")
                                   .GetValue(DefaultGatewayIP);

                // Get array of settings for each NIC interface
                IEnumerable <XElement[]> interfaceSettingsMap = networkSettingsGroup
                                                                .Descendants("SettingsGroup")
                                                                .WhereAttribute("Type").Is("NetworkGroup")
                                                                .Descendants("Instance")
                                                                .WhereAttribute("Type").Is("NetworkInterfaceCard")
                                                                .Select(element => element.Descendants("Setting").ToArray());

                foreach (XElement[] interfaceSettings in interfaceSettingsMap)
                {
                    string name = interfaceSettings
                                  .WhereAttribute("Name").Is("Name")
                                  .GetValue(null);

                    if (string.IsNullOrWhiteSpace(name))
                    {
                        continue;
                    }

                    string ipAddress = interfaceSettings
                                       .WhereAttribute("Name").Is("IPAddress")
                                       .GetValue(null);

                    if (string.IsNullOrWhiteSpace(ipAddress))
                    {
                        continue;
                    }

                    deviceIPs[name] = ipAddress;
                }

                // Set the target device IP to the one that matches gateway IP the closest,
                // this is just a guess, user must select proper device IP
                configFrame.TargetDeviceIP = deviceIPs
                                             .ToDictionary(pair => pair.Key, pair => gatewayIP.OverlapCoefficient(pair.Value))
                                             .Aggregate((x, y) => x.Value > y.Value ? x : y).Key;

                if (string.IsNullOrWhiteSpace(configFrame.TargetDeviceIP) && deviceIPs.Count > 0)
                {
                    configFrame.TargetDeviceIP = deviceIPs.First().Key;
                }
            }

            return(configFrame);
        }
 public void Navigate(Page page)
 {
     ((ViewModelBase)page.DataContext).DisplayState = this;
     ConfigurationFrame.Navigate(page);
 }
        // Static Methods       

        /// <summary>
        /// Creates a new IEC 61850-90-5 (i.e., IEEE C37.118) <see cref="ConfigurationFrame"/> based on provided protocol independent <paramref name="baseConfigurationFrame"/>.
        /// </summary>
        /// <param name="baseConfigurationFrame">Protocol independent <see cref="GSF.PhasorProtocols.Anonymous.ConfigurationFrame"/>.</param>
        /// <param name="timeBase">Timebase to use for fraction second resolution.</param>
        /// <param name="nominalFrequency">The nominal <see cref="LineFrequency"/> to use for the new <see cref="ConfigurationFrame"/></param>.
        /// <returns>A new IEEE C37.118 <see cref="ConfigurationFrame"/>.</returns>
        public static ConfigurationFrame CreateConfigurationFrame(GSF.PhasorProtocols.Anonymous.ConfigurationFrame baseConfigurationFrame, uint timeBase, LineFrequency nominalFrequency)
        {
            ConfigurationCell newCell;
            uint maskValue;

            // Create a new IEEE C37.118 configuration frame 2 using base configuration
            ConfigurationFrame configurationFrame = new ConfigurationFrame(timeBase, baseConfigurationFrame.IDCode, DateTime.UtcNow.Ticks, baseConfigurationFrame.FrameRate);

            foreach (GSF.PhasorProtocols.Anonymous.ConfigurationCell baseCell in baseConfigurationFrame.Cells)
            {
                // Create a new IEEE C37.118 configuration cell (i.e., a PMU configuration)
                newCell = new ConfigurationCell(configurationFrame, baseCell.IDCode, nominalFrequency);

                // Update other cell level attributes
                newCell.StationName = baseCell.StationName;
                newCell.IDLabel = baseCell.IDLabel;
                newCell.PhasorDataFormat = baseCell.PhasorDataFormat;
                newCell.PhasorCoordinateFormat = baseCell.PhasorCoordinateFormat;
                newCell.FrequencyDataFormat = baseCell.FrequencyDataFormat;
                newCell.AnalogDataFormat = baseCell.AnalogDataFormat;

                // Add phasor definitions
                foreach (IPhasorDefinition phasorDefinition in baseCell.PhasorDefinitions)
                {
                    newCell.PhasorDefinitions.Add(new PhasorDefinition(newCell, phasorDefinition.Label, phasorDefinition.ScalingValue, phasorDefinition.Offset, phasorDefinition.PhasorType, null));
                }

                // Add frequency definition
                newCell.FrequencyDefinition = new FrequencyDefinition(newCell, baseCell.FrequencyDefinition.Label);

                // Add analog definitions
                foreach (IAnalogDefinition analogDefinition in baseCell.AnalogDefinitions)
                {
                    newCell.AnalogDefinitions.Add(new AnalogDefinition(newCell, analogDefinition.Label, analogDefinition.ScalingValue, analogDefinition.Offset, analogDefinition.AnalogType));
                }

                // Add digital definitions
                foreach (IDigitalDefinition digitalDefinition in baseCell.DigitalDefinitions)
                {
                    // Attempt to derive user defined mask value if available
                    DigitalDefinition anonymousDigitalDefinition = digitalDefinition as DigitalDefinition;

                    if (anonymousDigitalDefinition != null)
                        maskValue = anonymousDigitalDefinition.MaskValue;
                    else
                        maskValue = 0U;

                    newCell.DigitalDefinitions.Add(new GSF.PhasorProtocols.IEC61850_90_5.DigitalDefinition(newCell, digitalDefinition.Label, maskValue.LowWord(), maskValue.HighWord()));
                }

                // Add new PMU configuration (cell) to protocol specific configuration frame
                configurationFrame.Cells.Add(newCell);
            }

            return configurationFrame;
        }
Example #20
0
        public static void SaveConnection(ImportParameters importParams)
        {
            AdoDataConnection            connection      = importParams.Connection;
            ConfigurationFrame           configFrame     = importParams.TargetConfigFrame;
            TableOperations <Device>     deviceTable     = importParams.DeviceTable;
            TableOperations <SignalType> signalTypeTable = new(connection);
            Guid   nodeID           = importParams.NodeID;
            string connectionString = importParams.EditedConnectionString;

            // Load a list of all existing device records
            s_devices = deviceTable.QueryRecords().ToArray();

            // Apply other connection string parameters that are specific to device operation
            importParams.EditedConnectionString = string.Format(ConnectionStringTemplate, importParams.EditedConnectionString);

            if (s_deviceSignalTypes is null)
            {
                s_deviceSignalTypes = signalTypeTable.LoadSignalTypes("PMU").ToDictionary(key => key.Acronym, StringComparer.OrdinalIgnoreCase);
            }

            if (s_phasorSignalTypes is null)
            {
                s_phasorSignalTypes = signalTypeTable.LoadSignalTypes("Phasor").ToDictionary(key => key.Acronym, StringComparer.OrdinalIgnoreCase);
            }

            Device device = s_devices.FindDeviceByIDCodeAndIPAddress(configFrame.IDCode, importParams.IPAddress) ?? deviceTable.NewDevice();
            Dictionary <string, string> settings = connectionString.ParseKeyValuePairs();

            bool autoStartDataParsingSequence = true;
            bool skipDisableRealTimeData      = false;

            // Handle connection string parameters that are fields in the device table
            if (settings.ContainsKey("autoStartDataParsingSequence"))
            {
                autoStartDataParsingSequence = bool.Parse(settings["autoStartDataParsingSequence"]);
                settings.Remove("autoStartDataParsingSequence");
                connectionString = settings.JoinKeyValuePairs();
            }

            if (settings.ContainsKey("skipDisableRealTimeData"))
            {
                skipDisableRealTimeData = bool.Parse(settings["skipDisableRealTimeData"]);
                settings.Remove("skipDisableRealTimeData");
                connectionString = settings.JoinKeyValuePairs();
            }

            string deviceAcronym = configFrame.Acronym;
            string deviceName    = null;

            if (string.IsNullOrWhiteSpace(deviceAcronym))
            {
                if (string.IsNullOrWhiteSpace(configFrame.Name))
                {
                    throw new InvalidOperationException("Unable to get name or acronym for PDC from parsed configuration frame");
                }

                deviceAcronym = configFrame.Name.GetCleanAcronym();
            }

            if (!string.IsNullOrWhiteSpace(configFrame.Name))
            {
                deviceName = configFrame.Name;
            }

            device.NodeID                       = nodeID;
            device.ParentID                     = null;
            device.HistorianID                  = configFrame.HistorianID;
            device.Acronym                      = deviceAcronym;
            device.Name                         = deviceName ?? deviceAcronym;
            device.ProtocolID                   = importParams.IeeeC37_118ProtocolID;
            device.FramesPerSecond              = configFrame.FrameRate;
            device.AccessID                     = configFrame.IDCode;
            device.IsConcentrator               = true;
            device.ConnectionString             = connectionString;
            device.AutoStartDataParsingSequence = autoStartDataParsingSequence;
            device.SkipDisableRealTimeData      = skipDisableRealTimeData;
            device.Enabled                      = true;

            // Check if this is a new device or an edit to an existing one
            if (device.ID == 0)
            {
                // Add new device record
                deviceTable.AddNewDevice(device);

                // Get newly added device with auto-incremented ID
                Device newDevice = deviceTable.QueryDevice(device.Acronym);

                // Save associated PMU records
                UpdatePMUDevices(importParams, newDevice);
            }
            else
            {
                // Update existing device record
                deviceTable.UpdateDevice(device);

                // Save associated PMU records
                UpdatePMUDevices(importParams, device);
            }
        }
Example #21
0
        private void EditDetails_Load(object sender, EventArgs e)
        {
            ConfigurationFrame selPDCConfigFrame = ImportParams.SELPDCConfigFrame;
            ConfigurationFrame gsfPDCConfigFrame = ImportParams.GSFPDCConfigFrame;

            TargetConfigFrame = ConfigurationFrame.Clone(gsfPDCConfigFrame ?? selPDCConfigFrame, false);

            checkBoxDeleteAll.CheckedChanged += (_, _) =>
            {
                foreach (CheckBox checkBox in m_deleteCheckBoxes)
                {
                    checkBox.Checked = checkBoxDeleteAll.Checked;
                }
            };

            buttonImport.Click += (_, _) =>
            {
                int validationErrors = m_validatedControls.Count(control => !string.IsNullOrWhiteSpace(errorProvider.GetError(control)));

                if (validationErrors > 0)
                {
                    MessageBox.Show(this, $"Cannot Import: There {(validationErrors == 1 ? "is" : "are")} {validationErrors:N0} validation error{(validationErrors == 1 ? "" : "s")} that must be corrected before PDC can be imported.", "Validation Errors", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (m_deleteCheckBoxes.All(checkBox => checkBox.Checked))
                {
                    if (MessageBox.Show(this, $"All PMUs ({TargetConfigFrame.Cells.Count:N0} total) are marked for deletion, are you sure this is the desired operation?", "Delete All Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
                    {
                        return;
                    }

                    MessageBox.Show(this, $"All PMUs will now be deleted. Note that associated connection \"{textBoxTCFConnectionName.Text}\" will need to be manually removed from GSF host application.", "Deleting All PMUs", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }

                DialogResult = DialogResult.OK;
                ImportParams.TargetConfigFrame = TargetConfigFrame;
                Close();
            };

            textBoxSCFConnectionName.Text   = selPDCConfigFrame.Acronym;
            textBoxSCFConnectionName.Click += ConnectionNameOnClick;

            textBoxGCFConnectionName.Text   = gsfPDCConfigFrame?.Acronym;
            textBoxGCFConnectionName.Click += ConnectionNameOnClick;

            textBoxTCFConnectionName.TextChanged += (_, _) =>
            {
                TargetConfigFrame.Acronym = textBoxTCFConnectionName.Text;

                bool matchesSCF = string.Equals(textBoxTCFConnectionName.Text, textBoxSCFConnectionName.Text);
                bool matchesGSF = string.Equals(textBoxTCFConnectionName.Text, textBoxGCFConnectionName.Text);

                textBoxTCFConnectionName.BackColor = matchesSCF || matchesGSF ? m_matchedColor : m_unmatchedColor;
                textBoxSCFConnectionName.BackColor = matchesSCF ? m_matchedColor : m_unmatchedColor;
                textBoxGCFConnectionName.BackColor = matchesGSF ? m_matchedColor : m_unmatchedColor;

                ValidateChildren();
            };

            textBoxTCFConnectionName.Validated += (_, _) => errorProvider.SetError(textBoxTCFConnectionName, ParentDeviceIsUnique() ? string.Empty : "Acronym already exists with different ID Code!");

            m_validatedControls.Add(textBoxTCFConnectionName);

            textBoxTCFConnectionName.Leave += (_, _) => textBoxTCFConnectionName.Text = textBoxTCFConnectionName.Text.GetCleanAcronym();

            textBoxTCFConnectionName.Text = TargetConfigFrame.Acronym;

            TableLayoutPanel         table        = tableLayoutPanelConfigDetails;
            List <ConfigurationCell> matchedCells = new List <ConfigurationCell>();

            table.SuspendLayout();

            for (int i = 0; i < selPDCConfigFrame.Cells.Count; i++)
            {
                ConfigurationCell selConfigCell    = selPDCConfigFrame.Cells[i];
                ConfigurationCell gsfConfigCell    = gsfPDCConfigFrame?.Cells.FirstOrDefault(cell => cell.IDCode == selConfigCell.IDCode) as ConfigurationCell;
                ConfigurationCell targetConfigCell = new ConfigurationCell(
                    TargetConfigFrame,
                    gsfConfigCell?.StationName ?? selConfigCell.StationName,
                    gsfConfigCell?.IDCode ?? selConfigCell.IDCode,
                    gsfConfigCell?.IDLabel ?? selConfigCell.IDLabel)
                {
                    FrequencyDefinition = selConfigCell.FrequencyDefinition
                };

                foreach (IPhasorDefinition phasorDefinition in selConfigCell.PhasorDefinitions)
                {
                    targetConfigCell.PhasorDefinitions.Add(phasorDefinition);
                }

                foreach (IAnalogDefinition analogDefinition in selConfigCell.AnalogDefinitions)
                {
                    targetConfigCell.AnalogDefinitions.Add(analogDefinition);
                }

                foreach (IDigitalDefinition digitalDefinition in selConfigCell.DigitalDefinitions)
                {
                    targetConfigCell.DigitalDefinitions.Add(digitalDefinition);
                }

                TargetConfigFrame.Cells.Add(targetConfigCell);

                if (gsfConfigCell is not null)
                {
                    matchedCells.Add(gsfConfigCell);
                }

                Tuple <TextBox, CheckBox> dataControls = AddRow(table, $"PMU {i + 1:N0} Acronym:", selConfigCell.IDLabel, gsfConfigCell?.IDLabel);

                TextBox targetTextBox = dataControls.Item1;
                targetTextBox.TextChanged += (_, _) => targetConfigCell.IDLabel = targetTextBox.Text;
                targetTextBox.Validated   += (_, _) => ValidateChildDevice(targetTextBox, targetConfigCell);

                m_validatedControls.Add(targetTextBox);

                CheckBox deletedCheckBox = dataControls.Item2;
                deletedCheckBox.CheckedChanged += (_, _) => targetConfigCell.Delete = deletedCheckBox.Checked;
            }

            // Add unmatched cells
            if (gsfPDCConfigFrame is not null && gsfPDCConfigFrame.Cells.Count > 0)
            {
                HashSet <ConfigurationCell> unmatchedCells = new HashSet <ConfigurationCell>(gsfPDCConfigFrame.Cells.Select(cell => cell as ConfigurationCell));
                unmatchedCells.ExceptWith(matchedCells);
                int i = TargetConfigFrame.Cells.Count;

                foreach (ConfigurationCell gsfConfigCell in unmatchedCells)
                {
                    if (gsfConfigCell is null)
                    {
                        continue;
                    }

                    ConfigurationCell targetConfigCell = new ConfigurationCell(
                        TargetConfigFrame,
                        gsfConfigCell.StationName,
                        gsfConfigCell.IDCode,
                        gsfConfigCell.IDLabel)
                    {
                        FrequencyDefinition = gsfConfigCell.FrequencyDefinition,
                        Delete = true
                    };

                    foreach (IPhasorDefinition phasorDefinition in gsfConfigCell.PhasorDefinitions)
                    {
                        targetConfigCell.PhasorDefinitions.Add(phasorDefinition);
                    }

                    foreach (IAnalogDefinition analogDefinition in gsfConfigCell.AnalogDefinitions)
                    {
                        targetConfigCell.AnalogDefinitions.Add(analogDefinition);
                    }

                    foreach (IDigitalDefinition digitalDefinition in gsfConfigCell.DigitalDefinitions)
                    {
                        targetConfigCell.DigitalDefinitions.Add(digitalDefinition);
                    }

                    TargetConfigFrame.Cells.Add(targetConfigCell);

                    Tuple <TextBox, CheckBox> dataControls = AddRow(table, $"PMU {i++:N0} Acronym:", "", gsfConfigCell.IDLabel, true);

                    TextBox targetTextBox = dataControls.Item1;
                    targetTextBox.TextChanged += (_, _) => targetConfigCell.IDLabel = targetTextBox.Text;
                    targetTextBox.Validated   += (_, _) => ValidateChildDevice(targetTextBox, targetConfigCell);

                    m_validatedControls.Add(targetTextBox);

                    CheckBox deletedCheckBox = dataControls.Item2;
                    deletedCheckBox.CheckedChanged += (_, _) => targetConfigCell.Delete = deletedCheckBox.Checked;
                }
            }

            // Add a final blank row
            table.RowCount++;
            table.RowStyles.Add(new RowStyle(SizeType.Absolute, 10F));

            table.ResumeLayout();

            // Update tab ordering
            int tabIndex = 0;

            foreach (Control control in m_validatedControls)
            {
                control.TabIndex = tabIndex++;
            }

            buttonImport.TabIndex = tabIndex++;
            buttonCancel.TabIndex = tabIndex;

            // Load target historian list
            LoadHistorians();

            // Perform initial validation
            ValidateChildren();

            textBoxTCFConnectionName.Focus();

            if (!tableLayoutPanelConfigDetails.VerticalScroll.Visible)
            {
                return;
            }

            Width += 20;
        }
        /// <summary>
        /// Creates a new IEC 61850-90-5 specific <see cref="DataFrame"/> for the given <paramref name="timestamp"/>.
        /// </summary>
        /// <param name="timestamp">Timestamp for new <see cref="IFrame"/> in <see cref="Ticks"/>.</param>
        /// <param name="configurationFrame">Associated <see cref="ConfigurationFrame"/> for the new <see cref="DataFrame"/>.</param>
        /// <param name="msvID">MSVID to use for <see cref="DataFrame"/>.</param>
        /// <param name="asduCount">ASDU count.</param>
        /// <param name="asduImages">Concentrator's ASDU image cache.</param>
        /// <param name="configurationRevision">Configuration revision.</param>
        /// <returns>New IEC 61850-90-5 <see cref="DataFrame"/> at given <paramref name="timestamp"/>.</returns>
        public static DataFrame CreateDataFrame(Ticks timestamp, ConfigurationFrame configurationFrame, string msvID, int asduCount, byte[][] asduImages, uint configurationRevision)
        {
            // We create a new IEC 61850-90-5 data frame based on current configuration frame
            DataFrame dataFrame = new DataFrame(timestamp, configurationFrame, msvID, asduCount, asduImages, configurationRevision);
            DataCell dataCell;

            foreach (ConfigurationCell configurationCell in configurationFrame.Cells)
            {
                // Create a new IEC 61850-90-5 data cell (i.e., a PMU entry for this frame)
                dataCell = new DataCell(dataFrame, configurationCell, true);

                // Add data cell to the frame
                dataFrame.Cells.Add(dataCell);
            }

            return dataFrame;
        }
Example #23
0
        /// <summary>
        /// Creates a new BPA PDCstream specific <see cref="IConfigurationFrame"/> based on provided protocol independent <paramref name="baseConfigurationFrame"/>.
        /// </summary>
        /// <param name="baseConfigurationFrame">Protocol independent <see cref="GSF.PhasorProtocols.Anonymous.ConfigurationFrame"/>.</param>
        /// <returns>A new BPA PDCstream specific <see cref="IConfigurationFrame"/>.</returns>
        protected override IConfigurationFrame CreateNewConfigurationFrame(GSF.PhasorProtocols.Anonymous.ConfigurationFrame baseConfigurationFrame)
        {
            ConfigurationCell newCell;
            int count = 0;

            // Fix ID labels to use BPA PDCstream 4 character label
            foreach (GSF.PhasorProtocols.Anonymous.ConfigurationCell baseCell in baseConfigurationFrame.Cells)
            {
                baseCell.StationName = baseCell.IDLabel.TruncateLeft(baseCell.MaximumStationNameLength);
                baseCell.IDLabel = DataSource.Tables["OutputStreamDevices"].Select(string.Format("IDCode={0}", baseCell.IDCode))[0]["BpaAcronym"].ToNonNullString(baseCell.IDLabel).TruncateLeft(4);

                // If no ID label was provided, we default to first 4 characters of station name
                if (string.IsNullOrEmpty(baseCell.IDLabel))
                {
                    string stationName = baseCell.StationName;
                    string pmuID = count.ToString();

                    if (string.IsNullOrEmpty(stationName))
                        stationName = "PMU";

                    baseCell.IDLabel = stationName.Substring(0, 4 - pmuID.Length).ToUpper() + pmuID;
                }

                count++;
            }

            // Create a default INI file if one doesn't exist
            if (!File.Exists(m_iniFileName))
            {
                using (StreamWriter iniFile = File.CreateText(m_iniFileName))
                {
                    iniFile.Write(GSF.PhasorProtocols.BPAPDCstream.ConfigurationFrame.GetIniFileImage(baseConfigurationFrame));
                }
            }

            // Create a new BPA PDCstream configuration frame using base configuration
            ConfigurationFrame configurationFrame = new ConfigurationFrame(DateTime.UtcNow.Ticks, m_iniFileName, 1, RevisionNumber.Revision2, StreamType.Compact);

            foreach (GSF.PhasorProtocols.Anonymous.ConfigurationCell baseCell in baseConfigurationFrame.Cells)
            {
                // Create a new BPA PDCstream configuration cell (i.e., a PMU configuration)
                newCell = new ConfigurationCell(configurationFrame, baseCell.IDCode, base.NominalFrequency);

                // Update other cell level attributes
                newCell.StationName = baseCell.StationName;
                newCell.IDLabel = baseCell.IDLabel;
                newCell.PhasorDataFormat = DataFormat.FixedInteger;             //baseCell.PhasorDataFormat;
                newCell.PhasorCoordinateFormat = CoordinateFormat.Rectangular;  //baseCell.PhasorCoordinateFormat;
                newCell.FrequencyDataFormat = DataFormat.FixedInteger;          //baseCell.FrequencyDataFormat;
                newCell.AnalogDataFormat = DataFormat.FixedInteger;             //baseCell.AnalogDataFormat;

                // Add phasor definitions
                foreach (IPhasorDefinition phasorDefinition in baseCell.PhasorDefinitions)
                {
                    newCell.PhasorDefinitions.Add(new PhasorDefinition(newCell, phasorDefinition.Label, phasorDefinition.ScalingValue, phasorDefinition.Offset, phasorDefinition.PhasorType, null));
                }

                // Add frequency definition
                newCell.FrequencyDefinition = new FrequencyDefinition(newCell, baseCell.FrequencyDefinition.Label);

                // Add analog definitions
                foreach (IAnalogDefinition analogDefinition in baseCell.AnalogDefinitions)
                {
                    newCell.AnalogDefinitions.Add(new AnalogDefinition(newCell, analogDefinition.Label, analogDefinition.ScalingValue, analogDefinition.Offset, analogDefinition.AnalogType));
                }

                // Add digital definitions
                foreach (IDigitalDefinition digitalDefinition in baseCell.DigitalDefinitions)
                {
                    newCell.DigitalDefinitions.Add(new DigitalDefinition(newCell, digitalDefinition.Label));
                }

                // Add new PMU configuration (cell) to protocol specific configuration frame
                configurationFrame.Cells.Add(newCell);
            }

            // Setup new configuration cells with their proper INI file settings
            configurationFrame.Refresh(true);

            // Cache new BPA PDCstream for later use
            Interlocked.Exchange(ref m_configurationFrame, configurationFrame);

            return configurationFrame;
        }
Example #24
0
        private void configureCandleCharts(bool bEnableOverlay, List <PlotCollectionSet> rgSet, bool bLoadedFromFile)
        {
            timerData.Enabled  = false;
            toolStrip1.Visible = true;

            simpleGraphingControl1.Configuration.Surface.EnableSmoothing = false;
            simpleGraphingControl1.Configuration.Frames[0].EnableRelativeScaling(true, btnScaleToVisible.Checked);

            if (!bLoadedFromFile)
            {
                int nIdx1 = 30;
                int nIdx2 = 60;

                if (nIdx1 > rgSet[0][0].Count)
                {
                    nIdx1 = rgSet[0][0].Count - 1;
                }

                if (nIdx2 > rgSet[0][0].Count)
                {
                    nIdx2 = rgSet[0][0].Count - 1;
                }

                DateTime dt0 = DateTime.FromFileTime((long)rgSet[0][0][nIdx1].X);
                DateTime dt1 = DateTime.FromFileTime((long)rgSet[0][0][nIdx2].X);

                simpleGraphingControl1.Configuration.Frames[0].PlotArea.TimeZones = new List <ConfigurationTimeZone>();
                simpleGraphingControl1.Configuration.Frames[0].PlotArea.TimeZones.Add(new ConfigurationTimeZone(dt0, dt1, Color.LightGray, true));
            }
            else
            {
                simpleGraphingControl1.Configuration.Frames[0].MinimumYRange = 5;
            }

            for (int i = 0; i < simpleGraphingControl1.Configuration.Frames.Count; i++)
            {
                ConfigurationFrame frame = simpleGraphingControl1.Configuration.Frames[i];

                if (i == 0)
                {
                    frame.Visible           = true;
                    frame.Plots[0].PlotType = ConfigurationPlot.PLOTTYPE.CANDLE;

                    for (int j = 2; j < frame.Plots.Count; j++)
                    {
                        if (frame.Plots[j].PlotType == ConfigurationPlot.PLOTTYPE.CUSTOM)
                        {
                            frame.Plots[j].Visible = false;
                        }
                        else if (frame.Plots[j].PlotType == ConfigurationPlot.PLOTTYPE.HIGHLOW)
                        {
                            if (frame.Plots[j].ExtraSettings == null)
                            {
                                frame.Plots[j].ExtraSettings = new Dictionary <string, double>();
                            }
                            if (!frame.Plots[j].ExtraSettings.ContainsKey("DrawLines"))
                            {
                                frame.Plots[j].ExtraSettings.Add("DrawLines", 1.0);
                            }
                        }
                        else if (frame.Plots[j].PlotType == ConfigurationPlot.PLOTTYPE.LINE)
                        {
                            if (frame.Plots[j].Name == "Regression" ||
                                frame.Plots[j].Name == "Conf+" ||
                                frame.Plots[j].Name == "Conf-")
                            {
                                frame.Plots[j].Visible = true;
                            }
                        }

                        //if (frame.Plots[j].PlotType != ConfigurationPlot.PLOTTYPE.BOLLINGERBANDS)
                        //    frame.Plots[j].Visible = false;
                    }

                    frame.Plots[4].Visible = bEnableOverlay;
                    frame.Plots[5].Visible = true;
                }
                else if (i == 1)
                {
                    frame.Visible                = true;
                    frame.Plots[0].PlotType      = ConfigurationPlot.PLOTTYPE.RSI;
                    frame.Plots[0].Interval      = 14;
                    frame.Plots[0].LineColor     = Color.DarkGreen;
                    frame.Plots[0].LineWidth     = 2.0f;
                    frame.Plots[0].PlotFillColor = Color.Transparent;
                    frame.Plots[0].PlotLineColor = Color.Transparent;

                    if (frame.Plots.Count > 1)
                    {
                        frame.Plots[1].PlotType  = ConfigurationPlot.PLOTTYPE.HIGHLOW;
                        frame.Plots[1].DataName  = "RSI";
                        frame.Plots[1].DataIndex = 1;
                        frame.Plots[1].Visible   = true;
                    }

                    for (int j = 2; j < frame.Plots.Count; j++)
                    {
                        if (frame.Plots[j].PlotType == ConfigurationPlot.PLOTTYPE.CUSTOM)
                        {
                            frame.Plots[j].Visible = true;
                        }
                        else
                        {
                            frame.Plots[j].Visible = false;
                        }
                    }

                    frame.TargetLines.Add(new ConfigurationTargetLine(30, Color.Maroon));
                    frame.TargetLines.Add(new ConfigurationTargetLine(70, Color.Green));
                    frame.YAxis.InitialMaximum = 100;
                    frame.YAxis.InitialMinimum = 0;
                }
                else if (i == 2)
                {
                    frame.Visible                = true;
                    frame.Plots[0].PlotType      = ConfigurationPlot.PLOTTYPE.VOLUME;
                    frame.Plots[0].LineColor     = Color.Blue;
                    frame.Plots[0].LineWidth     = 1.0f;
                    frame.Plots[0].PlotFillColor = Color.Transparent;
                    frame.Plots[0].PlotLineColor = Color.Transparent;
                    frame.MinMaxTarget           = PlotCollection.MINMAX_TARGET.COUNT;
                }
                else
                {
                    frame.Visible = false;
                }

                frame.XAxis.ValueType       = ConfigurationAxis.VALUE_TYPE.TIME;
                frame.XAxis.ValueResolution = ConfigurationAxis.VALUE_RESOLUTION.DAY;
                frame.YAxis.Decimals        = 2;
            }

            simpleGraphingControl1.SetLookahead(3);
        }