//******************************************************************************************************
// 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
}
}