729 lines
28 KiB
C#
729 lines
28 KiB
C#
/*-------------------------------------------------------------------------
|
|
// UNCLASSIFIED
|
|
/*-------------------------------------------------------------------------
|
|
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
|
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
|
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
|
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
|
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
|
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
|
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
|
COMPANY.
|
|
|
|
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
|
GOVERNMENT.
|
|
|
|
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
|
-------------------------------------------------------------------------*/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media.Imaging;
|
|
using System.Xml.XPath;
|
|
using MeasurementManagerLib;
|
|
using NLog;
|
|
using ProgramGui.GUI.ViewModel;
|
|
using ProgramLib.GUI.Model;
|
|
using Raytheon.Common.Coe;
|
|
using Raytheon.Instruments;
|
|
using Raytheon.Instruments.PowerSupply;
|
|
|
|
namespace ProgramLib.GUI.View
|
|
{
|
|
/// <summary>
|
|
/// Interaction logic for ManualControlWindow.xaml
|
|
/// </summary>
|
|
internal partial class ManualControlWindow : Window
|
|
{
|
|
public ManualWindowViewModel _manualWindowViewModel;
|
|
|
|
public LiveDataWindow LiveDataWindow { get; set; }
|
|
|
|
private ILogger _logger;
|
|
|
|
private Message _currentMsg;
|
|
|
|
private Dictionary<string, MessageXmlDocument> _xmlDocs = new Dictionary<string, MessageXmlDocument>();
|
|
|
|
private Dictionary<string, CoeMessageDataModel> _fieldNameToCoeMessageDataDict = new Dictionary<string, CoeMessageDataModel>();
|
|
|
|
private ManualGuiPowerSupplyReadThread _powerSupplyReadThread;
|
|
|
|
private CancellationTokenSource _coeSendMessageTaskCancellationSource = new CancellationTokenSource();
|
|
|
|
public ManualControlWindow()
|
|
{
|
|
InitializeComponent();
|
|
|
|
_logger = LogManager.GetCurrentClassLogger();
|
|
|
|
Uri iconUri = new Uri($"pack://application:,,,/{GetType().Assembly.GetName().Name};component/Resources/Icons/app.ico");
|
|
this.Icon = BitmapFrame.Create(iconUri);
|
|
|
|
WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
|
|
|
|
_manualWindowViewModel = new ManualWindowViewModel();
|
|
DataContext = _manualWindowViewModel;
|
|
|
|
_manualWindowViewModel._poweredModuleDataItems = new ObservableCollection<PowerModuleDataModel>();
|
|
_manualWindowViewModel._powerModuleComboBoxDataItems = new ObservableCollection<PowerModuleDataModel>();
|
|
}
|
|
|
|
~ManualControlWindow()
|
|
{
|
|
_logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() ...");
|
|
|
|
_coeSendMessageTaskCancellationSource.Cancel();
|
|
|
|
if (_powerSupplyReadThread != null)
|
|
{
|
|
_powerSupplyReadThread.Quit();
|
|
_powerSupplyReadThread.WaitForExit();
|
|
}
|
|
}
|
|
|
|
|
|
private void btnClose_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (_powerSupplyReadThread != null)
|
|
{
|
|
_powerSupplyReadThread.Quit();
|
|
_powerSupplyReadThread.WaitForExit();
|
|
_powerSupplyReadThread = null;
|
|
}
|
|
this.Hide();
|
|
if (LiveDataWindow != null)
|
|
{
|
|
LiveDataWindow.Show();
|
|
LiveDataWindow = null;
|
|
}
|
|
}
|
|
|
|
private void btnMax_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (this.WindowState == WindowState.Maximized)
|
|
{
|
|
this.WindowState = WindowState.Normal;
|
|
imgMax.Source = new BitmapImage(new System.Uri($"pack://application:,,,/{GetType().Assembly.GetName().Name};component/Resources/Images/Title_Bar_Buttons/maximize.png"));
|
|
}
|
|
else
|
|
{
|
|
this.WindowState = WindowState.Maximized;
|
|
imgMax.Source = new BitmapImage(new System.Uri($"pack://application:,,,/{GetType().Assembly.GetName().Name};component/Resources/Images/Title_Bar_Buttons/restore.png"));
|
|
}
|
|
}
|
|
|
|
private void btnMin_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
this.WindowState = WindowState.Minimized;
|
|
}
|
|
|
|
private void Window_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
|
{
|
|
TextBox textBox = Keyboard.FocusedElement as TextBox;
|
|
// unfocus text box if click outside of textbox
|
|
if (textBox != null)
|
|
{
|
|
// Kill logical focus
|
|
FocusManager.SetFocusedElement(FocusManager.GetFocusScope(textBox), null);
|
|
// Kill keyboard focus
|
|
Keyboard.ClearFocus();
|
|
}
|
|
|
|
DragMove();
|
|
}
|
|
|
|
private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
|
{
|
|
TextBox textBox = Keyboard.FocusedElement as TextBox;
|
|
// unfocus text box if enter key is pressed
|
|
if (textBox != null)
|
|
{
|
|
if (e.Key == Key.Return)
|
|
{
|
|
if (e.Key == Key.Enter)
|
|
{
|
|
// Kill logical focus
|
|
FocusManager.SetFocusedElement(FocusManager.GetFocusScope(textBox), null);
|
|
// Kill keyboard focus
|
|
Keyboard.ClearFocus();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void TextBox_GotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
|
|
{
|
|
TextBox tb = (TextBox)sender;
|
|
tb.Dispatcher.BeginInvoke(new Action(() => tb.SelectAll()));
|
|
}
|
|
|
|
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
|
|
{
|
|
TextBox tb = (TextBox)sender;
|
|
tb.SelectAll();
|
|
}
|
|
|
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
poppulatePowerSupplyTab();
|
|
poppulateDiscreteTab();
|
|
poppulateCoeTab();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex.Message + "\r\n" + ex.StackTrace);
|
|
}
|
|
}
|
|
|
|
private void Window_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
if (this.Visibility == Visibility.Visible)
|
|
{
|
|
List<string> moduleList = Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.GetPowerModuleList();
|
|
|
|
foreach (string module in moduleList)
|
|
{
|
|
PowerModuleDataModel powerData = GetPowerModuleDataFromDatagridDataItems(module);
|
|
PowerModuleDataModel powerData2 = GetPowerModuleDataFromComboBoxDataItems(module);
|
|
if (powerData != null && !Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.IsPowerSupplyOn(module))
|
|
{
|
|
// update datagrid
|
|
_manualWindowViewModel._poweredModuleDataItems.Remove(powerData);
|
|
|
|
if (powerData2 != null)
|
|
powerData2.PowerLed = _manualWindowViewModel._imageToResourcePathDict[ManualWindowViewModel.Images.LED_OFF];
|
|
}
|
|
else if (Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.IsPowerSupplyOn(module))
|
|
{
|
|
// update datagrid
|
|
_manualWindowViewModel._poweredModuleDataItems.Add(powerData);
|
|
|
|
if (powerData2 != null)
|
|
powerData2.PowerLed = _manualWindowViewModel._imageToResourcePathDict[ManualWindowViewModel.Images.LED_ON];
|
|
}
|
|
}
|
|
|
|
if (powerModuleCb.SelectedItem != null)
|
|
{
|
|
string powerModule = ((PowerModuleDataModel)powerModuleCb.SelectedItem).Name;
|
|
if (Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.IsPowerSupplyOn(powerModule))
|
|
{
|
|
powerOnBtn.Content = "Power Off";
|
|
}
|
|
else
|
|
powerOnBtn.Content = "Power On";
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Populate power supply tab
|
|
/// </summary>
|
|
private void poppulatePowerSupplyTab()
|
|
{
|
|
string sectionName = "MANUAL_CONTROL_GUI.POWER_MODULES";
|
|
|
|
List<string> keys = Program.Instance().ProgramSpecificConfig.ReadAllKeys(sectionName);
|
|
|
|
try
|
|
{
|
|
List<string> moduleList = Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.GetPowerModuleList();
|
|
|
|
foreach (string module in moduleList)
|
|
{
|
|
PowerModuleDataModel data = new PowerModuleDataModel();
|
|
data.PowerLed = _manualWindowViewModel._imageToResourcePathDict[ManualWindowViewModel.Images.LED_OFF];
|
|
if (Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.IsPowerSupplyOn(module))
|
|
{
|
|
data.PowerLed = _manualWindowViewModel._imageToResourcePathDict[ManualWindowViewModel.Images.LED_ON];
|
|
}
|
|
data.Name = module;
|
|
|
|
data.ExpectedVoltage = Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.GetVoltageSetpoint(module).ToString("0.00");
|
|
_manualWindowViewModel._powerModuleComboBoxDataItems.Add(data);
|
|
}
|
|
}
|
|
catch (MalMeasurementManagerNullReferenceException ex)
|
|
{
|
|
_logger.Warn(ex.Message + "\r\n" + ex.StackTrace);
|
|
}
|
|
}
|
|
|
|
private void powerOnBtn_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
bool success = true;
|
|
|
|
if (Program.Instance().IsUutPwrOn)
|
|
{
|
|
MessageBox.Show("Power to UUT is currently on. Please turn off power to UUT before manually controlling the power modules.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
((Button)sender).IsEnabled = false;
|
|
|
|
_manualWindowViewModel.GetPoweredModuleDataItemsSem().WaitOne();
|
|
|
|
string moduleName = ((PowerModuleDataModel)powerModuleCb.SelectedValue).Name;
|
|
|
|
PowerData data = Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.ReadPowerData(moduleName);
|
|
|
|
if (data.Voltage > 0.0)
|
|
{
|
|
Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.OutputDisable(moduleName);
|
|
}
|
|
|
|
string text = ((Button)sender).Content.ToString();
|
|
|
|
if (Regex.IsMatch(text, "power on", RegexOptions.IgnoreCase))
|
|
{
|
|
double voltageSetpoint = 0.0;
|
|
double ovp = 0.0;
|
|
double ocp = 0.0;
|
|
|
|
if (!Double.TryParse(voltageSetpointTb.Text, out voltageSetpoint))
|
|
{
|
|
MessageBox.Show("Voltage setpoint is invalid.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
success = false;
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
if (!Double.TryParse(ovpTb.Text, out ovp))
|
|
{
|
|
MessageBox.Show("OVP is invalid.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
success = false;
|
|
}
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
if (!Double.TryParse(ocpTb.Text, out ocp))
|
|
{
|
|
MessageBox.Show("OCP is invalid.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
success = false;
|
|
}
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.SetOverVoltageProtection(moduleName, ovp);
|
|
Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.SetVoltageSetpoint(moduleName, voltageSetpoint);
|
|
Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.SetOverCurrentProtection(moduleName, ocp);
|
|
Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.OutputEnable(moduleName);
|
|
|
|
((Button)sender).Content = "Power Off";
|
|
|
|
if (_powerSupplyReadThread == null)
|
|
{
|
|
_powerSupplyReadThread = new ManualGuiPowerSupplyReadThread();
|
|
_powerSupplyReadThread.Start();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.OutputDisable(moduleName);
|
|
((Button)sender).Content = "Power On";
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex.Message + "\r\n" + ex.StackTrace);
|
|
|
|
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
finally
|
|
{
|
|
_manualWindowViewModel.GetPoweredModuleDataItemsSem().Release();
|
|
|
|
((Button)sender).IsEnabled = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void powerModuleCb_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
string moduleName = ((PowerModuleDataModel)((ComboBox)sender).SelectedValue).Name;
|
|
|
|
double voltageSetpoint = 0.0;
|
|
double ovp = 0.0;
|
|
double ocp = 0.0;
|
|
|
|
voltageSetpoint = Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.GetVoltageSetpoint(moduleName);
|
|
ovp = Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.GetOverVoltageProtection(moduleName);
|
|
ocp = Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.GetOverCurrentProtection(moduleName);
|
|
|
|
voltageSetpointTb.Text = voltageSetpoint.ToString("0.00");
|
|
ovpTb.Text = ovp.ToString("0.00");
|
|
ocpTb.Text = ocp.ToString("0.00");
|
|
|
|
if (Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.IsPowerSupplyOn(moduleName))
|
|
{
|
|
powerOnBtn.Content = "Power Off";
|
|
}
|
|
else
|
|
powerOnBtn.Content = "Power On";
|
|
}
|
|
|
|
private void voltageSetpointTb_LostFocus(object sender, RoutedEventArgs e)
|
|
{
|
|
double voltageSetpoint = 0.0;
|
|
|
|
if (Double.TryParse(((TextBox)sender).Text, out voltageSetpoint) && powerModuleCb.SelectedItem != null)
|
|
{
|
|
string moduleName = ((PowerModuleDataModel)powerModuleCb.SelectedValue).Name;
|
|
PowerModuleDataModel data = GetPowerModuleDataFromComboBoxDataItems(moduleName);
|
|
string currentVoltageSetpoint = data.ExpectedVoltage;
|
|
if (voltageSetpoint.ToString("0.00") != currentVoltageSetpoint)
|
|
{
|
|
data.ExpectedVoltage = voltageSetpoint.ToString("0.00");
|
|
double ovp = voltageSetpoint + 0.5;
|
|
ovpTb.Text = ovp.ToString("0.00");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get power module data from ComboBox
|
|
/// </summary>
|
|
public PowerModuleDataModel GetPowerModuleDataFromComboBoxDataItems(string powerModuleName)
|
|
{
|
|
PowerModuleDataModel data = null;
|
|
foreach (PowerModuleDataModel item in _manualWindowViewModel._powerModuleComboBoxDataItems)
|
|
{
|
|
if (item.Name == powerModuleName)
|
|
data = item;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get power module data from datagrid
|
|
/// </summary>
|
|
public PowerModuleDataModel GetPowerModuleDataFromDatagridDataItems(string powerModuleName)
|
|
{
|
|
PowerModuleDataModel data = null;
|
|
foreach (PowerModuleDataModel item in _manualWindowViewModel._poweredModuleDataItems)
|
|
{
|
|
if (item.Name == powerModuleName)
|
|
data = item;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Populate Discrete tab
|
|
/// </summary>
|
|
private void poppulateDiscreteTab()
|
|
{
|
|
try
|
|
{
|
|
foreach (KeyValuePair<string, IODatatypes.DIOChannelInfo> item in Program.Instance().MalMeasurementLibManager.DioMeasurementManager.SignalNameToChannelInfoMap)
|
|
{
|
|
if (item.Value.ioType == IODatatypes.IOType.DigitalInput)
|
|
{
|
|
inputDiscretesCb.Items.Add(item.Key);
|
|
}
|
|
else
|
|
outputDiscretesCb.Items.Add(item.Key);
|
|
}
|
|
}
|
|
catch (MalMeasurementManagerNullReferenceException ex)
|
|
{
|
|
_logger.Warn(ex.Message + "\r\n" + ex.StackTrace);
|
|
}
|
|
}
|
|
|
|
private void inputDiscreteReadBtn_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (inputDiscretesCb.SelectedItem != null)
|
|
{
|
|
if (Program.Instance().MalMeasurementLibManager != null && Program.Instance().MalMeasurementLibManager.DioMeasurementManager != null)
|
|
{
|
|
IODatatypes.BitState state = Program.Instance().MalMeasurementLibManager.DioMeasurementManager.GetInputSignalState(inputDiscretesCb.SelectedValue.ToString());
|
|
|
|
inputDiscreteStatusTb.Text = state.ToString();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show("Please select an input signal.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex.Message + "\r\n" + ex.StackTrace);
|
|
}
|
|
}
|
|
|
|
private void outputDiscreteWriteBtn_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
bool success = true;
|
|
try
|
|
{
|
|
if (outputDiscretesCb.SelectedItem == null)
|
|
{
|
|
MessageBox.Show("Please select an output signal.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
success = false;
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
if (outputDiscreteStateCb.SelectedItem == null)
|
|
{
|
|
MessageBox.Show("Please select an output signal state.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
success = false;
|
|
}
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
if (Program.Instance().MalMeasurementLibManager != null && Program.Instance().MalMeasurementLibManager.DioMeasurementManager != null)
|
|
{
|
|
IODatatypes.BitState state;
|
|
if (Enum.TryParse(outputDiscreteStateCb.SelectedValue.ToString(), out state))
|
|
{
|
|
Program.Instance().MalMeasurementLibManager.DioMeasurementManager.SetOutputSignalState(outputDiscretesCb.SelectedValue.ToString(), state);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex.Message + "\r\n" + ex.StackTrace);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Populate COE tab
|
|
/// </summary>
|
|
private void poppulateCoeTab()
|
|
{
|
|
try
|
|
{
|
|
ICollection<object> coeDeviceList = Program.Instance().InstrumentManager.GetInstruments(typeof(CoeComm));
|
|
foreach (CoeComm coeDevice in coeDeviceList)
|
|
{
|
|
coeDeviceCb.Items.Add(Path.GetFileName(coeDevice.Name));
|
|
}
|
|
|
|
}
|
|
catch (MalMeasurementManagerNullReferenceException ex)
|
|
{
|
|
_logger.Warn(ex.Message + "\r\n" + ex.StackTrace);
|
|
}
|
|
}
|
|
|
|
private void coeDeviceCb_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
xmlFileCb.Items.Clear();
|
|
|
|
var xmlDocObject = Program.Instance().MalMeasurementLibManager.CoeMeasurementManager.GetXmlDocs(coeDeviceCb.SelectedValue.ToString());
|
|
|
|
if (xmlDocObject != null && xmlDocObject.GetType() == _xmlDocs.GetType())
|
|
{
|
|
_xmlDocs = (Dictionary<string, MessageXmlDocument>)xmlDocObject;
|
|
|
|
foreach (KeyValuePair<string, MessageXmlDocument> item in _xmlDocs)
|
|
{
|
|
xmlFileCb.Items.Add(Path.GetFileName(item.Key));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void xmlFileCb_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
coeMessagesCb.Items.Clear();
|
|
_manualWindowViewModel._coeMessageDataItems.Clear();
|
|
string coeXmlFolderPath = Path.GetDirectoryName(_xmlDocs.First().Key.ToString());
|
|
string coeXmlFilePath = Path.Combine(coeXmlFolderPath, ((ComboBox)sender).SelectedValue.ToString());
|
|
XPathNavigator Node = _xmlDocs[coeXmlFilePath].CreateNavigator();
|
|
XPathNodeIterator Nodeset = Node.Select("interface/message/name");
|
|
while (Nodeset.MoveNext())
|
|
{
|
|
coeMessagesCb.Items.Add(Nodeset.Current.Value);
|
|
}
|
|
}
|
|
|
|
private void coeMessagesCb_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
if (((ComboBox)sender).SelectedItem != null)
|
|
{
|
|
string coeXmlFolderPath = Path.GetDirectoryName(_xmlDocs.First().Key.ToString());
|
|
string coeXmlFilePath = Path.Combine(coeXmlFolderPath, xmlFileCb.SelectedValue.ToString());
|
|
_currentMsg = new Message(((ComboBox)sender).SelectedValue.ToString(), _xmlDocs[coeXmlFilePath]);
|
|
_currentMsg.Default();
|
|
List<MessageData> visibleData = new List<MessageData>();
|
|
visibleData.AddRange(_currentMsg.MessageDataArray);
|
|
|
|
_manualWindowViewModel._coeMessageDataItems.Clear();
|
|
_fieldNameToCoeMessageDataDict.Clear();
|
|
CoeMessageDataModel coeMessage;
|
|
foreach (MessageData messageData in visibleData)
|
|
{
|
|
coeMessage = new CoeMessageDataModel(messageData.FieldName, messageData.FieldValue, messageData.FieldType);
|
|
if (!String.IsNullOrEmpty(messageData.FormattedValue) && Regex.IsMatch(messageData.FormattedValue, @"^0x.+", RegexOptions.IgnoreCase))
|
|
{
|
|
coeMessage.Value = messageData.FormattedValue;
|
|
}
|
|
_fieldNameToCoeMessageDataDict[messageData.FieldName] = coeMessage;
|
|
if (messageData.FieldName[0] == '$')
|
|
{
|
|
coeMessage.IsFocusable = Boolean.FalseString;
|
|
}
|
|
// add data item to TreeView control
|
|
_manualWindowViewModel._coeMessageDataItems.Add(coeMessage);
|
|
ProcessChildMessage(messageData.MessageArray, coeMessage);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process child message
|
|
/// </summary>
|
|
private void ProcessChildMessage(MessageData[] messageArray, CoeMessageDataModel coeMessageParent)
|
|
{
|
|
if (messageArray != null && messageArray.Count() > 0)
|
|
{
|
|
coeMessageParent.SubItems = new ObservableCollection<CoeMessageDataModel>();
|
|
foreach (var message in messageArray)
|
|
{
|
|
string simpliedFiledName = message.FieldName;
|
|
Match regexMatch = Regex.Match(message.FieldName, @"([^\\.]+)$", RegexOptions.IgnoreCase);
|
|
|
|
if (regexMatch.Success)
|
|
{
|
|
simpliedFiledName = regexMatch.Groups[1].Value;
|
|
}
|
|
CoeMessageDataModel coeMessage = new CoeMessageDataModel(simpliedFiledName, message.FieldValue, message.FieldType);
|
|
_fieldNameToCoeMessageDataDict[message.FieldName] = coeMessage;
|
|
if (String.IsNullOrEmpty(message.FieldValue))
|
|
{
|
|
coeMessage.IsFocusable = Boolean.FalseString;
|
|
}
|
|
coeMessageParent.SubItems.Add(coeMessage);
|
|
ProcessChildMessage(message.MessageArray, coeMessage);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void coeSendBtn_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (_currentMsg != null)
|
|
{
|
|
string text = ((Button)sender).Content.ToString();
|
|
|
|
if (Regex.IsMatch(text, "send", RegexOptions.IgnoreCase))
|
|
{
|
|
var parms = GetParameters(_currentMsg.MessageDataArray);
|
|
int rateHz = -1;
|
|
if (int.TryParse(coeSendRate.Text, out rateHz))
|
|
{
|
|
int minRateHz = 1;
|
|
int maxRateHz = 60;
|
|
if (rateHz < minRateHz || rateHz > maxRateHz)
|
|
{
|
|
MessageBox.Show($"Rate {rateHz} Hz is out of range. Must be between {minRateHz} and {maxRateHz} Hz");
|
|
}
|
|
else
|
|
{
|
|
_coeSendMessageTaskCancellationSource = new CancellationTokenSource();
|
|
string instr = coeDeviceCb.SelectedValue.ToString();
|
|
Task.Factory.StartNew(() => SendCoeMessageTask(instr, _currentMsg.Name, parms, rateHz));
|
|
((Button)sender).Content = "Stop";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
Program.Instance().MalMeasurementLibManager.CoeMeasurementManager.SendMessage(coeDeviceCb.SelectedValue.ToString(), _currentMsg.Name, parms);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex.Message + "\r\n" + ex.StackTrace);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_coeSendMessageTaskCancellationSource.Cancel();
|
|
((Button)sender).Content = "Send";
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send COE message periodically
|
|
/// </summary>
|
|
private async void SendCoeMessageTask(string instr, string msgName, List<KeyValuePair<string, string>> parms, int rateHz)
|
|
{
|
|
_logger?.Debug($"{this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() is running...");
|
|
|
|
int sleepIntervalMs = 1000 / rateHz;
|
|
|
|
try
|
|
{
|
|
while (!_coeSendMessageTaskCancellationSource.Token.IsCancellationRequested)
|
|
{
|
|
Program.Instance().MalMeasurementLibManager.CoeMeasurementManager.SendMessage(instr, msgName, parms);
|
|
|
|
await Task.Delay(sleepIntervalMs);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex.Message + "\r\n" + ex.StackTrace);
|
|
}
|
|
|
|
_logger?.Debug($"{this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() is exiting...");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get parameters in the message
|
|
/// </summary>
|
|
private List<KeyValuePair<string, string>> GetParameters(MessageData[] array)
|
|
{
|
|
if (array == null || array.Length == 0)
|
|
return null;
|
|
|
|
List<KeyValuePair<string, string>> parms = new List<KeyValuePair<string, string>>();
|
|
|
|
foreach (var item in array.Where(m => !m.FieldName.StartsWith("$")))
|
|
{
|
|
if (_fieldNameToCoeMessageDataDict.ContainsKey(item.FieldName))
|
|
{
|
|
parms.Add(new KeyValuePair<string, string>(item.FieldName, _fieldNameToCoeMessageDataDict[item.FieldName].Value));
|
|
}
|
|
if (item.MessageArray != null && item.MessageArray.Any())
|
|
{
|
|
var innerParams = GetParameters(item.MessageArray);
|
|
if (innerParams != null)
|
|
{
|
|
parms.AddRange(innerParams);
|
|
}
|
|
}
|
|
}
|
|
|
|
return parms;
|
|
}
|
|
}
|
|
}
|