ConveyorControlViewModel.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. using GSG.NET.Concurrent;
  2. using GSG.NET.Extensions;
  3. using OHV.Common.Events;
  4. using OHV.Common.Model;
  5. using OHV.Common.Shareds;
  6. using Prism.Commands;
  7. using Prism.Events;
  8. using Prism.Mvvm;
  9. using Prism.Services.Dialogs;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. using System.Windows;
  17. using System.Windows.Input;
  18. using System.Windows.Media;
  19. using VehicleControlSystem;
  20. using VehicleControlSystem.ControlLayer.IO;
  21. using static OHV.Common.Events.AxisControlEventArgs;
  22. namespace OHV.Module.Interactivity.PopUp
  23. {
  24. public class ConveyorControlViewModel : BindableBase, IDialogAware
  25. {
  26. private DelegateCommand<string> _closeDialogCommand;
  27. public DelegateCommand<string> CloseDialogCommand =>
  28. _closeDialogCommand ?? (_closeDialogCommand = new DelegateCommand<string>(CloseDialog));
  29. public event Action<IDialogResult> RequestClose;
  30. private string _title = "ConveyorControlView";
  31. public string Title
  32. {
  33. get { return this._title; }
  34. set
  35. {
  36. this.SetProperty(ref this._title, value);
  37. }
  38. }
  39. #region Brushes
  40. private Brush cWOnBrush = Brushes.DodgerBlue;
  41. public Brush CWOnBrush
  42. {
  43. get { return cWOnBrush; }
  44. set { SetProperty(ref this.cWOnBrush, value); }
  45. }
  46. private Brush cCWOnBrush = Brushes.DodgerBlue;
  47. public Brush CCWOnBrush
  48. {
  49. get { return cCWOnBrush; }
  50. set { SetProperty(ref this.cCWOnBrush, value); }
  51. }
  52. private Brush _axisLeftIsOrg = Brushes.Red;
  53. private Brush _axisLeftAmpFault = Brushes.Gray;
  54. private Brush _axisLeftIsServoOn = Brushes.Gray;
  55. private Brush _axisRightIsServoOn = Brushes.Gray;
  56. private Brush _axisRightIsOrg = Brushes.Red;
  57. private Brush _axisRightAmpFault = Brushes.Gray;
  58. public Brush AxisLeftIsServoOn
  59. {
  60. get { return this._axisLeftIsServoOn; }
  61. set
  62. {
  63. this.SetProperty(ref this._axisLeftIsServoOn, value);
  64. }
  65. }
  66. public Brush AxisLeftIsOrg
  67. {
  68. get { return _axisLeftIsOrg; }
  69. set
  70. {
  71. SetProperty(ref _axisLeftIsOrg, value);
  72. }
  73. }
  74. public Brush AxisLeftAmpFault
  75. {
  76. get { return _axisLeftAmpFault; }
  77. set
  78. {
  79. SetProperty(ref _axisLeftAmpFault, value);
  80. }
  81. }
  82. public Brush AxisRightIsServoOn
  83. {
  84. get { return this._axisRightIsServoOn; }
  85. set
  86. {
  87. this.SetProperty(ref this._axisRightIsServoOn, value);
  88. }
  89. }
  90. public Brush AxisRightIsOrg
  91. {
  92. get { return _axisRightIsOrg; }
  93. set
  94. {
  95. SetProperty(ref _axisRightIsOrg, value);
  96. }
  97. }
  98. public Brush AxisRightAmpFault
  99. {
  100. get { return _axisRightAmpFault; }
  101. set
  102. {
  103. SetProperty(ref _axisRightAmpFault, value);
  104. }
  105. }
  106. #endregion
  107. public ICommand ConveyorRunCommand { get; set; }
  108. public ICommand PosMoveCommand { get; set; }
  109. public ICommand LoadUnloadCommand { get; set; }
  110. public ICommand PIOCharge { get; set; }
  111. IEventAggregator eventAggregator;
  112. MessageController messageController;
  113. List<BitBlock> allIOList = new List<BitBlock>();
  114. VCSystem VCSystem;
  115. EzIO IO = null;
  116. private bool isBusy;
  117. public bool IsBusy
  118. {
  119. get { return isBusy; }
  120. set { SetProperty(ref this.isBusy, value); }
  121. }
  122. private string busyText;
  123. public string BusyText
  124. {
  125. get { return busyText; }
  126. set { SetProperty(ref this.busyText, value); }
  127. }
  128. private eConveyorState conveyorState;
  129. public eConveyorState ConveyorState
  130. {
  131. get { return conveyorState; }
  132. set { SetProperty(ref this.conveyorState, value); }
  133. }
  134. private AutoResetEvent eventBusy = new AutoResetEvent(false);
  135. public ConveyorControlViewModel(IEventAggregator _ea, MessageController _msg, VCSystem vcSystem)
  136. {
  137. this.eventAggregator = _ea;
  138. this.VCSystem = vcSystem;
  139. this.IO = VCSystem.IO as EzIO;
  140. this.IO.OnChangedIO += IO_OnChangedIO;
  141. /*Lock&UnLock Publish Event*/
  142. this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Unsubscribe(AxisUICallbackCommunication);
  143. this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Subscribe(AxisUICallbackCommunication, ThreadOption.UIThread);
  144. /*GUI Pubsub Event*/
  145. this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Unsubscribe(UICallbackCommunication);
  146. this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Subscribe(UICallbackCommunication, ThreadOption.UIThread);
  147. this.messageController = _msg;
  148. this.ConveyorRunCommand = new DelegateCommand<object>(ExecuteCvCommand);
  149. this.PosMoveCommand = new DelegateCommand<object>(ExecutePosMoveCommand);
  150. this.LoadUnloadCommand = new DelegateCommand<string>(ExecuteLoadUnloadCommand);
  151. this.PIOCharge = new DelegateCommand<string>(ExecutePIOChargeCommand);
  152. }
  153. void UpdateCvState()
  154. {
  155. if (IO.IsOn("OUT_CV_RUN", false))
  156. {
  157. if (IO.IsOn("OUT_CV_CWCCW", false))
  158. {
  159. this.CWOnBrush = Brushes.DodgerBlue;
  160. this.CCWOnBrush = Brushes.LimeGreen;
  161. this.ConveyorState = eConveyorState.CCW;
  162. }
  163. else
  164. {
  165. this.CWOnBrush = Brushes.LimeGreen;
  166. this.CCWOnBrush = Brushes.DodgerBlue;
  167. this.ConveyorState = eConveyorState.CW;
  168. }
  169. }
  170. else
  171. {
  172. this.CWOnBrush = Brushes.DodgerBlue;
  173. this.CCWOnBrush = Brushes.DodgerBlue;
  174. this.ConveyorState = eConveyorState.Stop;
  175. }
  176. }
  177. private void ExecutePIOChargeCommand(string obj)
  178. {
  179. this.messageController.ShowConfirmationPopupView($"PIO Battery Charge ?", r =>
  180. {
  181. if (r.Result == ButtonResult.OK)
  182. {
  183. this.SetBusy();
  184. var msg = new VCSMessageEventArgs();
  185. switch (obj)
  186. {
  187. case "PB":
  188. msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqPIOBatteryCharge;
  189. msg.MessageText = obj.ToString();
  190. break;
  191. case "PBStop":
  192. msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqPIOBatteryChargeStop;
  193. msg.MessageText = obj.ToString();
  194. break;
  195. default:
  196. break;
  197. }
  198. this.VcsMessagePublish(msg);
  199. }
  200. });
  201. }
  202. private void ExecuteLoadUnloadCommand(string obj)
  203. {
  204. this.messageController.ShowConfirmationPopupView($"Conveyor Move Start ?", r =>
  205. {
  206. if (r.Result == ButtonResult.OK)
  207. {
  208. this.SetBusy();
  209. var msg = new VCSMessageEventArgs();
  210. switch (obj)
  211. {
  212. case "Load":
  213. msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqConveyorLoad;
  214. break;
  215. case "Unload":
  216. msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqConveyorUnload;
  217. break;
  218. case "PL":
  219. msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqPIOConveyor;
  220. msg.MessageText = obj.ToString();
  221. break;
  222. case "PU":
  223. msg.Kind = VCSMessageEventArgs.eVCSMessageKind.ReqPIOConveyor;
  224. msg.MessageText = obj.ToString();
  225. break;
  226. default:
  227. break;
  228. }
  229. this.VcsMessagePublish(msg);
  230. }
  231. });
  232. }
  233. void VcsMessagePublish(VCSMessageEventArgs msg)
  234. {
  235. this.eventAggregator.GetEvent<VCSMessagePubSubEvent>().Publish(msg);
  236. }
  237. private void IO_OnChangedIO(BitBlock bit)
  238. {
  239. if (bit.Tag.Equals("OUT_CV_RUN"))
  240. {
  241. this.UpdateCvState();
  242. }
  243. }
  244. private void UICallbackCommunication(GUIMessageEventArgs _args)
  245. {
  246. var msg = "FAIL";
  247. switch (_args.Kind)
  248. {
  249. case GUIMessageEventArgs.eGUIMessageKind.ModelPropertyChange:
  250. break;
  251. case GUIMessageEventArgs.eGUIMessageKind.RspIOObject:
  252. break;
  253. case GUIMessageEventArgs.eGUIMessageKind.RspIOMapList:
  254. break;
  255. case GUIMessageEventArgs.eGUIMessageKind.RspCommandList:
  256. break;
  257. case GUIMessageEventArgs.eGUIMessageKind.RspAutoModeChange:
  258. break;
  259. case GUIMessageEventArgs.eGUIMessageKind.RspManualModeChange:
  260. break;
  261. case GUIMessageEventArgs.eGUIMessageKind.RspAlarmReset:
  262. break;
  263. case GUIMessageEventArgs.eGUIMessageKind.RspVehicleModeChange:
  264. break;
  265. case GUIMessageEventArgs.eGUIMessageKind.RspEStop:
  266. break;
  267. case GUIMessageEventArgs.eGUIMessageKind.RspVihicleState:
  268. break;
  269. case GUIMessageEventArgs.eGUIMessageKind.RspMachineModeChg:
  270. break;
  271. case GUIMessageEventArgs.eGUIMessageKind.RspAddCommand:
  272. break;
  273. case GUIMessageEventArgs.eGUIMessageKind.RspConveyorMove:
  274. break;
  275. case GUIMessageEventArgs.eGUIMessageKind.RspConveyorLoad:
  276. if (_args.Result.IsSuccess)
  277. {
  278. this.ResetBusy();
  279. this.messageController.ShowNotificationView("SUCCESS");
  280. }
  281. else
  282. {
  283. this.messageController.ShowNotificationView(msg);
  284. this.ResetBusy();
  285. }
  286. break;
  287. case GUIMessageEventArgs.eGUIMessageKind.RspConveyorUnload:
  288. if (_args.Result.IsSuccess)
  289. {
  290. this.ResetBusy();
  291. this.messageController.ShowNotificationView("SUCCESS");
  292. }
  293. else
  294. {
  295. this.messageController.ShowNotificationView(msg);
  296. this.ResetBusy();
  297. }
  298. break;
  299. case GUIMessageEventArgs.eGUIMessageKind.RspPIOConveyor:
  300. if (_args.Result.IsSuccess)
  301. {
  302. this.ResetBusy();
  303. this.messageController.ShowNotificationView("SUCCESS");
  304. }
  305. else
  306. {
  307. this.messageController.ShowNotificationView(msg);
  308. this.ResetBusy();
  309. }
  310. break;
  311. case GUIMessageEventArgs.eGUIMessageKind.RspPIOBatteryCharge:
  312. if (_args.Result.IsSuccess)
  313. {
  314. this.ResetBusy();
  315. this.messageController.ShowNotificationView("SUCCESS");
  316. }
  317. else
  318. {
  319. this.messageController.ShowNotificationView(msg);
  320. this.ResetBusy();
  321. }
  322. break;
  323. case GUIMessageEventArgs.eGUIMessageKind.RsqPIOBatteryChargeStop:
  324. if (_args.Result.IsSuccess)
  325. {
  326. this.ResetBusy();
  327. this.messageController.ShowNotificationView("SUCCESS");
  328. }
  329. else
  330. {
  331. this.messageController.ShowNotificationView(msg);
  332. this.ResetBusy();
  333. }
  334. break;
  335. case GUIMessageEventArgs.eGUIMessageKind.RspObstaclePatternChg:
  336. break;
  337. case GUIMessageEventArgs.eGUIMessageKind.RspObstaclePatternNo:
  338. break;
  339. case GUIMessageEventArgs.eGUIMessageKind.RspBatteryState:
  340. break;
  341. case GUIMessageEventArgs.eGUIMessageKind.RspRouteManager:
  342. break;
  343. case GUIMessageEventArgs.eGUIMessageKind.RspDirveSpeed:
  344. break;
  345. case GUIMessageEventArgs.eGUIMessageKind.RspSpeedProfile:
  346. break;
  347. case GUIMessageEventArgs.eGUIMessageKind.RspJogSpeed:
  348. break;
  349. case GUIMessageEventArgs.eGUIMessageKind.RspParamsSave:
  350. break;
  351. }
  352. }
  353. private void ExecutePosMoveCommand(object obj)
  354. {
  355. this.messageController.ShowConfirmationPopupView("Clamp Move ?", r =>
  356. {
  357. if (r.Result == ButtonResult.OK)
  358. {
  359. //this.IsBusy = true;
  360. SetBusy();
  361. var selectedPos = obj.ToString();
  362. var msg = new AxisControlEventArgs
  363. {
  364. Dir = eEventDir.ToBack,
  365. Kind = eAxisControlKind.SyncMove,
  366. };
  367. switch (selectedPos)
  368. {
  369. case "Lock":
  370. msg.PosDir = ePosDir.Lock;
  371. break;
  372. case "UnLock":
  373. msg.PosDir = ePosDir.UnLock;
  374. break;
  375. }
  376. this.AxisPublishEvent(msg);
  377. }
  378. });
  379. }
  380. private void AxisPublishEvent(AxisControlEventArgs msg)
  381. {
  382. this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Publish(msg);
  383. }
  384. private void AxisUICallbackCommunication(AxisControlEventArgs _args)
  385. {
  386. var msg = "FAIL";
  387. if (_args.Dir == eEventDir.ToFront)
  388. {
  389. switch (_args.Kind)
  390. {
  391. case eAxisControlKind.NONE:
  392. break;
  393. case eAxisControlKind.OriginReturn:
  394. break;
  395. case eAxisControlKind.Stop:
  396. break;
  397. case eAxisControlKind.EStop:
  398. break;
  399. case eAxisControlKind.Move:
  400. ResponseMove(_args);
  401. break;
  402. case eAxisControlKind.Jog:
  403. break;
  404. case eAxisControlKind.ServoOn:
  405. break;
  406. case eAxisControlKind.ServoOff:
  407. break;
  408. case eAxisControlKind.ReqCurrentPosition:
  409. break;
  410. case eAxisControlKind.ReqStopCurrentPosition:
  411. break;
  412. case eAxisControlKind.FaultReset:
  413. break;
  414. case eAxisControlKind.AxisState:
  415. AxisState(_args);
  416. break;
  417. case eAxisControlKind.SyncMove:
  418. if (_args.Result.IsSuccess)
  419. {
  420. this.ResetBusy();
  421. this.messageController.ShowNotificationView("SUCCESS");
  422. }
  423. else
  424. {
  425. this.messageController.ShowNotificationView(msg);
  426. this.ResetBusy();
  427. }
  428. break;
  429. default:
  430. break;
  431. }
  432. }
  433. //this.CurrentBusyCheck();
  434. }
  435. private void ResponseMove(AxisControlEventArgs _args)
  436. {
  437. var msg = string.Empty;
  438. if (_args.Result.IsSuccess)
  439. msg = ("Move Success");
  440. else
  441. {
  442. var error = _args.Result.Errors.FirstOrDefault();
  443. var alarm = error.Metadata["Alarm"] as Alarm;
  444. msg = alarm.Name + " " + alarm.Text;
  445. }
  446. this.messageController.ShowNotificationView(msg);
  447. }
  448. private void AxisState(AxisControlEventArgs args)
  449. {
  450. var left = args.Args["Left"] as AxisState;
  451. var right = args.Args["Right"] as AxisState;
  452. /*Left*/
  453. if (left.IsServoOn)
  454. this.AxisLeftIsServoOn = Brushes.LimeGreen;
  455. else
  456. this.AxisLeftIsServoOn = Brushes.Gray;
  457. if (left.IsOriginReturn)
  458. this.AxisLeftIsOrg = Brushes.LimeGreen;
  459. else
  460. this.AxisLeftIsOrg = Brushes.Gray;
  461. if (left.IsAmpFault)
  462. this.AxisLeftAmpFault = Brushes.Red;
  463. else
  464. this.AxisLeftAmpFault = Brushes.Gray;
  465. /*Right*/
  466. if (right.IsServoOn)
  467. this.AxisRightIsServoOn = Brushes.LimeGreen;
  468. else
  469. this.AxisRightIsServoOn = Brushes.Gray;
  470. if (right.IsOriginReturn)
  471. this.AxisRightIsOrg = Brushes.LimeGreen;
  472. else
  473. this.AxisRightIsOrg = Brushes.Gray;
  474. if (right.IsAmpFault)
  475. this.AxisRightAmpFault = Brushes.Red;
  476. else
  477. this.AxisRightAmpFault = Brushes.Gray;
  478. }
  479. private void ExecuteCvCommand(object _obj)
  480. {
  481. var dir = _obj.ToString();
  482. var msg = new VCSMessageEventArgs()
  483. {
  484. Kind = VCSMessageEventArgs.eVCSMessageKind.ReqConveyorMove,
  485. MessageText = dir
  486. };
  487. this.VcsMessagePublish(msg);
  488. }
  489. void SetBusy()
  490. {
  491. this.IsBusy = true;
  492. Task.Run(() =>
  493. {
  494. if (eventBusy.WaitOne(10000) == false)
  495. {
  496. Application.Current.Dispatcher.Invoke(() =>
  497. {
  498. this.IsBusy = false;
  499. this.messageController.ShowNotificationView("Response Time Out", false);
  500. });
  501. }
  502. });
  503. }
  504. void ResetBusy()
  505. {
  506. eventBusy.Set();
  507. this.IsBusy = false;
  508. }
  509. #region Dialog
  510. public bool CanCloseDialog()
  511. {
  512. return true;
  513. }
  514. public void OnDialogClosed()
  515. {
  516. this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Publish(new AxisControlEventArgs
  517. {
  518. Dir = AxisControlEventArgs.eEventDir.ToBack,
  519. Kind = AxisControlEventArgs.eAxisControlKind.NONE
  520. });
  521. this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Unsubscribe(AxisUICallbackCommunication);
  522. this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish(new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack, ControlKind = DriveControlEventArgs.eControlKind.ReqStopCurrentPos });
  523. this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Unsubscribe(UICallbackCommunication);
  524. }
  525. public void OnDialogOpened(IDialogParameters parameters)
  526. {
  527. var msg = new VCSMessageEventArgs() { Kind = VCSMessageEventArgs.eVCSMessageKind.ReqIOObject };
  528. this.eventAggregator.GetEvent<VCSMessagePubSubEvent>().Publish(msg);
  529. this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Publish(new AxisControlEventArgs { Dir = AxisControlEventArgs.eEventDir.ToBack, Kind = AxisControlEventArgs.eAxisControlKind.ReqCurrentPosition });
  530. this.UpdateCvState();
  531. }
  532. private void CloseDialog(string parameter)
  533. {
  534. ButtonResult result = ButtonResult.None;
  535. if (parameter?.ToLower() == "true")
  536. result = ButtonResult.OK;
  537. else if (parameter?.ToLower() == "false")
  538. result = ButtonResult.Cancel;
  539. RaiseRequestClose(new DialogResult(result));
  540. }
  541. public virtual void RaiseRequestClose(IDialogResult dialogResult)
  542. {
  543. RequestClose?.Invoke(dialogResult);
  544. }
  545. #endregion
  546. }
  547. }