StandardHotReservoirInitializeRoutine.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  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.Persistent.Reservoirs;
  6. using MECF.Framework.Common.RecipeCenter;
  7. using MECF.Framework.Common.Routine;
  8. using System;
  9. using System.Collections.Generic;
  10. using MECF.Framework.Common.Alarm;
  11. using CyberX8_Core;
  12. using CyberX8_RT.Devices.Facilities;
  13. using CyberX8_RT.Devices.Metal;
  14. using CyberX8_RT.Devices.PowerSupplier;
  15. using CyberX8_RT.Devices.Reservoir;
  16. using CyberX8_RT.Devices.Temperature;
  17. using MECF.Framework.Common.ToolLayout;
  18. using Aitex.Core.Util;
  19. namespace CyberX8_RT.Modules.Reservoir
  20. {
  21. public class StandardHotReservoirInitializeRoutine : RoutineBase, IRoutine
  22. {
  23. private enum InitializeStep
  24. {
  25. AutoDiReplen,
  26. CellPump,
  27. WaitCellPump,
  28. WaitRegulatePumpOn,
  29. CheckCellFlow,
  30. ManualCellByPass,
  31. AutoCellManual,
  32. AutoEnableCMM,
  33. AutoEnableCMMWait,
  34. AutoCMMFlowDelay,
  35. AutoCMMFlowCheck,
  36. AutoPHDetect,
  37. AutoCellAutoFlow,
  38. AutoCellAutoFlowDelay,
  39. AutoCellAutoFlowCheck,
  40. AutoCellAutoEnableHED,
  41. AutoCellAutoEnableHEDDelay,
  42. AutoCellAutoEnableHEDCheck,
  43. AutoCellAutoCheckPowerSupplier,
  44. AutoCellAutoLinmotReset,
  45. AutoCellAutoLinmotResetCheck,
  46. CellWSUnclamp,
  47. End
  48. }
  49. #region 常量
  50. private const string AUTO = "Auto";
  51. private const string MANUAL = "Manual";
  52. private const int ENABLE = 5;
  53. #endregion
  54. #region 内部变量
  55. List<StandardHotMetalDevice> _metalDevices = new List<StandardHotMetalDevice>();
  56. private double _cellFlowLowLimit;
  57. private StandardHotReservoirDevice _reservoirDevice;
  58. private ResRecipe _recipe;
  59. private CellPowerSupplier _cellPowerSupplier;
  60. private TemperatureController _temperatureController;
  61. private int _autoHedDelay = 0;
  62. private bool _isRegulatePump;
  63. private int _cellFlowFaultHoldOffTime = 5000;
  64. /// <summary>
  65. /// CMM Check Flow延时
  66. /// </summary>
  67. private int _cmmFlowCheckDelay = 6;
  68. /// <summary>
  69. /// CMM Flow High Fault
  70. /// </summary>
  71. private double _cmmFlowHighFault;
  72. /// <summary>
  73. /// CMM Flow High Warning
  74. /// </summary>
  75. private double _cmmFlowHighWarning;
  76. /// <summary>
  77. /// CMM Flow High Warning
  78. /// </summary>
  79. private double _cmmFlowLowFault;
  80. /// <summary>
  81. /// CMM Flow High Warning
  82. /// </summary>
  83. private double _cmmFlowLowWarning;
  84. /// <summary>
  85. /// Reservoir Persistent
  86. /// </summary>
  87. private ReservoirsPersistentValue _persistentValue;
  88. #endregion
  89. /// <summary>
  90. /// 构造函数
  91. /// </summary>
  92. /// <param name="module"></param>
  93. public StandardHotReservoirInitializeRoutine(string module) : base(module)
  94. {
  95. }
  96. /// <summary>
  97. /// 中止
  98. /// </summary>
  99. public void Abort()
  100. {
  101. Runner.Stop("Manual Abort");
  102. }
  103. /// <summary>
  104. /// 监控
  105. /// </summary>
  106. /// <returns></returns>
  107. public RState Monitor()
  108. {
  109. //Cell Pump
  110. Runner.RunIf(InitializeStep.AutoDiReplen, _recipe.DIReplenEnable, CheckFacilitiesDiReplenStatus, _delay_1ms)
  111. .RunIf(InitializeStep.CellPump, !_isRegulatePump,CellsPumpOn, _delay_1ms)
  112. .WaitWithStopConditionIf(InitializeStep.WaitCellPump, !_isRegulatePump, CheckPumpOnEndStatus, CheckPumpOnStopStatus)
  113. .RunIf(InitializeStep.CellPump, _isRegulatePump, ReservoirPumpOn, _delay_1ms)
  114. .WaitIf(InitializeStep.WaitCellPump, _isRegulatePump, CheckRegulatePumpOn,_delay_3m)
  115. .DelayIf(InitializeStep.WaitRegulatePumpOn,_isRegulatePump, _cellFlowFaultHoldOffTime)
  116. .Run(InitializeStep.CheckCellFlow, CheckCellFlow, _delay_1ms)
  117. //Manual cell Bypass同时disable HED
  118. .RunIf(InitializeStep.ManualCellByPass, _reservoirDevice.OperationMode == MANUAL, CellsByPassEnableHed, _delay_1ms)
  119. //Auto 所有metal 处于Manual, cell Bypass,Enable HED,设置温度
  120. .RunIf(InitializeStep.AutoCellManual, CheckAutoAndAllMetalManual(), AutoCellManualByPassEnableHed, CheckCellManualByPassAndTemperature, _delay_2s)
  121. //Auto 同时recipe enable cmm,并检测CMM Flow
  122. .RunIf(InitializeStep.AutoEnableCMM, CheckAutoEnableCMM(), AutoEnableCMM, _delay_1ms)
  123. .WaitWithStopConditionIf(InitializeStep.AutoEnableCMMWait, CheckAutoEnableCMM(), () => { return _cellPowerSupplier.Status == RState.End; }
  124. , () => { return _cellPowerSupplier.Status == RState.Failed; }, _delay_5s)
  125. .DelayIf(InitializeStep.AutoCMMFlowDelay, CheckAutoEnableCMM(), _cmmFlowCheckDelay * 1000)
  126. .RunIf(InitializeStep.AutoCMMFlowCheck, CheckAutoEnableCMM(), CheckCMMTargetFlow, _delay_1ms)
  127. //Auto 启动PH检测
  128. .RunIf(InitializeStep.AutoPHDetect, _reservoirDevice.OperationMode == AUTO && ReservoirItemManager.Instance.GetReservoirItem(Module.ToString()).PHProbeType == "Standard", StartAutoPHDetect, _delay_1ms)
  129. //Auto Cell Flow
  130. .Run(InitializeStep.AutoCellAutoFlow, AllMetalSwitchFlow, _delay_1ms)
  131. .Delay(InitializeStep.AutoCellAutoFlowDelay, 500)
  132. .Run(InitializeStep.AutoCellAutoFlowCheck, AllMetalCheckFlow, _delay_1ms)
  133. //Auto HED
  134. .Run(InitializeStep.AutoCellAutoEnableHED, AutoHedOn, _delay_1ms)
  135. .Delay(InitializeStep.AutoCellAutoEnableHEDDelay, _autoHedDelay)
  136. .Run(InitializeStep.AutoCellAutoEnableHEDCheck, AutoHedSuccess, _delay_1ms)
  137. //检验PowerSupplier通信
  138. .Run(InitializeStep.AutoCellAutoCheckPowerSupplier, AutoMetalsPowerSupplierCommuncationStatus, _delay_1ms)
  139. //Cell Linmot Reset
  140. .RunIf(InitializeStep.AutoCellAutoLinmotReset, _reservoirDevice.OperationMode == AUTO, AutoMetalResetLinmot, _delay_1ms)
  141. .WaitWithStopCondition(InitializeStep.AutoCellAutoLinmotResetCheck, CheckAutoMetalResetStatus, CheckAutoMetalResetStopStatus)
  142. //Cell Unclamp
  143. .Run(InitializeStep.CellWSUnclamp, MetalsWHUnclampOn, _delay_1ms)
  144. .End(InitializeStep.End, ClearAlarmDataError, _delay_1ms);
  145. return Runner.Status;
  146. }
  147. /// <summary>
  148. /// 检验总Di有没有开
  149. /// </summary>
  150. /// <returns></returns>
  151. private bool CheckFacilitiesDiReplenStatus()
  152. {
  153. SystemFacilities systemFacilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
  154. if (systemFacilities != null)
  155. {
  156. bool result = systemFacilities.DIReplenEnable;
  157. if (!result)
  158. {
  159. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Facilities DiReplen is disable");
  160. }
  161. return result;
  162. }
  163. return false;
  164. }
  165. /// <summary>
  166. /// Metals Pump On
  167. /// </summary>
  168. /// <returns></returns>
  169. private bool CellsPumpOn()
  170. {
  171. for (int i = 0; i < _metalDevices.Count; i++)
  172. {
  173. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  174. hotMetalDevice.OpenPump("", null);
  175. }
  176. return true;
  177. }
  178. /// <summary>
  179. /// Reservoir Pump On
  180. /// </summary>
  181. /// <returns></returns>
  182. private bool ReservoirPumpOn()
  183. {
  184. return _reservoirDevice.RegulatePumpOn("",null);
  185. }
  186. /// <summary>
  187. /// Cell ByPass
  188. /// </summary>
  189. /// <returns></returns>
  190. private bool CellsByPassEnableHed()
  191. {
  192. for (int i = 0; i < _metalDevices.Count; i++)
  193. {
  194. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  195. hotMetalDevice.SwitchToBypass("", null);
  196. }
  197. _temperatureController.EnableOperation("", null);
  198. return true;
  199. }
  200. /// <summary>
  201. /// 检验metal Pump
  202. /// </summary>
  203. /// <returns></returns>
  204. private bool CheckPumpOnEndStatus()
  205. {
  206. int totalCount = 0;
  207. for (int i = 0; i < _metalDevices.Count; i++)
  208. {
  209. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  210. if (hotMetalDevice.Status == RState.End)
  211. {
  212. totalCount++;
  213. }
  214. }
  215. if (totalCount >= _metalDevices.Count)
  216. {
  217. return true;
  218. }
  219. else
  220. {
  221. return false;
  222. }
  223. }
  224. private bool CheckRegulatePumpOn()
  225. {
  226. bool result = _reservoirDevice.ReservoirData.RegulatePumpSignalIn;
  227. return result;
  228. }
  229. /// <summary>
  230. /// 检验metal Pump停止状态
  231. /// </summary>
  232. /// <returns></returns>
  233. private bool CheckPumpOnStopStatus()
  234. {
  235. for (int i = 0; i < _metalDevices.Count; i++)
  236. {
  237. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  238. if (hotMetalDevice.Status == RState.Failed)
  239. {
  240. PumpOffMetals();
  241. return true;
  242. }
  243. }
  244. return false;
  245. }
  246. /// <summary>
  247. /// Pump Off All Metals
  248. /// </summary>
  249. private void PumpOffMetals()
  250. {
  251. for (int i = 0; i < _metalDevices.Count; i++)
  252. {
  253. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  254. hotMetalDevice.ClosePump("",null);
  255. }
  256. }
  257. /// <summary>
  258. /// 检验Cell Flow
  259. /// </summary>
  260. /// <returns></returns>
  261. private bool CheckCellFlow()
  262. {
  263. double toatalCellFlow = 0;
  264. for (int i = 0; i < _metalDevices.Count; i++)
  265. {
  266. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  267. if (hotMetalDevice!=null && hotMetalDevice.MetalDeviceData!=null)
  268. {
  269. toatalCellFlow += hotMetalDevice.MetalDeviceData.CellFlow;
  270. }
  271. }
  272. if (toatalCellFlow < _cellFlowLowLimit)
  273. {
  274. LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} Cell flow:{toatalCellFlow} is less than config item CellFlowLowLimit:{_cellFlowLowLimit}");
  275. return false;
  276. }
  277. return true;
  278. }
  279. /// <summary>
  280. /// 检验所有Metal处于Manual
  281. /// </summary>
  282. /// <returns></returns>
  283. private bool CheckAutoAndAllMetalManual()
  284. {
  285. if (_reservoirDevice.OperationMode != AUTO)
  286. {
  287. return false;
  288. }
  289. for (int i = 0; i < _metalDevices.Count; i++)
  290. {
  291. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  292. if (hotMetalDevice.OperationMode != MANUAL)
  293. {
  294. return false;
  295. }
  296. }
  297. return true;
  298. }
  299. /// <summary>
  300. /// Auto 同时Metal均为Manual,Bypass metal,enable HED,设置温度
  301. /// </summary>
  302. /// <returns></returns>
  303. private bool AutoCellManualByPassEnableHed()
  304. {
  305. for (int i = 0; i < _metalDevices.Count; i++)
  306. {
  307. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  308. hotMetalDevice.SwitchToBypass("", null);
  309. }
  310. _temperatureController.EnableOperation("", null);
  311. _temperatureController.SetTargetTemperatureOperation("", new object[] { _recipe.TemperatureSetPoint });
  312. return true;
  313. }
  314. /// <summary>
  315. /// 检验cell By Pass和温度
  316. /// </summary>
  317. /// <returns></returns>
  318. private bool CheckCellManualByPassAndTemperature()
  319. {
  320. for (int i = 0; i < _metalDevices.Count; i++)
  321. {
  322. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  323. if (hotMetalDevice.MetalDeviceData.Circulation)
  324. {
  325. return false;
  326. }
  327. }
  328. if (_temperatureController.TemperatureData.ControlOperationModel == 0)
  329. {
  330. return false;
  331. }
  332. if (Math.Abs(_recipe.TemperatureSetPoint - _temperatureController.TemperatureData.TargetTemperature) >= 0.1 * _recipe.TemperatureSetPoint)
  333. {
  334. return false;
  335. }
  336. return true;
  337. }
  338. /// <summary>
  339. /// 检验 Auto ,同时Enable CMM
  340. /// </summary>
  341. /// <returns></returns>
  342. private bool CheckAutoEnableCMM()
  343. {
  344. if (_reservoirDevice.OperationMode != AUTO || ReservoirItemManager.Instance.GetReservoirItem(Module.ToString()).CMMType != "Standard")
  345. {
  346. return false;
  347. }
  348. return _recipe.CMMEnable;
  349. }
  350. /// <summary>
  351. /// 自动Enable CMM
  352. /// </summary>
  353. /// <returns></returns>
  354. private bool AutoEnableCMM()
  355. {
  356. return _cellPowerSupplier.SetCurrentAndOutput(_recipe.CMMCurrentSetPoint);
  357. }
  358. /// <summary>
  359. /// 检验目标Flow是否到达设定值
  360. /// </summary>
  361. /// <returns></returns>
  362. private bool CheckCMMTargetFlow()
  363. {
  364. double flow = _reservoirDevice.ReservoirData.Flow;
  365. if (flow < _cmmFlowLowFault)
  366. {
  367. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} CMM flow:{flow} is less than config item CMMFlowLowFault:{_cmmFlowLowFault}");
  368. if (_cellPowerSupplier.PowerSupplierData.Enabled) _cellPowerSupplier.DisableOperation("", null);
  369. return false;
  370. }
  371. else if (flow < _cmmFlowLowWarning)
  372. {
  373. LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} CMM flow:{flow} is less than config item CMMFlowLowWarning:{_cmmFlowLowWarning}");
  374. }
  375. else if (flow > _cmmFlowHighFault)
  376. {
  377. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} CMM flow:{flow} is over config item CMMFlowHighFault:{_cmmFlowLowFault}");
  378. if (_cellPowerSupplier.PowerSupplierData.Enabled) _cellPowerSupplier.DisableOperation("", null);
  379. return false;
  380. }
  381. else if (flow > _cmmFlowHighWarning)
  382. {
  383. LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} CMM flow:{flow} is over config item CMMFlowHighWarning:{_cmmFlowLowWarning}");
  384. }
  385. return true;
  386. }
  387. /// <summary>
  388. /// 启动自动检测
  389. /// </summary>
  390. /// <returns></returns>
  391. private bool StartAutoPHDetect()
  392. {
  393. return _reservoirDevice.StartDetectPHValve();
  394. }
  395. /// <summary>
  396. /// 检验所有Metal处于Manual
  397. /// </summary>
  398. /// <returns></returns>
  399. private bool CheckAutoAndAllMetalAuto()
  400. {
  401. if (_reservoirDevice.OperationMode != AUTO)
  402. {
  403. return false;
  404. }
  405. for (int i = 0; i < _metalDevices.Count; i++)
  406. {
  407. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  408. if (hotMetalDevice.OperationMode != AUTO)
  409. {
  410. return false;
  411. }
  412. }
  413. return true;
  414. }
  415. /// <summary>
  416. /// 所有Metal切换Flow
  417. /// </summary>
  418. /// <returns></returns>
  419. private bool AllMetalSwitchFlow()
  420. {
  421. for (int i = 0; i < _metalDevices.Count; i++)
  422. {
  423. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  424. if (hotMetalDevice != null && !hotMetalDevice.IsDisable && hotMetalDevice.IsAuto)
  425. {
  426. bool result = hotMetalDevice.SwitchToFlow("", null);
  427. if (!result)
  428. {
  429. return false;
  430. }
  431. }
  432. }
  433. return true;
  434. }
  435. /// <summary>
  436. /// 检验所有Metal Flow检验
  437. /// </summary>
  438. /// <returns></returns>
  439. private bool AllMetalCheckFlow()
  440. {
  441. for (int i = 0; i < _metalDevices.Count; i++)
  442. {
  443. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  444. if (hotMetalDevice != null && !hotMetalDevice.IsDisable && hotMetalDevice.IsAuto)
  445. {
  446. double cellFlow = hotMetalDevice.MetalDeviceData.CellFlow;
  447. if (cellFlow <= _recipe.CAFlowRateErrorLow)
  448. {
  449. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"cell {hotMetalDevice.Name} flow {cellFlow} is less than {_recipe.CAFlowRateErrorLow}");
  450. return false;
  451. }
  452. else if (cellFlow <= _recipe.CAFlowRateWarningLow)
  453. {
  454. LOG.WriteLog(eEvent.WARN_METAL, Module, $"cell {hotMetalDevice.Name} flow {cellFlow} is less than {_recipe.CAFlowRateWarningLow}");
  455. }
  456. }
  457. }
  458. return true;
  459. }
  460. /// <summary>
  461. /// 自动HED On
  462. /// </summary>
  463. /// <returns></returns>
  464. private bool AutoHedOn()
  465. {
  466. //double hedFlow = _reservoirDevice.ReservoirData.HedFlow;
  467. //bool result = hedFlow > _hedFlowLowLimit;
  468. //if (!result)
  469. //{
  470. // LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"HED Flow {hedFlow} is less than {_hedFlowLowLimit}");
  471. // return false;
  472. //}
  473. _autoHedDelay = _delay_2s;
  474. _temperatureController.EnableOperation("", null);
  475. _temperatureController.SetTargetTemperatureOperation("", new object[] { _recipe.TemperatureSetPoint });
  476. return true;
  477. }
  478. /// <summary>
  479. /// 检验Hed是否成功
  480. /// </summary>
  481. /// <returns></returns>
  482. private bool AutoHedSuccess()
  483. {
  484. if (_temperatureController.TemperatureData.ControlOperationModel == 0)
  485. {
  486. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Temperature control is disable");
  487. return false;
  488. }
  489. if (Math.Abs(_recipe.TemperatureSetPoint - _temperatureController.TemperatureData.TargetTemperature) >= 0.1 * _recipe.TemperatureSetPoint)
  490. {
  491. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"recipe temperature {_recipe.TemperatureSetPoint} is not match temperature target point {_temperatureController.TemperatureData.TargetTemperature}");
  492. return false;
  493. }
  494. return true;
  495. }
  496. /// <summary>
  497. /// 检验Metal A/B PowerSupplier通信状态
  498. /// </summary>
  499. /// <returns></returns>
  500. private bool AutoMetalsPowerSupplierCommuncationStatus()
  501. {
  502. for (int i = 0; i < _metalDevices.Count; i++)
  503. {
  504. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  505. if (!hotMetalDevice.IsDisable && hotMetalDevice.IsAuto)
  506. {
  507. if (hotMetalDevice.SideAPowerSupplier == null)
  508. {
  509. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Side A PowerSupplier is null");
  510. return false;
  511. }
  512. if (hotMetalDevice.SideBPowerSupplier == null)
  513. {
  514. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Side B PowerSupplier is null");
  515. return false;
  516. }
  517. if (!hotMetalDevice.SideAPowerSupplier.IsConnected)
  518. {
  519. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Side A PowerSupplier {hotMetalDevice.SideAPowerSupplier.Name} is not connected");
  520. return false;
  521. }
  522. if (!hotMetalDevice.SideBPowerSupplier.IsConnected)
  523. {
  524. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Side B PowerSupplier {hotMetalDevice.SideBPowerSupplier.Name} is not connected");
  525. return false;
  526. }
  527. }
  528. }
  529. return true;
  530. }
  531. /// <summary>
  532. /// Auto Metal reset linmot
  533. /// </summary>
  534. /// <returns></returns>
  535. private bool AutoMetalResetLinmot()
  536. {
  537. for (int i = 0; i < _metalDevices.Count; i++)
  538. {
  539. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  540. if (hotMetalDevice.OperationMode == AUTO)
  541. {
  542. bool result = hotMetalDevice.ResetLinmot();
  543. if (!result)
  544. {
  545. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Reset linmot error");
  546. return false;
  547. }
  548. }
  549. }
  550. return true;
  551. }
  552. /// <summary>
  553. /// Auto Metal reset linmot
  554. /// </summary>
  555. /// <returns></returns>
  556. private bool CheckAutoMetalResetStatus()
  557. {
  558. if (_reservoirDevice.OperationMode == MANUAL)
  559. {
  560. return true;
  561. }
  562. for (int i = 0; i < _metalDevices.Count; i++)
  563. {
  564. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  565. if (hotMetalDevice.OperationMode == AUTO)
  566. {
  567. bool result = hotMetalDevice.CheckLinmotRoutineEnd();
  568. if (!result)
  569. {
  570. return false;
  571. }
  572. }
  573. }
  574. return true;
  575. }
  576. /// <summary>
  577. /// Auto Metal reset linmot
  578. /// </summary>
  579. /// <returns></returns>
  580. private bool CheckAutoMetalResetStopStatus()
  581. {
  582. if (_reservoirDevice.OperationMode == MANUAL)
  583. {
  584. return false;
  585. }
  586. for (int i = 0; i < _metalDevices.Count; i++)
  587. {
  588. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  589. if (hotMetalDevice.OperationMode == AUTO)
  590. {
  591. bool result = hotMetalDevice.CheckLinmotRoutineError();
  592. if (result)
  593. {
  594. return true;
  595. }
  596. }
  597. }
  598. return false;
  599. }
  600. /// Metal WS Unclamp
  601. /// </summary>
  602. /// <returns></returns>
  603. private bool MetalsWHUnclampOn()
  604. {
  605. for (int i = 0; i < _metalDevices.Count; i++)
  606. {
  607. StandardHotMetalDevice hotMetalDevice = _metalDevices[i];
  608. bool result = hotMetalDevice.WaferHolderClampOff("", null);
  609. if (!result)
  610. {
  611. return false;
  612. }
  613. }
  614. return true;
  615. }
  616. /// <summary>
  617. /// 清除alarm界面相关的dataerror
  618. /// </summary>
  619. private bool ClearAlarmDataError()
  620. {
  621. AlarmListManager.Instance.RemoveDataError(Module);
  622. _reservoirDevice.ClearErrorLogSet(Module); //清除device里面的ErrorLogSet
  623. return true;
  624. }
  625. /// <summary>
  626. /// 启动
  627. /// </summary>
  628. /// <param name="objs"></param>
  629. /// <returns></returns>
  630. public RState Start(params object[] objs)
  631. {
  632. List<MetalCellDevice> lstDevice = (List<MetalCellDevice>)objs[0];
  633. _metalDevices.Clear();
  634. for (int i = 0; i < lstDevice.Count; i++)
  635. {
  636. _metalDevices.Add((StandardHotMetalDevice)lstDevice[i]);
  637. }
  638. if (ReservoirItemManager.Instance.GetReservoirItem(Module.ToString()).PumpType == "Regulate")
  639. {
  640. _isRegulatePump = true;
  641. }
  642. _reservoirDevice = DEVICE.GetDevice<StandardHotReservoirDevice>(Module.ToString());
  643. _recipe = _reservoirDevice.Recipe;
  644. if (!(objs[1] is null))
  645. {
  646. _cellPowerSupplier = (CellPowerSupplier)objs[1];
  647. }
  648. _temperatureController = (TemperatureController)objs[2];
  649. _cellFlowLowLimit = SC.GetValue<double>($"Reservoir.{Module}.CellFlowLowLimit");
  650. if (!CheckPreCondition())
  651. {
  652. return RState.Failed;
  653. }
  654. if (ReservoirItemManager.Instance.GetReservoirItem(Module.ToString()).CMMType == "Standard")
  655. {
  656. _cmmFlowHighFault = SC.GetValue<double>($"Reservoir.{Module}.CMMFlowHighFault");
  657. _cmmFlowHighWarning = SC.GetValue<double>($"Reservoir.{Module}.CMMFlowHighWarning");
  658. _cmmFlowLowFault = SC.GetValue<double>($"Reservoir.{Module}.CMMFlowLowFault");
  659. _cmmFlowLowWarning = SC.GetValue<double>($"Reservoir.{Module}.CMMFlowLowWarning");
  660. _cmmFlowCheckDelay = SC.GetValue<int>($"Reservoir.{Module}.CMMFlowCheckDelaySeconds");
  661. }
  662. if (_recipe.CMMEnable)
  663. {
  664. _persistentValue = ReservoirsPersistentManager.Instance.GetReservoirsPersistentValue(Module);
  665. }
  666. _cellFlowFaultHoldOffTime = SC.GetValue<int>("Metal.CellFlowFaultHoldOffTime");
  667. return Runner.Start(Module, "Start Initialize");
  668. }
  669. /// <summary>
  670. /// 检验前置条件
  671. /// </summary>
  672. /// <returns></returns>
  673. private bool CheckPreCondition()
  674. {
  675. if (_recipe == null)
  676. {
  677. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "recipe is null");
  678. return false;
  679. }
  680. if (_recipe.CMMEnable && _cellPowerSupplier != null && !_cellPowerSupplier.IsConnected)
  681. {
  682. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "PowerSupplier is not connected");
  683. return false;
  684. }
  685. if (!_temperatureController.IsConnected)
  686. {
  687. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Temperature is not connected");
  688. return false;
  689. }
  690. WaterLevelMonitor();
  691. return true;
  692. }
  693. /// <summary>
  694. /// WaterLevelMonitor
  695. /// </summary>
  696. private bool WaterLevelMonitor()
  697. {
  698. ReservoirEntity reservoirEntity = Singleton<RouteManager>.Instance.GetModule<ReservoirEntity>(Module);
  699. //触发水位过高或者过低将reservoir切成error
  700. if (_reservoirDevice.ReservoirData.WaterLevel < SC.GetValue<double>($"Reservoir.{Module}.LowLevel"))
  701. {
  702. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"WaterLevel low is Activate");
  703. return false;
  704. }
  705. else if (_reservoirDevice.ReservoirData.WaterLevel > SC.GetValue<double>($"Reservoir.{Module}.HighLevel"))
  706. {
  707. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"WaterLevel:{_reservoirDevice.ReservoirData.WaterLevel} is larger than HighLevel Config:{SC.GetValue<double>($"Reservoir.{Module}.HighLevel")}");
  708. return false;
  709. }
  710. //水位触发reservoir里面的high/low将对应的reservoir切成error
  711. if (_reservoirDevice.ReservoirData.Level < _recipe.CALevelErrorLow)
  712. {
  713. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Current level:{_reservoirDevice.ReservoirData.Level} is lower than recipe's CA Errorlow paramater:{_recipe.CALevelErrorLow}");
  714. return false;
  715. }
  716. else if (_reservoirDevice.ReservoirData.Level > _recipe.CALevelErrorHigh)
  717. {
  718. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Current level:{_reservoirDevice.ReservoirData.Level} is larger than recipe's CA ErrorHigh paramater:{_recipe.CALevelErrorHigh}");
  719. return false ;
  720. }
  721. return true;
  722. }
  723. }
  724. }