DMReservoirInitializeRoutine.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.RT.SCCore;
  5. using MECF.Framework.Common.Alarm;
  6. using MECF.Framework.Common.RecipeCenter;
  7. using MECF.Framework.Common.Routine;
  8. using MECF.Framework.Common.Utilities;
  9. using PunkHPX8_Core;
  10. using PunkHPX8_RT.Devices.Facilities;
  11. using PunkHPX8_RT.Devices.PlatingCell;
  12. using PunkHPX8_RT.Devices.Reservoir;
  13. using PunkHPX8_RT.Devices.Temperature;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using System.Text;
  18. using System.Threading.Tasks;
  19. namespace PunkHPX8_RT.Modules.Reservoir
  20. {
  21. public class DMReservoirInitializeRoutine : RoutineBase, IRoutine
  22. {
  23. private enum InitializeStep
  24. {
  25. OpenIsolationValve,
  26. CAPump,
  27. CAPumpWait,
  28. ANPump,
  29. ANPumpWait,
  30. CheckFlowWait,
  31. CellManualCheckFlow,
  32. CellAutoCheckFlow,
  33. CheckDiReplen,
  34. AutoDiReplen,
  35. AutoCellAutoEnableHED,
  36. End
  37. }
  38. #region 常量
  39. private const string AUTO = "Auto";
  40. private const string MANUAL = "Manual";
  41. private const int ENABLE = 5;
  42. #endregion
  43. #region 内部变量
  44. CAPumpOnRoutine _caPumpOnRoutine;
  45. ANPumpOnRoutine _anPumpOnRoutine;
  46. DMReservoirDevice _dmReservoirDevice;
  47. private ResRecipe _recipe;
  48. private PlatingCellDevice _platingCellDevices;
  49. private TemperatureController _temperatureController;
  50. private double _hedFlowLowLimit;
  51. private int _autoHedDelay = 0;
  52. private int _flowFaultHoldOffTime = 1000;
  53. private double _cellFlowStartLowLimit = 3;
  54. private double _anFlowStartLowLimit = 0.5;
  55. #endregion
  56. /// <summary>
  57. /// 构造函数
  58. /// </summary>
  59. /// <param name="module"></param>
  60. public DMReservoirInitializeRoutine(string module) : base(module)
  61. {
  62. }
  63. /// <summary>
  64. /// 中止
  65. /// </summary>
  66. public void Abort()
  67. {
  68. _caPumpOnRoutine.Abort();
  69. _anPumpOnRoutine.Abort();
  70. }
  71. /// <summary>
  72. /// 监控
  73. /// </summary>
  74. /// <returns></returns>
  75. public RState Monitor()
  76. {
  77. Runner.Run(InitializeStep.OpenIsolationValve, OpenIsolationValve,_delay_1ms)
  78. .Run(InitializeStep.CAPump, () => { return _caPumpOnRoutine.Start() == RState.Running; }, _delay_1s)
  79. .WaitWithStopCondition(InitializeStep.CAPumpWait, () => CommonFunction.CheckRoutineEndState(_caPumpOnRoutine), () => CommonFunction.CheckRoutineStopState(_caPumpOnRoutine))
  80. .Run(InitializeStep.ANPump, () => { return _anPumpOnRoutine.Start() == RState.Running; }, _delay_1ms)
  81. .WaitWithStopCondition(InitializeStep.ANPumpWait, () => CommonFunction.CheckRoutineEndState(_anPumpOnRoutine), () => CommonFunction.CheckRoutineStopState(_anPumpOnRoutine))
  82. .Delay(InitializeStep.CheckFlowWait, _flowFaultHoldOffTime)
  83. .RunIf(InitializeStep.CellManualCheckFlow,_dmReservoirDevice.OperationMode == MANUAL,ManualCheckFlow,_delay_1ms)
  84. .RunIf(InitializeStep.CellAutoCheckFlow,_dmReservoirDevice.OperationMode == AUTO, AutoCheckFlow, _delay_1ms)
  85. .RunIf(InitializeStep.AutoDiReplen, _recipe.DIReplenEnable || _recipe.ANDIReplenEnable, CheckFacilitiesDiReplenStatus, _delay_1ms)
  86. .Run(InitializeStep.AutoCellAutoEnableHED, AutoHedOn, _delay_1ms)
  87. .End(InitializeStep.End, ClearAlarmDataError, _delay_1ms);
  88. return Runner.Status;
  89. }
  90. /// <summary>
  91. /// 打开Isolation valve
  92. /// </summary>
  93. /// <returns></returns>
  94. private bool OpenIsolationValve()
  95. {
  96. return _dmReservoirDevice.ANIsolationOn() && _dmReservoirDevice.CAIsolationOn();
  97. }
  98. /// <summary>
  99. /// 检查cell flow 和an flow是否大于配置项
  100. /// </summary>
  101. /// <returns></returns>
  102. private bool ManualCheckFlow()
  103. {
  104. //cell flow 校验待完成
  105. if(_dmReservoirDevice.ReservoirData.AnFlow < _anFlowStartLowLimit)
  106. {
  107. _dmReservoirDevice.AnPumpOff();
  108. _dmReservoirDevice.ANIsolationOff();
  109. return false;
  110. }
  111. return true;
  112. }
  113. /// <summary>
  114. /// 检查cell flow 和an flow是否大于recipe的设定
  115. /// </summary>
  116. /// <returns></returns>
  117. private bool AutoCheckFlow()
  118. {
  119. //cell flow 校验待完成
  120. if (_dmReservoirDevice.ReservoirData.AnFlow < _recipe.ANFlowRateErrorLow)
  121. {
  122. return false;
  123. }
  124. return true;
  125. }
  126. /// <summary>
  127. /// 检验总Di有没有开
  128. /// </summary>
  129. /// <returns></returns>
  130. private bool CheckFacilitiesDiReplenStatus()
  131. {
  132. SystemFacilities systemFacilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
  133. if (systemFacilities != null)
  134. {
  135. bool result = systemFacilities.DIReplenEnable;
  136. if (!result)
  137. {
  138. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Facilities DiReplen is disable");
  139. }
  140. return result;
  141. }
  142. return false;
  143. }
  144. /// <summary>
  145. /// 启用HED
  146. /// </summary>
  147. /// <returns></returns>
  148. private bool EnableHED()
  149. {
  150. return _temperatureController.EnableOperation("", null);
  151. }
  152. /// <summary>
  153. /// 检验所有Metal处于Manual
  154. /// </summary>
  155. /// <returns></returns>
  156. private bool CheckAutoAndAllMetalAuto()
  157. {
  158. //if (_reservoirDevice.OperationMode != AUTO)
  159. //{
  160. // return false;
  161. //}
  162. //for (int i = 0; i < _metalDevices.Count; i++)
  163. //{
  164. // CompactMembranMetalDevice hotMetalDevice = _metalDevices[i];
  165. // if (hotMetalDevice.OperationMode != AUTO)
  166. // {
  167. // return false;
  168. // }
  169. //}
  170. return true;
  171. }
  172. /// <summary>
  173. /// 自动HED On
  174. /// </summary>
  175. /// <returns></returns>
  176. private bool AutoHedOn()
  177. {
  178. bool result = _dmReservoirDevice.ReservoirData.CaFlow < _cellFlowStartLowLimit;
  179. if (result)
  180. {
  181. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"CA Flow {_dmReservoirDevice.ReservoirData.CaFlow} is less than CellFlowStartLowLimit{_cellFlowStartLowLimit}");
  182. return false;
  183. }
  184. result = _temperatureController.EnableOperation("", null);
  185. if (!result)
  186. {
  187. return false;
  188. }
  189. result = _temperatureController.SetTargetTemperatureOperation("", new object[] { _recipe.TemperatureSetPoint });
  190. if (!result)
  191. {
  192. return false;
  193. }
  194. return true;
  195. }
  196. /// <summary>
  197. /// 检验Hed是否成功
  198. /// </summary>
  199. /// <returns></returns>
  200. private bool AutoHedSuccess()
  201. {
  202. if (_temperatureController.TemperatureData.ControlOperationModel == 0)
  203. {
  204. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Temperature control is disable");
  205. return false;
  206. }
  207. if (Math.Abs(_recipe.TemperatureSetPoint - _temperatureController.TemperatureData.TargetTemperature) >= 0.1 * _recipe.TemperatureSetPoint)
  208. {
  209. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"recipe temperature {_recipe.TemperatureSetPoint} is not match temperature target point {_temperatureController.TemperatureData.TargetTemperature}");
  210. return false;
  211. }
  212. return true;
  213. }
  214. /// <summary>
  215. /// 检验Metal A/B PowerSupplier通信状态
  216. /// </summary>
  217. /// <returns></returns>
  218. private bool AutoMetalsPowerSupplierCommuncationStatus()
  219. {
  220. //for (int i = 0; i < _metalDevices.Count; i++)
  221. //{
  222. // CompactMembranMetalDevice hotMetalDevice = _metalDevices[i];
  223. // if (hotMetalDevice.IsAuto)
  224. // {
  225. // if (hotMetalDevice.SideAPowerSupplier == null)
  226. // {
  227. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Side A PowerSupplier is null");
  228. // return false;
  229. // }
  230. // if (hotMetalDevice.SideBPowerSupplier == null)
  231. // {
  232. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Side B PowerSupplier is null");
  233. // return false;
  234. // }
  235. // if (!hotMetalDevice.SideAPowerSupplier.IsConnected)
  236. // {
  237. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Side A PowerSupplier {hotMetalDevice.SideAPowerSupplier.Name} is not connected");
  238. // return false;
  239. // }
  240. // if (!hotMetalDevice.SideBPowerSupplier.IsConnected)
  241. // {
  242. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Side B PowerSupplier {hotMetalDevice.SideBPowerSupplier.Name} is not connected");
  243. // return false;
  244. // }
  245. // }
  246. //}
  247. return true;
  248. }
  249. /// <summary>
  250. /// Auto Metal reset linmot
  251. /// </summary>
  252. /// <returns></returns>
  253. private bool AutoMetalResetLinmot()
  254. {
  255. //for (int i = 0; i < _metalDevices.Count; i++)
  256. //{
  257. // CompactMembranMetalDevice hotMetalDevice = _metalDevices[i];
  258. // if (hotMetalDevice.OperationMode == AUTO)
  259. // {
  260. // bool result = hotMetalDevice.ResetLinmot();
  261. // if (!result)
  262. // {
  263. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Reset linmot error");
  264. // return false;
  265. // }
  266. // }
  267. //}
  268. return true;
  269. }
  270. /// <summary>
  271. /// Auto Metal reset linmot
  272. /// </summary>
  273. /// <returns></returns>
  274. private bool CheckAutoMetalResetStatus()
  275. {
  276. //if (_reservoirDevice.OperationMode == MANUAL)
  277. //{
  278. // return true;
  279. //}
  280. //for (int i = 0; i < _metalDevices.Count; i++)
  281. //{
  282. // CompactMembranMetalDevice metalDevice = _metalDevices[i];
  283. // if (metalDevice.OperationMode == AUTO)
  284. // {
  285. // bool result = metalDevice.CheckLinmotRoutineEnd();
  286. // if (!result)
  287. // {
  288. // return false;
  289. // }
  290. // }
  291. //}
  292. return true;
  293. }
  294. /// <summary>
  295. /// Auto Metal reset linmot
  296. /// </summary>
  297. /// <returns></returns>
  298. private bool CheckAutoMetalResetStopStatus()
  299. {
  300. //if (_reservoirDevice.OperationMode == MANUAL)
  301. //{
  302. // return false;
  303. //}
  304. //for (int i = 0; i < _metalDevices.Count; i++)
  305. //{
  306. // CompactMembranMetalDevice hotMetalDevice = _metalDevices[i];
  307. // if (hotMetalDevice.OperationMode == AUTO)
  308. // {
  309. // bool result = hotMetalDevice.CheckLinmotRoutineError();
  310. // if (result)
  311. // {
  312. // return true;
  313. // }
  314. // }
  315. //}
  316. return false;
  317. }
  318. /// Metal WS Unclamp
  319. /// </summary>
  320. /// <returns></returns>
  321. private bool MetalsWHUnclampOn()
  322. {
  323. //for (int i = 0; i < _metalDevices.Count; i++)
  324. //{
  325. // CompactMembranMetalDevice hotMetalDevice = _metalDevices[i];
  326. // if (hotMetalDevice != null && !hotMetalDevice.IsDisable)
  327. // {
  328. // bool result = hotMetalDevice.WaferHolderUnclampOn("", null);
  329. // if (!result)
  330. // {
  331. // return false;
  332. // }
  333. // }
  334. //}
  335. //_reservoirDevice.InitializeCrossDose(true);
  336. return true;
  337. }
  338. /// <summary>
  339. /// 清除alarm界面相关的dataerror
  340. /// </summary>
  341. private bool ClearAlarmDataError()
  342. {
  343. //AlarmListManager.Instance.RemoveDataError(Module);
  344. //_dmReservoirDevice.ClearErrorLogSet(Module); //清除device里面的ErrorLogSet
  345. return true;
  346. }
  347. /// <summary>
  348. /// 启动
  349. /// </summary>
  350. /// <param name="objs"></param>
  351. /// <returns></returns>
  352. public RState Start(params object[] objs)
  353. {
  354. _caPumpOnRoutine = new CAPumpOnRoutine(Module);
  355. _anPumpOnRoutine = new ANPumpOnRoutine(Module);
  356. _dmReservoirDevice = DEVICE.GetDevice<DMReservoirDevice>(Module);
  357. //_dmReservoirDevice.ClearErrorLogSet(Module);
  358. _platingCellDevices = (PlatingCellDevice)objs[0];
  359. _temperatureController = (TemperatureController)objs[1];
  360. _recipe = _dmReservoirDevice.Recipe;
  361. _flowFaultHoldOffTime = SC.GetValue<int>($"PlatingCell.FlowFaultHoldOffTime");
  362. _cellFlowStartLowLimit = SC.GetValue<double>($"PlatingCell.CellFlowStartLowLimit");
  363. _anFlowStartLowLimit = SC.GetValue<double>($"PlatingCell.ANFlowStartLowLimit");
  364. if (!CheckPreCondition())
  365. {
  366. return RState.Failed;
  367. }
  368. return Runner.Start(Module, "Start D&M Initialize");
  369. }
  370. /// <summary>
  371. /// 检验前置条件
  372. /// </summary>
  373. /// <returns></returns>
  374. private bool CheckPreCondition()
  375. {
  376. if (_recipe == null)
  377. {
  378. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "recipe is null");
  379. return false;
  380. }
  381. if (!_temperatureController.IsConnected)
  382. {
  383. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Temperature is not connected");
  384. return false;
  385. }
  386. if (!CheckFacility())
  387. {
  388. return false;
  389. }
  390. return true;
  391. }
  392. /// <summary>
  393. /// 检验facility
  394. /// </summary>
  395. /// <returns></returns>
  396. private bool CheckFacility()
  397. {
  398. SystemFacilities systemFacilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
  399. if (systemFacilities != null)
  400. {
  401. if (!systemFacilities.HouseChilledWaterEnable)
  402. {
  403. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "HouseChilledWaterEnable is false");
  404. return false;
  405. }
  406. if (!systemFacilities.DIFillEnable)
  407. {
  408. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "DIFillEnable is false");
  409. return false;
  410. }
  411. if (!systemFacilities.DIReplenEnable)
  412. {
  413. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "DIReplenEnable is false");
  414. return false;
  415. }
  416. }
  417. else
  418. {
  419. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "DIReplenEnable is false");
  420. return false;
  421. }
  422. return true;
  423. }
  424. }
  425. }