IoTurnOverHHV1.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. using System;
  2. using System.Xml;
  3. using Aitex.Core.RT.DataCenter;
  4. using Aitex.Core.RT.Event;
  5. using Aitex.Core.RT.IOCore;
  6. using Aitex.Core.RT.Log;
  7. using Aitex.Core.RT.OperationCenter;
  8. using Aitex.Core.RT.SCCore;
  9. using Aitex.Core.Util;
  10. using MECF.Framework.Common.Equipment;
  11. using MECF.Framework.Common.SubstrateTrackings;
  12. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Flipper.FlipperBase;
  13. namespace Aitex.Core.RT.Device.Unit
  14. {
  15. /// <summary>
  16. ///
  17. /// </summary>
  18. public class IoTurnOverHHV1 : FlipperBaseDevice
  19. {
  20. private readonly DIAccessor _di0Degree;
  21. private readonly DIAccessor _di180Degree;
  22. private readonly DIAccessor _diAlarm;
  23. private readonly DIAccessor _diBusy;
  24. private readonly DIAccessor _diGrip;
  25. private readonly DIAccessor _diOrigin;
  26. private readonly DIAccessor _diPlacement;
  27. private readonly DIAccessor _diPressureError;
  28. private readonly DIAccessor _diUngrip;
  29. private readonly DOAccessor _doGrip;
  30. private readonly DOAccessor _doM0;
  31. private readonly DOAccessor _doM1;
  32. private readonly DOAccessor _doOrigin;
  33. private readonly DOAccessor _doResetError;
  34. private readonly DOAccessor _doStop;
  35. private readonly DOAccessor _doUngrip;
  36. private DateTime _dtActionStart;
  37. //private DeviceTimer _loopTimeout = new DeviceTimer();
  38. //private readonly DeviceTimer _loopTimer = new DeviceTimer();
  39. //private readonly SCConfigItem _scLoopInterval;
  40. //private TurnOverState _state = TurnOverState.Idle;
  41. //public TurnOverState State => _state;
  42. //private R_TRIG _trigCloseError = new R_TRIG();
  43. //private R_TRIG _trigOpenError = new R_TRIG();
  44. //private R_TRIG _trigReset = new R_TRIG();
  45. //private R_TRIG _trigSetPointDone = new R_TRIG();
  46. // DI_TurnOverPlacement
  47. // DI_TurnOverGrip
  48. // DI_TurnOverUngrip
  49. // DI_TurnOverBusy
  50. // DI_TurnOverPressureError
  51. //
  52. // DI_TurnOverAlarm
  53. // DI_TurnOverOrigin
  54. // DI_TurnOver0Degree
  55. // DI_TurnOver180Degree
  56. //
  57. // DO_TurnOverGrip
  58. // DO_TurnOverUngrip
  59. // DO_TurnOverM0
  60. // DO_TurnOverM1
  61. // DO_TurnOverStop
  62. //
  63. // DO_TurnOverOrigin
  64. // DO_TurnOverResetError
  65. public string Display, DeviceID;
  66. private PeriodicJob _thread;
  67. public IoTurnOverHHV1(string module, XmlElement node, string ioModule = ""):base(node.GetAttribute("module"), node.GetAttribute("id"))
  68. {
  69. Module = node.GetAttribute("module");
  70. Name = node.GetAttribute("id");
  71. Display = node.GetAttribute("display");
  72. DeviceID = node.GetAttribute("schematicId");
  73. _diPlacement = ParseDiNode("DI_TurnOverPlacement", node, ioModule);
  74. _diGrip = ParseDiNode("DI_TurnOverGrip", node, ioModule);
  75. _diUngrip = ParseDiNode("DI_TurnOverUngrip", node, ioModule);
  76. _diBusy = ParseDiNode("DI_TurnOverBusy", node, ioModule);
  77. _diPressureError = ParseDiNode("DI_TurnOverPressureError", node, ioModule);
  78. _diAlarm = ParseDiNode("DI_TurnOverAlarm", node, ioModule);
  79. _diOrigin = ParseDiNode("DI_TurnOverOrigin", node, ioModule);
  80. _di0Degree = ParseDiNode("DI_TurnOver0Degree", node, ioModule);
  81. _di180Degree = ParseDiNode("DI_TurnOver180Degree", node, ioModule);
  82. _doGrip = ParseDoNode("DO_TurnOverGrip", node, ioModule);
  83. _doUngrip = ParseDoNode("DO_TurnOverUngrip", node, ioModule);
  84. _doM0 = ParseDoNode("DO_TurnOverM0", node, ioModule);
  85. _doM1 = ParseDoNode("DO_TurnOverM1", node, ioModule);
  86. _doStop = ParseDoNode("DO_TurnOverStop", node, ioModule);
  87. _doOrigin = ParseDoNode("DO_TurnOverOrigin", node, ioModule);
  88. _doResetError = ParseDoNode("DO_TurnOverResetError", node, ioModule);
  89. //_scLoopInterval = SC.GetConfigItem("Turnover.IntervalTimeLimit");
  90. InitializeIoTurnover();
  91. }
  92. public override bool IsPlacement
  93. {
  94. get
  95. {
  96. if(_diPlacement !=null) return !_diPlacement.Value;
  97. return WaferManager.Instance.CheckHasWafer(ModuleName.TurnOverStation, 0);
  98. }
  99. }
  100. public bool IsAlarm => !_diAlarm.Value;
  101. public bool IsPressureError => _diPressureError ==null? false: !_diPressureError.Value;
  102. public override FlipperPosEnum CurrentFlipperPosition
  103. {
  104. get
  105. {
  106. if (_di0Degree.Value && !_di180Degree.Value) return FlipperPosEnum.FrontSide;
  107. if (!_di0Degree.Value && _di180Degree.Value) return FlipperPosEnum.BackSide;
  108. return FlipperPosEnum.Unknow;
  109. }
  110. }
  111. public override GripPosEnum CurrentGripperPositon
  112. {
  113. get
  114. {
  115. if (_diGrip.Value && !_diUngrip.Value) return GripPosEnum.Close;
  116. if (!_diGrip.Value && _diUngrip.Value) return GripPosEnum.Open;
  117. return GripPosEnum.Unknow;
  118. }
  119. }
  120. //public bool IsBusy => _diBusy.Value || _state != TurnOverState.Idle;
  121. //public bool IsIdle => !_diBusy.Value && _state == TurnOverState.Idle;
  122. //public bool IsGrip => _diGrip.Value && !_diUngrip.Value;
  123. //public bool IsUnGrip => _diUngrip.Value && !_diGrip.Value;
  124. //public bool Is0Degree => _di0Degree.Value &&!_di180Degree.Value;
  125. //public bool Is180Degree => _di180Degree.Value&&!_di0Degree.Value;
  126. //public bool IsEnableWaferTransfer => Is0Degree && !IsBusy && IsUnGrip && !IsAlarm &&
  127. // IsPlacement;
  128. public bool InitializeIoTurnover()
  129. {
  130. //DATA.Subscribe($"{Module}.{Name}.State", () => _state.ToString());
  131. DATA.Subscribe($"{Module}.{Name}.IsHomed", () => _diOrigin.Value);
  132. DATA.Subscribe($"{Module}.{Name}.IsBusy", () => _diBusy.Value);
  133. DATA.Subscribe($"{Module}.{Name}.IsGrip", () => _diGrip.Value);
  134. DATA.Subscribe($"{Module}.{Name}.IsUnGrip", () => _diUngrip.Value);
  135. DATA.Subscribe($"{Module}.{Name}.Is0Degree", () => _di0Degree.Value);
  136. DATA.Subscribe($"{Module}.{Name}.Is180Degree", () => _di180Degree.Value);
  137. DATA.Subscribe($"{Module}.{Name}.IsPlacement", () => IsPlacement);
  138. DATA.Subscribe($"{Module}.{Name}.IsAlarm", () => _diAlarm.Value);
  139. DATA.Subscribe($"{Module}.{Name}.IsPressureError", () => _diPressureError==null?false: _diPressureError.Value);
  140. DATA.Subscribe($"{Module}.{Name}.GripCmd", () => _doGrip.Value);
  141. DATA.Subscribe($"{Module}.{Name}.TurnTo0Cmd", () => _doM0.Value);
  142. DATA.Subscribe($"{Module}.{Name}.TurnTo180Cmd", () => _doM1.Value);
  143. DATA.Subscribe($"{Module}.{Name}.HomeCmd", () => _doOrigin.Value);
  144. DATA.Subscribe($"{Module}.{Name}.ResetCmd", () => _doResetError.Value);
  145. DATA.Subscribe($"{Module}.{Name}.StopCmd", () => _doStop==null?false: _doStop.Value);
  146. DATA.Subscribe($"{Module}.{Name}.UnGripCmd", () => _doUngrip.Value);
  147. _trigError = new R_TRIG();
  148. _thread = new PeriodicJob(50, OnTimerMonitor, $"{Module}.{Name} MonitorHandler", true);
  149. return true;
  150. }
  151. private R_TRIG _trigError;
  152. private bool OnTimerMonitor()
  153. {
  154. _trigError.CLK = (_diAlarm != null && !_diAlarm.Value) || (_diPressureError != null && !_diPressureError.Value);
  155. if(_trigError.Q)
  156. {
  157. OnError($"{FlipperModuleName}Error");
  158. }
  159. return true;
  160. }
  161. public override void Terminate()
  162. {
  163. }
  164. public DOAccessor ParseDoNode(string name, XmlElement node, string ioModule = "")
  165. {
  166. if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
  167. return IO.DO[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"];
  168. return null;
  169. }
  170. public DIAccessor ParseDiNode(string name, XmlElement node, string ioModule = "")
  171. {
  172. if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
  173. return IO.DI[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"];
  174. return null;
  175. }
  176. protected override bool fStartGrip(object[] param)
  177. {
  178. _doGrip.SetValue(true, out _);
  179. _doUngrip.SetValue(false, out _);
  180. _dtActionStart = DateTime.Now;
  181. return true;
  182. }
  183. protected override bool fMonitorGrip(object[] param)
  184. {
  185. IsBusy = false;
  186. if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
  187. {
  188. OnError("Grip timeout");
  189. return false;
  190. }
  191. if (_diGrip.Value && !_diUngrip.Value && !_diBusy.Value)
  192. {
  193. EV.PostInfoLog("Flipper", $"{FlipperModuleName} grip completed");
  194. return true;
  195. }
  196. return false;
  197. }
  198. protected override bool fStartUnGrip(object[] param)
  199. {
  200. _doGrip.SetValue(false, out _);
  201. _doUngrip.SetValue(true, out _);
  202. _dtActionStart = DateTime.Now;
  203. return true;
  204. }
  205. protected override bool fMonitorUnGrip(object[] param)
  206. {
  207. IsBusy = false;
  208. if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
  209. {
  210. OnError("UnGrip timeout");
  211. return false;
  212. }
  213. if (!_diGrip.Value && _diUngrip.Value && !_diBusy.Value)
  214. {
  215. EV.PostInfoLog("Flipper", $"{FlipperModuleName} ungrip completed");
  216. return true;
  217. }
  218. return false;
  219. }
  220. protected override bool fStartHome(object[] param)
  221. {
  222. _doM0.SetValue(false, out _);
  223. _doM1.SetValue(false, out _);
  224. _doOrigin.SetValue(true, out _);
  225. _dtActionStart = DateTime.Now;
  226. _dtActionStart = DateTime.Now;
  227. return true;
  228. }
  229. protected override bool fMonitorHome(object[] param)
  230. {
  231. IsBusy = false;
  232. if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
  233. {
  234. OnError("Home timeout");
  235. _doM1.SetValue(false, out _);
  236. _doM0.SetValue(false, out _);
  237. _doOrigin.SetValue(false, out _);
  238. return false;
  239. }
  240. if (_diOrigin.Value && !_diBusy.Value)
  241. {
  242. _doOrigin.SetValue(false, out _);
  243. EV.PostInfoLog("Flipper", $"{FlipperModuleName} home completed");
  244. _doM1.SetValue(false, out _);
  245. _doM0.SetValue(false, out _);
  246. _doOrigin.SetValue(false, out _);
  247. return true;
  248. }
  249. return false;
  250. }
  251. protected override bool fStartTurnTo0(object[] param)
  252. {
  253. _doM0.SetValue(true, out _);
  254. _doM1.SetValue(false, out _);
  255. _dtActionStart = DateTime.Now;
  256. var wafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
  257. if (!wafer.IsEmpty)
  258. {
  259. var dvid = new SerializableDictionary<string, string>()
  260. {
  261. {"LOT_ID", wafer.LotId},
  262. {"WAFER_ID", wafer.WaferID},
  263. {"ARRIVE_POS_NAME", FlipperModuleName.ToString()}
  264. };
  265. EV.Notify(EventWaferTurnOverStart, dvid);
  266. }
  267. return true;
  268. }
  269. protected override bool fMonitorTurnTo0(object[] param)
  270. {
  271. IsBusy = false;
  272. if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
  273. {
  274. OnError("Turn to 0 timeout");
  275. _doM1.SetValue(false, out _);
  276. _doM0.SetValue(false, out _);
  277. _doOrigin.SetValue(false, out _);
  278. return false;
  279. }
  280. if (_di0Degree.Value && !_di180Degree.Value && !_diBusy.Value)
  281. {
  282. EV.PostInfoLog("Flipper", $"{FlipperModuleName} turn to 0 degree completed");
  283. var wafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
  284. if (!wafer.IsEmpty)
  285. {
  286. var dvid = new SerializableDictionary<string, string>()
  287. {
  288. {"LOT_ID", wafer.LotId},
  289. {"WAFER_ID", wafer.WaferID},
  290. {"ARRIVE_POS_NAME", FlipperModuleName.ToString()}
  291. };
  292. EV.Notify(EventWaferTurnOverStart, dvid);
  293. }
  294. _doM1.SetValue(false, out _);
  295. _doM0.SetValue(false, out _);
  296. _doOrigin.SetValue(false, out _);
  297. return true;
  298. }
  299. return false;
  300. }
  301. protected override bool fStartTurnTo180(object[] param)
  302. {
  303. _doM0.SetValue(false, out _);
  304. _doM1.SetValue(true, out _);
  305. _dtActionStart = DateTime.Now;
  306. var wafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
  307. if (!wafer.IsEmpty)
  308. {
  309. var dvid = new SerializableDictionary<string, string>()
  310. {
  311. {"LOT_ID", wafer.LotId},
  312. {"WAFER_ID", wafer.WaferID},
  313. {"ARRIVE_POS_NAME", "TRN1"}
  314. };
  315. EV.Notify(EventWaferTurnOverStart, dvid);
  316. }
  317. return true;
  318. }
  319. protected override bool fMonitorTurnTo180(object[] param)
  320. {
  321. IsBusy = false;
  322. if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
  323. {
  324. OnError("Turn to 180 timeout");
  325. _doM1.SetValue(false, out _);
  326. _doM0.SetValue(false, out _);
  327. _doOrigin.SetValue(false, out _);
  328. return false;
  329. }
  330. if (!_di0Degree.Value && _di180Degree.Value && !_diBusy.Value)
  331. {
  332. EV.PostInfoLog("Flipper", $"{FlipperModuleName} turn to 180 degree completed");
  333. var wafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0);
  334. if (!wafer.IsEmpty)
  335. {
  336. var dvid = new SerializableDictionary<string, string>()
  337. {
  338. {"LOT_ID", wafer.LotId},
  339. {"WAFER_ID", wafer.WaferID},
  340. {"ARRIVE_POS_NAME", FlipperModuleName.ToString()}
  341. };
  342. EV.Notify(EventWaferTurnOverStart, dvid);
  343. }
  344. _doM1.SetValue(false, out _);
  345. _doM0.SetValue(false, out _);
  346. _doOrigin.SetValue(false, out _);
  347. return true;
  348. }
  349. return false;
  350. }
  351. protected override bool fStartAbort(object[] param)
  352. {
  353. _doStop.SetValue(true, out _);
  354. _doResetError.SetValue(false, out _);
  355. _doM0.SetValue(false, out _);
  356. _doM1.SetValue(false, out _);
  357. IsBusy = false;
  358. return true;
  359. }
  360. protected override bool fStartReset(object[] param)
  361. {
  362. _doM0.SetValue(false, out _);
  363. _doM1.SetValue(false, out _);
  364. _doOrigin.SetValue(false, out _);
  365. _doStop.SetValue(false, out _);
  366. _doResetError.SetValue(true, out _);
  367. _dtActionStart = DateTime.Now;
  368. return true;
  369. }
  370. protected override bool fMonitorReset(object[] param)
  371. {
  372. IsBusy = false;
  373. if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(TimelimitAction))
  374. {
  375. OnError("Reset timeout");
  376. _doResetError.SetValue(false, out _);
  377. return false;
  378. }
  379. if (_diAlarm != null && !_diAlarm.Value)
  380. return false;
  381. EV.PostInfoLog("Flipper", $"{FlipperModuleName} reset completed");
  382. _doResetError.SetValue(false, out _);
  383. return true;
  384. }
  385. }
  386. }