//****************************************************************************************************** // ConfigurationFrame.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 04/26/2009 - J. Ritchie Carroll // Generated original version of source code. // 08/07/2009 - Josh L. Patterson // Edited Comments. // 09/15/2009 - Stephen C. Wills // Added new header and license agreement. // 12/17/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.Runtime.Serialization; using GSF.Units.EE; namespace GSF.PhasorProtocols.SelFastMessage { /// /// Represents the SEL Fast Message implementation of a that can be sent or received. /// [Serializable] public class ConfigurationFrame : ConfigurationFrameBase { #region [ Members ] // Fields private uint m_idCode; #endregion #region [ Constructors ] /// /// Creates a new . /// /// /// This constructor is used by a consumer to generate a SEL Fast Message configuration frame. /// /// A object. /// An as the id code. /// A object. public ConfigurationFrame(FrameSize frameSize, MessagePeriod messagePeriod, uint idCode) : base(0, new ConfigurationCellCollection(), 0, 0) { FrameSize = frameSize; MessagePeriod = messagePeriod; IDCode = idCode; ConfigurationCell configCell = new(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) FrameRate = messagePeriod switch { MessagePeriod.DefaultRate or MessagePeriod.TwentyPerSecond => 20, MessagePeriod.TenPerSecond => 10, MessagePeriod.FivePerSecond => 5, MessagePeriod.FourPerSecond => 4, MessagePeriod.TwoPerSecond => 2, MessagePeriod.OnePerSecond => 1, _ => 0, }; } /// /// Creates a new from serialization parameters. /// /// The with populated with data. /// The source for this deserialization. protected ConfigurationFrame(SerializationInfo info, StreamingContext context) : base(info, context) { // Deserialize configuration frame FrameSize = (FrameSize)info.GetValue("frameSize", typeof(FrameSize)); MessagePeriod = (MessagePeriod)info.GetValue("messagePeriod", typeof(MessagePeriod)); m_idCode = info.GetUInt32("idCode32Bit"); } #endregion #region [ Properties ] /// /// Gets reference to the for this . /// public new ConfigurationCellCollection Cells => base.Cells as ConfigurationCellCollection; /// /// Gets the SEL Fast Message frame size of this . /// public FrameSize FrameSize { get; } /// /// Gets defined for SEL device. /// public MessagePeriod MessagePeriod { get; } /// /// Gets or sets the ID code of this . /// public new uint IDCode { get => m_idCode; set { m_idCode = value; // Base classes constrain maximum value to 65535 base.IDCode = value > ushort.MaxValue ? ushort.MaxValue : (ushort)value; } } /// /// of string based property names and values for the object. /// public override Dictionary Attributes { get { Dictionary baseAttributes = base.Attributes; baseAttributes.Add("Frame Size", $"{(byte)FrameSize}: {FrameSize}"); baseAttributes.Add("Defined Message Period", $"{(ushort)MessagePeriod}: {MessagePeriod}"); baseAttributes.Add("32-Bit ID Code", IDCode.ToString()); return baseAttributes; } } #endregion #region [ Methods ] /// /// Determines if checksum in the is valid. /// /// Buffer image to validate. /// Start index into to perform checksum. /// Flag that determines if checksum over is valid. /// /// SEL Fast Message doesn't define a binary configuration frame - so no checksum is defined - this always returns true. /// protected override bool ChecksumIsValid(byte[] buffer, int startIndex) { return true; } /// /// Method is not implemented. /// /// SEL Fast Message doesn't define a binary configuration frame - so no checksum is defined. /// An value for the checksum. /// A buffer to read data from. /// An number of bytes to read. /// An offset to read from. protected override ushort CalculateChecksum(byte[] buffer, int offset, int length) { throw new NotImplementedException(); } /// /// Populates a with the data needed to serialize the target object. /// /// The to populate with data. /// The destination for this serialization. public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); // Serialize configuration frame info.AddValue("frameSize", FrameSize, typeof(FrameSize)); info.AddValue("messagePeriod", MessagePeriod, typeof(MessagePeriod)); info.AddValue("idCode32Bit", m_idCode); } #endregion } }