474 lines · 18.7 KB · C#
RawDownload
//******************************************************************************************************//  ObservationRecord.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/03/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{    #region [ Enumerations ]     /// <summary>    /// Type of trigger which caused the observation.    /// </summary>    public enum TriggerMethod : uint    {        /// <summary>        /// No trigger.        /// </summary>        None = 0u,         /// <summary>        /// A specific channel (or channels) caused the trigger; should be        /// used with tagChannelTriggerIdx to specify which channels.        /// </summary>        Channel = 1u,         /// <summary>        /// Periodic data trigger.        /// </summary>        Periodic = 2u,         /// <summary>        /// External system trigger.        /// </summary>        External = 3u,         /// <summary>        /// Periodic statistical data.        /// </summary>        PeriodicStats = 4u    }     #endregion     /// <summary>    /// Represents an observation record in a PQDIF file.    /// </summary>    public class ObservationRecord    {        #region [ Members ]         // Fields        private readonly Record m_physicalRecord;        private readonly DataSourceRecord m_dataSource;        private readonly MonitorSettingsRecord m_settings;         #endregion         #region [ Constructors ]         /// <summary>        /// Creates a new instance of the <see cref="ObservationRecord"/> class.        /// </summary>        /// <param name="physicalRecord">The physical structure of the observation record.</param>        /// <param name="dataSource">The data source record that defines the channels in this observation record.</param>        /// <param name="settings">The monitor settings to be applied to this observation record.</param>        private ObservationRecord(Record physicalRecord, DataSourceRecord dataSource, MonitorSettingsRecord settings)        {            m_physicalRecord = physicalRecord;            m_dataSource = dataSource;            m_settings = settings;        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets the physical structure of the observation record.        /// </summary>        public Record PhysicalRecord        {            get            {                return m_physicalRecord;            }        }         /// <summary>        /// Gets the data source record that defines        /// the channels in this observation record.        /// </summary>        public DataSourceRecord DataSource        {            get            {                return m_dataSource;            }        }         /// <summary>        /// Gets the monitor settings record that defines the        /// settings to be applied to this observation record.        /// </summary>        public MonitorSettingsRecord Settings        {            get            {                return m_settings;            }        }         /// <summary>        /// Gets the name of the observation record.        /// </summary>        public string Name        {            get            {                CollectionElement collectionElement = m_physicalRecord.Body.Collection;                VectorElement nameElement = collectionElement.GetVectorByTag(ObservationNameTag);                return Encoding.ASCII.GetString(nameElement.GetValues()).Trim((char)0);            }            set            {                CollectionElement collectionElement = m_physicalRecord.Body.Collection;                byte[] bytes = Encoding.ASCII.GetBytes(value + (char)0);                collectionElement.AddOrUpdateVector(ObservationNameTag, PhysicalType.Char1, bytes);            }        }         /// <summary>        /// Gets the creation time of the observation record.        /// </summary>        public DateTime CreateTime        {            get            {                return m_physicalRecord.Body.Collection                    .GetScalarByTag(TimeCreateTag)                    .GetTimestamp();            }            set            {                CollectionElement collectionElement = m_physicalRecord.Body.Collection;                ScalarElement timeCreateElement = collectionElement.GetOrAddScalar(TimeCreateTag);                timeCreateElement.TypeOfValue = PhysicalType.Timestamp;                timeCreateElement.SetTimestamp(value);            }        }         /// <summary>        /// Gets the starting time of the data in the observation record. This time should        /// be used as the base time for all relative seconds recorded in the series instances.        /// </summary>        /// <remarks>        /// The <see cref="ObservationRecord"/> contains two timestamp fields: <see cref="StartTime"/> and        /// <see cref="TimeTriggered"/>. The StartTime is a required part of any Observation, whereas the         /// <see cref="TimeTriggered"/> is optional.         ///         /// The <see cref="StartTime"/> does not have to be the same as the trigger time and can therefore         /// be chosen more or less arbitrarily. For instance, you can choose to record the         /// <see cref="StartTime"/> as the timestamp of the first data point in the observation or the top         /// of an interval in which the data was captured. The trigger time field is more well defined,         /// essentially always representing the point in time at which the data source decided to capture         /// some data in the PQDIF file.        /// </remarks>        public DateTime StartTime        {            get            {                return m_physicalRecord.Body.Collection                    .GetScalarByTag(TimeStartTag)                    .GetTimestamp();            }            set            {                CollectionElement collectionElement = m_physicalRecord.Body.Collection;                ScalarElement timeStartElement = collectionElement.GetOrAddScalar(TimeStartTag);                timeStartElement.TypeOfValue = PhysicalType.Timestamp;                timeStartElement.SetTimestamp(value);            }        }         /// <summary>        /// Gets or sets the type of trigger which caused the observation.        /// </summary>        public TriggerMethod TriggerMethod        {            get            {                return (TriggerMethod)m_physicalRecord.Body.Collection                    .GetScalarByTag(TriggerMethodTag)                    .GetUInt4();            }            set            {                CollectionElement collectionElement = m_physicalRecord.Body.Collection;                ScalarElement triggerMethodElement = collectionElement.GetOrAddScalar(TriggerMethodTag);                triggerMethodElement.TypeOfValue = PhysicalType.UnsignedInteger4;                triggerMethodElement.SetUInt4((uint)value);            }        }          /// <summary>        /// Gets the time the observation was triggered. For more information regarding recording        /// time in PQD files, see <see cref="StartTime"/>.        /// </summary>        public DateTime TimeTriggered        {            get            {                ScalarElement timeTriggeredElement = m_physicalRecord.Body.Collection                    .GetScalarByTag(TimeTriggeredTag);                 if ((object)timeTriggeredElement == null)                    return DateTime.MinValue;                 return timeTriggeredElement.GetTimestamp();            }            set            {                CollectionElement collectionElement = m_physicalRecord.Body.Collection;                ScalarElement timeTriggeredElement = collectionElement.GetOrAddScalar(TimeTriggeredTag);                timeTriggeredElement.TypeOfValue = PhysicalType.Timestamp;                timeTriggeredElement.SetTimestamp(value);            }        }         /// <summary>        /// Gets or sets the Disturbance Category ID        /// </summary>        public Guid DisturbanceCategoryID        {            get            {                CollectionElement collectionElement = m_physicalRecord.Body.Collection;                ScalarElement DisturbanceIDElement = collectionElement.GetScalarByTag(DisturbanceCategoryTag);                 if ((object)DisturbanceIDElement == null)                    return DisturbanceCategory.None;                 return DisturbanceIDElement.GetGuid();            }            set            {                CollectionElement collectionElement = m_physicalRecord.Body.Collection;                ScalarElement vendorIDElement = collectionElement.GetOrAddScalar(DisturbanceCategoryTag);                vendorIDElement.TypeOfValue = PhysicalType.Guid;                vendorIDElement.SetGuid(value);            }        }             /// <summary>        /// Gets or sets the index into <see cref="ChannelInstancesTag"/> collection within this record which initiated the observation.        /// </summary>        public uint[] ChannelTriggerIndex        {            get            {                VectorElement channelTriggerIndexElement = m_physicalRecord.Body.Collection                    .GetVectorByTag(ChannelTriggerIndexTag);                 if ((object)channelTriggerIndexElement == null)                    return new uint[0];                 return Enumerable.Range(0, channelTriggerIndexElement.Size)                    .Select(index => channelTriggerIndexElement.GetUInt4(index))                    .ToArray();            }            set            {                CollectionElement collectionElement = m_physicalRecord.Body.Collection;                VectorElement channelTriggerIndexElement = collectionElement.GetOrAddVector(ChannelTriggerIndexTag);                channelTriggerIndexElement.TypeOfValue = PhysicalType.UnsignedInteger4;                channelTriggerIndexElement.Size = value.Length;                 for (int i = 0; i < value.Length; i++)                    channelTriggerIndexElement.SetUInt4(i, value[i]);            }        }         /// <summary>        /// Gets the channel instances in this observation record.        /// </summary>        public IList<ChannelInstance> ChannelInstances        {            get            {                return m_physicalRecord.Body.Collection                    .GetCollectionByTag(ChannelInstancesTag)                    .GetElementsByTag(OneChannelInstanceTag)                    .Cast<CollectionElement>()                    .Select(collection => new ChannelInstance(collection, this))                    .ToList();            }        }         #endregion         #region [ Methods ]         /// <summary>        /// Adds a new channel instance to the collection        /// of channel instances in this observation record.        /// </summary>        public ChannelInstance AddNewChannelInstance(ChannelDefinition channelDefinition)        {            CollectionElement channelInstanceElement = new CollectionElement() { TagOfElement = OneChannelInstanceTag };            ChannelInstance channelInstance = new ChannelInstance(channelInstanceElement, this);             channelInstance.ChannelDefinitionIndex = (uint)channelDefinition.DataSource.ChannelDefinitions.IndexOf(channelDefinition);            channelInstanceElement.AddElement(new CollectionElement() { TagOfElement = ChannelInstance.SeriesInstancesTag });             CollectionElement channelInstancesElement = m_physicalRecord.Body.Collection.GetCollectionByTag(ChannelInstancesTag);             if ((object)channelInstancesElement == null)            {                channelInstancesElement = new CollectionElement() { TagOfElement = ChannelInstancesTag };                m_physicalRecord.Body.Collection.AddElement(channelInstancesElement);            }             channelInstancesElement.AddElement(channelInstanceElement);             return channelInstance;        }         /// <summary>        /// Removes the given channel instance from the collection of channel instances.        /// </summary>        /// <param name="channelInstance">The channel instance to be removed.</param>        public void Remove(ChannelInstance channelInstance)        {            CollectionElement channelInstancesElement = m_physicalRecord.Body.Collection.GetCollectionByTag(ChannelInstancesTag);            List<CollectionElement> channelInstanceElements;            ChannelInstance instance;             if ((object)channelInstancesElement == null)                return;             channelInstanceElements = channelInstancesElement.GetElementsByTag(OneChannelInstanceTag).Cast<CollectionElement>().ToList();             foreach (CollectionElement channelSettingElement in channelInstanceElements)            {                instance = new ChannelInstance(channelSettingElement, this);                 if (Equals(channelInstance, instance))                    channelInstancesElement.RemoveElement(channelSettingElement);            }        }         #endregion         #region [ Static ]         // Static Fields         /// <summary>        /// Tag that identifies the name of the observation record.        /// </summary>        public static readonly Guid ObservationNameTag = new Guid("3d786f8a-f76e-11cf-9d89-0080c72e70a3");         /// <summary>        /// Tag that identifies the time that the observation record was created.        /// </summary>        public static readonly Guid TimeCreateTag = new Guid("3d786f8b-f76e-11cf-9d89-0080c72e70a3");         /// <summary>        /// Tag that identifies the start time of the data in the observation record.        /// </summary>        public static readonly Guid TimeStartTag = new Guid("3d786f8c-f76e-11cf-9d89-0080c72e70a3");         /// <summary>        /// Tag that identifies the type of trigger that caused the observation.        /// </summary>        public static readonly Guid TriggerMethodTag = new Guid("3d786f8d-f76e-11cf-9d89-0080c72e70a3");         /// <summary>        /// Tag that identifies the time the observation was triggered.        /// </summary>        public static readonly Guid TimeTriggeredTag = new Guid("3d786f8e-f76e-11cf-9d89-0080c72e70a3");         /// <summary>        /// Tag that identifies the index into <see cref="ChannelInstancesTag"/> collection within this record. This specifies which channel(s) initiated the observation.        /// </summary>        public static readonly Guid ChannelTriggerIndexTag = new Guid("3d786f8f-f76e-11cf-9d89-0080c72e70a3");         /// <summary>        /// Tag that identifies the channel instances collection.        /// </summary>        public static readonly Guid ChannelInstancesTag = new Guid("3d786f91-f76e-11cf-9d89-0080c72e70a3");         /// <summary>        /// Tag that identifies a single channel instance in the collection.        /// </summary>        public static readonly Guid OneChannelInstanceTag = new Guid("3d786f92-f76e-11cf-9d89-0080c72e70a3");         /// <summary>        /// Tag that identifies the Disturbance Category.        /// </summary>        public static readonly Guid DisturbanceCategoryTag = new Guid("b48d8597-f5f5-11cf-9d89-0080c72e70a3");          // Static Methods         /// <summary>        /// Creates a new observation record from scratch with the given data source and settings.        /// </summary>        /// <param name="dataSource">The data source record that defines the channels in this observation record.</param>        /// <param name="settings">The monitor settings to be applied to this observation record.</param>        /// <returns>The new observation record.</returns>        public static ObservationRecord CreateObservationRecord(DataSourceRecord dataSource, MonitorSettingsRecord settings)        {            Guid recordTypeTag = Record.GetTypeAsTag(RecordType.Observation);            Record physicalRecord = new Record(recordTypeTag);            ObservationRecord observationRecord = new ObservationRecord(physicalRecord, dataSource, settings);             DateTime now = DateTime.UtcNow;            observationRecord.Name = now.ToString();            observationRecord.CreateTime = now;            observationRecord.StartTime = now;            observationRecord.TriggerMethod = TriggerMethod.None;             CollectionElement bodyElement = physicalRecord.Body.Collection;            bodyElement.AddElement(new CollectionElement() { TagOfElement = ChannelInstancesTag });             return observationRecord;        }         /// <summary>        /// Creates a new observation record from the given physical record        /// if the physical record is of type observation. Returns null if        /// it is not.        /// </summary>        /// <param name="physicalRecord">The physical record used to create the observation record.</param>        /// <param name="dataSource">The data source record that defines the channels in this observation record.</param>        /// <param name="settings">The monitor settings to be applied to this observation record.</param>        /// <returns>The new observation record, or null if the physical record does not define a observation record.</returns>        public static ObservationRecord CreateObservationRecord(Record physicalRecord, DataSourceRecord dataSource, MonitorSettingsRecord settings)        {            bool isValidObservationRecord = physicalRecord.Header.TypeOfRecord == RecordType.Observation;            return isValidObservationRecord ? new ObservationRecord(physicalRecord, dataSource, settings) : null;        }         #endregion    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t