/// <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.Compare(entry[index].Trim(), "F", StringComparison.OrdinalIgnoreCase) == 0) { index++; } ScalingValue = entry.Length > index?uint.Parse(entry[index++].Trim()) : defaultFrequency.ScalingValue; Offset = entry.Length > index?double.Parse(entry[index++].Trim()) : defaultFrequency.Offset; DfDtScalingValue = entry.Length > index?uint.Parse(entry[index++].Trim()) : defaultFrequency.DfDtScalingValue; DfDtOffset = entry.Length > index?double.Parse(entry[index++].Trim()) : defaultFrequency.DfDtOffset; m_dummy = entry.Length > index?int.Parse(entry[index++].Trim()) : defaultFrequency.m_dummy; Label = entry.Length > index ? entry[index].Trim() : defaultFrequency.Label; }
// Attempts to cast given frame into a Macrodyne 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, string deviceLabel) { // See if frame is already a Macrodyne frame (if so, we don't need to do any work) ConfigurationFrame derivedFrame = sourceFrame as ConfigurationFrame; if (derivedFrame == null) { // Create a new Macrodyne configuration frame converted from equivalent configuration information; Macrodyne only supports one device if (sourceFrame.Cells.Count > 0) { IConfigurationCell sourceCell = sourceFrame.Cells[0]; string stationName = sourceCell.StationName; if (string.IsNullOrEmpty(stationName)) { stationName = "Unit " + sourceCell.IDCode.ToString(); } stationName = stationName.TruncateLeft(8); derivedFrame = new ConfigurationFrame(Common.GetFormatFlagsFromPhasorCount(sourceFrame.Cells[0].PhasorDefinitions.Count), stationName, configurationFileName, deviceLabel); derivedFrame.IDCode = sourceFrame.IDCode; // Create new derived configuration cell ConfigurationCell derivedCell = new ConfigurationCell(derivedFrame); IFrequencyDefinition sourceFrequency; // Create equivalent derived phasor definitions foreach (IPhasorDefinition sourcePhasor in sourceCell.PhasorDefinitions) { derivedCell.PhasorDefinitions.Add(new PhasorDefinition(derivedCell, sourcePhasor.Label, sourcePhasor.PhasorType, null)); } // Create equivalent derived frequency definition sourceFrequency = sourceCell.FrequencyDefinition; if (sourceFrequency != null) { derivedCell.FrequencyDefinition = new FrequencyDefinition(derivedCell) { Label = sourceFrequency.Label }; } // 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> /// 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; } } Ratio = entry.Length > 1 ? double.Parse(entry[1].Trim()) : defaultPhasor.Ratio; if (entry.Length > 2) { CalFactor = double.Parse(entry[2].Trim()); } else { ConversionFactor = defaultPhasor.ConversionFactor; } Offset = entry.Length > 3 ? double.Parse(entry[3].Trim()) : defaultPhasor.Offset; Shunt = entry.Length > 4 ? double.Parse(entry[4].Trim()) : defaultPhasor.Shunt; VoltageReferenceIndex = entry.Length > 5 ? (int)double.Parse(entry[5].Trim()) : defaultPhasor.VoltageReferenceIndex; Label = entry.Length > 6 ? entry[6].Trim() : defaultPhasor.Label; Index = index; }
/// <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="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); } }
/// <summary> /// Creates a new <see cref="ConfigurationFrame"/>. /// </summary> /// <param name="onlineDataFormatFlags">Online data format flags to use in this Macrodyne <see cref="ConfigurationFrame"/>.</param> /// <param name="unitID">8 character unit ID to use in this Macrodyne <see cref="ConfigurationFrame"/>.</param> /// <param name="configurationFileName">INI configuration file name, if specified.</param> /// <param name="deviceLabel">INI section name.</param> /// <remarks> /// This constructor is used by a consumer to generate a Macrodyne configuration frame. /// </remarks> public ConfigurationFrame(OnlineDataFormatFlags onlineDataFormatFlags, string unitID, string configurationFileName = null, string deviceLabel = null) : base(0, new ConfigurationCellCollection(), 0, 0) { m_onlineDataFormatFlags = onlineDataFormatFlags; m_stationName = unitID; ConfigurationCell configCell = new ConfigurationCell(this, deviceLabel); // Macrodyne protocol sends data for one device Cells.Add(configCell); if (!string.IsNullOrEmpty(configurationFileName)) { m_iniFile = new IniFile(configurationFileName); } Refresh(); }
/// <summary> /// Creates a new <see cref="ConfigurationCell"/> from serialization parameters. /// </summary> /// <param name="info">The <see cref="SerializationInfo"/> with populated with data.</param> /// <param name="context">The source <see cref="StreamingContext"/> for this deserialization.</param> protected ConfigurationCell(SerializationInfo info, StreamingContext context) : base(info, context) { // Deserialize configuration cell try { m_sectionEntry = info.GetString("sectionEntry"); } catch (SerializationException) { m_sectionEntry = null; } try { m_configurationFileCell = info.GetValue("configurationFileCell", typeof(ConfigurationCell)) as ConfigurationCell; } catch (SerializationException) { m_configurationFileCell = null; } }
/// <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> /// Parses the binary body image. /// </summary> /// <param name="buffer">Binary image to parse.</param> /// <param name="startIndex">Start index into <paramref name="buffer"/> to begin parsing.</param> /// <param name="length">Length of valid data within <paramref name="buffer"/>.</param> /// <returns>The length of the data that was parsed.</returns> protected override int ParseBodyImage(byte[] buffer, int startIndex, int length) { ConfigurationCell configCell = ConfigurationCell; ConfigurationFrame configFrame = configCell.Parent; ProtocolVersion protocolVersion = configFrame.CommonHeader.ProtocolVersion; IPhasorValue phasorValue; IDigitalValue digitalValue; int parsedLength, index = startIndex; if (protocolVersion == ProtocolVersion.M) { // Parse out optional STATUS2 flags if (configFrame.Status2Included) { m_status2Flags = buffer[index]; index++; } else { m_status2Flags = 0; } // We interpret status bytes together as one word (matches other protocols this way) base.StatusFlags = Word.MakeWord((byte)Status1Flags, m_status2Flags); } else { // Read sample number for G protocol m_sampleNumber = BigEndian.ToUInt16(buffer, index); index += 2; } // Parse out time tag if (configFrame.TimestampIncluded) { m_clockStatusFlags = (ClockStatusFlags)buffer[index]; index += 1; ushort day = BinaryCodedDecimal.Decode(BigEndian.ToUInt16(buffer, index)); byte hours = BinaryCodedDecimal.Decode(buffer[index + 2]); byte minutes = BinaryCodedDecimal.Decode(buffer[index + 3]); byte seconds = BinaryCodedDecimal.Decode(buffer[index + 4]); double timebase = 2880.0D; index += 5; // Read sample number for M protocol if (protocolVersion == ProtocolVersion.M) { m_sampleNumber = BigEndian.ToUInt16(buffer, index + 5); timebase = 719.0D; index += 2; } // TODO: Think about how to handle year change with floating clock... // Calculate timestamp Parent.Timestamp = new DateTime(DateTime.UtcNow.Year, 1, 1).AddDays(day - 1).AddHours(hours).AddMinutes(minutes).AddSeconds(seconds + m_sampleNumber / timebase); } else { Parent.Timestamp = DateTime.UtcNow.Ticks; SynchronizationIsValid = false; m_sampleNumber = BigEndian.ToUInt16(buffer, index); index += 2; } // Parse out first five phasor values (1 - 5) int phasorIndex = 0; // Phasor 1 (always present) phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor2Enabled) == OnlineDataFormatFlags.Phasor2Enabled) { // Phasor 2 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor3Enabled) == OnlineDataFormatFlags.Phasor3Enabled) { // Phasor 3 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor4Enabled) == OnlineDataFormatFlags.Phasor4Enabled) { // Phasor 4 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor5Enabled) == OnlineDataFormatFlags.Phasor5Enabled) { // Phasor 5 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // For 1690M format the frequency, reference phasor, dF/dt and first digital follow phasors 1-5 if (protocolVersion == ProtocolVersion.M) { // Parse out frequency value FrequencyValue = Macrodyne.FrequencyValue.CreateNewValue(this, configCell.FrequencyDefinition, buffer, index, out parsedLength); index += parsedLength; // Parse reference phasor information if (configFrame.ReferenceIncluded) { m_referenceSampleNumber = BigEndian.ToUInt16(buffer, index); m_referencePhasor = PhasorValue.CreateNewValue(this, new PhasorDefinition(null, "Reference Phasor", PhasorType.Voltage, null), buffer, index, out parsedLength) as PhasorValue; index += 6; } // Parse first digital value if (configFrame.Digital1Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[0], buffer, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } } // Parse out next five phasor values (6 - 10) if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor6Enabled) == OnlineDataFormatFlags.Phasor6Enabled) { // Phasor 6 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor7Enabled) == OnlineDataFormatFlags.Phasor7Enabled) { // Phasor 7 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor8Enabled) == OnlineDataFormatFlags.Phasor8Enabled) { // Phasor 8 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor9Enabled) == OnlineDataFormatFlags.Phasor9Enabled) { // Phasor 9 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor10Enabled) == OnlineDataFormatFlags.Phasor10Enabled) { // Phasor 10 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // For 1690G format the channel phasors, reference phasor, frequency, dF/dt and digitals follow phasors 1-10 if (protocolVersion == ProtocolVersion.G) { // Technically 30 more possible channel phasors can be defined for (int i = phasorIndex; i < ConfigurationCell.PhasorDefinitions.Count; i++) { phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // Parse reference phasor information if (configFrame.ReferenceIncluded) { m_referencePhasor = PhasorValue.CreateNewValue(this, new PhasorDefinition(null, "Reference Phasor", PhasorType.Voltage, null), buffer, index, out parsedLength) as PhasorValue; index += parsedLength; } // Parse out frequency value FrequencyValue = Macrodyne.FrequencyValue.CreateNewValue(this, configCell.FrequencyDefinition, buffer, index, out parsedLength); index += parsedLength; // Parse first digital value if (configFrame.Digital1Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[0], buffer, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } } // Parse second digital value if (configFrame.Digital2Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[configCell.DigitalDefinitions.Count - 1], buffer, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } // Return total parsed length return(index - startIndex); }
/// <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="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, PhasorType type, PhasorDefinition voltageReference) : base(parent, label, 1, 0.0D, type, voltageReference) { }
/// <summary> /// Reload Macrodyne INI based configuration file. /// </summary> public void Refresh() { if ((object)m_iniFile == null) { return; } // 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(int.MaxValue); } 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); 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]; pmuCell.PhasorDefinitions.Clear(); 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); // 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)); pmuCell.PhasorDefinitions.Clear(); 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 single Macrodyne cell with its associated cell hopefully defined in INI file if (m_configurationFileCells.Count > 0 && (object)Cells != null && Cells.Count > 0) { ConfigurationCell configurationFileCell = null; // Assign INI file cell associating by section entry ConfigurationCell cell = Cells[0]; // 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; m_onlineDataFormatFlags = Common.GetFormatFlagsFromPhasorCount(cell.PhasorDefinitions.Count); m_stationName = cell.StationName; } } else { throw new InvalidOperationException("Macrodyne 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="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; if (parent != null) { defaultFrequency = parent.Parent.DefaultFrequency; } else { defaultFrequency = new FrequencyDefinition(null as IConfigurationCell); } // If initial entry is an F - we just ignore this if (string.Compare(entry[index].Trim(), "F", StringComparison.OrdinalIgnoreCase) == 0) { index++; } if (entry.Length > index) { ScalingValue = uint.Parse(entry[index++].Trim()); } else { ScalingValue = defaultFrequency.ScalingValue; } if (entry.Length > index) { Offset = double.Parse(entry[index++].Trim()); } else { Offset = defaultFrequency.Offset; } if (entry.Length > index) { DfDtScalingValue = uint.Parse(entry[index++].Trim()); } else { DfDtScalingValue = defaultFrequency.DfDtScalingValue; } if (entry.Length > index) { DfDtOffset = double.Parse(entry[index++].Trim()); } else { DfDtOffset = defaultFrequency.DfDtOffset; } if (entry.Length > index) { m_dummy = int.Parse(entry[index++].Trim()); } else { m_dummy = defaultFrequency.m_dummy; } if (entry.Length > index) { Label = entry[index++].Trim(); } else { Label = defaultFrequency.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; 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) { Ratio = double.Parse(entry[1].Trim()); } else { Ratio = defaultPhasor.Ratio; } if (entry.Length > 2) { CalFactor = double.Parse(entry[2].Trim()); } else { ConversionFactor = defaultPhasor.ConversionFactor; } if (entry.Length > 3) { Offset = double.Parse(entry[3].Trim()); } else { Offset = defaultPhasor.Offset; } if (entry.Length > 4) { Shunt = double.Parse(entry[4].Trim()); } else { Shunt = defaultPhasor.Shunt; } if (entry.Length > 5) { VoltageReferenceIndex = (int)double.Parse(entry[5].Trim()); } else { VoltageReferenceIndex = defaultPhasor.VoltageReferenceIndex; } if (entry.Length > 6) { Label = entry[6].Trim(); } else { Label = defaultPhasor.Label; } this.Index = index; }