PlatingCellEntity.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.DataCenter;
  3. using Aitex.Core.RT.Device;
  4. using Aitex.Core.RT.Fsm;
  5. using Aitex.Core.RT.Log;
  6. using Aitex.Core.RT.OperationCenter;
  7. using Aitex.Core.RT.RecipeCenter;
  8. using Aitex.Core.RT.SCCore;
  9. using Aitex.Core.Util;
  10. using Aitex.Core.Utilities;
  11. using CyberX12_RT.Modules.VpwCell;
  12. using MECF.Framework.Common.Equipment;
  13. using MECF.Framework.Common.Persistent.Reservoirs;
  14. using MECF.Framework.Common.ProcessCell;
  15. using MECF.Framework.Common.RecipeCenter;
  16. using MECF.Framework.Common.Routine;
  17. using MECF.Framework.Common.SubstrateTrackings;
  18. using MECF.Framework.Common.ToolLayout;
  19. using MECF.Framework.RT.Core.Equipments;
  20. using PunkHPX8_Core;
  21. using PunkHPX8_RT.Devices.PlatingCell;
  22. using PunkHPX8_RT.Devices.PowerSupplier;
  23. using PunkHPX8_RT.Devices.Reservoir;
  24. using PunkHPX8_RT.Devices.Temperature;
  25. using PunkHPX8_RT.Modules.Reservoir;
  26. using PunkHPX8_RT.Modules.VpwCell;
  27. using PunkHPX8_RT.Modules.VpwMain;
  28. using System;
  29. using System.Collections.Generic;
  30. using System.Linq;
  31. using System.Text;
  32. using System.Threading.Tasks;
  33. namespace PunkHPX8_RT.Modules.PlatingCell
  34. {
  35. public class PlatingCellEntity : Entity, IEntity, IModuleEntity
  36. {
  37. public enum PlatingCellMsg
  38. {
  39. NONE,
  40. Error,
  41. ResumeError,
  42. Initialize,
  43. Manual,
  44. Auto,
  45. CloseFlowValve,
  46. OpenFlowValve,
  47. RunRecipe,
  48. Abort,
  49. Init,
  50. CCR,
  51. CCRAbort
  52. }
  53. #region 常量
  54. private const string STRATUS = "Stratus";
  55. private const string AUTO = "Auto";
  56. private const string MANUAL = "Manual";
  57. private const string DISABLED = "Disabled";
  58. private const string ENGINEERING = "Engineering";
  59. private const string PRODUCTION = "Production";
  60. #endregion
  61. #region 内部变量
  62. /// <summary>
  63. /// 持久化数值
  64. /// </summary>
  65. private PlatingCellPersistentValue _persistentValue;
  66. /// <summary>
  67. /// 当前recipe
  68. /// </summary>
  69. private DepRecipe _currentRecipe;
  70. /// <summary>
  71. /// recipe时间
  72. /// </summary>
  73. private int _recipeTime;
  74. /// <summary>
  75. /// c&m Initialize routine
  76. /// </summary>
  77. private PlatingCellInitializeRoutine _initializeRoutine;
  78. /// <summary>
  79. /// CCR routine
  80. /// </summary>
  81. private PlatingCellCCRRoutine _platingCellCRRoutine;
  82. /// <summary>
  83. /// Run recipe routine
  84. /// </summary>
  85. private PlatingCellRunRecipeRoutine _runRecipeRoutine;
  86. #endregion
  87. #region 属性
  88. /// <summary>
  89. /// 模块名称
  90. /// </summary>
  91. public ModuleName Module { get; private set; }
  92. /// <summary>
  93. /// 是否Init
  94. /// </summary>
  95. public bool IsInit
  96. {
  97. get { return fsm.State == (int)PlatingCellState.Init; }
  98. }
  99. /// <summary>
  100. /// 是否Idle
  101. /// </summary>
  102. public bool IsIdle
  103. {
  104. get
  105. {
  106. return fsm.State == (int)PlatingCellState.Idle;
  107. }
  108. }
  109. /// <summary>
  110. /// 是否错误
  111. /// </summary>
  112. public bool IsError
  113. {
  114. get { return fsm.State == (int)PlatingCellState.Error; }
  115. }
  116. /// <summary>
  117. /// 正在忙碌
  118. /// </summary>
  119. public bool IsBusy
  120. {
  121. get { return fsm.State == (int)PlatingCellState.Initializing; }
  122. }
  123. /// <summary>
  124. /// 化学液
  125. /// </summary>
  126. public string Chemistry
  127. {
  128. get { return _currentRecipe != null ? _currentRecipe.Chemistry : ""; }
  129. }
  130. /// <summary>
  131. /// 是否禁用
  132. /// </summary>
  133. public bool IsDisable { get { return _persistentValue == null || _persistentValue.OperatingMode == DISABLED; } }
  134. /// <summary>
  135. /// 自动模式
  136. /// </summary>
  137. public bool IsAuto { get { return _persistentValue != null && _persistentValue.OperatingMode == AUTO; } }
  138. /// <summary>
  139. /// 自动模式
  140. /// </summary>
  141. public bool IsManual { get { return _persistentValue != null && _persistentValue.OperatingMode == MANUAL; } }
  142. /// <summary>
  143. /// 是否为工程模式
  144. /// </summary>
  145. public bool IsEngineering { get { return _persistentValue != null && _persistentValue.RecipeOperatingMode == ENGINEERING; } }
  146. /// <summary>
  147. /// 是否为产品模式
  148. /// </summary>
  149. public bool IsProduction { get { return _persistentValue != null && _persistentValue.RecipeOperatingMode == PRODUCTION; } }
  150. /// <summary>
  151. /// 当前状态机状态
  152. /// </summary>
  153. public int State { get { return fsm.State; } }
  154. /// <summary>
  155. /// 是否初始化完成
  156. /// </summary>
  157. public bool IsInitialized { get { return fsm.State >= (int)PlatingCellState.Initialized; } }
  158. /// <summary>
  159. /// Reservoir项
  160. /// </summary>
  161. private ReservoirItem _reservoirItem;
  162. /// <summary>
  163. /// Wafer信息
  164. /// </summary>
  165. public WaferInfo WaferInfo { get { return WaferManager.Instance.GetWafer(Module,0); } }
  166. /// <summary>
  167. /// 当前Metal设置的WaferSize
  168. /// </summary>
  169. public int MetalWaferSize { get { return _persistentValue.PlatingCellWaferSize; } }
  170. #endregion
  171. /// <summary>
  172. /// 构造函数
  173. /// </summary>
  174. /// <param name="module"></param>
  175. public PlatingCellEntity(ModuleName module)
  176. {
  177. this.Module = module;
  178. InitialFsm();
  179. }
  180. /// <summary>
  181. /// 初始化
  182. /// </summary>
  183. /// <returns></returns>
  184. protected override bool Init()
  185. {
  186. WaferManager.Instance.SubscribeLocation(Module, 1);
  187. InitializeRoutine();
  188. InitializeDATA();
  189. InitializeOperation();
  190. InitializeParameter();
  191. return true;
  192. }
  193. /// <summary>
  194. /// 初始化参数
  195. /// </summary>
  196. private void InitializeParameter()
  197. {
  198. _persistentValue = PlatingCellPersistentManager.Instance.GetPlatingCellPersistentValue(Module.ToString());
  199. if (_persistentValue == null)
  200. {
  201. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module.ToString(), "Persistent Value Object is not exist");
  202. }
  203. }
  204. /// <summary>
  205. /// 初始化Routine
  206. /// </summary>
  207. private void InitializeRoutine()
  208. {
  209. _initializeRoutine = new PlatingCellInitializeRoutine(Module.ToString());
  210. _platingCellCRRoutine = new PlatingCellCCRRoutine(Module.ToString());
  211. _runRecipeRoutine=new PlatingCellRunRecipeRoutine(Module.ToString());
  212. }
  213. /// <summary>
  214. /// 初始化DATA
  215. /// </summary>
  216. private void InitializeDATA()
  217. {
  218. DATA.Subscribe($"{Module}.FsmState", () => ((PlatingCellState)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
  219. DATA.Subscribe($"{Module}.CurrentRecipe", () => _currentRecipe != null ? _currentRecipe.Ppid : "", SubscriptionAttribute.FLAG.IgnoreSaveDB);
  220. DATA.Subscribe($"{Module}.TotalTime", () => _recipeTime, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  221. DATA.Subscribe($"{Module}.TimeRemain", () => _recipeTime != 0 && _runRecipeRoutine != null ? (_recipeTime - Math.Round((double)_runRecipeRoutine.ElapsedMilliseconds / 1000, 0)) : 0, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  222. DATA.Subscribe($"{Module}.Chemistry", () => _currentRecipe != null ? _currentRecipe.Chemistry : "", SubscriptionAttribute.FLAG.IgnoreSaveDB);
  223. DATA.Subscribe($"{Module}.IsInit", () => IsInit, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  224. DATA.Subscribe($"{Module}.IsIdle", () => IsIdle, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  225. DATA.Subscribe($"{Module}.IsError", () => IsError, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  226. DATA.Subscribe($"{Module}.IsBusy", () => IsBusy, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  227. DATA.Subscribe($"{Module}.IsDisable", () => IsDisable, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  228. }
  229. /// <summary>
  230. /// 初始化Operation
  231. /// </summary>
  232. private void InitializeOperation()
  233. {
  234. OP.Subscribe($"{Module}.InitializeAll", (cmd, args) => { return CheckToPostMessage<PlatingCellState, PlatingCellMsg>(eEvent.ERR_RESERVOIR, Module.ToString(), (int)PlatingCellMsg.Initialize); });
  235. OP.Subscribe($"{Module}.ManualCCRStart", (cmd, args) => { return CheckToPostMessage<PlatingCellState, PlatingCellMsg>(eEvent.ERR_RESERVOIR, Module.ToString(), (int)PlatingCellMsg.CCR); });
  236. OP.Subscribe($"{Module}.ManualCCRStop", (cmd, args) => { return CheckToPostMessage<PlatingCellState, PlatingCellMsg>(eEvent.ERR_RESERVOIR, Module.ToString(), (int)PlatingCellMsg.CCRAbort); });
  237. }
  238. /// 初始化状态机
  239. /// </summary>
  240. private void InitialFsm()
  241. {
  242. fsm = new StateMachine<PlatingCellEntity>(Module.ToString(), (int)PlatingCellState.Idle, 100);
  243. fsm.EnableRepeatedMsg(true);
  244. AnyStateTransition(PlatingCellMsg.Error, NullFunc, PlatingCellState.Error);
  245. //Initialized
  246. Transition(PlatingCellState.Error, PlatingCellMsg.Initialize, InitializeAll, PlatingCellState.Initializing);
  247. Transition(PlatingCellState.Init, PlatingCellMsg.Initialize, InitializeAll, PlatingCellState.Initializing);
  248. Transition(PlatingCellState.Idle, PlatingCellMsg.Initialize, InitializeAll, PlatingCellState.Initializing);
  249. Transition(PlatingCellState.Initializing, FSM_MSG.TIMER, InitializeAllMonitor, PlatingCellState.Idle);
  250. //CCR
  251. Transition(PlatingCellState.Idle, PlatingCellMsg.CCR, ManualCCRStart, PlatingCellState.CCRing);
  252. Transition(PlatingCellState.CCRing, FSM_MSG.TIMER, CCRMonitor, PlatingCellState.Idle);
  253. Transition(PlatingCellState.CCRing, PlatingCellMsg.CCRAbort, CCRAbort, PlatingCellState.Init);
  254. //Cycle Manual Process
  255. Transition(PlatingCellState.Idle, PlatingCellMsg.RunRecipe, CycleManualProcess, PlatingCellState.RunReciping);
  256. Transition(PlatingCellState.RunReciping, FSM_MSG.TIMER, CycleManualMonitor, PlatingCellState.Idle);
  257. Transition(PlatingCellState.RunReciping, VPWCellMsg.Abort, RunRecipeAbort, PlatingCellState.Idle);
  258. //直接进入Idle
  259. Transition(PlatingCellState.Initialized, FSM_MSG.TIMER, NullFunc, PlatingCellState.Idle);
  260. //Enter Init
  261. Transition(PlatingCellState.Idle, PlatingCellMsg.Init, NullFunc, PlatingCellState.Init);
  262. EnumLoop<PlatingCellState>.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
  263. EnumLoop<PlatingCellState>.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
  264. }
  265. /// <summary>
  266. /// 手动CCR
  267. /// </summary>
  268. /// <returns></returns>
  269. private bool ManualCCRStart(object[] param)
  270. {
  271. bool result = _platingCellCRRoutine.Start() == RState.Running;
  272. return result;
  273. }
  274. /// <summary>
  275. /// CCR 监控
  276. /// </summary>
  277. /// <param name="param"></param>
  278. /// <returns></returns>
  279. private bool CCRMonitor(object[] param)
  280. {
  281. RState rsstate = RState.Running;
  282. rsstate = _platingCellCRRoutine.Monitor();
  283. if (rsstate == RState.End)
  284. {
  285. return true;
  286. }
  287. else if (rsstate == RState.Failed || rsstate == RState.Timeout)
  288. {
  289. PostMsg(PlatingCellMsg.Error);
  290. return false;
  291. }
  292. return false;
  293. }
  294. /// <summary>
  295. /// CCR abort
  296. /// </summary>
  297. /// <param name="param"></param>
  298. /// <returns></returns>
  299. private bool CCRAbort(object[] param)
  300. {
  301. if(_platingCellCRRoutine.Monitor() == RState.Running)
  302. {
  303. _platingCellCRRoutine.Abort();
  304. }
  305. return true;
  306. }
  307. /// <summary>
  308. /// 初始化
  309. /// </summary>
  310. /// <returns></returns>
  311. private bool InitializeAll(object[] param)
  312. {
  313. if (_persistentValue == null)
  314. {
  315. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module.ToString(), "persistent is null");
  316. return false;
  317. }
  318. if (fsm.State == (int)PlatingCellState.Initializing)
  319. {
  320. LOG.WriteLog(eEvent.WARN_PLATINGCELL, Module.ToString(), "state is Initializing,cannot do initialize");
  321. return false;
  322. }
  323. if (!CheckReservoirInitialized())
  324. {
  325. LOG.WriteLog(eEvent.ERR_METAL, Module.ToString(), "Reservoir is not initialized");
  326. return false;
  327. }
  328. if (!MetalUsageMointor(Module.ToString()))
  329. {
  330. return false;
  331. }
  332. if ("Auto".Equals(_persistentValue.OperatingMode))
  333. {
  334. if (!CheckReservoirIsAuto())
  335. {
  336. LOG.WriteLog(eEvent.ERR_METAL, Module.ToString(), "Reservoir is not in Auto OperationMode");
  337. return false;
  338. }
  339. }
  340. bool result = _initializeRoutine.Start(_persistentValue) == RState.Running;
  341. return result;
  342. }
  343. /// <summary>
  344. /// 检验Reservoir是否Auto
  345. /// </summary>
  346. /// <returns></returns>
  347. private bool CheckReservoirIsAuto()
  348. {
  349. string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module.ToString());
  350. ReservoirsPersistentValue reservoirsPersistentValue = ReservoirsPersistentManager.Instance.GetReservoirsPersistentValue(reservoir);
  351. if ("Auto".Equals(reservoirsPersistentValue.OperatingMode))
  352. {
  353. return true;
  354. }
  355. return false;
  356. }
  357. /// <summary>
  358. /// 检验Reservoir是否Initialized
  359. /// </summary>
  360. /// <returns></returns>
  361. private bool CheckReservoirInitialized()
  362. {
  363. string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module.ToString());
  364. ReservoirEntity reservoirEntity = Singleton<RouteManager>.Instance.GetModule<ReservoirEntity>(reservoir);
  365. if (reservoirEntity != null)
  366. {
  367. return reservoirEntity.IsInitialized;
  368. }
  369. return false;
  370. }
  371. /// <summary>
  372. /// 监控 PM Counter Metal用量
  373. /// </summary>
  374. private bool MetalUsageMointor(string Module)
  375. {
  376. return true;
  377. }
  378. /// <summary>
  379. /// Initialize 监控
  380. /// </summary>
  381. /// <param name="param"></param>
  382. /// <returns></returns>
  383. private bool InitializeAllMonitor(object[] param)
  384. {
  385. RState rsstate = RState.Running;
  386. rsstate = _initializeRoutine.Monitor();
  387. if (rsstate == RState.End)
  388. {
  389. return true;
  390. }
  391. else if (rsstate == RState.Failed || rsstate == RState.Timeout)
  392. {
  393. PostMsg(PlatingCellMsg.Error);
  394. return false;
  395. }
  396. return false;
  397. }
  398. /// <summary>
  399. /// EnterInit
  400. /// </summary>
  401. public void EnterInit()
  402. {
  403. if ((PlatingCellState)fsm.State != PlatingCellState.Idle) return;
  404. else
  405. {
  406. CheckToPostMessage<PlatingCellState, PlatingCellMsg>(eEvent.ERR_PLATINGCELL, Module.ToString(), (int)PlatingCellMsg.Init);
  407. }
  408. }
  409. #region cycle manual process
  410. /// <summary>
  411. /// process
  412. /// </summary>
  413. /// <param name="param"></param>
  414. /// <returns></returns>
  415. private bool CycleManualProcess(object[] param)
  416. {
  417. bool result = _runRecipeRoutine.Start(param) == RState.Running;
  418. return result;
  419. }
  420. /// <summary>
  421. /// 监控
  422. /// </summary>
  423. /// <param name="param"></param>
  424. /// <returns></returns>
  425. private bool CycleManualMonitor(object[] param)
  426. {
  427. RState state = _runRecipeRoutine.Monitor();
  428. if (state == RState.Failed || state == RState.Timeout)
  429. {
  430. return false;
  431. }
  432. bool result = state == RState.End;
  433. if (result)
  434. {
  435. }
  436. return result;
  437. }
  438. /// <summary>
  439. /// 中止
  440. /// </summary>
  441. /// <param name="param"></param>
  442. /// <returns></returns>
  443. private bool RunRecipeAbort(object[] param)
  444. {
  445. _runRecipeRoutine.Abort();
  446. VpwMainEntity vpwMainEntity = Singleton<RouteManager>.Instance.GetModule<VpwMainEntity>("VPWMain1");
  447. if (vpwMainEntity != null)
  448. {
  449. //把main的状态置为暂停
  450. vpwMainEntity.PostMsg(VPWMainMsg.Abort);
  451. }
  452. return true;
  453. }
  454. #endregion
  455. public bool Check(int msg, out string reason, params object[] args)
  456. {
  457. reason = "";
  458. return true;
  459. }
  460. public bool CheckAcked(int msg)
  461. {
  462. throw new NotImplementedException();
  463. }
  464. public int Invoke(string function, params object[] args)
  465. {
  466. switch (function)
  467. {
  468. case "HomeAll":
  469. if (IsIdle)
  470. {
  471. return (int)FSM_MSG.NONE;
  472. }
  473. if (CheckToPostMessage<PlatingCellState, PlatingCellMsg>(eEvent.ERR_PLATINGCELL, Module.ToString(), (int)PlatingCellMsg.Initialize))
  474. {
  475. return (int)PlatingCellMsg.Initialize;
  476. }
  477. else
  478. {
  479. return (int)FSM_MSG.NONE;
  480. }
  481. }
  482. return (int)FSM_MSG.NONE;
  483. }
  484. }
  485. }