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