// 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); } }
/// <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); }
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); }
/// <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); }
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); } } } }
/// <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); }
/// <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); }
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); }
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); } }
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); }
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); } }
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); }
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); }
/// <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; }
/// <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); }
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; }
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); } }
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; }
/// <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; }
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); }