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