DMReservoirInitializeRoutine.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  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. if(_dmReservoirDevice.ReservoirData.CaFlow < _cellFlowStartLowLimit)
  105. {
  106. _dmReservoirDevice.AnPumpOff();
  107. _dmReservoirDevice.ANIsolationOff();
  108. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "CA Flow is less than cellFlowStartLowLimit ");
  109. return false;
  110. }
  111. if(_dmReservoirDevice.ReservoirData.AnFlow < _anFlowStartLowLimit)
  112. {
  113. _dmReservoirDevice.AnPumpOff();
  114. _dmReservoirDevice.ANIsolationOff();
  115. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "AN Flow is less than ANFlowStartLowLimit");
  116. return false;
  117. }
  118. return true;
  119. }
  120. /// <summary>
  121. /// 检查cell flow 和an flow是否大于recipe的设定
  122. /// </summary>
  123. /// <returns></returns>
  124. private bool AutoCheckFlow()
  125. {
  126. if (_dmReservoirDevice.ReservoirData.CaFlow < _recipe.CAFlowRateErrorLow)
  127. {
  128. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "CA Flow is less than recipe CAFlowRateErrorLow");
  129. return false;
  130. }
  131. if (_dmReservoirDevice.ReservoirData.AnFlow < _recipe.ANFlowRateErrorLow)
  132. {
  133. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "AN Flow is less than recipe ANFlowRateErrorLow");
  134. return false;
  135. }
  136. return true;
  137. }
  138. /// <summary>
  139. /// 检验总Di有没有开
  140. /// </summary>
  141. /// <returns></returns>
  142. private bool CheckFacilitiesDiReplenStatus()
  143. {
  144. SystemFacilities systemFacilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
  145. if (systemFacilities != null)
  146. {
  147. bool result = systemFacilities.DIReplenEnable;
  148. if (!result)
  149. {
  150. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Facilities DiReplen is disable");
  151. }
  152. return result;
  153. }
  154. return false;
  155. }
  156. /// <summary>
  157. /// 启用HED
  158. /// </summary>
  159. /// <returns></returns>
  160. private bool EnableHED()
  161. {
  162. return _temperatureController.EnableOperation("", null);
  163. }
  164. /// <summary>
  165. /// 检验所有Metal处于Manual
  166. /// </summary>
  167. /// <returns></returns>
  168. private bool CheckAutoAndAllMetalAuto()
  169. {
  170. //if (_reservoirDevice.OperationMode != AUTO)
  171. //{
  172. // return false;
  173. //}
  174. //for (int i = 0; i < _metalDevices.Count; i++)
  175. //{
  176. // CompactMembranMetalDevice hotMetalDevice = _metalDevices[i];
  177. // if (hotMetalDevice.OperationMode != AUTO)
  178. // {
  179. // return false;
  180. // }
  181. //}
  182. return true;
  183. }
  184. /// <summary>
  185. /// 自动HED On
  186. /// </summary>
  187. /// <returns></returns>
  188. private bool AutoHedOn()
  189. {
  190. bool result = _dmReservoirDevice.ReservoirData.CaFlow < _cellFlowStartLowLimit;
  191. if (result)
  192. {
  193. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"CA Flow {_dmReservoirDevice.ReservoirData.CaFlow} is less than CellFlowStartLowLimit{_cellFlowStartLowLimit}");
  194. return false;
  195. }
  196. result = _temperatureController.EnableOperation("", null);
  197. if (!result)
  198. {
  199. return false;
  200. }
  201. result = _temperatureController.SetTargetTemperatureOperation("", new object[] { _recipe.TemperatureSetPoint });
  202. if (!result)
  203. {
  204. return false;
  205. }
  206. return true;
  207. }
  208. /// <summary>
  209. /// 检验Hed是否成功
  210. /// </summary>
  211. /// <returns></returns>
  212. private bool AutoHedSuccess()
  213. {
  214. if (_temperatureController.TemperatureData.ControlOperationModel == 0)
  215. {
  216. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Temperature control is disable");
  217. return false;
  218. }
  219. if (Math.Abs(_recipe.TemperatureSetPoint - _temperatureController.TemperatureData.TargetTemperature) >= 0.1 * _recipe.TemperatureSetPoint)
  220. {
  221. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"recipe temperature {_recipe.TemperatureSetPoint} is not match temperature target point {_temperatureController.TemperatureData.TargetTemperature}");
  222. return false;
  223. }
  224. return true;
  225. }
  226. /// <summary>
  227. /// 检验Metal A/B PowerSupplier通信状态
  228. /// </summary>
  229. /// <returns></returns>
  230. private bool AutoMetalsPowerSupplierCommuncationStatus()
  231. {
  232. //for (int i = 0; i < _metalDevices.Count; i++)
  233. //{
  234. // CompactMembranMetalDevice hotMetalDevice = _metalDevices[i];
  235. // if (hotMetalDevice.IsAuto)
  236. // {
  237. // if (hotMetalDevice.SideAPowerSupplier == null)
  238. // {
  239. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Side A PowerSupplier is null");
  240. // return false;
  241. // }
  242. // if (hotMetalDevice.SideBPowerSupplier == null)
  243. // {
  244. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Side B PowerSupplier is null");
  245. // return false;
  246. // }
  247. // if (!hotMetalDevice.SideAPowerSupplier.IsConnected)
  248. // {
  249. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Side A PowerSupplier {hotMetalDevice.SideAPowerSupplier.Name} is not connected");
  250. // return false;
  251. // }
  252. // if (!hotMetalDevice.SideBPowerSupplier.IsConnected)
  253. // {
  254. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Side B PowerSupplier {hotMetalDevice.SideBPowerSupplier.Name} is not connected");
  255. // return false;
  256. // }
  257. // }
  258. //}
  259. return true;
  260. }
  261. /// <summary>
  262. /// Auto Metal reset linmot
  263. /// </summary>
  264. /// <returns></returns>
  265. private bool AutoMetalResetLinmot()
  266. {
  267. //for (int i = 0; i < _metalDevices.Count; i++)
  268. //{
  269. // CompactMembranMetalDevice hotMetalDevice = _metalDevices[i];
  270. // if (hotMetalDevice.OperationMode == AUTO)
  271. // {
  272. // bool result = hotMetalDevice.ResetLinmot();
  273. // if (!result)
  274. // {
  275. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Reset linmot error");
  276. // return false;
  277. // }
  278. // }
  279. //}
  280. return true;
  281. }
  282. /// <summary>
  283. /// Auto Metal reset linmot
  284. /// </summary>
  285. /// <returns></returns>
  286. private bool CheckAutoMetalResetStatus()
  287. {
  288. //if (_reservoirDevice.OperationMode == MANUAL)
  289. //{
  290. // return true;
  291. //}
  292. //for (int i = 0; i < _metalDevices.Count; i++)
  293. //{
  294. // CompactMembranMetalDevice metalDevice = _metalDevices[i];
  295. // if (metalDevice.OperationMode == AUTO)
  296. // {
  297. // bool result = metalDevice.CheckLinmotRoutineEnd();
  298. // if (!result)
  299. // {
  300. // return false;
  301. // }
  302. // }
  303. //}
  304. return true;
  305. }
  306. /// <summary>
  307. /// Auto Metal reset linmot
  308. /// </summary>
  309. /// <returns></returns>
  310. private bool CheckAutoMetalResetStopStatus()
  311. {
  312. //if (_reservoirDevice.OperationMode == MANUAL)
  313. //{
  314. // return false;
  315. //}
  316. //for (int i = 0; i < _metalDevices.Count; i++)
  317. //{
  318. // CompactMembranMetalDevice hotMetalDevice = _metalDevices[i];
  319. // if (hotMetalDevice.OperationMode == AUTO)
  320. // {
  321. // bool result = hotMetalDevice.CheckLinmotRoutineError();
  322. // if (result)
  323. // {
  324. // return true;
  325. // }
  326. // }
  327. //}
  328. return false;
  329. }
  330. /// Metal WS Unclamp
  331. /// </summary>
  332. /// <returns></returns>
  333. private bool MetalsWHUnclampOn()
  334. {
  335. //for (int i = 0; i < _metalDevices.Count; i++)
  336. //{
  337. // CompactMembranMetalDevice hotMetalDevice = _metalDevices[i];
  338. // if (hotMetalDevice != null && !hotMetalDevice.IsDisable)
  339. // {
  340. // bool result = hotMetalDevice.WaferHolderUnclampOn("", null);
  341. // if (!result)
  342. // {
  343. // return false;
  344. // }
  345. // }
  346. //}
  347. //_reservoirDevice.InitializeCrossDose(true);
  348. return true;
  349. }
  350. /// <summary>
  351. /// 清除alarm界面相关的dataerror
  352. /// </summary>
  353. private bool ClearAlarmDataError()
  354. {
  355. //AlarmListManager.Instance.RemoveDataError(Module);
  356. //_dmReservoirDevice.ClearErrorLogSet(Module); //清除device里面的ErrorLogSet
  357. return true;
  358. }
  359. /// <summary>
  360. /// 启动
  361. /// </summary>
  362. /// <param name="objs"></param>
  363. /// <returns></returns>
  364. public RState Start(params object[] objs)
  365. {
  366. _caPumpOnRoutine = new CAPumpOnRoutine(Module);
  367. _anPumpOnRoutine = new ANPumpOnRoutine(Module);
  368. _dmReservoirDevice = DEVICE.GetDevice<DMReservoirDevice>(Module);
  369. //_dmReservoirDevice.ClearErrorLogSet(Module);
  370. _platingCellDevices = (PlatingCellDevice)objs[0];
  371. _temperatureController = (TemperatureController)objs[1];
  372. _recipe = _dmReservoirDevice.Recipe;
  373. _flowFaultHoldOffTime = SC.GetValue<int>($"PlatingCell.FlowFaultHoldOffTime");
  374. _cellFlowStartLowLimit = SC.GetValue<double>($"PlatingCell.CellFlowStartLowLimit");
  375. _anFlowStartLowLimit = SC.GetValue<double>($"PlatingCell.ANFlowStartLowLimit");
  376. if (!CheckPreCondition())
  377. {
  378. return RState.Failed;
  379. }
  380. return Runner.Start(Module, "Start D&M Initialize");
  381. }
  382. /// <summary>
  383. /// 检验前置条件
  384. /// </summary>
  385. /// <returns></returns>
  386. private bool CheckPreCondition()
  387. {
  388. if (_recipe == null)
  389. {
  390. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "recipe is null");
  391. return false;
  392. }
  393. if (!_temperatureController.IsConnected)
  394. {
  395. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Temperature is not connected");
  396. return false;
  397. }
  398. if (!CheckFacility())
  399. {
  400. return false;
  401. }
  402. return true;
  403. }
  404. /// <summary>
  405. /// 检验facility
  406. /// </summary>
  407. /// <returns></returns>
  408. private bool CheckFacility()
  409. {
  410. SystemFacilities systemFacilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
  411. if (systemFacilities != null)
  412. {
  413. if (!systemFacilities.HouseChilledWaterEnable)
  414. {
  415. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "HouseChilledWaterEnable is false");
  416. return false;
  417. }
  418. if (!systemFacilities.DIFillEnable)
  419. {
  420. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "DIFillEnable is false");
  421. return false;
  422. }
  423. if (!systemFacilities.DIReplenEnable)
  424. {
  425. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "DIReplenEnable is false");
  426. return false;
  427. }
  428. }
  429. else
  430. {
  431. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "DIReplenEnable is false");
  432. return false;
  433. }
  434. return true;
  435. }
  436. }
  437. }