//******************************************************************************************************// 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:// ----------------------------------------------------------------------------------------------------// 11/09/2011 - Mehulbhai P Thakkar// Generated original version of source code.// 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;using GSF.TimeSeries.Transport;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.Local// ReSharper disable RedundantNameQualifiernamespace GSF.PhasorProtocols.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 1351. Load more
//****************************************************************************************************** // 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: // ---------------------------------------------------------------------------------------------------- // 11/09/2011 - Mehulbhai P Thakkar // Generated original version of source code. // 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; using GSF.TimeSeries.Transport; 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.Local // ReSharper disable RedundantNameQualifier namespace GSF.PhasorProtocols.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; }