using System; using System.Collections.Generic; using System.Linq; using System.Net.Mime; using System.Text; using System.IO; using System.ComponentModel; using System.Collections.ObjectModel; using ElmoMotionControlComponents.Drive.EASComponents; using System.Collections.Specialized; using System.Windows.Controls; using DriveDotNetGuiClient.SettingsObjects; using ElmoMotionControlComponents.Drive.EASComponents.Locator; using System.Windows; using System.Windows.Input; using GalaSoft.MvvmLight.Command; using System.Net; using Microsoft.Win32; using ElmoMotionControlComponents.Drive.EASComponents.UploadsAndDownloads; using ElmoMotionControlComponents.Drive.EASComponents.DriveCompiler; using ElmoMotionControlComponents.Drive.EASComponents.DriveCAN; using System.Diagnostics; using DriveDotNetGuiClient.CANObjects; namespace DriveDotNetGuiClient { public class ViewModel : INotifyPropertyChanged,INotifyCollectionChanged { public ViewModel() { //commands init LocateUdpDevicesCommand = new RelayCommand(this.LocateUdpDevices); SelectUdpDeviceCommand = new RelayCommand(this.SelectUdpDevice); LocateUsbDevicesCommand = new RelayCommand(this.LocateUsbDevices); LocateRS232DevicesCommand = new RelayCommand(this.LocateRS232Devices); ConnectCommand = new RelayCommand(this.Connect, this.IsDisconnected); DisconnectCommand = new RelayCommand(this.Disconnect, this.IsConnected); SendCommandCommand = new RelayCommand(this.SendCommand, this.IsConnected); StartUploadOrDownloadCommand = new RelayCommand(this.StartUploadOrDownload, this.IsConnected); CancelUploadOrDownloadCommand = new RelayCommand(this.CancelUploadOrDownload, this.IsConnected); ClearLogsCommand = new RelayCommand(this.ClearLogs,this.ClearLogsCanExecute); cmdCompile = new RelayCommand(this.OnCompile, canCompile); //GUI Components init Manufacturers = Enum.GetValues(typeof(CANBoardManufacturer)).Cast().ToList(); NodeTypes = Enum.GetValues(typeof(CANNodeType)).Cast().ToList(); UploadsAndDownloadsActions = Enum.GetValues(typeof(OPERATION_TYPE)).Cast().ToList(); Logs = new ObservableCollection(); SelectedAction = OPERATION_TYPE.DOWNLOAD_FW; //CAN defaults CANBaudRate = "500"; BusID = "0"; CANNodeID = "1"; SelectedManufacturer = CANBoardManufacturer.Kvaser; GmasIP = "192.168.1.123"; GmasHostIP = "192.168.1.244"; AxisName = "a01"; // set Debug compilation mode CompilationMode = 0; } #region properties private Cursor cursorState = Cursors.Arrow; public Cursor CursorState { get { return cursorState; } set { cursorState = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("CursorState")); } } private TabItem selectedTab; public TabItem SelectedTab { get { return selectedTab; } set { selectedTab = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedTab")); } } #region Communication parameters public IDriveCommunication communication; public IDriveCommunicationInfo communicationInfo; #region RS232 private string comPort; public string ComPort { get { return comPort; } set { comPort = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("ComPort")); } } private List buadRates = new List { 4800, 9600, 19200, 38400, 57600, 115200, 230400 }; public List BuadRates { get { return buadRates; } } private string buadRate; public string BuadRate { get { return buadRate; } set { buadRate = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("BuadRate")); } } #endregion RS232 #region USB private string usbComPort; public string UsbComPort { get { return usbComPort; } set { usbComPort = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("UsbComPort")); } } #endregion USB #region UDP private string driveIP; public string DriveIP { get { return driveIP; } set { driveIP = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("DriveIP")); } } private string hostIP; public string HostIP { get { return hostIP; } set { hostIP = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("HostIP")); } } private ushort ipPortUDP = 5001; public ushort IpPortUDP { get { return ipPortUDP; } set { ipPortUDP = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IpPortUDP")); } } #endregion UDP #region CAN private UserControl canObject; public UserControl CANObject { get { return canObject; } set { canObject = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("CANObject")); } } public List Manufacturers { get; set; } private CANBoardManufacturer selectedManufacturer; public CANBoardManufacturer SelectedManufacturer { get { return selectedManufacturer; } set { selectedManufacturer = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedManufacturer")); switch (selectedManufacturer) { case CANBoardManufacturer.GMAS: { CANObject = new GMASCANObject(); break; } case CANBoardManufacturer.IXXAT: { CANObject = new IXXATCANObject(); break; } case CANBoardManufacturer.Kvaser: { CANObject = new KvaserCANObject(); break; } } } } public List NodeTypes { get; set; } private CANNodeType selectedNodeType = CANNodeType.ElmoGold; public CANNodeType SelectedNodeType { get { return selectedNodeType; } set { selectedNodeType = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedNodeType")); } } #region Kvaser private List canbuadRates = new List { "10", "20", "50", "100", "125", "250", "500", "800", "1000" }; public List CanBuadRates { get { return canbuadRates; } } private string canBuadRate = "500"; public string CanBuadRate { get { return canBuadRate; } set { canBuadRate = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("CanBuadRate")); } } public string CANBaudRate { get; set; } public string BusID { get; set; } public string CANNodeID { get; set; } #endregion Kvaser #region G-MAS private string gmasIP; public string GmasIP { get { return gmasIP; } set { gmasIP = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("GmasIP")); } } private string gmasHostIP; public string GmasHostIP { get { return gmasHostIP; } set { gmasHostIP = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("GmasHostIP")); } } private string axisName; public string AxisName { get { return axisName; } set { axisName = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("AxisName")); } } #endregion CAN #endregion Communication parameters #endregion Communication parameters #region Device Locator private ObservableCollection locatorResults = new ObservableCollection(); public ObservableCollection LocatorResults { get { return locatorResults; } set { locatorResults = value; } } #endregion Device Locator #region Personality Model public string personalityPath; public string PersonalityPath { get { return personalityPath; } set { personalityPath = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("PersonalityPath")); } } #endregion Personality Model #region Terminal public string Command { get; set; } #endregion Terminal #region Uploads and Downloads public string Path { get { try { string toReturn = null; App.Current.Dispatcher.Invoke((Action)(() => { if (SettingsObject == null || SettingsObject.DataContext == null || !(SettingsObject.DataContext is SettingsObjectViewModel)) toReturn = string.Empty; else toReturn = (SettingsObject.DataContext as SettingsObjectViewModel).Path; })); return toReturn; } catch { return null; } } set { if (SettingsObject != null && SettingsObject.DataContext != null && (SettingsObject.DataContext is SettingsObjectViewModel)) (SettingsObject.DataContext as SettingsObjectViewModel).Path = value; } } public IUploadDownloadModel UploadDownloadModel; public int percent; public int Percent { get { return percent; } set { percent = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Percent")); } } public List UploadsAndDownloadsActions { get; set; } public OPERATION_TYPE selectedAction; public OPERATION_TYPE SelectedAction { get { return selectedAction; } set { selectedAction = value; switch (selectedAction) { case OPERATION_TYPE.DOWNLOAD_FW: SettingsObject = new SimplePathOpen(); SettingsObjectVM = new SettingsObjectViewModel(null, selectedAction); SettingsObject.DataContext = SettingsObjectVM; break; case OPERATION_TYPE.DOWNLOAD_BIN_PARAMS: SettingsObject = new DownloadBinParams(); SettingsObjectVM = new SettingsObjectViewModel(new DownloadBinSettings(), selectedAction); SettingsObject.DataContext = SettingsObjectVM; break; case OPERATION_TYPE.DOWNLOAD_TXT_PARAMS: SettingsObject = new DownloadTxtParams(); SettingsObjectVM = new SettingsObjectViewModel(new DownloadTxtSettings(), selectedAction); SettingsObject.DataContext = SettingsObjectVM; break; case OPERATION_TYPE.DOWNLOAD_PROGRAM: SettingsObject = new SimplePathOpen(); SettingsObjectVM = new SettingsObjectViewModel(null, selectedAction); SettingsObject.DataContext = SettingsObjectVM; break; case OPERATION_TYPE.UPLOAD_PERSONALITY: SettingsObject = new SimplePathSave(); SettingsObjectVM = new SettingsObjectViewModel(null, selectedAction); SettingsObject.DataContext = SettingsObjectVM; break; case OPERATION_TYPE.UPLOAD_BIN_PARAMS: SettingsObject = new UploadBinParams(); SettingsObjectVM = new SettingsObjectViewModel(new UploadBinSettings(), selectedAction); SettingsObject.DataContext = SettingsObjectVM; break; case OPERATION_TYPE.UPLOAD_TXT_PARAMS: SettingsObject = new UploadTxtParams(); SettingsObjectVM = new SettingsObjectViewModel(new UploadTxtSettings(), selectedAction); SettingsObject.DataContext = SettingsObjectVM; break; case OPERATION_TYPE.UPLOAD_PROGRAM: SettingsObject = new SimplePathSave(); SettingsObjectVM = new SettingsObjectViewModel(null, selectedAction); SettingsObject.DataContext = SettingsObjectVM; break; case OPERATION_TYPE.DOWNLOAD_PAL: SettingsObject = new DownloadPal(); SettingsObjectVM = new SettingsObjectViewModel(new PalSettings(HardwareType.Undef, 0), selectedAction); SettingsObject.DataContext = SettingsObjectVM; break; } if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedAction")); } } private UserControl settingsObject; public UserControl SettingsObject { get { return settingsObject; } set { settingsObject = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SettingsObject")); } } private SettingsObjectViewModel settingsObjectVM; public SettingsObjectViewModel SettingsObjectVM { get { return settingsObjectVM; } set { settingsObjectVM = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SettingsObjectVM")); } } #endregion Uploads and Downloads #region Compile program private string _compilerPath; public string CompilerPath { get { return _compilerPath; } set { _compilerPath = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("CompilerPath")); cmdCompile.RaiseCanExecuteChanged(); } } private string _ProgramPath; public string ProgramPath { get { return _ProgramPath; } set { _ProgramPath = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("ProgramPath")); cmdCompile.RaiseCanExecuteChanged(); } } private int _compilationMode; public int CompilationMode { get { return _compilationMode; } set { _compilationMode = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("CompilationMode")); } } private string _outputPath; public string OutputPath { get { return _outputPath; } set { _outputPath = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("OutputPath")); cmdCompile.RaiseCanExecuteChanged(); } } #endregion #region Log public ObservableCollection Logs { get; set; } #endregion log #endregion properties #region Commands #region Locate devices public RelayCommand LocateUdpDevicesCommand { get; set; } public RelayCommand SelectUdpDeviceCommand { get; set; } public RelayCommand LocateUsbDevicesCommand { get; set; } public RelayCommand LocateRS232DevicesCommand { get; set; } private void LocateUdpDevices() { CursorState = Cursors.Wait; LocatorResults.Clear(); foreach (var v in DriveLocator.GetUDPDevices()) { var ipIinfo = v.Value; LocatorResults.Add("Ip: [" + ipIinfo.IPCommInfo.Address + "] , Host: [" + ipIinfo.IPCommInfo.HostAddress + "]"); } CursorState = Cursors.Arrow; } private void SelectUdpDevice(string selectedItem) { if (selectedItem == null) return; string[] splitedStr = selectedItem.Split(new char[] { '[', ']' }); DriveIP = splitedStr[1]; HostIP = splitedStr[3]; } private void LocateUsbDevices() { CursorState = Cursors.Wait; LocatorResults.Clear(); foreach (var v in DriveLocator.GetUSBDevices()) { LocatorResults.Add(v.SerialCommInfo.ComPort); } CursorState = Cursors.Arrow; } private void LocateRS232Devices() { CursorState = Cursors.Wait; LocatorResults.Clear(); foreach (var v in DriveLocator.GetRS232Devices()) { LocatorResults.Add(v.SerialCommInfo.ComPort); } CursorState = Cursors.Arrow; } #endregion Locate devices #region Connect \ Disconnect public RelayCommand ConnectCommand { get; set; } public RelayCommand DisconnectCommand { get; set; } public bool ConnectedAndNotNull { get { if (communication == null) return false; return communication.IsConnected; } } public bool IsDisconnected() { if (communication == null) return true; return !ConnectedAndNotNull; } public bool IsConnected() { return ConnectedAndNotNull; } private void Connect() { if (communication != null && communication.IsConnected) { AddLog("Drive is already connected"); return; } try { //create communication switch (SelectedTab.Header.ToString()) { case "USB": { communicationInfo = DriveCommunicationFactory.CreateUSBCommunicationInfo(UsbComPort); break; } case "RS232": { communicationInfo = DriveCommunicationFactory.CreateRS232CommunicationInfo(ComPort, uint.Parse(BuadRate)); break; } case "UDP": { communicationInfo = DriveCommunicationFactory.CreateUDPCommunicationInfo(IPAddress.Parse(DriveIP), IPAddress.Parse(HostIP), IpPortUDP); break; } case "CAN": { switch (SelectedManufacturer) { case CANBoardManufacturer.GMAS: { communicationInfo = DriveCommunicationFactory.CreateCANGMASCommunicationInfo(IPAddress.Parse(GmasIP), IPAddress.Parse(GmasHostIP),AxisName, SelectedNodeType); break; } case CANBoardManufacturer.Kvaser: { ushort nodeID = Convert.ToUInt16(CANNodeID); uint busID = Convert.ToUInt32(BusID); communicationInfo = DriveCommunicationFactory.CreateCANKvaserCommunicationInfo(CANBaudRate, busID, nodeID, SelectedNodeType); break; } } break; } default: return; } } catch (Exception ex) { AddLog(ex.Message); return; } communication = DriveCommunicationFactory.CreateCommunication(communicationInfo); //checking if personality model need to be created IDriveErrorObject err; if (!string.IsNullOrWhiteSpace(PersonalityPath)) { if (!communication.CreatePersonalityModel(PersonalityPath, out err)) AddLog(err.ToString()); } //connect if (!communication.Connect(out err)) { AddLog(err.ToString()); } else AddLog("Connected"); } private void Disconnect() { if (communication == null || !communication.IsConnected) AddLog("Drive is already disconnected"); else { communication.Disconnect(); AddLog("Disconnected"); } } #endregion Connect \ Disconnect #region Terminal public RelayCommand SendCommandCommand { get; set; } private void SendCommand() { if (communication != null) { if (communication.IsConnected) { Stopwatch sw = new Stopwatch(); string res; IDriveErrorObject err; int timeout; if (communication.ProductInfo == null) timeout = 1000; else if (communication.ProductInfo.HardwareType == DriveHardwareType.SimplIQ) timeout = 1000; else {// GOLD if (communication is DriveCANCommunication) timeout = 1000; //CAN Communication else timeout = 500; } sw.Start(); if (communication.SendCommandAnalyzeError(Command, out res, out err, timeout)) { sw.Stop(); AddLog(res); } else { sw.Stop(); AddLog(res); AddLog(err.ToString()); } AddLog("Time = " + sw.ElapsedMilliseconds + " ms"); } else { AddLog("Drive is not connected!"); } } } #endregion Terminal #region Uploads and Downloads public RelayCommand StartUploadOrDownloadCommand { get; set; } public RelayCommand CancelUploadOrDownloadCommand { get; set; } private void StartUploadOrDownload() { if (communication == null) { AddLog("No connection exists"); return; } IDriveErrorObject err = null; switch (SelectedAction) { case OPERATION_TYPE.UPLOAD_PERSONALITY: { UploadDownloadModel = communication.UploadPersonality(Path, out err); break; } case OPERATION_TYPE.UPLOAD_TXT_PARAMS: { UploadTxtSettings settings = SettingsObjectVM.Settings as UploadTxtSettings; UploadDownloadModel = communication.UploadTxtParameters(Path, settings, out err); break; } case OPERATION_TYPE.DOWNLOAD_BIN_PARAMS: { DownloadBinSettings settings = SettingsObjectVM.Settings as DownloadBinSettings; UploadDownloadModel = communication.DownloadBinParameters(Path, settings, out err); break; } case OPERATION_TYPE.DOWNLOAD_FW: { try { UploadDownloadModel = communication.DownloadFirmware(Path, out err); } catch (Exception ex) { AddLog("Exception when trying to start Download Firmware: " + ex.Message); return; } break; } case OPERATION_TYPE.DOWNLOAD_PAL: { try { PalSettings settings = SettingsObjectVM.Settings as PalSettings; UploadDownloadModel = communication.DownloadPal(Path, settings, out err); } catch (Exception ex) { AddLog("Exception when trying to start Download PAL: " + ex.Message); return; } break; } case OPERATION_TYPE.DOWNLOAD_PROGRAM: { UploadDownloadModel = communication.DownloadProgram(Path, out err); break; } case OPERATION_TYPE.DOWNLOAD_TXT_PARAMS: { DownloadTxtSettings settings = SettingsObjectVM.Settings as DownloadTxtSettings; UploadDownloadModel = communication.DownloadTxtParameters(Path, settings, out err); break; } case OPERATION_TYPE.UPLOAD_BIN_PARAMS: { UploadBinSettings settings = SettingsObjectVM.Settings as UploadBinSettings; UploadDownloadModel = communication.UploadBinParameters(Path, settings, out err); break; } case OPERATION_TYPE.UPLOAD_PROGRAM: { UploadDownloadModel = communication.UploadProgram(Path, out err); break; } default: return; } if (UploadDownloadModel == null) { AddLog(err.ToString()); return; } UploadDownloadModel.OnStart += uploadDownloadModel_Event; UploadDownloadModel.OnProgress += uploadDownloadModel_ProgressEvent; UploadDownloadModel.OnFinish += uploadDownloadModel_Event; UploadDownloadModel.OnFailed += uploadDownloadModel_Event; UploadDownloadModel.OnCancel += uploadDownloadModel_Event; if (!UploadDownloadModel.Start(out err)) { AddLog(err.ToString()); UploadDownloadModel.OnStart -= uploadDownloadModel_Event; UploadDownloadModel.OnProgress -= uploadDownloadModel_ProgressEvent; UploadDownloadModel.OnFinish -= uploadDownloadModel_Event; UploadDownloadModel.OnFailed -= uploadDownloadModel_Event; UploadDownloadModel.OnCancel -= uploadDownloadModel_Event; } } private void CancelUploadOrDownload() { if (UploadDownloadModel != null) { if (UploadDownloadModel.CancelAllowed) { AddLog("Cancelling"); UploadDownloadModel.Cancel(); } else AddLog("Cancel is not Allowed"); } else { AddLog("No operation started"); } } void uploadDownloadModel_Event(object sender, EventArgs e) { Percent = UploadDownloadModel.Percent; AddLog("Status= " + UploadDownloadModel.OperationStatus + " Description= " + UploadDownloadModel.Description); if (UploadDownloadModel.OperationStatus == OPERATION_STATUS.FINISHED) { UploadDownloadModel.OnStart -= new EventHandler(uploadDownloadModel_Event); UploadDownloadModel.OnProgress -= new EventHandler(uploadDownloadModel_ProgressEvent); UploadDownloadModel.OnFinish -= new EventHandler(uploadDownloadModel_Event); UploadDownloadModel.OnFailed -= new EventHandler(uploadDownloadModel_Event); UploadDownloadModel.OnCancel -= new EventHandler(uploadDownloadModel_Event); if (UploadDownloadModel.OperationType == OPERATION_TYPE.UPLOAD_PERSONALITY) { PersonalityPath = Path; IDriveErrorObject err; if (!communication.CreatePersonalityModel(PersonalityPath, out err)) AddLog(err.ToString()); } } } void uploadDownloadModel_ProgressEvent(object sender, EventArgs e) { Percent = UploadDownloadModel.Percent; string log = ("Status= " + UploadDownloadModel.OperationStatus + " Description= " + UploadDownloadModel.Description); if (Logs.Count != 0 && !Logs.First().Equals(log)) AddLog("Status= " + UploadDownloadModel.OperationStatus + " Description= " + UploadDownloadModel.Description); } #endregion Uploads and Downloads #region Compile program public RelayCommand cmdCompile { get; set; } private void OnCompile() { ClearLogs(); CompilerSettings settings = new CompilerSettings() { CompilerFolder = CompilerPath, ProgramPath = this.ProgramPath, DebugMode = CompilationMode == 0, ForceRecreationOfCompilerFiles = false, }; settings.ProgramImagePath = BuildImagePath(settings); if (!string.IsNullOrEmpty(this.PersonalityPath)) { settings.PersonalityPath = this.PersonalityPath; settings.ApplyPersonalityInfo = true; settings.ForceRecreationOfCompilerFiles = true; } CompileResponse response = DriveCompiler.Check(settings); if (response.Response != ResponseType.Error) { response = DriveCompiler.Build(settings, OnCompilerMessage); } AddLog(response.ToString(), false); } private string BuildImagePath(CompilerSettings settings) { string folder = OutputPath; if (settings != null && !string.IsNullOrEmpty(settings.ProgramPath) && !string.IsNullOrEmpty(OutputPath)) { string name = System.IO.Path.GetFileName(settings.ProgramPath); name = System.IO.Path.ChangeExtension(name, ".img"); return System.IO.Path.Combine(folder, name); } else return string.Empty; } private bool canCompile() { if (File.Exists(ProgramPath) && !string.IsNullOrEmpty(OutputPath)) return true; return false; } private void OnCompilerMessage(CompileResponse responce) { if (responce.Response == ResponseType.Error || responce.Response == ResponseType.Message || responce.Response == ResponseType.Success) AddLog(responce.ToString(), false); } #endregion Compile program #region Log public RelayCommand ClearLogsCommand { get; set; } public void AddLog(string log, bool reverseOrder = true) { try { App.Current.Dispatcher.Invoke((Action)(() => { if (reverseOrder) Logs.Insert(0, log); else Logs.Add(log); if (CollectionChanged != null) CollectionChanged(Logs, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add)); })); if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedLog")); } catch { } } public bool ClearLogsCanExecute() { return Logs.Count > 0; } public void ClearLogs() { try { App.Current.Dispatcher.Invoke((Action)(() => { Logs.Clear(); })); if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedLog")); } catch { } } #endregion Log #endregion Commands public event PropertyChangedEventHandler PropertyChanged; public event NotifyCollectionChangedEventHandler CollectionChanged; } }