EquipmentDevice.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using System.Xml;
  6. using Aitex.Core.Common;
  7. using Aitex.Core.RT.DataCenter;
  8. using Aitex.Core.RT.Device;
  9. using Aitex.Core.RT.Device.Unit;
  10. using Aitex.Core.RT.Event;
  11. using Aitex.Core.RT.Fsm;
  12. using Aitex.Core.RT.Log;
  13. using Aitex.Core.RT.OperationCenter;
  14. using Aitex.Core.RT.RecipeCenter;
  15. using Aitex.Core.RT.Routine;
  16. using Aitex.Core.RT.SCCore;
  17. using Aitex.Core.Util;
  18. using Aitex.Core.Utilities;
  19. using FurnaceRT.Equipments.Boats;
  20. using FurnaceRT.Equipments.CarrierRobots;
  21. using FurnaceRT.Equipments.FIMSs;
  22. using FurnaceRT.Equipments.LPs;
  23. using FurnaceRT.Equipments.PMs;
  24. using FurnaceRT.Equipments.PMs.RecipeExecutions;
  25. using FurnaceRT.Equipments.Stockers;
  26. using FurnaceRT.Equipments.WaferRobots;
  27. using MECF.Framework.Common.Equipment;
  28. using MECF.Framework.Common.SubstrateTrackings;
  29. using MECF.Framework.RT.Core.Applications;
  30. using MECF.Framework.RT.Core.IoProviders;
  31. namespace FurnaceRT.Equipments.Systems
  32. {
  33. public partial class EquipmentManager
  34. {
  35. private CarrierRobotModule _cassetteRobotModule;
  36. private WaferRobotModule _waferRobotModule;
  37. private LoadPortModule _lp1Module;
  38. private LoadPortModule _lp2Module;
  39. private LoadPortModule _lp3Module;
  40. private LoadPortModule _lp4Module;
  41. private FIMSModule _fims1Module;
  42. private FIMSModule _fims2Module;
  43. private BoatModule _boatModule;
  44. private RD_TRIG _pauseTrig = new RD_TRIG();
  45. private IoSensor _sensorEMSTP;
  46. private IoSensor _sensorEnableTP;
  47. private IoSensor _sensorPort1LockUnlock;
  48. private IoSensor _sensorPort2LockUnlock;
  49. private IoSensor _sensorBuzzerOff;
  50. private IoSensor _sensorIn;
  51. private IoSensor _sensorOut;
  52. private IoSensor _sensorMECHIlkReset;
  53. private IoSensor _sensorTXPauseFront;
  54. private IoSensor _sensorELVPauseFront;
  55. private IoSensor _sensorTXPauseBack;
  56. private IoSensor _sensorELVPauseBack;
  57. private IoTrigger _trigPort1LockUnlockLight;
  58. private IoTrigger _trigPort2LockUnlockLight;
  59. private IoTrigger _trigBuzzerOffLight;
  60. private IoTrigger _trigCassetteInLight;
  61. private IoTrigger _trigCassetteOutLight;
  62. private IoTrigger _trigMECHIlkResetLight;
  63. private IoTrigger _trigTXPauseFrontLight;
  64. private IoTrigger _trigELVPauseFrontLight;
  65. private IoTrigger _trigTXPauseBackLight;
  66. private IoTrigger _trigELVPauseBackLight;
  67. private int _TXPauseTrigCount = 0;
  68. private int _ELVPauseTrigCount = 0;
  69. private PeriodicJob _monitorInCommandJob;
  70. private List<IoSensor> _inCommandLst;
  71. private Dictionary<string, RD_TRIG> _inCommandTirgs = new Dictionary<string, RD_TRIG>();
  72. protected virtual void InitModules()
  73. {
  74. for (int i = 1; i <= 30; i++)
  75. {
  76. if (SC.ContainsItem($"System.SetUp.IsStocker{i}Installed") && SC.GetValue<bool>($"System.SetUp.IsStocker{i}Installed"))
  77. {
  78. var module = ModuleHelper.Converter($"Stocker{i}");
  79. var stocker = new StockerModule(module);
  80. Modules[module] = stocker;
  81. }
  82. }
  83. Modules[ModuleName.PM1] = new PMModule(ModuleName.PM1);
  84. if (SC.GetValue<bool>($"System.SetUp.IsLP1Installed"))
  85. {
  86. _lp1Module = new LoadPortModule(ModuleName.LP1);
  87. Modules[ModuleName.LP1] = _lp1Module;
  88. }
  89. if (SC.GetValue<bool>($"System.SetUp.IsLP2Installed"))
  90. {
  91. _lp2Module = new LoadPortModule(ModuleName.LP2);
  92. Modules[ModuleName.LP2] = _lp2Module;
  93. }
  94. if (SC.GetValue<bool>($"System.SetUp.IsLP3Installed"))
  95. {
  96. _lp3Module = new LoadPortModule(ModuleName.LP3);
  97. Modules[ModuleName.LP3] = _lp3Module;
  98. }
  99. if (SC.GetValue<bool>($"System.SetUp.IsLP4Installed"))
  100. {
  101. _lp4Module = new LoadPortModule(ModuleName.LP4);
  102. Modules[ModuleName.LP4] = _lp4Module;
  103. }
  104. _cassetteRobotModule = new CarrierRobotModule(ModuleName.CarrierRobot);
  105. Modules[ModuleName.CarrierRobot] = _cassetteRobotModule;
  106. _waferRobotModule = new WaferRobotModule(ModuleName.WaferRobot);
  107. Modules[ModuleName.WaferRobot] = _waferRobotModule;
  108. if (SC.GetValue<bool>($"System.SetUp.IsFIMS1Installed"))
  109. {
  110. _fims1Module = new FIMSModule(ModuleName.FIMS1);
  111. Modules[ModuleName.FIMS1] = _fims1Module;
  112. }
  113. if (SC.GetValue<bool>($"System.SetUp.IsFIMS2Installed"))
  114. {
  115. _fims2Module = new FIMSModule(ModuleName.FIMS2);
  116. Modules[ModuleName.FIMS2] = _fims2Module;
  117. }
  118. _boatModule = new BoatModule(ModuleName.Boat);
  119. Modules[ModuleName.Boat] = _boatModule;
  120. foreach (var modulesValue in Modules.Values)
  121. {
  122. modulesValue.Initialize();
  123. }
  124. //_monitorInCommandJob = new PeriodicJob(50, ModulesOnTimer, "Modules monitor thread", true);
  125. }
  126. private bool ModulesOnTimer()
  127. {
  128. return true;
  129. foreach (var item in _inCommandLst)
  130. {
  131. if (item == null)
  132. continue;
  133. if (!_inCommandTirgs.ContainsKey(item.Name))
  134. {
  135. _inCommandTirgs.Add(item.Name, new RD_TRIG());
  136. }
  137. _inCommandTirgs[item.Name].CLK = item.Value;
  138. }
  139. if ((_inCommandTirgs.ContainsKey(_sensorTXPauseFront?.Name) && _inCommandTirgs[_sensorTXPauseFront?.Name].R) ||
  140. (_inCommandTirgs.ContainsKey(_sensorTXPauseBack?.Name) && _inCommandTirgs[_sensorTXPauseBack?.Name].R))
  141. {
  142. _TXPauseTrigCount++;
  143. if (_TXPauseTrigCount % 2 == 1)
  144. {
  145. _trigTXPauseFrontLight?.SetTrigger(true, out _);
  146. _trigTXPauseBackLight?.SetTrigger(true, out _);
  147. _cassetteRobotModule.CarrierRobotDevice.SetPauseResume(true);
  148. _waferRobotModule.WaferRobotDevice.SetPauseResume(true);
  149. _fims1Module.FIMSDevice.SetPauseResume(true);
  150. _fims2Module.FIMSDevice.SetPauseResume(true);
  151. }
  152. else
  153. {
  154. _trigTXPauseFrontLight?.SetTrigger(false, out _);
  155. _trigTXPauseBackLight?.SetTrigger(false, out _);
  156. _cassetteRobotModule.CarrierRobotDevice.SetPauseResume(false);
  157. _waferRobotModule.WaferRobotDevice.SetPauseResume(false);
  158. _fims1Module.FIMSDevice.SetPauseResume(false);
  159. _fims2Module.FIMSDevice.SetPauseResume(false);
  160. }
  161. }
  162. if ((_inCommandTirgs.ContainsKey(_sensorELVPauseFront?.Name) && _inCommandTirgs[_sensorELVPauseFront?.Name].R) ||
  163. (_inCommandTirgs.ContainsKey(_sensorELVPauseBack?.Name) && _inCommandTirgs[_sensorELVPauseBack?.Name].R))
  164. {
  165. _ELVPauseTrigCount++;
  166. if (_ELVPauseTrigCount % 2 == 1)
  167. {
  168. _trigELVPauseFrontLight?.SetTrigger(true, out _);
  169. _trigELVPauseBackLight?.SetTrigger(true, out _);
  170. _boatModule.ZAxisDevice.SetPauseResume(true);
  171. _boatModule.RAxisDevice.SetPauseResume(true);
  172. }
  173. else
  174. {
  175. _trigELVPauseFrontLight?.SetTrigger(false, out _);
  176. _trigELVPauseBackLight?.SetTrigger(false, out _);
  177. _boatModule.ZAxisDevice.SetPauseResume(false);
  178. _boatModule.RAxisDevice.SetPauseResume(false);
  179. }
  180. }
  181. foreach (var modulesValue in Modules.Values)
  182. {
  183. if (modulesValue != null)
  184. modulesValue.Monitor();
  185. }
  186. return true;
  187. }
  188. protected virtual void InitDevices()
  189. {
  190. _sensorEMSTP = DEVICE.GetDevice<IoSensor>($"System.SensorEMSTP");
  191. _sensorEnableTP = DEVICE.GetDevice<IoSensor>($"System.SensorEnableTP");
  192. _sensorPort1LockUnlock = DEVICE.GetDevice<IoSensor>($"System.SensorPort1LockUnlock");
  193. _sensorPort2LockUnlock = DEVICE.GetDevice<IoSensor>($"System.SensorPort2LockUnlock");
  194. _sensorBuzzerOff = DEVICE.GetDevice<IoSensor>($"System.SensorBuzzerOff");
  195. _sensorIn = DEVICE.GetDevice<IoSensor>($"System.SensorIn");
  196. _sensorOut = DEVICE.GetDevice<IoSensor>($"System.SensorOut");
  197. _sensorMECHIlkReset = DEVICE.GetDevice<IoSensor>($"System.SensorMECHIlkReset");
  198. _sensorTXPauseFront = DEVICE.GetDevice<IoSensor>($"System.SensorTXPauseFront");
  199. _sensorELVPauseFront = DEVICE.GetDevice<IoSensor>($"System.SensorELVPauseFront");
  200. _sensorTXPauseBack = DEVICE.GetDevice<IoSensor>($"System.SensorTXPauseBack");
  201. _sensorELVPauseBack = DEVICE.GetDevice<IoSensor>($"System.SensorELVPauseBack");
  202. _trigPort1LockUnlockLight = DEVICE.GetDevice<IoTrigger>($"System.TrigPort1LockUnlockLight");
  203. _trigPort2LockUnlockLight = DEVICE.GetDevice<IoTrigger>($"System.TrigPort2LockUnlockLight");
  204. _trigBuzzerOffLight = DEVICE.GetDevice<IoTrigger>($"System.TrigBuzzerOffLight");
  205. _trigCassetteInLight = DEVICE.GetDevice<IoTrigger>($"System.TrigCassetteInLight");
  206. _trigCassetteOutLight = DEVICE.GetDevice<IoTrigger>($"System.TrigCassetteOutLight");
  207. _trigMECHIlkResetLight = DEVICE.GetDevice<IoTrigger>($"System.TrigMECHIlkResetLight");
  208. _trigTXPauseFrontLight = DEVICE.GetDevice<IoTrigger>($"System.TrigTXPauseFrontLight");
  209. _trigELVPauseFrontLight = DEVICE.GetDevice<IoTrigger>($"System.TrigELVPauseFrontLight");
  210. _trigTXPauseBackLight = DEVICE.GetDevice<IoTrigger>($"System.TrigTXPauseBackLight");
  211. _trigELVPauseBackLight = DEVICE.GetDevice<IoTrigger>($"System.TrigELVPauseBackLight");
  212. if (_trigTXPauseFrontLight != null && _trigTXPauseFrontLight.Value)
  213. _TXPauseTrigCount = 1;
  214. if (_trigELVPauseFrontLight != null && _trigELVPauseFrontLight.Value)
  215. _ELVPauseTrigCount = 1;
  216. _inCommandLst = new List<IoSensor>()
  217. {
  218. _sensorEMSTP,
  219. _sensorEnableTP,
  220. _sensorPort1LockUnlock,
  221. _sensorPort2LockUnlock,
  222. _sensorBuzzerOff,
  223. _sensorIn,
  224. _sensorOut,
  225. _sensorMECHIlkReset,
  226. _sensorTXPauseFront,
  227. _sensorELVPauseFront,
  228. _sensorTXPauseBack,
  229. _sensorELVPauseBack,
  230. };
  231. this.OnDeviceAlarmStateChanged += OnModuleDeviceAlarmStateChanged;
  232. }
  233. public bool GetJobRecipeInfor(string jobRecipeName, out string processRecipe, out string layoutRecipe, out int coolTimeSec, out string reason)
  234. {
  235. processRecipe = "";
  236. layoutRecipe = "";
  237. reason = "";
  238. coolTimeSec = 0;
  239. string abortRecipeName = SC.ContainsItem("System.Recipe.Abort Recipe") ? SC.GetStringValue("System.Recipe.Abort Recipe") : string.Empty;
  240. if (string.IsNullOrEmpty(abortRecipeName))
  241. {
  242. reason = $"Load abort recipe failed, recipe file is null";
  243. return false;
  244. }
  245. if (!RecipeParser.Parse(abortRecipeName, ModuleName.PM1.ToString(), out var abortRecipeHead, out var abortRecipeSteps, out reason, "Abort"))
  246. {
  247. reason = $"Load abort recipe {abortRecipeName} failed, {reason}";
  248. return false;
  249. }
  250. var module = "PM1";
  251. var processType = SC.GetStringValue("System.Recipe.SupportedJobType");
  252. var prefixPath = $"Furnace\\{processType}";
  253. var recipeContent = RecipeFileManager.Instance.LoadRecipe(prefixPath, jobRecipeName, false);
  254. if (string.IsNullOrEmpty(recipeContent))
  255. {
  256. reason = $"{prefixPath}\\{jobRecipeName} is empty, please confirm the file is valid.";
  257. return false;
  258. }
  259. var doc = new XmlDocument();
  260. doc.LoadXml(recipeContent);
  261. var nodeModule = doc.SelectSingleNode($"Aitex/TableRecipeData/Module[@Name='{module}']/Step");
  262. XmlElement stepNode = nodeModule as XmlElement;
  263. if (nodeModule == null)
  264. {
  265. reason = $"{prefixPath}\\{jobRecipeName} is empty, please confirm the file is valid.";
  266. return false;
  267. }
  268. var strCoolTime = "";
  269. foreach (XmlAttribute att in stepNode.Attributes)
  270. {
  271. switch (att.Name)
  272. {
  273. case "ProcessRecipe":
  274. processRecipe = att.Value;
  275. break;
  276. case "LayoutRecipe":
  277. layoutRecipe = att.Value;
  278. break;
  279. case "CoolTime":
  280. strCoolTime = att.Value;
  281. break;
  282. }
  283. }
  284. if (!string.IsNullOrEmpty(strCoolTime))
  285. {
  286. if (System.Text.RegularExpressions.Regex.Match(strCoolTime, @"[a-zA-Z]").Success)
  287. {
  288. if (SC.ContainsItem($"PM1.RecipeEditParameter.CoolTime.{strCoolTime}"))
  289. {
  290. var time = DateTime.Parse(SC.GetStringValue($"PM1.RecipeEditParameter.CoolTime.{strCoolTime}"));
  291. coolTimeSec = time.Second + time.Minute * 60 + time.Hour * 3600;
  292. }
  293. else
  294. {
  295. reason = $"Configuration does not contains cool time config {strCoolTime}";
  296. return false;
  297. }
  298. }
  299. else
  300. {
  301. if (DateTime.TryParse(strCoolTime, out DateTime time))
  302. {
  303. coolTimeSec = time.Second + time.Minute * 60 + time.Hour * 3600;
  304. }
  305. else if (Int32.TryParse(strCoolTime, out int timeInSec))
  306. {
  307. coolTimeSec = timeInSec;
  308. }
  309. else
  310. {
  311. reason = $"Cool time {strCoolTime} is invalid";
  312. return false;
  313. }
  314. }
  315. }
  316. return true;
  317. }
  318. }
  319. }