1211 lines · 53.8 KB · C#
RawDownload
//******************************************************************************************************//  OutputStream.cs - Gbtc////  Copyright © 2010, 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://  ----------------------------------------------------------------------------------------------------//  07/26/2011 - Magdiel Lorenzo//       Generated original version of source code.//  09/08/2011 - Mehulbhai Thakkar//       Modified code to use SQL queries directly instead from script file resource.//       Added comments to all properties and static methods.//  09/14/2012 - Aniket Salver //       Added paging and sorting technique. //  03/08/2017 - J. Ritchie Carroll//       Modified UI code to auto-set assign default auto publish config frame based on selections.////****************************************************************************************************** using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.ComponentModel;using System.ComponentModel.DataAnnotations;using System.Data;using System.Globalization;using System.Linq;using System.Text.RegularExpressions;using System.Windows;using System.Windows.Data;using GSF.ComponentModel.DataAnnotations;using GSF.Data;using GSF.Diagnostics;using GSF.PhasorProtocols.IEEEC37_118;using GSF.TimeSeries.UI;using GSF.TimeSeries.UI.DataModels;using Measurement = GSF.TimeSeries.UI.DataModels.Measurement;using C37Concentrator = PhasorProtocolAdapters.IeeeC37_118.Concentrator; // ReSharper disable ConstantConditionalAccessQualifier// ReSharper disable AccessToDisposedClosure// ReSharper disable ConstantConditionalAccessQualifiernamespace GSF.PhasorProtocols.UI.DataModels{    /// <summary>    /// Supported Synchrophasor Output Protocols.    /// </summary>    public enum OutputProtocol    {        /// <summary>        /// IEEE C37.118-2011 Output.        /// </summary>        IEEE_C37_118_2011 = 3,        /// <summary>        /// IEEE C37.118-2005 Output.        /// </summary>        IEEE_C37_118_2005 = 0,        /// <summary>        /// BPA PDCstream Output.        /// </summary>        BPA_PDCSTREAM = 1,        /// <summary>        /// IEC 61850-90-5 Output.        /// </summary>        IEC_61850_90_5 = 2    }     /// <summary>    /// Defines a value converter for the <see cref="OutputProtocol"/> enumeration.    /// </summary>    public class OutputProtocolValueConverter : IValueConverter    {        /// <summary>Converts a value.</summary>        /// <param name="value">The value produced by the binding source.</param>        /// <param name="targetType">The type of the binding target property.</param>        /// <param name="parameter">The converter parameter to use.</param>        /// <param name="culture">The culture to use in the converter.</param>        /// <returns>A converted value. If the method returns <see langword="null" />, the valid null value is used.</returns>        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)        {            if (value is null)                return null;             if (parameter is null)                return null;             if (parameter is not CollectionViewSource viewSource)                return null;             if (viewSource.Source is not Dictionary<OutputProtocol, string> typeList)                return null;             string name = value.ToString();             if (Enum.TryParse(name, out OutputProtocol type) && typeList.TryGetValue(type, out string typeName))                return new KeyValuePair<OutputProtocol, string>(type, typeName);             return null;        }         /// <summary>Converts a value.</summary>        /// <param name="value">The value that is produced by the binding target.</param>        /// <param name="targetType">The type to convert to.</param>        /// <param name="parameter">The converter parameter to use.</param>        /// <param name="culture">The culture to use in the converter.</param>        /// <returns>A converted value. If the method returns <see langword="null" />, the valid null value is used.</returns>        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)        {            return value is KeyValuePair<OutputProtocol, string> pair ? (object)pair.Key : null;        }         /// <summary>        /// Gets default instance of the <see cref="OutputProtocolValueConverter"/>.        /// </summary>        public static readonly OutputProtocolValueConverter Default = new();    }     /// <summary>    /// Represents a record of <see cref="OutputStream"/> as defined in the database.    /// </summary>    public class OutputStream : DataModelBase    {        #region [ Members ]         private Guid m_nodeID;        private int m_ID;        private string m_acronym;        private string m_name;        private OutputProtocol m_type = OutputProtocol.IEEE_C37_118_2005;        private string m_connectionString;        private int m_idCode;        private string m_commandChannel;        private string m_dataChannel;        private bool m_autoPublishConfigFrame;        private bool m_autoStartDataChannel;        private int m_nominalFrequency;        private int m_framesPerSecond;        private double m_lagTime;        private double m_leadTime;        private bool m_useLocalClockAsRealTime;        private bool m_allowSortsByArrival;        private int m_loadOrder;        private bool m_enabled;        private bool m_ignoreBadTimeStamps;        private int m_timeResolution;        private bool m_allowPreemptivePublishing;        private string m_downsamplingMethod;        private string m_dataFormat;        private string m_coordinateFormat;        private int m_currentScalingValue;        private int m_voltageScalingValue;        private int m_analogScalingValue;        private int m_digitalMaskValue;        private bool m_performTimestampReasonabilityCheck;        private bool m_roundToNearestTimestamp;        private string m_mirroringSourceDevice = "";         // ReSharper disable once MemberInitializerValueIgnored        // Assign initial changed state to true before calling base class constructor call to prevent unintended updates during default value initialization        private bool m_autoPublishConfigFrameChangedByUser = true; // Called 1st         #endregion         #region [ Constructors ]         /// <summary>        /// Creates a new <see cref="OutputStream"/>.        /// </summary>        public OutputStream() : base(false) // Called 2nd        {            // Post base class constructor call, reset changed state value back to false            m_autoPublishConfigFrameChangedByUser = false; // Called 3rd             try            {                // Set default lead/lag time settings to those used by manager screens                object lagTimeValue = IsolatedStorageManager.ReadFromIsolatedStorage("LagTime");                 if (lagTimeValue is not null && double.TryParse(lagTimeValue.ToString(), out double lagTime) && lagTime > 0.0D)                    m_lagTime = lagTime;                 object leadTimeValue = IsolatedStorageManager.ReadFromIsolatedStorage("LeadTime");                 if (leadTimeValue is not null && double.TryParse(leadTimeValue.ToString(), out double leadTime) && leadTime > 0.0D)                    m_leadTime = leadTime;            }            catch (Exception ex)            {                Logger.SwallowException(ex);            }        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets or sets function to call when config frame size calculation should be updated.        /// </summary>        public Action UpdateConfigFrameSize { get; set; }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s NodeID.        /// </summary>        public Guid NodeID        {            get => m_nodeID;            set            {                m_nodeID = value;                OnPropertyChanged("NodeID");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s ID.        /// </summary>        // Field is populated by database via auto-increment and has no screen interaction, so no validation attributes are applied.        public int ID        {            get => m_ID;            set            {                m_ID = value;                OnPropertyChanged("ID");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s Acronym.        /// </summary>        [Required(ErrorMessage = "Output stream acronym is a required field, please provide value.")]        [StringLength(200, ErrorMessage = "Output stream acronym cannot exceed 200 characters.")]        [AcronymValidation]        public string Acronym        {            get => m_acronym;            set            {                m_acronym = value;                OnPropertyChanged("Acronym");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s Name.        /// </summary>        [StringLength(200, ErrorMessage = "Output stream name cannot exceed 200 characters.")]        public string Name        {            get => m_name;            set            {                m_name = value;                OnPropertyChanged("Name");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s output protocol type.        /// </summary>        [Required(ErrorMessage = "Output stream type is a required, please provide a value.")]        public OutputProtocol Type        {            get => m_type;            set            {                const string ConfigTypeKey = nameof(C37Concentrator.TargetConfigurationType);                 m_type = value;                 Dictionary<string, string> settings = ConnectionString?.ParseKeyValuePairs() ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);                 switch (m_type)                {                    case OutputProtocol.IEEE_C37_118_2011:                        settings[ConfigTypeKey] = DraftRevision.Std2011.ToString();                        break;                    case OutputProtocol.IEEE_C37_118_2005:                        settings[ConfigTypeKey] = DraftRevision.Std2005.ToString();                        break;                    default:                        settings.Remove(ConfigTypeKey);                        break;                }                 ConnectionString = settings.JoinKeyValuePairs();                 OnPropertyChanged("Type");                UpdateConfigFrameSize?.Invoke();            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s ConnectionString.        /// </summary>        [DefaultValue("addPhaseLabelSuffix=false; replaceWithSpaceChar=_")]        public string ConnectionString        {            get => m_connectionString;            set            {                Dictionary<string, string> settings = value.ParseKeyValuePairs();                 if (settings.TryGetValue(nameof(RoundToNearestTimestamp), out string setting))                {                    RoundToNearestTimestamp = setting.ParseBoolean();                    settings.Remove(nameof(RoundToNearestTimestamp));                    m_connectionString = settings.JoinKeyValuePairs();                }                else                {                    m_connectionString = value;                }                 OnPropertyChanged("ConnectionString");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s IDCode.        /// </summary>        [Required(ErrorMessage = "Output stream IDCode is a required field, please provide a value.")]        public int IDCode        {            get => m_idCode;            set            {                m_idCode = value;                OnPropertyChanged("IDCode");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s CommandChannel.        /// </summary>        public string CommandChannel        {            get => m_commandChannel;            set            {                m_commandChannel = value;                SetDefaultAutoPublishConfigFrameState();                OnPropertyChanged("CommandChannel");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s DataChannel.        /// </summary>        public string DataChannel        {            get => m_dataChannel;            set            {                m_dataChannel = value;                SetDefaultAutoPublishConfigFrameState();                OnPropertyChanged("DataChannel");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s AutoPublishConfigFrame flag.        /// </summary>        [Required(ErrorMessage = "Output stream auto publish config frame is a required field, please provide a value.")]        [DefaultValue(false)]        public bool AutoPublishConfigFrame        {            get => m_autoPublishConfigFrame;            set            {                m_autoPublishConfigFrame = value;                m_autoPublishConfigFrameChangedByUser = true;                OnPropertyChanged("AutoPublishConfigFrame");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s AutoStartDataChannel flag.        /// </summary>        [Required(ErrorMessage = "Output stream auto start data channel is a required field, please provide a value.")]        [DefaultValue(true)]        public bool AutoStartDataChannel        {            get => m_autoStartDataChannel;            set            {                m_autoStartDataChannel = value;                OnPropertyChanged("AutoStartDataChannel");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s Nominal Frequency.        /// </summary>        [Required(ErrorMessage = "Output stream nominal frequency is a required field, please provide a value.")]        [DefaultValue(60)]        public int NominalFrequency        {            get => m_nominalFrequency;            set            {                m_nominalFrequency = value;                OnPropertyChanged("NominalFrequency");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s Frames Per Second.        /// </summary>        [Required(ErrorMessage = "Output stream frames per second is a required field, please provide a value.")]        [DefaultValue(30)]        public int FramesPerSecond        {            get => m_framesPerSecond;            set            {                m_framesPerSecond = value;                OnPropertyChanged("FramesPerSecond");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s LagTime.        /// </summary>        [Required(ErrorMessage = "Output stream lag time is a required field, please provide a value.")]        [DefaultValue(3.0)]        public double LagTime        {            get => m_lagTime;            set            {                m_lagTime = value;                OnPropertyChanged("LagTime");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s LeadTime.        /// </summary>        [Required(ErrorMessage = "Output stream lead time is a required field, please provide a value.")]        [DefaultValue(1.0)]        public double LeadTime        {            get => m_leadTime;            set            {                m_leadTime = value;                OnPropertyChanged("LeadTime");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s UseLocalClockAsRealTime flag.        /// </summary>        [Required(ErrorMessage = "Output stream use local clock as real-time is a required field, please provide a value.")]        [DefaultValue(false)]        public bool UseLocalClockAsRealTime        {            get => m_useLocalClockAsRealTime;            set            {                m_useLocalClockAsRealTime = value;                OnPropertyChanged("UseLocalClockAsRealTime");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s AllowSortsByArrival flag.        /// </summary>        [Required(ErrorMessage = "Output stream allow sorts by arrival is a required field, please provide a value.")]        [DefaultValue(true)]        public bool AllowSortsByArrival        {            get => m_allowSortsByArrival;            set            {                m_allowSortsByArrival = value;                OnPropertyChanged("AllowSortsByArrival");            }        }         /// <summary>        /// Gets or sets <see cref="OutputStream"/>'s LoadOrder.        /// </summary>        [Required(ErrorMessage = "Output stream load order is a required field, please provide a value.")]        [DefaultValue(0)]        public int LoadOrder        {

Lines 1–500 of 1211.

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