using GSG.NET.Concurrent; using GSG.NET.Extensions; using GSG.NET.Utils; using MaterialDesignThemes.Wpf; using OHV.Common.Events; using OHV.Common.Model; using OHV.Common.Shareds; using OHV.SqliteDAL; using Prism.Commands; using Prism.Events; using Prism.Mvvm; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using VehicleControlSystem; using VehicleControlSystem.ControlLayer; using VehicleControlSystem.ControlLayer.IO; using VehicleControlSystem.ControlLayer.MQ; using VehicleControlSystem.Managers; using static OHV.Common.Events.TCZEventArgs; namespace OHV.Module.Interactivity.PopUp { public class DriveServoViewModel : BindableBase, IDialogAware { private DelegateCommand _closeDialogCommand; public DelegateCommand CloseDialogCommand => _closeDialogCommand ?? ( _closeDialogCommand = new DelegateCommand( CloseDialog ) ); private string _title = "DriveServoView"; public string Title { get { return this._title; } set { this.SetProperty( ref this._title , value ); } } private string _selectedPosition = string.Empty; public string SelectedPosition { get => this._selectedPosition; set { this.SetProperty( ref this._selectedPosition , value ); } } private string _selectDirection = string.Empty; public string SelectDirection { get => this._selectDirection; set { this.SetProperty( ref this._selectDirection , value ); } } private eDriveState driveState; public eDriveState DriveState { get { return driveState; } set { SetProperty(ref this.driveState, value); } } private bool isBreakOff; public bool IsBreakOff { get { return isBreakOff; } set { SetProperty(ref this.isBreakOff, value); } } #region Motor Left Binding Value private double _driveTargetPos; public double DriveTargetPos { get { return this._driveTargetPos; } set { this.SetProperty( ref this._driveTargetPos , value ); } } private double _currentPosition; /// /// * Drive Current Position /// public double CurrentPosition { get { return this._currentPosition; } set { this.SetProperty( ref this._currentPosition , value ); } } private double _differenceDrive; public double DifferenceDrive { get { return this._differenceDrive; } set { this.SetProperty( ref this._differenceDrive , value ); } } private double _jogVelocity = 3.0; public double JogVelocity { get { return this._jogVelocity; } set { this.SetProperty( ref this._jogVelocity , value ); } } #endregion public event Action RequestClose; #region Commands public ICommand SelectAxisCommand { get; set; } public ICommand KeyInTargetPosCommand { get; set; } public ICommand SelectPosCommand { get; set; } public ICommand MoveToCommand { get; set; } public ICommand CurrentToTargetCommand { get; set; } public ICommand ServoOnCommand { get; set; } public ICommand ServoOffCommand { get; set; } public ICommand FaultResetCommand { get; set; } public ICommand OriginCommand { get; set; } public IEventAggregator eventAggregator; public ICommand PositionAddCommand { get; set; } public ICommand PositionDeleteCommand { get; set; } public ICommand PositionSaveCommand { get; set; } public ICommand SteeringMoveCommand { get; set; } public ICommand SelectedDirection { get; set; } public ICommand JogVelPopupCommand { get; set; } public ICommand JogCommand { get; set; } public ICommand BreakOffCommand { get; set; } #endregion #region Brushes private Brush steeringLeftBrush = Brushes.Gray; public Brush SteeringLeftBrushProperty { get { return steeringLeftBrush; } set { SetProperty( ref this.steeringLeftBrush , value ); } } private Brush steeringRightBrush = Brushes.Gray; public Brush SteeringRightBrushProperty { get { return steeringRightBrush; } set { SetProperty( ref this.steeringRightBrush , value ); } } Brush driveOnStateBrush = Brushes.DodgerBlue; public Brush DriveOnStateBrush { get { return this.driveOnStateBrush; } set { SetProperty( ref this.driveOnStateBrush , value ); } } Brush driveOffStateBrush = Brushes.DodgerBlue; public Brush DriveOffStateBrush { get { return this.driveOffStateBrush; } set { SetProperty( ref this.driveOffStateBrush , value ); } } private Brush driveFaultStateBrush = Brushes.DodgerBlue; public Brush DriveFaultStateBrush { get { return driveFaultStateBrush; } set { SetProperty( ref this.driveFaultStateBrush , value ); } } #endregion #region Property private ObservableCollection _routeList; public ObservableCollection RouteList { get { return this._routeList; } set { SetProperty(ref this._routeList, value); } } private string autoReadyFlag = "NG"; public string AutoReadyFlag { get { return autoReadyFlag; } set { this.SetProperty(ref this.autoReadyFlag, value); } } Brush autoReadyFlagColor = Brushes.Gray; public Brush AutoReadyFlagColor { get { return this.autoReadyFlagColor; } set { this.SetProperty(ref this.autoReadyFlagColor, value); } } private string currentMCR = "None"; public string CurrentMCR { get { return currentMCR; } set { this.SetProperty(ref this.currentMCR, value); } } private string currentTag = "None"; public string CurrentTag { get { return currentTag; } set { SetProperty(ref this.currentTag, value); } } private bool isBusy; public bool IsBusy { get { return isBusy; } set { SetProperty(ref this.isBusy, value); } } private string busyText; public string BusyText { get { return busyText; } set { SetProperty(ref this.busyText, value); } } eOcsState ocsState = eOcsState.DisConnect; public eOcsState OcsState { get { return this.ocsState; } set { this.SetProperty(ref this.ocsState, value); } } eTCZState isTCZ = eTCZState.None; public eTCZState IsTCZ { get { return this.isTCZ; } set { this.SetProperty(ref this.isTCZ, value); } } eOperatationMode operationMode = eOperatationMode.ManualMode; public eOperatationMode OperationMode { get { return this.operationMode; } set { this.SetProperty(ref this.operationMode, value); } } #endregion VCSystem vcSystem; ZmqManager zmqManager; HostManager hostManager; SqliteManager sql; MessageController messageController; public DriveServoViewModel(IEventAggregator _ea , SqliteManager _sql , MessageController _messageController , VCSystem system) { this.eventAggregator = _ea; this.eventAggregator.GetEvent().Unsubscribe( DriveControlCallBack ); this.eventAggregator.GetEvent().Subscribe( DriveControlCallBack , ThreadOption.UIThread ); this.eventAggregator.GetEvent().Unsubscribe( UICallBackCommunication ); this.eventAggregator.GetEvent().Subscribe( UICallBackCommunication , ThreadOption.UIThread ); this.eventAggregator.GetEvent().Unsubscribe(OcsConnectCallBack); this.eventAggregator.GetEvent().Subscribe(OcsConnectCallBack, ThreadOption.UIThread); this.eventAggregator.GetEvent().Unsubscribe(TCZStateCallBack); this.eventAggregator.GetEvent().Subscribe(TCZStateCallBack, ThreadOption.UIThread); this.sql = _sql; this.messageController = _messageController; this.vcSystem = system; this.zmqManager = system.ZmqManager; system.ZmqManager.PropertyChanged += ZmqManager_PropertyChanged; this.hostManager = system.hostManager; this.SelectPosCommand = new DelegateCommand( ExecuteSelectPosCommand ); this.MoveToCommand = new DelegateCommand( ExecuteMoveToCommand ); this.CurrentToTargetCommand = new DelegateCommand( ExecuteCurrentToTargetCommand ); this.KeyInTargetPosCommand = new DelegateCommand( ExecuteKeyInCommadn ); this.ServoOnCommand = new DelegateCommand( ExecuteServoOnCommand ); this.ServoOffCommand = new DelegateCommand( ExecuteServoOffCommand ); this.FaultResetCommand = new DelegateCommand( ExecuteFaultResetCommand ); this.OriginCommand = new DelegateCommand( ExecuteOriginCommand ); this.PositionAddCommand = new DelegateCommand( ExecutePositionAddCommand ); this.PositionDeleteCommand = new DelegateCommand( ExecutePositionDeleteCommand ); this.PositionSaveCommand = new DelegateCommand( ExecutePositionSaveCommand ); this.SelectedDirection = new DelegateCommand( ExecuteSelectedDirection ); this.SteeringMoveCommand = new DelegateCommand( ExecuteSteeringMove ); this.JogVelPopupCommand = new DelegateCommand( ExecuteJogVelPopupCommand ); this.JogCommand = new DelegateCommand( ExecuteJogCommand ); this.BreakOffCommand = new DelegateCommand(ExecuteBreakOffCommand); this.IsBreakOff = this.vcSystem.IO.IsOn("OUT_DRIVE_BRAKE_OFF", false); var ezIO = this.vcSystem.IO as EzIO; ezIO.OnChangedIO += EzIO_OnChangedIO; } private void TCZStateCallBack(TCZEventArgs obj) { var state = obj.TCZState; switch (state) { case eTCZState.TCZ: this.IsTCZ = eTCZState.TCZ; break; case eTCZState.None: this.IsTCZ = eTCZState.None; break; } } private void ExecuteBreakOffCommand() { if (isBreakOff) this.vcSystem.IO.OutputOff("OUT_DRIVE_BRAKE_OFF"); else this.vcSystem.IO.OutputOn("OUT_DRIVE_BRAKE_OFF"); } private void EzIO_OnChangedIO(BitBlock bit) { if (bit.Tag.Equals("OUT_DRIVE_BRAKE_OFF")) this.IsBreakOff = bit.IsBitOn; } private void InitializeData() { this.CurrentMCR = this.zmqManager.CurrentMCR; this.CurrentTag = this.zmqManager.CurrentPointNo.ToString(); this.DriveAutoReadyState(this.zmqManager.IsCanStanbyLocation); this.UpdateDriveState(this.zmqManager.DriveState); if (hostManager.IsConnected) { this.OcsState = eOcsState.Connect; } //if (vcSystem.ZmqManager.SetOperationState(eOperatationMode.ManualMode)) //{ // if (!zmqManager.IsTCZ) // { // this.IsTCZ = eTCZState.TCZ; // } //} if (!vcSystem.ZmqManager.SetOperationState(eOperatationMode.ManualMode)) messageController.ShowNotificationView("Drive Manual Mode Change Fail", false); } void UpdateDriveState(eDriveState state) { this.DriveState = state; //switch ( state ) //{ // case eDriveState.None: // this.DriveOnStateBrush = Brushes.Gray; // break; // case eDriveState.ServoOff: // this.DriveOnStateBrush = Brushes.Gray; // break; // case eDriveState.ServoOn: // this.DriveOnStateBrush = Brushes.LimeGreen; // this.DriveFaultStateBrush = Brushes.DodgerBlue; // break; // case eDriveState.Fault: // this.DriveFaultStateBrush = Brushes.Red; // this.DriveOnStateBrush = Brushes.Gray; // break; // default: // break; //} } private void ZmqManager_PropertyChanged(object sender , System.ComponentModel.PropertyChangedEventArgs e) { var property = sender.GetType().GetProperty( e.PropertyName ); var newValue = property.GetValue( sender , null ); switch ( e.PropertyName ) { case "CurrentPointNo": this.CurrentTag = CastTo.From( newValue ).ToString(); break; case "CurrentMCR": this.CurrentMCR = CastTo.From( newValue ); break; case "IsCanStanbyLocation": { var result = CastTo.From( newValue ); DriveAutoReadyState( result ); } break; case "DriveState": { var result = CastTo.From( newValue ); this.UpdateDriveState( result ); } break; default: break; } } private void ExecuteSteeringMove(object obj) { var msg = new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.Steering , }; if ( obj.ToString().Equals( "CW" ) ) msg.MoveDir = DriveControlEventArgs.eMoveDir.LEFT; else msg.MoveDir = DriveControlEventArgs.eMoveDir.RIGHT; this.PublishEvent( msg ); } private void UICallBackCommunication(GUIMessageEventArgs obj) { if ( obj.Kind == GUIMessageEventArgs.eGUIMessageKind.ModelPropertyChange ) { if ( obj.MessageKey.Equals( MessageKey.Vehicle ) ) { switch ( obj.ModelPropertyName ) { case "SteeringState": { var dir = CastTo.From( obj.Args ); this.ChangeSteeringDirection( dir ); } break; case "VehicleStateProperty": { var v = CastTo.From( obj.Args ); this.ChagneVehicleState( v ); } break; case "CurrentPosition": { var v = CastTo.From( obj.Args ); this.CurrentPosition = v; } break; case "CurrentSpeed": break; case "CurrentTorque": break; default: break; } } } if ( obj.Kind == GUIMessageEventArgs.eGUIMessageKind.RspRouteManager ) { } } void DriveAutoReadyState(bool state) { if ( state ) { this.AutoReadyFlag = "OK"; this.AutoReadyFlagColor = Brushes.LimeGreen; } else { this.AutoReadyFlag = "NG"; this.AutoReadyFlagColor = Brushes.Gray; } } private void ChagneVehicleState(eVehicleState v) { switch ( v ) { case eVehicleState.None: break; case eVehicleState.Idle: break; case eVehicleState.Move: break; case eVehicleState.Load: break; case eVehicleState.Unload: break; case eVehicleState.Charge: break; case eVehicleState.Abnormal: break; case eVehicleState.Blocked: break; case eVehicleState.Decelerate: break; } } private void DriveControlCallBack(DriveControlEventArgs args) { if ( args.EventDir == DriveControlEventArgs.eEventDir.ToFront ) { switch ( args.ControlKind ) { case DriveControlEventArgs.eControlKind.MOVE: ResponseMove( args ); break; case DriveControlEventArgs.eControlKind.STOP: break; case DriveControlEventArgs.eControlKind.Steering: //if ( args.Result.IsSuccess ) //{ // var dir = args.Result.ToResult().Value; // this.ChangeSteeringDirection( dir ); //} break; case DriveControlEventArgs.eControlKind.SteeringState: if ( args.Result.IsSuccess ) { var dir = CastTo.From( args.Args ); this.ChangeSteeringDirection( dir ); } else { this.ChangeSteeringDirection( eSteeringState.None ); } break; case DriveControlEventArgs.eControlKind.ReqCurrentPos: this.CurrentPosition = args.CurrentPosition; break; case DriveControlEventArgs.eControlKind.ReqStopCurrentPos: break; case DriveControlEventArgs.eControlKind.FaultReset: if (args.Result.IsSuccess) this.messageController.ShowNotificationView("Fault Reset Success"); else this.messageController.ShowNotificationView("Fault Reset Fail", false); break; case DriveControlEventArgs.eControlKind.DriveON: if (args.Result.IsSuccess) { this.messageController.ShowNotificationView("Drive On Success"); } else { this.messageController.ShowNotificationView("Drive On Fail", false); } break; case DriveControlEventArgs.eControlKind.DriveOFF: break; case DriveControlEventArgs.eControlKind.JOG: break; case DriveControlEventArgs.eControlKind.VehicleState: ResponseVehicleState( args ); break; default: break; } } } private void ResponseVehicleState(DriveControlEventArgs args) { var state = CastTo.From( args.Args ); this.CurrentPosition = state.CurrentPosition; } private void ResponseMove(DriveControlEventArgs args) { var msg = string.Empty; if ( args.Result.IsSuccess ) { msg = "Move Success"; } else { var error = args.Result.Errors.FirstOrDefault(); var alarm = error.Metadata[ "Alarm" ] as Alarm; msg = alarm.Name + " " + alarm.Text; } this.messageController.ShowNotificationView( msg ); } void PublishEvent(DriveControlEventArgs args) { args.EventDir = DriveControlEventArgs.eEventDir.ToBack; this.eventAggregator.GetEvent().Publish( args ); } void ChangeSteeringDirection(eSteeringState state) { if ( state == eSteeringState.Left ) { this.SteeringLeftBrushProperty = ( Brush )new BrushConverter().ConvertFromString( "#FF00FFD3" ); this.SteeringRightBrushProperty = Brushes.Gray; } else if ( state == eSteeringState.Right ) { this.SteeringLeftBrushProperty = Brushes.Gray; this.SteeringRightBrushProperty = ( Brush )new BrushConverter().ConvertFromString( "#FF00FFD3" ); } else { this.SteeringLeftBrushProperty = Brushes.Gray; this.SteeringRightBrushProperty = Brushes.Gray; } } #region Execute Method private void OcsConnectCallBack(HostConnectedEventArgs obj) { var state = obj.State; switch (state) { case HostConnectedEventArgs.eConnectedState.Connected: this.OcsState = eOcsState.Connect; break; case HostConnectedEventArgs.eConnectedState.Disconnected: this.OcsState = eOcsState.DisConnect; break; } } private void ExecuteJogCommand(object obj) { if ( this.JogVelocity <= 0 ) { this.messageController.ShowNotificationView( "Check Jog Velocity" ); return; } if(this.vcSystem.vehicle.IsChargeCylinderForword()) { this.messageController.ShowNotificationView("Battery Charge Cylinder FWD !"); return; } var msg = new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.JOG , }; if ( obj.ToString().Equals( "+" ) ) msg.JogDir = DriveControlEventArgs.eJogMoveDir.Positive; else msg.JogDir = DriveControlEventArgs.eJogMoveDir.Negative; this.PublishEvent( msg ); } private void ExecuteJogVelPopupCommand() { var numPad = new CalcuratorView(); var result = numPad.ShowDialog( this.JogVelocity ); this.JogVelocity = result; } private void ExecuteSelectedDirection(object obj) { this.SelectDirection = obj.ToString(); } private void ExecutePositionSaveCommand() { this.messageController.ShowConfirmationPopupView("Save To Data ?", r => { if (r.Result == ButtonResult.OK) { var result = this.RouteList.Any(x => x.IsSelected != false); if (!result) { this.messageController.ShowNotificationView("Pos Not Selected"); return; } var ll = this.RouteList.Where(x => x.IsSelected).FirstOrDefault(); } }); } private void ExecutePositionDeleteCommand() { this.messageController.ShowConfirmationPopupView( "Select To Delete ?" , r => { if ( r.Result == ButtonResult.OK ) { var deleteList = new List(); foreach ( var item in this.RouteList ) { if ( item.IsSelected ) deleteList.Add( item ); } deleteList.ForEach( x => { this.RouteList.Remove( x ); } ); } } ); } private void ExecutePositionAddCommand() { this.messageController.ShowConfirmationPopupView( "Position Add ?" , r => { if ( r.Result == ButtonResult.OK ) { this.RouteList.Add( new Route() ); this.messageController.ShowNotificationView( "Create Success" ); } } ); } private void ExecuteKeyInCommadn(object obj) { var numPad = new CalcuratorView(); var result = numPad.ShowDialog( this.DriveTargetPos ); this.DriveTargetPos = result; } private void ExecuteOriginCommand() { this.messageController.ShowConfirmationPopupView( "Origin ?" , r => { if ( r.Result == ButtonResult.OK ) { } } ); } private void ExecuteFaultResetCommand() { var msg = new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.FaultReset , }; this.PublishEvent( msg ); } private void ExecuteServoOffCommand() { var msg = new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.DriveOFF , }; this.PublishEvent( msg ); } private void ExecuteServoOnCommand() { //this.IsBusy = true; var msg = new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.DriveON , }; this.PublishEvent( msg ); } private void ExecuteCurrentToTargetCommand() { this.messageController.ShowConfirmationPopupView( "Current To Target ?" , r => { if ( r.Result == ButtonResult.OK ) { this.DriveTargetPos = this.CurrentPosition; } } ); } private void ExecuteMoveToCommand() { this.messageController.ShowConfirmationPopupView( "Move To Selected Position ?" , r => { if ( r.Result == ButtonResult.OK ) { var result = this.RouteList.Any( x => x.IsSelected != false ); if ( !result ) { this.messageController.ShowNotificationView( "Pos Not Selected" ); return; } var ll = this.RouteList.Where( x => x.IsSelected ).FirstOrDefault(); var msg = new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.MOVE , TargetRouteID = ll.Id , }; this.PublishEvent( msg ); } } ); } private void ExecuteSelectPosCommand(object obj) { this.SelectedPosition = obj.ToString(); } #endregion #region Dialog Function public bool CanCloseDialog() { return true; } public void OnDialogClosed() { this.eventAggregator.GetEvent().Publish( new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.ReqStopCurrentPos } ); this.eventAggregator.GetEvent().Unsubscribe( DriveControlCallBack ); this.eventAggregator.GetEvent().Unsubscribe( UICallBackCommunication ); } public async void OnDialogOpened(IDialogParameters parameters) { Task task = Task.Run( () => { var msg = new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.SteeringState , }; this.PublishEvent( msg ); this.eventAggregator.GetEvent().Publish( new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.VehicleState } ); var vcsMsg = new VCSMessageEventArgs() { Kind = VCSMessageEventArgs.eVCSMessageKind.ReqRouteManager }; this.eventAggregator.GetEvent().Publish( vcsMsg ); //var sT = SwUtils.CurrentTimeMillis; //this.RouteList = new ObservableCollection(sql.RouteDal.GetAll()); //Console.WriteLine( SwUtils.Elapsed( sT ) ); }); this.InitializeData(); await task; } private void CloseDialog(string parameter) { ButtonResult result = ButtonResult.None; if ( parameter?.ToLower() == "true" ) result = ButtonResult.OK; else if ( parameter?.ToLower() == "false" ) result = ButtonResult.Cancel; RaiseRequestClose( new DialogResult( result ) ); } public virtual void RaiseRequestClose(IDialogResult dialogResult) { RequestClose?.Invoke( dialogResult ); } #endregion } }