using GSG.NET.Concurrent; using GSG.NET.Extensions; using OHV.Common.Events; using OHV.Common.Model; using OHV.Common.Shareds; using Prism.Commands; using Prism.Events; using Prism.Mvvm; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media; using VehicleControlSystem; using VehicleControlSystem.ControlLayer.IO; using static OHV.Common.Events.AxisControlEventArgs; namespace OHV.Module.Interactivity.PopUp { public class ConveyorControlViewModel : BindableBase, IDialogAware { private DelegateCommand _closeDialogCommand; public DelegateCommand CloseDialogCommand => _closeDialogCommand ?? (_closeDialogCommand = new DelegateCommand(CloseDialog)); public event Action RequestClose; private string _title = "ConveyorControlView"; public string Title { get { return this._title; } set { this.SetProperty(ref this._title, value); } } #region Brushes private Brush cWOnBrush = Brushes.DodgerBlue; public Brush CWOnBrush { get { return cWOnBrush; } set { SetProperty(ref this.cWOnBrush, value); } } private Brush cCWOnBrush = Brushes.DodgerBlue; public Brush CCWOnBrush { get { return cCWOnBrush; } set { SetProperty(ref this.cCWOnBrush, value); } } private Brush _axisLeftIsOrg = Brushes.Red; private Brush _axisLeftAmpFault = Brushes.Gray; private Brush _axisLeftIsServoOn = Brushes.Gray; private Brush _axisRightIsServoOn = Brushes.Gray; private Brush _axisRightIsOrg = Brushes.Red; private Brush _axisRightAmpFault = Brushes.Gray; public Brush AxisLeftIsServoOn { get { return this._axisLeftIsServoOn; } set { this.SetProperty(ref this._axisLeftIsServoOn, value); } } public Brush AxisLeftIsOrg { get { return _axisLeftIsOrg; } set { SetProperty(ref _axisLeftIsOrg, value); } } public Brush AxisLeftAmpFault { get { return _axisLeftAmpFault; } set { SetProperty(ref _axisLeftAmpFault, value); } } public Brush AxisRightIsServoOn { get { return this._axisRightIsServoOn; } set { this.SetProperty(ref this._axisRightIsServoOn, value); } } public Brush AxisRightIsOrg { get { return _axisRightIsOrg; } set { SetProperty(ref _axisRightIsOrg, value); } } public Brush AxisRightAmpFault { get { return _axisRightAmpFault; } set { SetProperty(ref _axisRightAmpFault, value); } } #endregion public ICommand ConveyorRunCommand { get; set; } public ICommand PosMoveCommand { get; set; } public ICommand LoadUnloadCommand { get; set; } public ICommand PIOCharge { get; set; } IEventAggregator eventAggregator; MessageController messageController; List allIOList = new List(); VCSystem VCSystem; EzIO IO = null; 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); } } private eConveyorState conveyorState; public eConveyorState ConveyorState { get { return conveyorState; } set { SetProperty(ref this.conveyorState, value); } } private AutoResetEvent eventBusy = new AutoResetEvent(false); public ConveyorControlViewModel(IEventAggregator _ea, MessageController _msg, VCSystem vcSystem) { this.eventAggregator = _ea; this.VCSystem = vcSystem; this.IO = VCSystem.IO as EzIO; this.IO.OnChangedIO += IO_OnChangedIO; /*Lock&UnLock Publish Event*/ this.eventAggregator.GetEvent().Unsubscribe(AxisUICallbackCommunication); this.eventAggregator.GetEvent().Subscribe(AxisUICallbackCommunication, ThreadOption.UIThread); /*GUI Pubsub Event*/ this.eventAggregator.GetEvent().Unsubscribe(UICallbackCommunication); this.eventAggregator.GetEvent().Subscribe(UICallbackCommunication, ThreadOption.UIThread); this.messageController = _msg; this.ConveyorRunCommand = new DelegateCommand(ExecuteCvCommand); this.PosMoveCommand = new DelegateCommand(ExecutePosMoveCommand); this.LoadUnloadCommand = new DelegateCommand(ExecuteLoadUnloadCommand); this.PIOCharge = new DelegateCommand(ExecutePIOChargeCommand); } void UpdateCvState() { if (IO.IsOn("OUT_CV_RUN", false)) { if (IO.IsOn("OUT_CV_CWCCW", false)) { this.CWOnBrush = Brushes.DodgerBlue; this.CCWOnBrush = Brushes.LimeGreen; this.ConveyorState = eConveyorState.CCW; } else { this.CWOnBrush = Brushes.LimeGreen; this.CCWOnBrush = Brushes.DodgerBlue; this.ConveyorState = eConveyorState.CW; } } else { this.CWOnBrush = Brushes.DodgerBlue; this.CCWOnBrush = Brushes.DodgerBlue; this.ConveyorState = eConveyorState.Stop; } } private void ExecutePIOChargeCommand(string obj) { this.messageController.ShowConfirmationPopupView($"PIO Battery Charge ?", r => { if (r.Result == ButtonResult.OK) { this.SetBusy(); var msg = new VCSMessageEventArgs(); switch (obj) { case "PB": msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqPIOBatteryCharge; msg.MessageText = obj.ToString(); break; case "PBStop": msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqPIOBatteryChargeStop; msg.MessageText = obj.ToString(); break; default: break; } this.VcsMessagePublish(msg); } }); } private void ExecuteLoadUnloadCommand(string obj) { this.messageController.ShowConfirmationPopupView($"Conveyor Move Start ?", r => { if (r.Result == ButtonResult.OK) { this.SetBusy(); var msg = new VCSMessageEventArgs(); switch (obj) { case "Load": msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqConveyorLoad; break; case "Unload": msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqConveyorUnload; break; case "PL": msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqPIOConveyor; msg.MessageText = obj.ToString(); break; case "PU": msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqPIOConveyor; msg.MessageText = obj.ToString(); break; default: break; } this.VcsMessagePublish(msg); } }); } void VcsMessagePublish(VCSMessageEventArgs msg) { this.eventAggregator.GetEvent().Publish(msg); } private void IO_OnChangedIO(BitBlock bit) { if (bit.Tag.Equals("OUT_CV_RUN")) { this.UpdateCvState(); } } private void UICallbackCommunication(GUIMessageEventArgs _args) { var msg = "FAIL"; switch (_args.Kind) { case GUIMessageEventArgs.eGUIMessageKind.ModelPropertyChange: break; case GUIMessageEventArgs.eGUIMessageKind.RspIOObject: break; case GUIMessageEventArgs.eGUIMessageKind.RspIOMapList: break; case GUIMessageEventArgs.eGUIMessageKind.RspCommandList: break; case GUIMessageEventArgs.eGUIMessageKind.RspAutoModeChange: break; case GUIMessageEventArgs.eGUIMessageKind.RspManualModeChange: break; case GUIMessageEventArgs.eGUIMessageKind.RspAlarmReset: break; case GUIMessageEventArgs.eGUIMessageKind.RspVehicleModeChange: break; case GUIMessageEventArgs.eGUIMessageKind.RspEStop: break; case GUIMessageEventArgs.eGUIMessageKind.RspVihicleState: break; case GUIMessageEventArgs.eGUIMessageKind.RspMachineModeChg: break; case GUIMessageEventArgs.eGUIMessageKind.RspAddCommand: break; case GUIMessageEventArgs.eGUIMessageKind.RspConveyorMove: break; case GUIMessageEventArgs.eGUIMessageKind.RspConveyorLoad: if (_args.Result.IsSuccess) { this.ResetBusy(); this.messageController.ShowNotificationView("SUCCESS"); } else { this.messageController.ShowNotificationView(msg); this.ResetBusy(); } break; case GUIMessageEventArgs.eGUIMessageKind.RspConveyorUnload: if (_args.Result.IsSuccess) { this.ResetBusy(); this.messageController.ShowNotificationView("SUCCESS"); } else { this.messageController.ShowNotificationView(msg); this.ResetBusy(); } break; case GUIMessageEventArgs.eGUIMessageKind.RspPIOConveyor: if (_args.Result.IsSuccess) { this.ResetBusy(); this.messageController.ShowNotificationView("SUCCESS"); } else { this.messageController.ShowNotificationView(msg); this.ResetBusy(); } break; case GUIMessageEventArgs.eGUIMessageKind.RspPIOBatteryCharge: if (_args.Result.IsSuccess) { this.ResetBusy(); this.messageController.ShowNotificationView("SUCCESS"); } else { this.messageController.ShowNotificationView(msg); this.ResetBusy(); } break; case GUIMessageEventArgs.eGUIMessageKind.RsqPIOBatteryChargeStop: if (_args.Result.IsSuccess) { this.ResetBusy(); this.messageController.ShowNotificationView("SUCCESS"); } else { this.messageController.ShowNotificationView(msg); this.ResetBusy(); } break; case GUIMessageEventArgs.eGUIMessageKind.RspObstaclePatternChg: break; case GUIMessageEventArgs.eGUIMessageKind.RspObstaclePatternNo: break; case GUIMessageEventArgs.eGUIMessageKind.RspBatteryState: break; case GUIMessageEventArgs.eGUIMessageKind.RspRouteManager: break; case GUIMessageEventArgs.eGUIMessageKind.RspDirveSpeed: break; case GUIMessageEventArgs.eGUIMessageKind.RspSpeedProfile: break; case GUIMessageEventArgs.eGUIMessageKind.RspJogSpeed: break; case GUIMessageEventArgs.eGUIMessageKind.RspParamsSave: break; } } private void ExecutePosMoveCommand(object obj) { this.messageController.ShowConfirmationPopupView("Clamp Move ?", r => { if (r.Result == ButtonResult.OK) { //this.IsBusy = true; SetBusy(); var selectedPos = obj.ToString(); var msg = new AxisControlEventArgs { Dir = eEventDir.ToBack, Kind = eAxisControlKind.SyncMove, }; switch (selectedPos) { case "Lock": msg.PosDir = ePosDir.Lock; break; case "UnLock": msg.PosDir = ePosDir.UnLock; break; } this.AxisPublishEvent(msg); } }); } private void AxisPublishEvent(AxisControlEventArgs msg) { this.eventAggregator.GetEvent().Publish(msg); } private void AxisUICallbackCommunication(AxisControlEventArgs _args) { var msg = "FAIL"; if (_args.Dir == eEventDir.ToFront) { switch (_args.Kind) { case eAxisControlKind.NONE: break; case eAxisControlKind.OriginReturn: break; case eAxisControlKind.Stop: break; case eAxisControlKind.EStop: break; case eAxisControlKind.Move: ResponseMove(_args); break; case eAxisControlKind.Jog: break; case eAxisControlKind.ServoOn: break; case eAxisControlKind.ServoOff: break; case eAxisControlKind.ReqCurrentPosition: break; case eAxisControlKind.ReqStopCurrentPosition: break; case eAxisControlKind.FaultReset: break; case eAxisControlKind.AxisState: AxisState(_args); break; case eAxisControlKind.SyncMove: if (_args.Result.IsSuccess) { this.ResetBusy(); this.messageController.ShowNotificationView("SUCCESS"); } else { this.messageController.ShowNotificationView(msg); this.ResetBusy(); } break; default: break; } } //this.CurrentBusyCheck(); } private void ResponseMove(AxisControlEventArgs _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); } private void AxisState(AxisControlEventArgs args) { var left = args.Args["Left"] as AxisState; var right = args.Args["Right"] as AxisState; /*Left*/ if (left.IsServoOn) this.AxisLeftIsServoOn = Brushes.LimeGreen; else this.AxisLeftIsServoOn = Brushes.Gray; if (left.IsOriginReturn) this.AxisLeftIsOrg = Brushes.LimeGreen; else this.AxisLeftIsOrg = Brushes.Gray; if (left.IsAmpFault) this.AxisLeftAmpFault = Brushes.Red; else this.AxisLeftAmpFault = Brushes.Gray; /*Right*/ if (right.IsServoOn) this.AxisRightIsServoOn = Brushes.LimeGreen; else this.AxisRightIsServoOn = Brushes.Gray; if (right.IsOriginReturn) this.AxisRightIsOrg = Brushes.LimeGreen; else this.AxisRightIsOrg = Brushes.Gray; if (right.IsAmpFault) this.AxisRightAmpFault = Brushes.Red; else this.AxisRightAmpFault = Brushes.Gray; } private void ExecuteCvCommand(object _obj) { var dir = _obj.ToString(); var msg = new VCSMessageEventArgs() { Kind = VCSMessageEventArgs.eVCSMessageKind.ReqConveyorMove, MessageText = dir }; this.VcsMessagePublish(msg); } void SetBusy() { this.IsBusy = true; Task.Run(() => { if (eventBusy.WaitOne(10000) == false) { Application.Current.Dispatcher.Invoke(() => { this.IsBusy = false; this.messageController.ShowNotificationView("Response Time Out", false); }); } }); } void ResetBusy() { eventBusy.Set(); this.IsBusy = false; } #region Dialog public bool CanCloseDialog() { return true; } public void OnDialogClosed() { this.eventAggregator.GetEvent().Publish(new AxisControlEventArgs { Dir = AxisControlEventArgs.eEventDir.ToBack, Kind = AxisControlEventArgs.eAxisControlKind.NONE }); this.eventAggregator.GetEvent().Unsubscribe(AxisUICallbackCommunication); this.eventAggregator.GetEvent().Publish(new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack, ControlKind = DriveControlEventArgs.eControlKind.ReqStopCurrentPos }); this.eventAggregator.GetEvent().Unsubscribe(UICallbackCommunication); } public void OnDialogOpened(IDialogParameters parameters) { var msg = new VCSMessageEventArgs() { Kind = VCSMessageEventArgs.eVCSMessageKind.ReqIOObject }; this.eventAggregator.GetEvent().Publish(msg); this.eventAggregator.GetEvent().Publish(new AxisControlEventArgs { Dir = AxisControlEventArgs.eEventDir.ToBack, Kind = AxisControlEventArgs.eAxisControlKind.ReqCurrentPosition }); this.UpdateCvState(); } 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 } }