//******************************************************************************************************
// ChannelInstance.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:
// ----------------------------------------------------------------------------------------------------
// 05/04/2012 - Stephen C. Wills, Grid Protection Alliance
// Generated original version of source code.
// 12/17/2012 - Starlynn Danyelle Gilliam
// Modified Header.
//
//******************************************************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GSF.PQDIF.Physical;
namespace GSF.PQDIF.Logical
{
///
/// Represents a channel instance in a PQDIF file. See IEEE 1159.3-2019 section 5.4.3
/// for details. A channel instance resides in an , and
/// is defined by a inside the observation record's
/// .
///
public class ChannelInstance : IEquatable
{
#region [ Members ]
// Fields
private readonly CollectionElement m_physicalStructure;
private readonly ObservationRecord m_observationRecord;
#endregion
#region [ Constructors ]
///
/// Creates a new instance of the class.
///
/// The collection element which is the physical structure of the channel instance.
/// The observation record in which the channel instance resides.
public ChannelInstance(CollectionElement physicalStructure, ObservationRecord observationRecord)
{
m_physicalStructure = physicalStructure;
m_observationRecord = observationRecord;
}
#endregion
#region [ Properties ]
///
/// Gets the physical structure of the channel instance.
///
public CollectionElement PhysicalStructure
{
get
{
return m_physicalStructure;
}
}
///
/// Gets the observation record in which the channel instance resides.
///
public ObservationRecord ObservationRecord
{
get
{
return m_observationRecord;
}
}
///
/// Gets the channel definition which defines the channel instance.
///
public ChannelDefinition Definition
{
get
{
return m_observationRecord.DataSource.ChannelDefinitions[(int)ChannelDefinitionIndex];
}
}
///
/// Gets the channel setting which defines the instrument settings for the channel.
///
public ChannelSetting Setting
{
get
{
MonitorSettingsRecord monitorSettings;
IList channelSettings;
monitorSettings = m_observationRecord.Settings;
if ((object)monitorSettings == null)
return null;
channelSettings = monitorSettings.ChannelSettings;
if ((object)channelSettings == null)
return null;
return channelSettings.FirstOrDefault(channelSetting => channelSetting.ChannelDefinitionIndex == ChannelDefinitionIndex);
}
}
///
/// Gets the index of the
/// which defines the channel instance.
///
public uint ChannelDefinitionIndex
{
get
{
return m_physicalStructure
.GetScalarByTag(ChannelDefinition.ChannelDefinitionIndexTag)
.GetUInt4();
}
set
{
ScalarElement channelDefinitionIndexElement = m_physicalStructure.GetOrAddScalar(ChannelDefinition.ChannelDefinitionIndexTag);
channelDefinitionIndexElement.TypeOfValue = PhysicalType.UnsignedInteger4;
channelDefinitionIndexElement.SetUInt4(value);
}
}
///
/// Gets the identifier for the harmonic or
/// interharmonic group represented by this channel.
///
public short ChannelGroupID
{
get
{
ScalarElement channelGroupIDElement = m_physicalStructure.GetScalarByTag(ChannelGroupIDTag);
if ((object)channelGroupIDElement == null)
return 0;
return channelGroupIDElement.GetInt2();
}
set
{
ScalarElement channelGroupIDElement = m_physicalStructure.GetOrAddScalar(ChannelGroupIDTag);
channelGroupIDElement.TypeOfValue = PhysicalType.Integer2;
channelGroupIDElement.SetInt2(value);
}
}
///
/// Gets the name of the of a device specific code or hardware
/// module, algorithm, or rule not necessarily channel based
/// that cause this channel to be recorded.
///
public string TriggerModuleName
{
get
{
VectorElement moduleNameElement = m_physicalStructure.GetVectorByTag(ChannelTriggerModuleNameTag);
if ((object)moduleNameElement == null)
return null;
return Encoding.ASCII.GetString(moduleNameElement.GetValues()).Trim((char)0);
}
set
{
byte[] bytes = Encoding.ASCII.GetBytes(value + (char)0);
m_physicalStructure.AddOrUpdateVector(ChannelTriggerModuleNameTag, PhysicalType.Char1, bytes);
}
}
///
/// Gets the name of the device involved in
/// an external cross trigger scenario.
///
public string CrossTriggerDeviceName
{
get
{
VectorElement deviceNameElement = m_physicalStructure.GetVectorByTag(CrossTriggerDeviceNameTag);
if ((object)deviceNameElement == null)
return null;
return Encoding.ASCII.GetString(deviceNameElement.GetValues()).Trim((char)0);
}
set
{
byte[] bytes = Encoding.ASCII.GetBytes(value + (char)0);
m_physicalStructure.AddOrUpdateVector(CrossTriggerDeviceNameTag, PhysicalType.Char1, bytes);
}
}
///
/// Gets the series instances contained in this channel.
///
public IList SeriesInstances
{
get
{
return m_physicalStructure
.GetCollectionByTag(SeriesInstancesTag)
.GetElementsByTag(OneSeriesInstanceTag)
.Cast()
.Zip(Definition.SeriesDefinitions, (collection, seriesDefinition) => new SeriesInstance(collection, this, seriesDefinition))
.ToList();
}
}
#endregion
#region [ Methods ]
///
/// Adds a new series instance to the collection
/// of series instances in this channel instance.
///
public SeriesInstance AddNewSeriesInstance()
{
if (Definition.SeriesDefinitions.Count <= SeriesInstances.Count)
throw new InvalidOperationException("Cannot create a series instance without a corresponding series definition.");
CollectionElement seriesInstanceElement = new CollectionElement() { TagOfElement = OneSeriesInstanceTag };
SeriesDefinition seriesDefinition = Definition.SeriesDefinitions[SeriesInstances.Count];
SeriesInstance seriesInstance = new SeriesInstance(seriesInstanceElement, this, seriesDefinition);
seriesInstanceElement.AddOrUpdateVector(SeriesInstance.SeriesValuesTag, PhysicalType.UnsignedInteger1, new byte[0]);
CollectionElement seriesInstancesElement = m_physicalStructure.GetCollectionByTag(SeriesInstancesTag);
if ((object)seriesInstancesElement == null)
{
seriesInstancesElement = new CollectionElement() { TagOfElement = SeriesInstancesTag };
m_physicalStructure.AddElement(seriesInstancesElement);
}
seriesInstancesElement.AddElement(seriesInstanceElement);
return seriesInstance;
}
///
/// Removes the given series instance from the collection of series instances.
///
/// The series instance to be removed.
public void Remove(SeriesInstance seriesInstance)
{
CollectionElement seriesInstancesElement;
List seriesInstanceElements;
IList seriesDefinitions;
SeriesInstance instance;
seriesInstancesElement = m_physicalStructure.GetCollectionByTag(SeriesInstancesTag);
if ((object)seriesInstancesElement == null)
return;
seriesDefinitions = Definition.SeriesDefinitions;
seriesInstanceElements = seriesInstancesElement.GetElementsByTag(OneSeriesInstanceTag).Cast().ToList();
for (int i = seriesInstanceElements.Count; i >= 0; i--)
{
instance = new SeriesInstance(seriesInstanceElements[i], this, seriesDefinitions[i]);
if (Equals(seriesInstance, instance))
seriesInstancesElement.RemoveElement(seriesInstancesElement);
}
}
///
/// Indicates whether the current object is equal to another object of the same type.
///
/// An object to compare with this object.
/// true if the current object is equal to the parameter; otherwise, false.
public bool Equals(ChannelInstance other)
{
if ((object)other == null)
return false;
return ReferenceEquals(m_physicalStructure, other.m_physicalStructure);
}
///
/// Determines whether the specified is equal to the current .
///
/// The object to compare with the current object.
/// true if the specified object is equal to the current object; otherwise, false.
/// 2
public override bool Equals(object obj)
{
return Equals(obj as ChannelInstance);
}
///
/// Serves as a hash function for a particular type.
///
/// A hash code for the current .
/// 2
public override int GetHashCode()
{
return m_physicalStructure.GetHashCode();
}
#endregion
#region [ Static ]
// Static Fields
///
/// Tag that identifies the channel group ID.
///
public static readonly Guid ChannelGroupIDTag = new Guid("f90de218-e67b-4cf1-a295-b021a2d46767");
///
/// Tag that identifies the series instances collection.
///
public static readonly Guid SeriesInstancesTag = new Guid("3d786f93-f76e-11cf-9d89-0080c72e70a3");
///
/// Tag that identifies a single series instance in the collection.
///
public static readonly Guid OneSeriesInstanceTag = new Guid("3d786f94-f76e-11cf-9d89-0080c72e70a3");
///
/// Tag that identifies the channel trigger module name.
///
public static readonly Guid ChannelTriggerModuleNameTag = new Guid("0fa118c6-cb4a-11cf-9d89-0080c72e70a3");
///
/// Tag that identifies the cross trigger device name.
///
public static readonly Guid CrossTriggerDeviceNameTag = new Guid("0fa118c5-cb4a-11cf-9d89-0080c72e70a3");
#endregion
}
}