using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Emulations.Emulators; using Tango.Logging; using Tango.SharedUI; using Tango.Core.Commands; using Tango.Transport.Adapters; using Tango.Transport.Servers; using Tango.Transport.Transporters; using Tango.Core; using Tango.Settings; using Tango.PMR.ThreadLoading; using Tango.PMR.DataStore; using System.Windows; namespace Tango.MachineEM.UI.ViewModels { public class MainViewVM : ExtendedObject { private TcpServer TcpServer; private bool _running; private LogManager logManager = LogManager.Default; private bool _isThreadLoading; #region Properties private MachineEmulator _emulator; /// /// Gets or sets the machine emulator. /// public MachineEmulator Emulator { get { return _emulator; } set { _emulator = value; RaisePropertyChanged(nameof(Emulator)); } } private String _log; /// /// Gets or sets the log. /// public String Log { get { return _log; } set { _log = value; RaisePropertyChanged(nameof(Log)); } } private List _ports; /// /// Gets or sets the ports. /// public List Ports { get { return _ports; } set { _ports = value; RaisePropertyChanged(nameof(Ports)); } } private String _selectedPort; /// /// Gets or sets the selected port. /// public String SelectedPort { get { return _selectedPort; } set { _selectedPort = value; RaisePropertyChanged(nameof(SelectedPort)); } } private ThreadLoadingState _threadLoadingState; public ThreadLoadingState ThreadLoadingState { get { return _threadLoadingState; } set { _threadLoadingState = value; OnThreadLoadingStateChanged(); } } #endregion #region Private Methods private void OnThreadLoadingStateChanged() { try { Emulator?.SetThreadLoadingState(ThreadLoadingState); } catch (Exception ex) { LogManager.Log(ex); } } #endregion #region Commands /// /// Gets or sets the start command. /// public RelayCommand StartCommand { get; set; } /// /// Gets or sets the stop command. /// public RelayCommand StopCommand { get; set; } /// /// Gets or sets the run command. /// public RelayCommand RunCommand { get; set; } /// /// Gets or sets the cancel command. /// public RelayCommand CancelCommand { get; set; } /// /// Gets or sets the clear command. /// public RelayCommand ClearCommand { get; set; } /// /// Gets or sets the validate cartridge command. /// public RelayCommand ValidateCartridgeCommand { get; set; } /// /// Gets or sets the start thread loading sequence command. /// public RelayCommand StartThreadLoadingCommand { get; set; } /// /// Gets or sets the finalize thread loading command. /// public RelayCommand FinalizeThreadLoadingCommand { get; set; } /// /// Gets or sets the abort job. /// public RelayCommand AbortJobCommand { get; set; } public RelayCommand GetDataStoreItemCommand { get; set; } public RelayCommand PutDataStoreItemCommand { get; set; } public RelayCommand PerformDataStoreTestCommand { get; set; } #endregion #region Constructors /// /// Initializes a new instance of the class. /// public MainViewVM() { CoreSettings settings = SettingsManager.Default.GetOrCreate(); settings.Save(); SimpleStringLogger logger = new SimpleStringLogger(LogCategory.Critical, LogCategory.Error, LogCategory.Info, LogCategory.Warning); logger.LogReceived += (sedner, log) => { Log += log.ToString() + Environment.NewLine; }; logManager.RegisterLogger(logger); logManager.Log("Embedded Emulator Started..."); Emulator = new MachineEmulator(new BasicTransporter()); StartCommand = new RelayCommand(Start, (x) => !Emulator.IsStarted); StopCommand = new RelayCommand(Stop, (x) => Emulator.IsStarted); CancelCommand = new RelayCommand(Cancel, (x) => _running); ClearCommand = new RelayCommand(() => Log = String.Empty); ValidateCartridgeCommand = new RelayCommand(ValidateCartridge, (x) => Emulator.IsStarted); StartThreadLoadingCommand = new RelayCommand(StartThreadLoading, (x) => Emulator.IsStarted && !_isThreadLoading); FinalizeThreadLoadingCommand = new RelayCommand(FinalizeThreadLoading, (x) => Emulator.IsStarted && _isThreadLoading); AbortJobCommand = new RelayCommand(() => Emulator?.AbortJob(), (x) => Emulator.IsStarted); Ports = new List() { "TCP", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", }; SelectedPort = Ports.First(); PerformDataStoreTestCommand = new RelayCommand(Emulator.PerformDataStoreTest); GetDataStoreItemCommand = new RelayCommand(GetDataStoreItem); PutDataStoreItemCommand = new RelayCommand(PutDataStoreItem); } #endregion #region Event Handlers /// /// Handles the ClientConnected event of the TcpServer control. /// /// The source of the event. /// The instance containing the event data. private void TcpServer_ClientConnected(object sender, ClientConnectedEventArgs e) { Emulator.Transporter.Adapter = new TcpTransportAdapter(e.Socket); } #endregion #region Command Handlers /// /// Stops the TCP server and emulator. /// private async void Start() { if (SelectedPort == Ports.First()) { TcpServer = new TcpServer(9999); TcpServer.ClientConnected += TcpServer_ClientConnected; TcpServer.Start(); } else { Emulator.Transporter.Adapter = new UsbTransportAdapter(SelectedPort); } await Emulator.Start(); InvalidateRelayCommands(); } /// /// Starts the TCP server/USB and emulator. /// private async void Stop() { if (TcpServer != null) { TcpServer.Stop(); } await Emulator.Stop(); InvalidateRelayCommands(); } private void Cancel() { } private async void ValidateCartridge() { LogManager.Log("Sending cartridge validation request..."); try { var index = await Emulator.ValidateCartridge(); LogManager.Log($"Cartridge validation response received: '{index}'."); } catch (Exception ex) { LogManager.Log(ex, "Cartridge validation request failed."); } } private async void StartThreadLoading() { LogManager.Log("Starting thread loading sequence..."); Emulator.StartThreadLoading(); _isThreadLoading = true; InvalidateRelayCommands(); await Task.Delay(10000); _isThreadLoading = false; InvalidateRelayCommands(); } private void FinalizeThreadLoading() { LogManager.Log("Finalizing thread loading sequence..."); Emulator.FinalizeThreadLoading(); _isThreadLoading = false; InvalidateRelayCommands(); } private void GetDataStoreItem() { try { var result = GetUserInput("Get Data Store Item", "Enter collection name", String.Empty); if (!result.Confirmed) return; var collectionName = result.Value; result = GetUserInput("Get Data Store Item", "Enter item key", String.Empty); if (!result.Confirmed) return; var key = result.Value; Emulator.GetDataStoreItem(new PMR.DataStore.GetDataStoreItemRequest() { Collection = collectionName, Key = key }); } catch { } } private void PutDataStoreItem() { try { var result = GetUserInput("Put Data Store Item", "Enter collection name", String.Empty); if (!result.Confirmed) return; var collectionName = result.Value; result = GetUserInput("Put Data Store Item", "Enter item key", String.Empty); if (!result.Confirmed) return; var key = result.Value; result = GetUserInput("Put Data Store Item", "Enter data type", "Int32"); if (!result.Confirmed) return; DataType dataType = (DataType)Enum.Parse(typeof(DataType), result.Value); result = GetUserInput("Put Data Store Item", "Enter value", "10"); if (!result.Confirmed) return; var value = result.Value; DataStoreItem item = new DataStoreItem(); item.DataType = dataType; switch (dataType) { case DataType.Int32: item.Int32Value = int.Parse(value); break; case DataType.Float: item.FloatValue = float.Parse(value); break; case DataType.Double: item.DoubleValue = double.Parse(value); break; case DataType.Boolean: item.BooleanValue = bool.Parse(value); break; case DataType.String: item.StringValue = value; break; default: LogManager.Log("Data type not supported by this emulator."); throw new NotSupportedException(); } Emulator.PutDataStoreItem(new PutDataStoreItemRequest() { Collection = collectionName, Key = key, Item = item }); } catch { } } #endregion #region Private Methods private class InputResult { public bool Confirmed { get; set; } public T Value { get; set; } } private InputResult GetUserInput(String title, String message, T defaultValue) { InputWindow window = new InputWindow(); window.Title = title; window.Message = message; window.Value = defaultValue.ToStringSafe(); window.Owner = Application.Current.MainWindow; window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner; window.WindowStyle = WindowStyle.ToolWindow; try { if (window.ShowDialog().Value) { return new InputResult() { Confirmed = true, Value = (T)Convert.ChangeType(window.Value, typeof(T)) }; } else { return new InputResult(); } } catch (Exception ex) { LogManager.Log(ex, "Error parsing input."); throw ex; } } #endregion } }