/// <summary> /// Creates a new <see cref="DataCell"/> from specified parameters. /// </summary> /// <param name="parent">The reference to parent <see cref="DataFrame"/> of this <see cref="DataCell"/>.</param> /// <param name="configurationCell">The <see cref="ConfigurationCell"/> associated with this <see cref="DataCell"/>.</param> /// <param name="addEmptyValues">If <c>true</c>, adds empty values for each defined configuration cell definition.</param> public DataCell(DataFrame parent, ConfigurationCell configurationCell, bool addEmptyValues) : this(parent, configurationCell) { if (addEmptyValues) { int x; // Define needed phasor values for (x = 0; x < configurationCell.PhasorDefinitions.Count; x++) { PhasorValues.Add(new PhasorValue(this, configurationCell.PhasorDefinitions[x])); } // Define a frequency and df/dt FrequencyValue = new FrequencyValue(this, configurationCell.FrequencyDefinition); // Define any analog values for (x = 0; x < configurationCell.AnalogDefinitions.Count; x++) { AnalogValues.Add(new AnalogValue(this, configurationCell.AnalogDefinitions[x])); } // Define any digital values for (x = 0; x < configurationCell.DigitalDefinitions.Count; x++) { DigitalValues.Add(new DigitalValue(this, configurationCell.DigitalDefinitions[x])); } } }
/// <summary> /// Creates a new <see cref="DataCell"/> from specified parameters. /// </summary> /// <param name="parent">The reference to parent <see cref="DataFrame"/> of this <see cref="DataCell"/>.</param> /// <param name="configurationCell">The <see cref="ConfigurationCell"/> associated with this <see cref="DataCell"/>.</param> /// <param name="addEmptyValues">If <c>true</c>, adds empty values for each defined configuration cell definition.</param> public DataCell(DataFrame parent, ConfigurationCell configurationCell, bool addEmptyValues) : this(parent, configurationCell) { if (!addEmptyValues) { return; } // Define needed phasor values foreach (IPhasorDefinition phasorDefinition in configurationCell.PhasorDefinitions) { PhasorValues.Add(new PhasorValue(this, phasorDefinition)); } // Define a frequency and df/dt FrequencyValue = new FrequencyValue(this, configurationCell.FrequencyDefinition); // Define any analog values foreach (IAnalogDefinition analogDefinition in configurationCell.AnalogDefinitions) { AnalogValues.Add(new AnalogValue(this, analogDefinition)); } // Define any digital values foreach (IDigitalDefinition digitalDefinition in configurationCell.DigitalDefinitions) { DigitalValues.Add(new DigitalValue(this, digitalDefinition)); } }
// Static Methods // Delegate handler to create a new BPA PDCstream configuration cell internal static IConfigurationCell CreateNewCell(IChannelFrame parent, IChannelFrameParsingState <IConfigurationCell> state, int index, byte[] buffer, int startIndex, out int parsedLength) { ConfigurationCell configCell = new ConfigurationCell(parent as IConfigurationFrame); parsedLength = configCell.ParseBinaryImage(buffer, startIndex, 0); return(configCell); }
// Static Methods // Attempts to cast given frame into a BPA PDCstream configuration frame - theoretically this will // allow the same configuration frame to be used for any protocol implementation internal static ConfigurationFrame CastToDerivedConfigurationFrame(IConfigurationFrame sourceFrame, string configurationFileName) { // See if frame is already a BPA PDCstream configuration frame (if so, we don't need to do any work) ConfigurationFrame derivedFrame = sourceFrame as ConfigurationFrame; if (derivedFrame == null) { // Create a new BPA PDCstream configuration frame converted from equivalent configuration information ConfigurationCell derivedCell; IFrequencyDefinition sourceFrequency; derivedFrame = new ConfigurationFrame(sourceFrame.Timestamp, configurationFileName, 1, RevisionNumber.Revision2, StreamType.Compact); foreach (IConfigurationCell sourceCell in sourceFrame.Cells) { // Create new derived configuration cell derivedCell = new ConfigurationCell(derivedFrame, sourceCell.IDCode, sourceCell.NominalFrequency); // Create equivalent derived phasor definitions foreach (IPhasorDefinition sourcePhasor in sourceCell.PhasorDefinitions) { derivedCell.PhasorDefinitions.Add(new PhasorDefinition(derivedCell, sourcePhasor.Label, sourcePhasor.ScalingValue, sourcePhasor.Offset, sourcePhasor.PhasorType, null)); } // Create equivalent derived frequency definition sourceFrequency = sourceCell.FrequencyDefinition; if (sourceFrequency != null) { derivedCell.FrequencyDefinition = new FrequencyDefinition(derivedCell, sourceFrequency.Label); } // Create equivalent derived analog definitions (assuming analog type = SinglePointOnWave) foreach (IAnalogDefinition sourceAnalog in sourceCell.AnalogDefinitions) { derivedCell.AnalogDefinitions.Add(new AnalogDefinition(derivedCell, sourceAnalog.Label, sourceAnalog.ScalingValue, sourceAnalog.Offset, sourceAnalog.AnalogType)); } // Create equivalent derived digital definitions foreach (IDigitalDefinition sourceDigital in sourceCell.DigitalDefinitions) { derivedCell.DigitalDefinitions.Add(new DigitalDefinition(derivedCell, sourceDigital.Label)); } // Add cell to frame derivedFrame.Cells.Add(derivedCell); } } return(derivedFrame); }
/// <summary> /// Attempts to retrieve a <see cref="ConfigurationCell"/> from this <see cref="ConfigurationCellCollection"/> with the specified <paramref name="sectionEntry"/>. /// </summary> /// <param name="sectionEntry"><see cref="ConfigurationCell.SectionEntry"/> value to try to find.</param> /// <param name="configurationCell"><see cref="ConfigurationCell"/> with the specified <paramref name="sectionEntry"/> if found; otherwise <c>null</c>.</param> /// <returns><c>true</c> if <see cref="ConfigurationCell"/> with the specified <paramref name="sectionEntry"/> is found; otherwise <c>false</c>.</returns> public bool TryGetBySectionEntry(string sectionEntry, ref ConfigurationCell configurationCell) { for (int i = 0; i < Count; i++) { configurationCell = this[i]; if (string.Compare(configurationCell.SectionEntry, sectionEntry, true) == 0) { return(true); } } configurationCell = null; return(false); }
/// <summary> /// Creates a new <see cref="FrequencyDefinition"/> from the specified parameters. /// </summary> /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="FrequencyDefinition"/>.</param> /// <param name="entryValue">The entry value from the INI based configuration file.</param> public FrequencyDefinition(ConfigurationCell parent, string entryValue) : base(parent) { string[] entry = entryValue.Split(','); FrequencyDefinition defaultFrequency; int index = 0; uint iValue; double dValue; if (parent != null) defaultFrequency = parent.Parent.DefaultFrequency; else defaultFrequency = new FrequencyDefinition(null as ConfigurationCell); // If initial entry is an F - we just ignore this if (string.Compare(entry[index].Trim(), "F", true) == 0) index++; if (entry.Length > index && uint.TryParse(entry[index++].Trim(), out iValue)) ScalingValue = iValue; else ScalingValue = defaultFrequency.ScalingValue; if (entry.Length > index && double.TryParse(entry[index++].Trim(), out dValue)) Offset = dValue; else Offset = defaultFrequency.Offset; if (entry.Length > index && uint.TryParse(entry[index++].Trim(), out iValue)) DfDtScalingValue = iValue; else DfDtScalingValue = defaultFrequency.DfDtScalingValue; if (entry.Length > index && double.TryParse(entry[index++].Trim(), out dValue)) DfDtOffset = dValue; else DfDtOffset = defaultFrequency.DfDtOffset; if (entry.Length > index && uint.TryParse(entry[index++].Trim(), out iValue)) m_dummy = iValue; else m_dummy = defaultFrequency.m_dummy; if (entry.Length > index) Label = entry[index++].Trim(); else Label = defaultFrequency.Label; }
// RowLength property calculates cell offsets - so it must be called before // accessing cell offsets - this happens automatically since HeaderImage is // called before base class BodyImage which just gets Cells.BinaryImage internal uint RowLength(bool recalculate) { if (m_rowLength == 0 || recalculate) { m_rowLength = 0; for (int x = 0; x < Cells.Count; x++) { ConfigurationCell cell = Cells[x]; cell.Offset = unchecked ((ushort)m_rowLength); m_rowLength += (8 + FrequencyValue.CalculateBinaryLength(cell.FrequencyDefinition)); for (int y = 0; y < cell.PhasorDefinitions.Count; y++) { m_rowLength += PhasorValue.CalculateBinaryLength(cell.PhasorDefinitions[y]); } } } return(m_rowLength); }
/// <summary> /// Creates a new <see cref="PhasorDefinition"/> from specified parameters. /// </summary> /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="PhasorDefinition"/>.</param> /// <param name="index">Index of phasor within INI based configuration file.</param> /// <param name="entryValue">The entry value from the INI based configuration file.</param> public PhasorDefinition(ConfigurationCell parent, int index, string entryValue) : base(parent) { string[] entry = entryValue.Split(','); string entryType = entry[0].Trim().Substring(0, 1).ToUpper(); PhasorDefinition defaultPhasor; double dValue; if (parent != null) { ConfigurationFrame configFile = this.Parent.Parent; if (entryType == "V") { PhasorType = PhasorType.Voltage; defaultPhasor = configFile.DefaultPhasorV; } else if (entryType == "I") { PhasorType = PhasorType.Current; defaultPhasor = configFile.DefaultPhasorI; } else { PhasorType = PhasorType.Voltage; defaultPhasor = configFile.DefaultPhasorV; } } else { defaultPhasor = new PhasorDefinition(null as ConfigurationCell); } if (entry.Length > 1 && double.TryParse(entry[1].Trim(), out dValue)) Ratio = dValue; else Ratio = defaultPhasor.Ratio; if (entry.Length > 2 && double.TryParse(entry[2].Trim(), out dValue)) CalFactor = dValue; else CalFactor = defaultPhasor.CalFactor; if (entry.Length > 3 && double.TryParse(entry[3].Trim(), out dValue)) Offset = dValue; else Offset = defaultPhasor.Offset; if (entry.Length > 4 && double.TryParse(entry[4].Trim(), out dValue)) Shunt = dValue; else Shunt = defaultPhasor.Shunt; if (entry.Length > 5 && double.TryParse(entry[5].Trim(), out dValue)) VoltageReferenceIndex = (int)dValue; else VoltageReferenceIndex = defaultPhasor.VoltageReferenceIndex; if (entry.Length > 6) Label = entry[6].Trim(); else Label = defaultPhasor.Label; this.Index = index; }
// Static Methods // Delegate handler to create a new BPA PDCstream configuration cell internal static IConfigurationCell CreateNewCell(IChannelFrame parent, IChannelFrameParsingState<IConfigurationCell> state, int index, byte[] buffer, int startIndex, out int parsedLength) { ConfigurationCell configCell = new ConfigurationCell(parent as IConfigurationFrame); parsedLength = configCell.ParseBinaryImage(buffer, startIndex, 0); return configCell; }
/// <summary> /// Creates a new <see cref="AnalogDefinition"/> from specified parameters. /// </summary> /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="AnalogDefinition"/>.</param> /// <param name="label">The label of this <see cref="AnalogDefinition"/>.</param> /// <param name="scale">The integer scaling value of this <see cref="AnalogDefinition"/>.</param> /// <param name="offset">The offset of this <see cref="AnalogDefinition"/>.</param> /// <param name="type">The <see cref="AnalogType"/> of this <see cref="AnalogDefinition"/>.</param> public AnalogDefinition(ConfigurationCell parent, string label, uint scale, double offset, AnalogType type) : base(parent, label, scale, offset, type) { }
/// <summary> /// Creates a new <see cref="DigitalDefinition"/> from specified parameters. /// </summary> /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="DigitalDefinition"/>.</param> /// <param name="label">The label of this <see cref="DigitalDefinition"/>.</param> public DigitalDefinition(ConfigurationCell parent, string label) : base(parent, label) { }
/// <summary> /// Creates a new <see cref="PhasorDefinition"/> from specified parameters. /// </summary> /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="PhasorDefinition"/>.</param> /// <param name="index">Index of phasor within INI based configuration file.</param> /// <param name="entryValue">The entry value from the INI based configuration file.</param> public PhasorDefinition(ConfigurationCell parent, int index, string entryValue) : base(parent) { string[] entry = entryValue.Split(','); string entryType = entry[0].Trim().Substring(0, 1).ToUpper(); PhasorDefinition defaultPhasor; double dValue; if (parent != null) { ConfigurationFrame configFile = this.Parent.Parent; if (entryType == "V") { PhasorType = PhasorType.Voltage; defaultPhasor = configFile.DefaultPhasorV; } else if (entryType == "I") { PhasorType = PhasorType.Current; defaultPhasor = configFile.DefaultPhasorI; } else { PhasorType = PhasorType.Voltage; defaultPhasor = configFile.DefaultPhasorV; } } else { defaultPhasor = new PhasorDefinition(null as ConfigurationCell); } if (entry.Length > 1 && double.TryParse(entry[1].Trim(), out dValue)) { Ratio = dValue; } else { Ratio = defaultPhasor.Ratio; } if (entry.Length > 2 && double.TryParse(entry[2].Trim(), out dValue)) { CalFactor = dValue; } else { CalFactor = defaultPhasor.CalFactor; } if (entry.Length > 3 && double.TryParse(entry[3].Trim(), out dValue)) { Offset = dValue; } else { Offset = defaultPhasor.Offset; } if (entry.Length > 4 && double.TryParse(entry[4].Trim(), out dValue)) { Shunt = dValue; } else { Shunt = defaultPhasor.Shunt; } if (entry.Length > 5 && double.TryParse(entry[5].Trim(), out dValue)) { VoltageReferenceIndex = (int)dValue; } else { VoltageReferenceIndex = defaultPhasor.VoltageReferenceIndex; } if (entry.Length > 6) { Label = entry[6].Trim(); } else { Label = defaultPhasor.Label; } this.Index = index; }
public void Refresh(bool refreshCausedByFrameParse) { // The only time we need an access lock is when we reload the config file... lock (m_iniFile) { if (File.Exists(m_iniFile.FileName)) { ConfigurationCell pmuCell; int phasorCount, pmuCount, x, y; m_defaultPhasorV = new PhasorDefinition(null, 0, m_iniFile["DEFAULT", "PhasorV", DefaultVoltagePhasorEntry]); m_defaultPhasorI = new PhasorDefinition(null, 0, m_iniFile["DEFAULT", "PhasorI", DefaultCurrentPhasorEntry]); m_defaultFrequency = new FrequencyDefinition(null, m_iniFile["DEFAULT", "Frequency", DefaultFrequencyEntry]); FrameRate = ushort.Parse(m_iniFile["CONFIG", "SampleRate", "30"]); // We read all cells in the config file into their own configuration cell collection - cells parsed // from the configuration frame will be mapped to their associated config file cell by ID label // when the configuration cell is parsed from the configuration frame if (m_configurationFileCells == null) { m_configurationFileCells = new ConfigurationCellCollection(); } m_configurationFileCells.Clear(); // Load phasor data for each section in config file... foreach (string section in m_iniFile.GetSectionNames()) { if (section.Length > 0) { // Make sure this is not a special section if (string.Compare(section, "DEFAULT", true) != 0 && string.Compare(section, "CONFIG", true) != 0) { // Create new PMU entry structure from config file settings... phasorCount = int.Parse(m_iniFile[section, "NumberPhasors", "0"]); // Check for PDC code int pdcID = int.Parse(m_iniFile[section, "PDC", "-1"]); if (pdcID == -1) { // No PDC entry exists, assume this is a PMU pmuCell = new ConfigurationCell(this, 0); pmuCell.IDCode = ushort.Parse(m_iniFile[section, "PMU", Cells.Count.ToString()]); pmuCell.SectionEntry = section; // This will automatically assign ID label as first 4 digits of section pmuCell.StationName = m_iniFile[section, "Name", section]; for (x = 0; x < phasorCount; x++) { pmuCell.PhasorDefinitions.Add(new PhasorDefinition(pmuCell, x + 1, m_iniFile[section, "Phasor" + (x + 1), DefaultVoltagePhasorEntry])); } pmuCell.FrequencyDefinition = new FrequencyDefinition(pmuCell, m_iniFile[section, "Frequency", DefaultFrequencyEntry]); m_configurationFileCells.Add(pmuCell); } else { // This is a PDC, need to define one virtual entry for each PMU pmuCount = int.Parse(m_iniFile[section, "NumberPMUs", "0"]); for (x = 0; x < pmuCount; x++) { // Create a new PMU cell for each PDC entry that exists pmuCell = new ConfigurationCell(this, 0); // For BPA INI files, PMUs tradionally have an ID number indexed starting at zero or one - so we multiply // ID by 1000 and add index to attempt to create a fairly unique ID to help optimize downstream parsing pmuCell.IDCode = unchecked ((ushort)(pdcID * 1000 + x)); pmuCell.SectionEntry = string.Format("{0}pmu{1}", section, x); // This will automatically assign ID label as first 4 digits of section pmuCell.StationName = string.Format("{0} - Device {1}", m_iniFile[section, "Name", section], (x + 1)); for (y = 0; y < 2; y++) { pmuCell.PhasorDefinitions.Add(new PhasorDefinition(pmuCell, y + 1, m_iniFile[section, "Phasor" + ((x * 2) + (y + 1)), DefaultVoltagePhasorEntry])); } pmuCell.FrequencyDefinition = new FrequencyDefinition(pmuCell, m_iniFile[section, "Frequency", DefaultFrequencyEntry]); m_configurationFileCells.Add(pmuCell); } } } } } // Associate parsed cells with cells defined in INI file if (m_configurationFileCells.Count > 0 && (Cells != null)) { ConfigurationCell configurationFileCell = null; IConfigurationCell configurationCell = null; if (refreshCausedByFrameParse) { // Create a new configuration cell collection that will account for PDC block cells ConfigurationCellCollection cellCollection = new ConfigurationCellCollection(); ConfigurationCell cell; // For freshly parsed configuration frames we'll have no PMU's in configuration // frame for PDCxchng blocks - so we'll need to dynamically create them for (x = 0; x < Cells.Count; x++) { // Get current configuration cell cell = Cells[x]; // Lookup INI file configuration cell by ID label m_configurationFileCells.TryGetByIDLabel(cell.IDLabel, out configurationCell); configurationFileCell = (ConfigurationCell)configurationCell; if (configurationFileCell == null) { // Couldn't find associated INI file cell - just append the parsed cell to the collection cellCollection.Add(cell); } else { if (configurationFileCell.IsPdcBlockSection) { // This looks like a PDC block section - so we'll keep adding cells for each defined PMU in the PDC block int index = 0; do { // Lookup PMU by section name m_configurationFileCells.TryGetBySectionEntry(string.Format("{0}pmu{1}", cell.IDLabel, index), ref configurationFileCell); // Add PDC block PMU configuration cell to the collection if (configurationFileCell != null) { cellCollection.Add(configurationFileCell); } index++; }while (configurationFileCell != null); } else { // As far as we can tell from INI file, this is just a regular PMU cell.ConfigurationFileCell = configurationFileCell; cellCollection.Add(cell); } } } // Assign "new" cell collection which will include PMU's from defined PDC blocks Cells.Clear(); Cells.AddRange(cellCollection); } else { // For simple INI file updates, we just re-assign INI file cells associating by section entry foreach (ConfigurationCell cell in Cells) { // Attempt to associate this configuration cell with information read from external INI based configuration file m_configurationFileCells.TryGetBySectionEntry(cell.SectionEntry, ref configurationFileCell); cell.ConfigurationFileCell = configurationFileCell; } } } } else { throw new InvalidOperationException("PDC config file \"" + m_iniFile.FileName + "\" does not exist."); } } // In case other classes want to know, we send out a notification that the config file has been reloaded (make sure // you do this after the write lock has been released to avoid possible dead-lock situations) if (ConfigurationFileReloaded != null) { ConfigurationFileReloaded(this, EventArgs.Empty); } }
/// <summary> /// Creates a new <see cref="PhasorDefinition"/> from specified parameters. /// </summary> /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="PhasorDefinition"/>.</param> /// <param name="index">Index of phasor within INI based configuration file.</param> /// <param name="entryValue">The entry value from the INI based configuration file.</param> public PhasorDefinition(ConfigurationCell parent, int index, string entryValue) : base(parent) { string[] entry = entryValue.Split(','); string entryType = entry[0].Trim().Substring(0, 1).ToUpper(); PhasorDefinition defaultPhasor; if (parent is null) { defaultPhasor = new PhasorDefinition(null); } else { ConfigurationFrame configFile = Parent.Parent; switch (entryType) { case "V": PhasorType = PhasorType.Voltage; defaultPhasor = configFile.DefaultPhasorV; break; case "I": PhasorType = PhasorType.Current; defaultPhasor = configFile.DefaultPhasorI; break; default: PhasorType = PhasorType.Voltage; defaultPhasor = configFile.DefaultPhasorV; break; } } if (entry.Length > 1 && double.TryParse(entry[1].Trim(), out double dValue)) { Ratio = dValue; } else { Ratio = defaultPhasor.Ratio; } if (entry.Length > 2 && double.TryParse(entry[2].Trim(), out dValue)) { CalFactor = dValue; } else { CalFactor = defaultPhasor.CalFactor; } if (entry.Length > 3 && double.TryParse(entry[3].Trim(), out dValue)) { Offset = dValue; } else { Offset = defaultPhasor.Offset; } if (entry.Length > 4 && double.TryParse(entry[4].Trim(), out dValue)) { Shunt = dValue; } else { Shunt = defaultPhasor.Shunt; } if (entry.Length > 5 && double.TryParse(entry[5].Trim(), out dValue)) { VoltageReferenceIndex = (int)dValue; } else { VoltageReferenceIndex = defaultPhasor.VoltageReferenceIndex; } Label = entry.Length > 6 ? entry[6].Trim() : defaultPhasor.Label; Index = index; }
/// <summary> /// Creates a new <see cref="FrequencyDefinition"/> from the specified parameters. /// </summary> /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="FrequencyDefinition"/>.</param> /// <param name="entryValue">The entry value from the INI based configuration file.</param> public FrequencyDefinition(ConfigurationCell parent, string entryValue) : base(parent) { string[] entry = entryValue.Split(','); int index = 0; FrequencyDefinition defaultFrequency = parent is null ? new FrequencyDefinition(null) : parent.Parent.DefaultFrequency; // If initial entry is an F - we just ignore this if (string.Equals(entry[index].Trim(), "F", StringComparison.OrdinalIgnoreCase)) { index++; } if (entry.Length > index && uint.TryParse(entry[index++].Trim(), out uint iValue)) { ScalingValue = iValue; } else { ScalingValue = defaultFrequency.ScalingValue; } if (entry.Length > index && double.TryParse(entry[index++].Trim(), out double dValue)) { Offset = dValue; } else { Offset = defaultFrequency.Offset; } if (entry.Length > index && uint.TryParse(entry[index++].Trim(), out iValue)) { DfDtScalingValue = iValue; } else { DfDtScalingValue = defaultFrequency.DfDtScalingValue; } if (entry.Length > index && double.TryParse(entry[index++].Trim(), out dValue)) { DfDtOffset = dValue; } else { DfDtOffset = defaultFrequency.DfDtOffset; } if (entry.Length > index && uint.TryParse(entry[index++].Trim(), out iValue)) { m_dummy = iValue; } else { m_dummy = defaultFrequency.m_dummy; } Label = entry.Length > index ? entry[index].Trim() : defaultFrequency.Label; }
/// <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; }
/// <summary> /// Creates a new <see cref="PhasorDefinition"/> from specified parameters. /// </summary> /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="PhasorDefinition"/>.</param> /// <param name="label">The label of this <see cref="PhasorDefinition"/>.</param> /// <param name="scale">The integer scaling value of this <see cref="PhasorDefinition"/>.</param> /// <param name="offset">The offset of this <see cref="PhasorDefinition"/>.</param> /// <param name="type">The <see cref="PhasorType"/> of this <see cref="PhasorDefinition"/>.</param> /// <param name="voltageReference">The associated <see cref="IPhasorDefinition"/> that represents the voltage reference (if any).</param> public PhasorDefinition(ConfigurationCell parent, string label, uint scale, double offset, PhasorType type, PhasorDefinition voltageReference) : base(parent, label, scale, offset, type, voltageReference) { }
/// <summary> /// Creates a new <see cref="FrequencyDefinition"/> from the specified parameters. /// </summary> /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="FrequencyDefinition"/>.</param> /// <param name="entryValue">The entry value from the INI based configuration file.</param> public FrequencyDefinition(ConfigurationCell parent, string entryValue) : base(parent) { string[] entry = entryValue.Split(','); FrequencyDefinition defaultFrequency; int index = 0; uint iValue; double dValue; if (parent != null) { defaultFrequency = parent.Parent.DefaultFrequency; } else { defaultFrequency = new FrequencyDefinition(null as ConfigurationCell); } // If initial entry is an F - we just ignore this if (string.Compare(entry[index].Trim(), "F", true) == 0) { index++; } if (entry.Length > index && uint.TryParse(entry[index++].Trim(), out iValue)) { ScalingValue = iValue; } else { ScalingValue = defaultFrequency.ScalingValue; } if (entry.Length > index && double.TryParse(entry[index++].Trim(), out dValue)) { Offset = dValue; } else { Offset = defaultFrequency.Offset; } if (entry.Length > index && uint.TryParse(entry[index++].Trim(), out iValue)) { DfDtScalingValue = iValue; } else { DfDtScalingValue = defaultFrequency.DfDtScalingValue; } if (entry.Length > index && double.TryParse(entry[index++].Trim(), out dValue)) { DfDtOffset = dValue; } else { DfDtOffset = defaultFrequency.DfDtOffset; } if (entry.Length > index && uint.TryParse(entry[index++].Trim(), out iValue)) { m_dummy = iValue; } else { m_dummy = defaultFrequency.m_dummy; } if (entry.Length > index) { Label = entry[index++].Trim(); } else { Label = defaultFrequency.Label; } }
/// <summary> /// Attempts to retrieve a <see cref="ConfigurationCell"/> from this <see cref="ConfigurationCellCollection"/> with the specified <paramref name="sectionEntry"/>. /// </summary> /// <param name="sectionEntry"><see cref="ConfigurationCell.SectionEntry"/> value to try to find.</param> /// <param name="configurationCell"><see cref="ConfigurationCell"/> with the specified <paramref name="sectionEntry"/> if found; otherwise <c>null</c>.</param> /// <returns><c>true</c> if <see cref="ConfigurationCell"/> with the specified <paramref name="sectionEntry"/> is found; otherwise <c>false</c>.</returns> public bool TryGetBySectionEntry(string sectionEntry, ref ConfigurationCell configurationCell) { for (int i = 0; i < Count; i++) { configurationCell = this[i]; if (string.Compare(configurationCell.SectionEntry, sectionEntry, true) == 0) return true; } configurationCell = null; return false; }