706 lines · 26.5 KB · C#
RawDownload
//******************************************************************************************************//  MainForm.cs - Gbtc////  Copyright © 2020, 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://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/06/2020 - J. Ritchie Carroll//       Generated original version of source code.////****************************************************************************************************** using System;using System.Collections;using System.Collections.Concurrent;using System.Collections.Generic;using System.Data;using System.Linq;using System.Windows.Forms;using AdapterExplorer.Model;using GSF;using GSF.Communication;using GSF.ComponentModel;using GSF.Data;using GSF.Data.Model;using GSF.Diagnostics;using GSF.ServiceProcess;using GSF.Threading;using GSF.TimeSeries;using GSF.TimeSeries.Adapters;using GSF.TimeSeries.Transport;using GSF.TimeSeries.UI;using GSF.Windows.Forms;using Measurement = AdapterExplorer.Model.Measurement; namespace AdapterExplorer{    public partial class MainForm : SecureForm    {        private DataSet m_dataSource;        private readonly LogPublisher m_log;        private AdoDataConnection m_database;        private WindowsServiceClient m_windowsServiceClient;        private Settings m_settings;        private readonly ConcurrentQueue<Action> m_subscriberOperationQueue;        private readonly ShortSynchronizedOperation m_subscriberOperations;        private DataSubscriber m_subscriber;        private UnsynchronizedSubscriptionInfo m_throttledSubscription;        private Guid[] m_inputSignalIDs;        private Guid[] m_outputSignalIDs;        private long m_lastRefresh;        private bool m_formLoaded;        private volatile bool m_formClosing;         public MainForm()        {            InitializeComponent();                        m_log = Program.Log;             m_subscriberOperationQueue = new ConcurrentQueue<Action>();            m_subscriberOperations = new ShortSynchronizedOperation(() =>            {                while (!m_formClosing && m_subscriberOperationQueue.TryDequeue(out Action operation))                {                    if (m_subscriber.IsConnected)                        operation();                }            },            ex => ShowUpdateMessage($"ERROR: Operations queue exception: {ex.Message}"));             groupBoxInputMeasurements.Tag = groupBoxInputMeasurements.Text;            groupBoxOutputMeasurements.Tag = groupBoxOutputMeasurements.Text;        }         private void MainForm_Load(object sender, EventArgs e)        {            try            {                // Set current principal and attempt host service connection                CommonFunctions.CurrentPrincipal = SecurityPrincipal;                CommonFunctions.ServiceConnectionRefreshed += CommonFunctions_ServiceConnectionRefreshed;                Program.HostNodeID.SetAsCurrentNodeID();            }            catch (Exception ex)            {                ShowUpdateMessage($"ERROR: Failed to initialize service connection: {ex.Message}");                m_log.Publish(MessageLevel.Error, "Initialize Service Connection", exception: ex);            }             try            {                Text += " - " + SecurityPrincipal.Identity.Provider.UserData.LoginID;                                m_database = Program.GetDatabaseConnection();                 if (m_database is null)                    throw new InvalidOperationException("Failed to connect to database.");                 MeasurementKey.EstablishDefaultCache(m_database.Connection, m_database.AdapterType);                 // Load current settings registering a symbolic reference to this form instance for use by default value expressions                m_settings = new Settings(new Dictionary<string, object> { { "Form", this } }.RegisterSymbols());                 // Restore last window size/location                this.RestoreLayout();                 LoadDataSource();                 InitializeDataGrid(dataGridViewInputMeasurements);                InitializeDataGrid(dataGridViewOutputMeasurements);                 InitializeDataSubscriber();                LoadAdapters(false);                 SetBottomPanelWidths();                 m_formLoaded = true;            }            catch (Exception ex)            {                ShowUpdateMessage($"ERROR: Failed during load: {ex.Message}");                m_log.Publish(MessageLevel.Error, "FormLoad", exception: ex);             #if DEBUG                throw;            #endif            }        }         private void MainForm_FormClosing(object sender, FormClosingEventArgs e)        {            try            {                m_formClosing = true;                 // Save current window size/location                this.SaveLayout();                 // Save any updates to current screen values                m_settings.Save();            }            catch (Exception ex)            {                m_log.Publish(MessageLevel.Error, "FormClosing", "Failed while saving settings", exception: ex);             #if DEBUG                throw;            #endif            }        }         private void MainForm_FormClosed(object sender, FormClosedEventArgs e)        {            CommonFunctions.DisconnectWindowsServiceClient();             if (!(m_subscriber is null))            {                m_subscriber.Stop();                m_subscriber.StatusMessage -= Subscriber_StatusMessage;                m_subscriber.ProcessException -= Subscriber_ProcessException;                m_subscriber.ConnectionTerminated -= Subscriber_ConnectionTerminated;                m_subscriber.NewMeasurements -= Subscriber_NewMeasurements;                m_subscriber.ServerConfigurationChanged -= Subscriber_ServerConfigurationChanged;                m_subscriber.Dispose();            }             m_settings?.Dispose();        }         private void FormElementChanged(object sender, EventArgs e)        {            if (InvokeRequired)            {                BeginInvoke(new Action<object, EventArgs>(FormElementChanged), sender, e);            }            else            {                if (Visible && m_formLoaded)                    m_settings?.UpdateProperties();            }        }         private void checkBoxAdapters_CheckedChanged(object sender, EventArgs e)        {            if (!Visible || !m_formLoaded)                return;             LoadAdapters(false);            FormElementChanged(sender, e);        }         private bool IsConnected { get; set; }         private void QueueSubscriberOperation(Action operation)        {            m_subscriberOperationQueue.Enqueue(operation);            m_subscriberOperations.RunOnceAsync();        }         private void CommonFunctions_ServiceConnectionRefreshed(object sender, EventArgs e)        {            ConnectToService();        }         private void ConnectToService()        {            ClientHelper helper = m_windowsServiceClient?.Helper;            ClientBase remotingClient = m_windowsServiceClient?.Helper?.RemotingClient;             if (!(helper is null))                helper.ReceivedServiceResponse -= Helper_ReceivedServiceResponse;             if (!(remotingClient is null))            {                remotingClient.ConnectionTerminated -= RemotingClient_ConnectionTerminated;                remotingClient.ConnectionEstablished -= RemotingClient_ConnectionEstablished;            }             m_windowsServiceClient = CommonFunctions.GetWindowsServiceClient();            helper = m_windowsServiceClient?.Helper;            remotingClient = m_windowsServiceClient?.Helper?.RemotingClient;             if (m_windowsServiceClient is null || helper is null || remotingClient is null)                return;             helper.ReceivedServiceResponse += Helper_ReceivedServiceResponse;            remotingClient.ConnectionEstablished += RemotingClient_ConnectionEstablished;            remotingClient.ConnectionTerminated += RemotingClient_ConnectionTerminated;             SetConnectionStatus(remotingClient.CurrentState == ClientState.Connected ? Status.Connected : Status.Disconnected);        }         private void Helper_ReceivedServiceResponse(object sender, EventArgs<ServiceResponse> e)        {            if (!ClientHelper.TryParseActionableResponse(e.Argument, out string sourceCommand, out _))                return;             Guid[] parseSignalIDs()            {                try                {                    List<object> attachments = e.Argument.Attachments;                     if (attachments is null || attachments.Count < 2 || !(attachments[0] is byte[][] signalIDs))                        return Array.Empty<Guid>();                     return signalIDs.Select(bytes => new Guid(bytes)).ToArray();                }                catch (Exception ex)                {                    m_log.Publish(MessageLevel.Info, "Parse actionable service response with Guid buffers", exception: ex);                    return Array.Empty<Guid>();                }            }             string command = sourceCommand.ToLower().Trim();             if (command.Equals("getinputmeasurements"))            {                m_inputSignalIDs = parseSignalIDs();                LoadMeasurements(m_inputSignalIDs, dataGridViewInputMeasurements, groupBoxInputMeasurements);            }            else if (command.Equals("getoutputmeasurements"))            {                m_outputSignalIDs = parseSignalIDs();                LoadMeasurements(m_outputSignalIDs, dataGridViewOutputMeasurements, groupBoxOutputMeasurements);                InitiateSubscribe();            }        }         private void RemotingClient_ConnectionTerminated(object sender, EventArgs e)        {            SetConnectionStatus(Status.Disconnected);        }         private void RemotingClient_ConnectionEstablished(object sender, EventArgs e)        {            SetConnectionStatus(Status.Connected);        }         private void SetConnectionStatus(Status status)        {            if (m_formClosing)                return;             if (InvokeRequired)            {                BeginInvoke(new Action<Status>(SetConnectionStatus), status);            }            else            {                IsConnected = status == Status.Connected;                pictureBoxStatus.Image = imageListStatus.Images[(int)status];                toolTip.SetToolTip(pictureBoxStatus, status.ToString());            }        }         private void LoadDataSource()        {            m_dataSource = m_database.RetrieveDataSet("SELECT * FROM ActiveMeasurement");            m_dataSource.Tables[0].TableName = "ActiveMeasurements";        }         private void InitializeDataSubscriber()        {            m_throttledSubscription = new UnsynchronizedSubscriptionInfo(true)            {                LagTime = 10.0D,                LeadTime = 10.0D,                PublishInterval = 0.5D            };             m_subscriber = new DataSubscriber            {                ConnectionString = $"server=localhost:{Program.GetGEPPort()}",                CompressionModes = CompressionModes.TSSC | CompressionModes.GZip,                OperationalModes = OperationalModes.UseCommonSerializationFormat | OperationalModes.CompressMetadata | OperationalModes.CompressSignalIndexCache | OperationalModes.CompressPayloadData            };             m_subscriber.StatusMessage += Subscriber_StatusMessage;            m_subscriber.ProcessException += Subscriber_ProcessException;            m_subscriber.ConnectionEstablished += Subscriber_ConnectionEstablished;            m_subscriber.ConnectionTerminated += Subscriber_ConnectionTerminated;            m_subscriber.NewMeasurements += Subscriber_NewMeasurements;            m_subscriber.ServerConfigurationChanged += Subscriber_ServerConfigurationChanged;             m_subscriber.Initialize();            m_subscriber.Start();        }         private void Subscriber_StatusMessage(object sender, EventArgs<string> e)        {            ShowUpdateMessage(e.Argument);        }         private void Subscriber_ProcessException(object sender, EventArgs<Exception> e)        {            ShowUpdateMessage($"ERROR: {e.Argument}", false);            m_log.Publish(MessageLevel.Info, "GEP Process Exception", exception: e.Argument);        }         private void Subscriber_ConnectionEstablished(object sender, EventArgs e)        {            if (m_formClosing)                return;             InitiateSubscribe();        }         private void Subscriber_ConnectionTerminated(object sender, EventArgs e)        {            if (m_formClosing)                return;             ShowUpdateMessage("Connection to publisher was terminated, restarting connection cycle...");            QueueSubscriberOperation(() => m_subscriber.Start());        }         private void Subscriber_NewMeasurements(object sender, EventArgs<ICollection<IMeasurement>> e)        {            if (m_formClosing)                return;             Dictionary<Guid, IMeasurement> receivedMeasurements = new Dictionary<Guid, IMeasurement>();             foreach (IMeasurement measurement in e.Argument)                receivedMeasurements[measurement.ID] = measurement;             AssignMeasurements(receivedMeasurements, dataGridViewInputMeasurements);            AssignMeasurements(receivedMeasurements, dataGridViewOutputMeasurements);             if (new TimeSpan(DateTime.UtcNow.Ticks - m_lastRefresh).TotalSeconds < 1.0D)                return;             BeginInvoke(new Action(dataGridViewInputMeasurements.Refresh));            BeginInvoke(new Action(dataGridViewOutputMeasurements.Refresh));             m_lastRefresh = DateTime.UtcNow.Ticks;        }         private void Subscriber_ServerConfigurationChanged(object sender, EventArgs e)        {            LoadAdapters(true);        }         private void InitiateSubscribe()        {            bool hasInputIDs = m_inputSignalIDs?.Length > 0;            bool hasOutputIDs = m_outputSignalIDs?.Length > 0;             if (!hasInputIDs && !hasOutputIDs)                return;             HashSet<Guid> signalIDs = new HashSet<Guid>();             if (hasInputIDs)                signalIDs.UnionWith(m_inputSignalIDs);             if (hasOutputIDs)                signalIDs.UnionWith(m_outputSignalIDs);             UnsynchronizedSubscriptionInfo subscription = (UnsynchronizedSubscriptionInfo)m_throttledSubscription.Copy();            subscription.FilterExpression = string.Join(";", signalIDs);             QueueSubscriberOperation(() =>            {                m_lastRefresh = 0L;                m_subscriber.UnsynchronizedSubscribe(subscription);            });        }         private void AssignMeasurements(Dictionary<Guid, IMeasurement> receivedMeasurements, DataGridView dataGridView)        {            if (!(dataGridView.DataSource is IList source))                return;             foreach (Measurement measurement in source)            {                if (!receivedMeasurements.TryGetValue(measurement.SignalID, out IMeasurement receivedMeasurement))                    continue;                 measurement.Value = receivedMeasurement.AdjustedValue;                measurement.Timestamp = receivedMeasurement.Timestamp;            }        }         private void LoadAdapters(bool restoreSelectedIndex)        {            if (m_formClosing)                return;             if (InvokeRequired)            {                BeginInvoke(new Action<bool>(LoadAdapters), restoreSelectedIndex);            }            else            {                int selectedIndex = comboBoxAdapters.SelectedIndex;                comboBoxAdapters.Items.Clear();                comboBoxAdapters.Text = "";                 void loadAdapters(ITableOperations table)                {                    foreach (IIaonAdapter iaonAdapter in table.QueryRecords("AdapterName"))                    {                        if (iaonAdapter is null)                            continue;                         comboBoxAdapters.Items.Add(iaonAdapter);                    }                }                 if (checkBoxActionAdapters.Checked)                    loadAdapters(new TableOperations<IaonActionAdapter>(m_database));                 if (checkBoxInputAdapters.Checked)                    loadAdapters(new TableOperations<IaonInputAdapter>(m_database));                 if (checkBoxOutputAdapters.Checked)                    loadAdapters(new TableOperations<IaonOutputAdapter>(m_database));                 int itemCount = comboBoxAdapters.Items.Count;                 if (itemCount == 0)                    return;                 if (restoreSelectedIndex && selectedIndex > -1 && selectedIndex < itemCount)                    comboBoxAdapters.SelectedIndex = selectedIndex;                else                    comboBoxAdapters.SelectedIndex = 0;            }        }         private void AssignInputMeasurements(Dictionary<string, string> settings)        {            if (!settings.ContainsKey("inputMeasurementKeys") && settings.TryGetValue("variableList", out string variableList))            {                Dictionary<string, string> variables = variableList.ParseKeyValuePairs();                 if (variables.Count > 0)                    settings["inputMeasurementKeys"] = string.Join(";", variables.Values);            }             MeasurementKey[] inputMeasurementKeys = settings.TryGetValue("inputMeasurementKeys", out string setting) ?                AdapterBase.ParseInputMeasurementKeys(m_dataSource, false, setting) :                Array.Empty<MeasurementKey>();             m_inputSignalIDs = inputMeasurementKeys.Select(k => k.SignalID).ToArray();

Lines 1–500 of 706.

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