1350 lines · 60.0 KB · C#
RawDownload
//******************************************************************************************************//  HomeUserControl.xaml.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/27/2011 - Mehulbhai P Thakkar//       Generated original version of source code.//  01/24/2011 - Aniket Salver//       Added Current Configuration group, System health and also ChartPlotter.//  30/07/2012 - Aniket Salver//       Remembers the last graph selection. //  05/05/2021 - J.Ritchie Carroll//       Added new alarm/warning stats row.////****************************************************************************************************** using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Diagnostics;using System.Globalization;using System.IO;using System.Linq;using System.Text.RegularExpressions;using System.Threading;using System.Windows;using System.Windows.Controls;using System.Windows.Input;using System.Windows.Media;using System.Windows.Threading;using System.Xml;using System.Xml.Linq;using System.Xml.Serialization;using GSF.Communication;using GSF.ComponentModel;using GSF.Configuration;using GSF.Data;using GSF.Data.Model;using GSF.Diagnostics;using GSF.IO;using GSF.Identity;using GSF.PhasorProtocols.UI.DataModels;using GSF.Reflection;using GSF.ServiceProcess;using GSF.TimeSeries.UI;using Microsoft.Research.DynamicDataDisplay;using Microsoft.Research.DynamicDataDisplay.Charts;using Microsoft.Research.DynamicDataDisplay.DataSources;using MeasurementModel = GSF.TimeSeries.UI.DataModels.Measurement; #pragma warning disable 612,618 // ReSharper disable UnusedMember.Local// ReSharper disable UnusedAutoPropertyAccessor.Localnamespace GSF.TimeSeries.Transport.UI.UserControls{    /// <summary>    /// Interaction logic for HomeUserControl.xaml    /// </summary>    public partial class HomeUserControl    {        #region [ Members ]         // Nested Types        private class CustomActionAdapter        {            [PrimaryKey(true)]            public int ID { get; set; }             public string AdapterName { get; set; }             public string AssemblyName { get; set; }             public string ConnectionString { get; set; }             [UpdateValueExpression("DateTime.UtcNow")]            public DateTime UpdatedOn { get; set; }             [UpdateValueExpression("UserInfo.CurrentUserID")]            public string UpdatedBy { get; set; }        }         // Constants        private const string SystemSettings = CommonFunctions.DefaultSettingsCategory;         // Fields        private readonly ObservableCollection<MenuDataItem> m_menuDataItems;        private WindowsServiceClient m_windowsServiceClient;        private DispatcherTimer m_refreshTimer;         // Subscription fields        private DataSubscriber m_chartSubscription;        private DataSubscriber m_statsSubscription;        private bool m_chartSubscriptionConnected;        private string m_signalID;        private int m_processingUnsynchronizedMeasurements;        private double m_refreshInterval = 0.25;        private int[] m_xAxisDataCollection;                                // Source data for the binding collection.        private EnumerableDataSource<int> m_xAxisBindingCollection;         // Values plotted on X-Axis.                private ConcurrentQueue<double> m_yAxisDataCollection;              // Source data for the binding collection. Format is <signalID, collection of values from subscription API>.        private EnumerableDataSource<double> m_yAxisBindingCollection;      // Values plotted on Y-Axis.        private LineGraph m_lineGraph;        private int m_numberOfPointsToPlot = 60;        private bool m_eventHandlerRegistered;        private MeasurementModel m_selectedMeasurement;        private Guid[] m_statSignalIDs;        private bool m_serverIsLocal;        private bool m_timeReasonabilityPopupIsForLocalTime;        private double m_lastLocalToServerTimeDeviation;        private double m_lastLocalTimeDeviation;        private double m_lastServerTimeDeviation;         #endregion         #region [ Constructor ]         /// <summary>        /// Creates an instance of <see cref="HomeUserControl"/>.        /// </summary>        public HomeUserControl()        {            InitializeComponent();            this.Loaded += HomeUserControl_Loaded;            this.Unloaded += HomeUserControl_Unloaded;             // Load Menu            XmlRootAttribute xmlRootAttribute = new XmlRootAttribute("MenuDataItems");            XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<MenuDataItem>), xmlRootAttribute);             using (XmlReader reader = XmlReader.Create(FilePath.GetAbsolutePath("Menu.xml")))            {                m_menuDataItems = (ObservableCollection<MenuDataItem>)serializer.Deserialize(reader);            }        }         #endregion         #region [ Methods ]         private void HomeUserControl_Unloaded(object sender, RoutedEventArgs e)        {            try            {                if (!(m_windowsServiceClient?.Helper is null))                    m_windowsServiceClient.Helper.ReceivedServiceResponse -= Helper_ReceivedServiceResponse;                 if (!(m_refreshTimer is null))                    m_refreshTimer.Stop();                 UnsubscribeChartData();                DisposeStatsSubscription();            }            finally            {                m_refreshTimer = null;                m_chartSubscription = null;                m_statsSubscription = null;            }        }         private void HomeUserControl_Loaded(object sender, RoutedEventArgs e)        {            if (!CommonFunctions.CurrentPrincipal.IsInRole("Administrator"))                ButtonRestart.IsEnabled = false;             if (!CommonFunctions.CurrentPrincipal.IsInRole("Administrator,Editor"))            {                //ButtonInputWizard.IsEnabled = false;                ApplyToServer.IsEnabled = false;                ApplyToServer.Foreground = new SolidColorBrush(Colors.Gray);                ServerTimeLabel.Cursor = null;            }             m_windowsServiceClient = CommonFunctions.GetWindowsServiceClient();             if (m_windowsServiceClient is null || m_windowsServiceClient.Helper.RemotingClient.CurrentState != ClientState.Connected)            {                ButtonRestart.IsEnabled = false;                m_statsSubscription?.Stop();            }            else            {                m_windowsServiceClient.Helper.ReceivedServiceResponse += Helper_ReceivedServiceResponse;                CommonFunctions.SendCommandToService("Health -actionable");                CommonFunctions.SendCommandToService("Version -actionable");                CommonFunctions.SendCommandToService("Status -actionable");                CommonFunctions.SendCommandToService("Time -actionable");                m_eventHandlerRegistered = true;            }             m_refreshTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5) };            m_refreshTimer.Tick += RefreshTimer_Tick;            m_refreshTimer.Start();             TextBlockInstance.Text = IntPtr.Size == 8 ? "64-bit" : "32-bit";            TextBlockLocalTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");             // Initialize default brush            if (s_defaultBrush is null)                s_defaultBrush = TextBlockInstance.Background;             // Get needed styles            if (s_underlineStyle is null)                s_underlineStyle = FindResource("Underline") as Style;             if (s_shadowStyle is null)                s_shadowStyle = FindResource("Shadow") as Style;             if (s_underlineShadowStyle is null)                s_underlineShadowStyle = FindResource("UnderlineShadow") as Style;             Version appVersion = AssemblyInfo.EntryAssembly.Version;            TextBlockManagerVersion.Text = $"{appVersion.Major}.{appVersion.Minor}.{appVersion.Build}.0";             try            {                using (AdoDataConnection database = new AdoDataConnection(CommonFunctions.DefaultSettingsCategory))                {                    TextBlockDatabaseType.Text = database.DatabaseType.ToString();                     try                    {                        if (database.IsSqlite || database.IsJetEngine)                        {                            // Extract database file name from connection string for file centric databases                            TextBlockDatabaseName.Text = FilePath.GetFileName(database.Connection.ConnectionString.ParseKeyValuePairs()["Data Source"]);                        }                        else if (database.IsOracle)                        {                            // Extract user name from connection string for Oracle databases                            TextBlockDatabaseName.Text = database.Connection.ConnectionString.ParseKeyValuePairs()["User Id"];                        }                        else                        {                            TextBlockDatabaseName.Text = database.Connection.Database;                        }                    }                    catch                    {                        // Fall back on database name if file anything fails                        TextBlockDatabaseName.Text = database.Connection.Database;                    }                }            }            catch            {                TextBlockDatabaseName.Text = "Not Available";            }             try            {                using (UserInfo info = new UserInfo(CommonFunctions.CurrentUser))                {                    TextBlockUser.Text = info.Exists ? info.LoginID : CommonFunctions.CurrentUser;                }            }            catch            {                TextBlockUser.Text = CommonFunctions.CurrentUser;            }             ((HorizontalAxis)ChartPlotterDynamic.MainHorizontalAxis).LabelProvider.LabelStringFormat = "";             //Remove legend on the right.            Panel legendParent = (Panel)ChartPlotterDynamic.Legend.ContentGrid.Parent;             if (!(legendParent is null))                legendParent.Children.Remove(ChartPlotterDynamic.Legend.ContentGrid);             ChartPlotterDynamic.NewLegendVisible = false;             m_xAxisDataCollection = new int[m_numberOfPointsToPlot];             for (int i = 0; i < m_numberOfPointsToPlot; i++)                m_xAxisDataCollection[i] = i;             m_xAxisBindingCollection = new EnumerableDataSource<int>(m_xAxisDataCollection);            m_xAxisBindingCollection.SetXMapping(x => x);             LoadComboBoxDeviceAsync();            InitializeStatsSubscription();            InitializeTimeReasonabilitySettings();        }         private void LoadComboBoxDeviceAsync()        {            Thread t = new Thread(() =>            {                Dictionary<int, string> deviceLookupList = Device.GetLookupList(null);                 Dispatcher.BeginInvoke(new Action(() =>                {                    ComboBoxDevice.ItemsSource = deviceLookupList;                     if (Application.Current.Resources.Contains("SelectedDevice_Home"))                        ComboBoxDevice.SelectedIndex = (int)Application.Current.Resources["SelectedDevice_Home"];                    else                        ComboBoxDevice.SelectedIndex = 0;                }));            });             t.IsBackground = true;            t.Start();        }         private void LoadComboBoxMeasurementAsync()        {            int selectedDeviceID = ((KeyValuePair<int, string>)ComboBoxDevice.SelectedItem).Key;             Thread t = new Thread(() =>            {                ObservableCollection<MeasurementModel> measurements = MeasurementModel.Load(null, selectedDeviceID);                ObservableCollection<MeasurementModel> itemsSource = new ObservableCollection<MeasurementModel>(measurements.Where(m => m.SignalSuffix == "PA" || m.SignalSuffix == "FQ"));                 Dispatcher.BeginInvoke(new Action(() =>                {                    ComboBoxMeasurement.ItemsSource = itemsSource;                     if (Application.Current.Resources.Contains("SelectedMeasurement_Home") && (int)Application.Current.Resources["SelectedMeasurement_Home"] != -1)                        ComboBoxMeasurement.SelectedIndex = (int)Application.Current.Resources["SelectedMeasurement_Home"];                    else                        ComboBoxMeasurement.SelectedIndex = 0;                }));            });             t.IsBackground = true;            t.Start();        }         private void RefreshTimer_Tick(object sender, EventArgs e)        {            if (!(m_windowsServiceClient?.Helper?.RemotingClient is null) && m_windowsServiceClient.Helper.RemotingClient.CurrentState == ClientState.Connected)            {                try                {                    ButtonRestart.IsEnabled = CommonFunctions.CurrentPrincipal.IsInRole("Administrator");                    //ButtonInputWizard.IsEnabled = CommonFunctions.CurrentPrincipal.IsInRole("Administrator,Editor");                     if (!m_eventHandlerRegistered)                    {                        m_windowsServiceClient.Helper.ReceivedServiceResponse += Helper_ReceivedServiceResponse;                        CommonFunctions.SendCommandToService("Version -actionable");                        m_eventHandlerRegistered = true;                    }                     CommonFunctions.SendCommandToService("Health -actionable");                    CommonFunctions.SendCommandToService("Time -actionable");                     if (PopupStatus.IsOpen)                        CommonFunctions.SendCommandToService("Status -actionable");                     if (!(m_statsSubscription is null) && !m_statsSubscription.Enabled)                        m_statsSubscription?.Start();                }                catch (Exception ex)                {                    Logger.SwallowException(ex);                }            }            else            {                ButtonRestart.IsEnabled = false;            }             TextBlockLocalTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");        }         private void ButtonQuickLink_Click(object sender, RoutedEventArgs e)        {            MenuDataItem item = new MenuDataItem();            string stringToMatch = ((Button)sender).Tag.ToString();             if (!string.IsNullOrEmpty(stringToMatch))            {                if (stringToMatch == "Restart")                {                    RestartService();                }                else                {                    GetMenuDataItem(m_menuDataItems, stringToMatch, ref item);                     if (!(item.MenuText is null))                        item.Command.Execute(null);                }            }        }         // Recursively finds menu item to navigate to when a button is clicked on the UI.        private void GetMenuDataItem(ObservableCollection<MenuDataItem> dataItems, string stringToMatch, ref MenuDataItem item)        {            foreach (MenuDataItem dataItem in dataItems)            {                if (string.Equals(dataItem.UserControlPath, stringToMatch, StringComparison.OrdinalIgnoreCase))                {                    item = dataItem;                    break;                }                 if (dataItem.SubMenuItems.Count > 0)                    GetMenuDataItem(dataItem.SubMenuItems, stringToMatch, ref item);            }        }         private void RestartService()        {            try            {                if (MessageBox.Show("Do you want to restart service?", "Restart Service", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)                {                    CommonFunctions.SendCommandToService("Restart");                    MessageBox.Show("Successfully sent RESTART command to the service.", "Restart Service", MessageBoxButton.OK, MessageBoxImage.Information);                }            }            catch            {                MessageBox.Show($"Failed sent RESTART command to the service.{Environment.NewLine}Service is either offline or disconnected.", "Restart Service", MessageBoxButton.OK, MessageBoxImage.Error);            }        }         /// <summary>        /// Handles ReceivedServiceResponse event.        /// </summary>        /// <param name="sender">Source of the event.</param>        /// <param name="e">Event arguments.</param>        private void Helper_ReceivedServiceResponse(object sender, EventArgs<ServiceResponse> e)        {            if (ClientHelper.TryParseActionableResponse(e.Argument, out string sourceCommand, out bool _))            {                switch (sourceCommand.ToLowerInvariant())                {                    case "health":                        this.Dispatcher.BeginInvoke((Action)delegate                        {                            string[] lines = e.Argument.Message.TrimEnd().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);                            TextBlockSystemHealth.Text = string.Join(Environment.NewLine, lines.Take(21));                            GroupBoxSystemHealth.Header = $"System Health (Last Refreshed: {DateTime.Now:HH:mm:ss.fff})";                        });                        break;                    case "status":                        this.Dispatcher.BeginInvoke((Action)delegate                        {                            string trimEnd(string value)                            {                                const int MaxLength = 80;                                 if (string.IsNullOrEmpty(value))                                    return "";                                 return value.Length <= MaxLength ? value : string.Concat(value.Substring(0, MaxLength - 3), "...");                            }                             string[] lines = e.Argument.Message.TrimEnd().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);                            TextBlockStatus.Text = string.Join(Environment.NewLine, lines.Select(trimEnd));                            GroupBoxStatus.Header = $"System Status (Last Refreshed: {DateTime.Now:HH:mm:ss.fff})";                        });                        break;                    case "version":                        this.Dispatcher.BeginInvoke((Action)delegate                        {                            TextBlockVersion.Text = e.Argument.Message.Substring(e.Argument.Message.ToLower().LastIndexOf("version:", StringComparison.Ordinal) + 8).Trim();                        });                        break;                    case "time":                        this.Dispatcher.BeginInvoke((Action)delegate                        {                            string[] lines = e.Argument.Message.TrimEnd().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);                             if (lines.Length > 0)                            {                                string[] currentServiceTimes = lines[0].Split(',');                                 if (currentServiceTimes.Length > 0)                                {                                    string currentServiceTime = currentServiceTimes[0].Substring(currentServiceTimes[0].ToLower().LastIndexOf("system time:", StringComparison.Ordinal) + 12).Trim();                                     if (DateTime.TryParse(currentServiceTime, out DateTime serviceTime) && DateTime.TryParse(TextBlockLocalTime.Text, out DateTime localTime))                                        m_lastLocalToServerTimeDeviation = new Ticks(localTime.Ticks - serviceTime.Ticks).ToSeconds();                                                                        TextBlockServerTime.Text = currentServiceTime;                                }                            }                        });                        break;                }            }

Lines 1–500 of 1350.

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