/// <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; IPhasorValue phasorValue; int x, parsedLength, index = startIndex; // Parse out frequency value FrequencyValue = SelFastMessage.FrequencyValue.CreateNewValue(this, configCell.FrequencyDefinition, buffer, index, out parsedLength); index += parsedLength; // Parse out phasor values for (x = 0; x < configCell.PhasorDefinitions.Count; x++) { phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[x], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // Parse out status flags StatusFlags = (StatusFlags)BigEndian.ToUInt16(buffer, index); index += 2; // Return total parsed length return(index - startIndex); }
// Attempts to cast given frame into a SEL Fast Message configuration frame - theoretically this will // allow the same configuration frame to be used for any protocol implementation internal static ConfigurationFrame CastToDerivedConfigurationFrame(IConfigurationFrame sourceFrame, MessagePeriod messagePeriod) { // See if frame is already a SEL Fast Message frame (if so, we don't need to do any work) ConfigurationFrame derivedFrame = sourceFrame as ConfigurationFrame; if (derivedFrame == null) { // Create a new SEL Fast Message configuration frame converted from equivalent configuration information; SEL Fast Message only supports one device if (sourceFrame.Cells.Count > 0) { IConfigurationCell sourceCell = sourceFrame.Cells[0]; switch (sourceCell.PhasorDefinitions.Count) { case 8: derivedFrame = new ConfigurationFrame(FrameSize.A, messagePeriod, sourceFrame.IDCode); break; case 4: derivedFrame = new ConfigurationFrame(FrameSize.V, messagePeriod, sourceFrame.IDCode); break; default: derivedFrame = new ConfigurationFrame(FrameSize.V1, messagePeriod, sourceFrame.IDCode); break; } // 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, sourceFrequency.Label); } // Add cell to frame derivedFrame.Cells.Add(derivedCell); } } return(derivedFrame); }
/// <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); }
/// <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="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> /// Creates a new <see cref="ConfigurationFrame"/>. /// </summary> /// <remarks> /// This constructor is used by a consumer to generate a SEL Fast Message configuration frame. /// </remarks> /// <param name="frameSize">A <see cref="FrameSize"/> object.</param> /// <param name="idCode">An <see cref="uint"/> as the id code.</param> /// <param name="messagePeriod">A <see cref="MessagePeriod"/> object.</param> public ConfigurationFrame(FrameSize frameSize, MessagePeriod messagePeriod, uint idCode) : base(0, new ConfigurationCellCollection(), 0, 0) { m_frameSize = frameSize; m_messagePeriod = messagePeriod; IDCode = idCode; ConfigurationCell configCell = new ConfigurationCell(this); // Assign station name configCell.StationName = "SEL Unit - " + idCode; // Add a single frequency definition configCell.FrequencyDefinition = new FrequencyDefinition(configCell, "Line frequency"); // Add phasors based on frame size switch (frameSize) { case FrameSize.V1: // Add a single positive sequence voltage phasor definition configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "V1", PhasorType.Voltage, null)); break; case FrameSize.V: // Add three-phase and positive sequence voltage phasors configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "VA", PhasorType.Voltage, null)); configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "VB", PhasorType.Voltage, null)); configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "VC", PhasorType.Voltage, null)); configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "V1", PhasorType.Voltage, null)); break; case FrameSize.A: // Add three-phase and positive sequence voltage and current phasors configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "VA", PhasorType.Voltage, null)); configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "VB", PhasorType.Voltage, null)); configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "VC", PhasorType.Voltage, null)); configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "V1", PhasorType.Voltage, null)); configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "IA", PhasorType.Current, configCell.PhasorDefinitions[0] as PhasorDefinition)); configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "IB", PhasorType.Current, configCell.PhasorDefinitions[1] as PhasorDefinition)); configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "IC", PhasorType.Current, configCell.PhasorDefinitions[2] as PhasorDefinition)); configCell.PhasorDefinitions.Add(new PhasorDefinition(configCell, "I1", PhasorType.Current, configCell.PhasorDefinitions[3] as PhasorDefinition)); break; } // SEL Fast Message protocol sends data for one device Cells.Add(configCell); // Define message rate (best-fit) switch (messagePeriod) { case MessagePeriod.DefaultRate: case MessagePeriod.TwentyPerSecond: FrameRate = 20; break; case MessagePeriod.TenPerSecond: FrameRate = 10; break; case MessagePeriod.FivePerSecond: FrameRate = 5; break; case MessagePeriod.FourPerSecond: FrameRate = 4; break; case MessagePeriod.TwoPerSecond: FrameRate = 2; break; case MessagePeriod.OnePerSecond: FrameRate = 1; break; default: FrameRate = 0; break; } }
/// <summary> /// Creates a new <see cref="FrequencyDefinition"/> from specified parameters. /// </summary> /// <param name="parent">The <see cref="ConfigurationCell"/> parent of this <see cref="FrequencyDefinition"/>.</param> /// <param name="label">The label of this <see cref="FrequencyDefinition"/>.</param> public FrequencyDefinition(ConfigurationCell parent, string label) : base(parent, label, 1000, 100, 0.0D) { }