//******************************************************************************************************
// ChannelValueBase.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:
// ----------------------------------------------------------------------------------------------------
// 03/07/2005 - 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.
// 10/5/2012 - Gavin E. Holden
// 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.TimeSeries;
namespace GSF.PhasorProtocols
{
///
/// Represents the common implementation of the protocol independent representation of any kind of data value.
///
/// Generic type.
[Serializable]
public abstract class ChannelValueBase : ChannelBase, IChannelValue where T : IChannelDefinition
{
#region [ Members ]
// Fields
private IDataCell m_parent;
private T m_definition;
private IMeasurement[] m_measurements;
#endregion
#region [ Constructors ]
///
/// Creates a new from specified parameters.
///
/// The parent of this .
/// The associated with this .
protected ChannelValueBase(IDataCell parent, T channelDefinition)
{
m_parent = parent;
m_definition = channelDefinition;
}
///
/// Creates a new from serialization parameters.
///
/// The with populated with data.
/// The source for this deserialization.
protected ChannelValueBase(SerializationInfo info, StreamingContext context)
{
// Deserialize channel value
m_parent = (IDataCell)info.GetValue("parent", typeof(IDataCell));
m_definition = (T)info.GetValue("definition", typeof(T));
}
#endregion
#region [ Properties ]
///
/// Gets or sets the parent of this .
///
public virtual IDataCell Parent
{
get => m_parent;
set => m_parent = value;
}
///
/// Gets or sets the associated with this .
///
public virtual T Definition
{
get => m_definition;
set => m_definition = value;
}
///
/// Gets the of this .
///
public virtual DataFormat DataFormat => m_definition.DataFormat;
///
/// Gets text based label of this .
///
public virtual string Label => m_definition.Label;
///
/// Gets boolean value that determines if none of the composite values of have been assigned a value.
///
/// true, if no composite values have been assigned a value; otherwise, false.
public abstract bool IsEmpty { get; }
///
/// Gets total number of composite values that this provides.
///
public abstract int CompositeValueCount { get; }
///
/// Gets the composite values of this as an array of values.
///
public virtual IMeasurement[] Measurements
{
get
{
// Create a measurement instance for each composite value the derived channel value exposes
if (m_measurements is null)
{
m_measurements = new IMeasurement[CompositeValueCount];
// ChannelValueMeasurement dynamically accesses CompositeValues[x] for its value
for (int x = 0; x < m_measurements.Length; x++)
m_measurements[x] = CreateMeasurement(x);
}
return m_measurements;
}
}
///
/// of string based property names and values for the object.
///
public override Dictionary Attributes
{
get
{
Dictionary baseAttributes = base.Attributes;
int compositeValues = CompositeValueCount;
baseAttributes.Add("Label", Label);
baseAttributes.Add("Data Format", $"{(int)DataFormat}: {DataFormat}");
baseAttributes.Add("Is Empty", IsEmpty.ToString());
baseAttributes.Add("Total Composite Values", compositeValues.ToString());
for (int x = 0; x < compositeValues; x++)
{
baseAttributes.Add($" Composite Value {x}", $" => {GetCompositeValue(x)}");
}
return baseAttributes;
}
}
#endregion
#region [ Methods ]
///
/// Gets the specified composite value of this .
///
/// Index of composite value to retrieve.
///
/// Some implementations can contain more than one value, this method is used to abstractly expose each value.
///
/// A representing the composite value.
public abstract double GetCompositeValue(int index);
///
/// Creates a new value for specified composite value for this .
///
/// Composite value index for which to derive new value.
/// New value for specified composite value for this .
protected virtual IMeasurement CreateMeasurement(int valueIndex)
{
Measurement measurement = new()
{
Timestamp = Parent.Parent.Timestamp,
Value = GetCompositeValue(valueIndex)
};
measurement.StateFlags =
(Parent.SynchronizationIsValid && measurement.Timestamp.Value != -1 ? MeasurementStateFlags.Normal : MeasurementStateFlags.BadTime) |
(Parent.DataIsValid ? MeasurementStateFlags.Normal : MeasurementStateFlags.BadData) |
(Parent.DeviceError ? MeasurementStateFlags.SystemError : MeasurementStateFlags.Normal);
return measurement;
}
///
/// Populates a with the data needed to serialize the target object.
///
/// The to populate with data.
/// The destination for this serialization.
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
// Serialize channel value
info.AddValue("parent", m_parent, typeof(IDataCell));
info.AddValue("definition", m_definition, typeof(T));
}
#endregion
}
}