FaHost.cs 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368
  1. using Aitex.Common.Util;
  2. using Aitex.Core.RT.Event;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.RT.RecipeCenter;
  5. using Aitex.Core.RT.SCCore;
  6. using Aitex.Core.Util;
  7. using FabConnect.SecsGemInterface.Common;
  8. using FabConnect.SecsGemInterface.Common.ToolModel;
  9. using FabConnect.SecsGemInterface.GemModel;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Threading;
  13. using System.Threading.Tasks;
  14. using System.Xml;
  15. using MECF.Framework.Common.CommonData;
  16. using VirgoRT.HostWrapper;
  17. namespace VirgoRT.FAs
  18. {
  19. public class FaHost : IFaHost
  20. {
  21. public string FaCommunicationState
  22. {
  23. get { return _gem.CommunicationState.ToString(); }
  24. }
  25. public string FaControlState
  26. {
  27. get { return _gem.ControlState.ToString(); }
  28. }
  29. public string FaControlSubState
  30. {
  31. get
  32. {
  33. return _gem.ControlRemoteSwitch.ToString();
  34. }
  35. }
  36. public bool IsConnected
  37. {
  38. get { return _gem.CommunicationState == CommunicationState.EnabledCommunicating; }
  39. }
  40. public int SpoolingState
  41. {
  42. get
  43. {
  44. return (int)_gem.SpoolingState;
  45. }
  46. }
  47. public string SpoolingActual
  48. {
  49. get
  50. {
  51. return
  52. _gem.GetAttribute(GEMVariables.SpoolCountActual, AttributeType.SV)
  53. ;
  54. }
  55. }
  56. public string SpoolingTotal
  57. {
  58. get { return _gem.GetAttribute(GEMVariables.SpoolCountTotal, AttributeType.SV); }
  59. }
  60. public string SpoolingFullTime
  61. {
  62. get { return _gem.GetAttribute(GEMVariables.SpoolFullTime, AttributeType.SV); }
  63. }
  64. public string SpoolingStartTime
  65. {
  66. get { return _gem.GetAttribute(GEMVariables.SpoolStartTime, AttributeType.SV); }
  67. }
  68. public bool IsSpoolingEnable
  69. {
  70. get { return Convert.ToBoolean(_gem.GetAttribute(GEMVariables.SpoolEnabled, AttributeType.EC)); }
  71. }
  72. private readonly GEMController _gem = new GEMController();
  73. public IHostCallback _equipment;
  74. private HashSet<string> _systemBuildInEc = new HashSet<string>();
  75. private HashSet<string> _systemBuildInVariables = new HashSet<string>();
  76. private PeriodicJob _faMonitorThread;
  77. private FixSizeQueue<FaEventItem> _lstEvent = new FixSizeQueue<FaEventItem>(300);
  78. FALogFileCleaner _logCleaner = new FALogFileCleaner();
  79. private ControlState _state = ControlState.Unknown;
  80. private const string EventTerminalMessage = "TerminalMessage";
  81. public void Initialize(IHostCallback equipment, string modelFile)
  82. {
  83. _equipment = equipment;
  84. _gem.CommunicationStateChanged += OnCommunicationStateChanged;
  85. _gem.RemoteCommandS2F49In += _gem_RemoteCommandS2F49In; ;
  86. _gem.PrimaryMessageIn += _gem_PrimaryMessageIn;
  87. _gem.ControlStateChanged += _gem_ControlStateChanged;
  88. _gem.ShowTrialMessageBox = false;
  89. _gem.AutoPPDataReply = false;
  90. string FilePath = PathManager.GetLogDir();
  91. if (SC.ContainsItem("System.LogFilePath") && SC.GetStringValue("System.LogFilePath") != "Default")
  92. {
  93. FilePath = SC.GetStringValue("System.LogFilePath");
  94. }
  95. _gem.Initialize(modelFile, FilePath);
  96. _gem.EquipmentModel.GemConnection.HSMS.localIPAddress = SC.GetStringValue("System.FA.LocalIpAddress");
  97. _gem.EquipmentModel.GemConnection.HSMS.localPortNumber = SC.GetValue<int>("System.FA.LocalPortNumber");
  98. _gem.EquipmentModel.GemConnection.HSMS.T3Timeout = SC.GetValue<int>("System.FA.T3Timeout");
  99. _gem.EquipmentModel.GemConnection.HSMS.T5Timeout = SC.GetValue<int>("System.FA.T5Timeout");
  100. _gem.EquipmentModel.GemConnection.HSMS.T6Timeout = SC.GetValue<int>("System.FA.T6Timeout");
  101. _gem.EquipmentModel.GemConnection.HSMS.T7Timeout = SC.GetValue<int>("System.FA.T7Timeout");
  102. _gem.EquipmentModel.GemConnection.HSMS.T8Timeout = SC.GetValue<int>("System.FA.T8Timeout");
  103. _gem.ReInitialize();
  104. //get system build in ec
  105. _systemBuildInEc = new HashSet<string>();
  106. _systemBuildInEc.Add("EstablishCommunicationsTimeout");
  107. _systemBuildInEc.Add("MaxSpoolTransmit");
  108. _systemBuildInEc.Add("OverWriteSpool");
  109. _systemBuildInEc.Add("MaxSpoolCapacity");
  110. _systemBuildInEc.Add("SpoolEnabled");
  111. _systemBuildInEc.Add("TimeFormat");
  112. //initial system build in variable
  113. _systemBuildInVariables.Add("AlarmsEnabled");
  114. _systemBuildInVariables.Add("AlarmsSet");
  115. _systemBuildInVariables.Add("Clock");
  116. _systemBuildInVariables.Add("ControlState");
  117. _systemBuildInVariables.Add("EventsEnabled");
  118. _systemBuildInVariables.Add("PPExecName");
  119. _systemBuildInVariables.Add("PreviousProcessState");
  120. _systemBuildInVariables.Add("ProcessState");
  121. _systemBuildInVariables.Add("SpoolCountActual");
  122. _systemBuildInVariables.Add("SpoolCountTotal");
  123. _systemBuildInVariables.Add("SpoolFullTime");
  124. _systemBuildInVariables.Add("SpoolStartTime");
  125. _systemBuildInVariables.Add("SpoolState");
  126. _systemBuildInVariables.Add("SpoolSubstate");
  127. _logCleaner.Run();
  128. _faMonitorThread = new PeriodicJob(200, MonitorFaTask, "Monitor FA Thread", true);
  129. EV.Subscribe(new EventItem("Host", EventTerminalMessage, "{0}", EventLevel.Warning, EventType.EventUI_Notify));
  130. }
  131. private void _gem_ControlStateChanged(object sender, SECsEventArgs e)
  132. {
  133. if (_state != _gem.ControlState)
  134. {
  135. _state = _gem.ControlState;
  136. if (_state == ControlState.OnlineRemote)
  137. {
  138. //EV.PostInfoLog("FA", Aitex.RT.Properties.Resources.HostControlModeChangeTo_stateNotifySystemChangeToAutoMode);
  139. //Singleton<PMEntity>.Instance.PostMsg((int)PMEntity.MSG.SetAutoMode);
  140. }
  141. }
  142. }
  143. public void Invoke(string method, object[] args)
  144. {
  145. switch (method)
  146. {
  147. case "FAEnable":
  148. _gem.SetEnable();
  149. break;
  150. case "FADisable":
  151. _gem.SetDisable();
  152. break;
  153. case "FAOnline":
  154. _gem.SetOnline();
  155. break;
  156. case "FAOffline":
  157. _gem.SetOffline();
  158. break;
  159. case "FALocal":
  160. _gem.SetLocal();
  161. break;
  162. case "FARemote":
  163. _gem.SetRemote();
  164. break;
  165. case "FAEnableSpooling":
  166. SetEnableSpooling();
  167. break;
  168. case "FADisableSpooling":
  169. SetDisableSpooling();
  170. break;
  171. }
  172. }
  173. private bool _gem_RemoteCommandS2F41In(SECsTransaction trans)
  174. {
  175. try
  176. {
  177. bool ret = true;
  178. string reason = string.Empty;
  179. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(2, 42, false);
  180. reply.DataItem.AddList();
  181. if (ret)
  182. {
  183. reply.DataItem[0].Add("HCACK", 0, SECsFormat.Binary);
  184. }
  185. _gem.SendReply(reply, trans.Id);
  186. }
  187. catch (Exception ex)
  188. {
  189. LOG.Write(string.Format("Handle_S2F41 Exception: {0}", ex.Message));
  190. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(2, 42, false);
  191. reply.DataItem.AddList();
  192. reply.DataItem[0].Add("HCACK", 3/*At least one parameter is invalid*/, SECsFormat.Binary);
  193. reply.DataItem[0].AddList();
  194. reply.DataItem[0][1].AddList();
  195. reply.DataItem[0][1].Add("CPVALUE", ex.Message, SECsFormat.Ascii);
  196. _gem.SendReply(reply, trans.Id);
  197. }
  198. return true;
  199. }
  200. private bool _gem_RemoteCommandS2F49In(SECsTransaction trans)
  201. {
  202. try
  203. {
  204. bool ret = true;
  205. string reason = string.Empty;
  206. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(2, 50, false);
  207. string remoteCommandName = trans.Primary.DataItem[0][2].ToString();
  208. switch (remoteCommandName.ToUpper())
  209. {
  210. case "MAPCASSETTE":
  211. {
  212. if (trans.Primary.DataItem[0][3][0][0].ToString() != "PortID")
  213. throw new Exception($"MAPCASSETTE Command Format Not Correct, CPNAME1 should be PortID");
  214. string portID = trans.Primary.DataItem[0][3][0][1].ToString();
  215. ret = _equipment.MapCassette(portID, out reason);
  216. }
  217. break;
  218. case "PP-SELECT":
  219. {
  220. if (trans.Primary.DataItem[0][3][0][0].ToString() != "PortID")
  221. throw new Exception($"PP-SELECT Command Format Not Correct, CPNAME1 should be PortID");
  222. if (trans.Primary.DataItem[0][3][1][0].ToString() != "JobID")
  223. throw new Exception($"PP-SELECT Command Format Not Correct, CPNAME2 should be JobID");
  224. if (trans.Primary.DataItem[0][3][2][0].ToString() != "LotID")
  225. throw new Exception($"PP-SELECT Command Format Not Correct, CPNAME3 should be LotID");
  226. if (trans.Primary.DataItem[0][3][3][0].ToString() != "SequenceID")
  227. throw new Exception($"PP-SELECT Command Format Not Correct, CPNAME4 should be SequenceID");
  228. int slotCount = SC.GetValue<int>("EFEM.LoadPort.SlotNumber");
  229. string[] slotSequence = new string[slotCount];
  230. for (int i = 0; i < slotCount; i++)
  231. {
  232. slotSequence[i] = trans.Primary.DataItem[0][3][3][1][i].ToString();
  233. if (slotSequence[i].Contains("*null"))
  234. slotSequence[i] = string.Empty;
  235. }
  236. string portID = trans.Primary.DataItem[0][3][0][1].ToString();
  237. string jobID = trans.Primary.DataItem[0][3][1][1].ToString();
  238. string lotID = trans.Primary.DataItem[0][3][2][1].ToString();
  239. ret = _equipment.PPSelect(portID, jobID, lotID, slotSequence, out reason);
  240. }
  241. break;
  242. case "STARTJOB":
  243. {
  244. if (trans.Primary.DataItem[0][3][0][0].ToString() != "JobID")
  245. throw new Exception($"STARTJOB Command Format Not Correct, CPNAME1 should be JobID");
  246. string jobID = trans.Primary.DataItem[0][3][0][1].ToString();
  247. ret = _equipment.StartJob(jobID, out reason);
  248. }
  249. break;
  250. case "ABORTJOB":
  251. {
  252. if (trans.Primary.DataItem[0][3][0][0].ToString() != "JobID")
  253. throw new Exception($"ABORTJOB Command Format Not Correct, CPNAME1 should be JobID");
  254. string jobID = trans.Primary.DataItem[0][3][0][1].ToString();
  255. ret = _equipment.AbortJob(jobID, out reason);
  256. }
  257. break;
  258. case "PAUSEJOB":
  259. {
  260. if (trans.Primary.DataItem[0][3][0][0].ToString() != "JobID")
  261. throw new Exception($"PAUSEJOB Command Format Not Correct, CPNAME1 should be JobID");
  262. string jobID = trans.Primary.DataItem[0][3][0][1].ToString();
  263. ret = _equipment.PauseJob(jobID, out reason);
  264. }
  265. break;
  266. case "RESUMEJOB":
  267. {
  268. if (trans.Primary.DataItem[0][3][0][0].ToString() != "JobID")
  269. throw new Exception($"RESUMEJOB Command Format Not Correct, CPNAME1 should be JobID");
  270. string jobID = trans.Primary.DataItem[0][3][0][1].ToString();
  271. ret = _equipment.ResumeJob(jobID, out reason);
  272. }
  273. break;
  274. case "STOPJOB":
  275. {
  276. if (trans.Primary.DataItem[0][3][0][0].ToString() != "JobID")
  277. throw new Exception($"STOPJOB Command Format Not Correct, CPNAME1 should be JobID");
  278. string jobID = trans.Primary.DataItem[0][3][0][1].ToString();
  279. ret = _equipment.StopJob(jobID, out reason);
  280. }
  281. break;
  282. case "LOAD":
  283. {
  284. if (trans.Primary.DataItem[0][3][0][0].ToString() != "PortID")
  285. throw new Exception($"LOAD Command Format Not Correct, CPNAME1 should be PortID");
  286. string portID = trans.Primary.DataItem[0][3][0][1].ToString();
  287. ret = _equipment.Load(portID, out reason);
  288. }
  289. break;
  290. case "UNLOAD":
  291. {
  292. if (trans.Primary.DataItem[0][3][0][0].ToString() != "PortID")
  293. throw new Exception($"UNLOAD Command Format Not Correct, CPNAME1 should be PortID");
  294. string portID = trans.Primary.DataItem[0][3][0][1].ToString();
  295. ret = _equipment.Unload(portID, out reason);
  296. }
  297. break;
  298. case "LOCK":
  299. {
  300. if (trans.Primary.DataItem[0][3][0][0].ToString() != "PortID")
  301. throw new Exception($"LOCK Command Format Not Correct, CPNAME1 should be PortID");
  302. string portID = trans.Primary.DataItem[0][3][0][1].ToString();
  303. ret = _equipment.Lock(portID, out reason);
  304. }
  305. break;
  306. case "UNLOCK":
  307. {
  308. if (trans.Primary.DataItem[0][3][0][0].ToString() != "PortID")
  309. throw new Exception($"UNLOCK Command Format Not Correct, CPNAME1 should be PortID");
  310. string portID = trans.Primary.DataItem[0][3][0][1].ToString();
  311. ret = _equipment.Unlock(portID, out reason);
  312. }
  313. break;
  314. case "READID":
  315. {
  316. if (trans.Primary.DataItem[0][3][0][0].ToString() != "PortID")
  317. throw new Exception($"READID Command Format Not Correct, CPNAME1 should be PortID");
  318. string portID = trans.Primary.DataItem[0][3][0][1].ToString();
  319. ret = _equipment.ReadID(portID, out reason);
  320. }
  321. break;
  322. case "WRITEID":
  323. {
  324. if (trans.Primary.DataItem[0][3][0][0].ToString() != "PortID")
  325. throw new Exception($"WRITEID Command Format Not Correct, CPNAME1 should be PortID");
  326. if (trans.Primary.DataItem[0][3][1][0].ToString() != "CarrierID")
  327. throw new Exception($"WRITEID Command Format Not Correct, CPNAME2 should be CarrierID");
  328. string portID = trans.Primary.DataItem[0][3][0][1].ToString();
  329. string carrierID = trans.Primary.DataItem[0][3][1][1].ToString();
  330. ret = _equipment.WriteID(portID, carrierID, out reason);
  331. }
  332. break;
  333. case "READTAG":
  334. {
  335. if (trans.Primary.DataItem[0][3][0][0].ToString() != "PortID")
  336. throw new Exception($"READTAG Command Format Not Correct, CPNAME1 should be PortID");
  337. string portID = trans.Primary.DataItem[0][3][0][1].ToString();
  338. ret = _equipment.ReadTag(portID, out reason);
  339. }
  340. break;
  341. case "WRITETAG":
  342. {
  343. if (trans.Primary.DataItem[0][3][0][0].ToString() != "PortID")
  344. throw new Exception($"WRITEID Command Format Not Correct, CPNAME1 should be PortID");
  345. if (trans.Primary.DataItem[0][3][1][0].ToString() != "TagData")
  346. throw new Exception($"WRITEID Command Format Not Correct, CPNAME2 should be TagData");
  347. string portID = trans.Primary.DataItem[0][3][0][1].ToString();
  348. string tagData = trans.Primary.DataItem[0][3][1][1].ToString();
  349. ret = _equipment.WriteTag(portID, tagData, out reason);
  350. }
  351. break;
  352. }
  353. reply.DataItem.AddList();
  354. if (ret)
  355. {
  356. reply.DataItem[0].Add("HCACK", 0, SECsFormat.Binary);
  357. }
  358. else
  359. {
  360. reply.DataItem[0].Add("HCACK", 3, SECsFormat.Binary);
  361. reply.DataItem[0].Add("CPVALUE", reason, SECsFormat.Ascii);
  362. }
  363. _gem.SendReply(reply, trans.Id);
  364. }
  365. catch (Exception ex)
  366. {
  367. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(2, 50, false);
  368. reply.DataItem.AddList();
  369. reply.DataItem[0].Add("HCACK", 3/*At least one parameter is invalid*/, SECsFormat.Binary);
  370. reply.DataItem[0].AddList();
  371. reply.DataItem[0][1].AddList();
  372. reply.DataItem[0][1].Add("CPVALUE", ex.Message, SECsFormat.Ascii);
  373. _gem.SendReply(reply, trans.Id);
  374. }
  375. return true;
  376. }
  377. private void _gem_PrimaryMessageIn(object sender, SECsPrimaryInEventArgs e)
  378. {
  379. string SF = "S" + e.Inputs.Stream.ToString() + "F" + e.Inputs.Function.ToString();
  380. switch (SF)
  381. {
  382. case "S7F1":
  383. Handle_S7F1(e);
  384. break;
  385. case "S7F5":
  386. Handle_S7F5(e);
  387. break;
  388. case "S7F3"://down load recipe
  389. Handle_S7F3(e); //Host must send S7F1/F2 and equipment application must either grant the host requests.
  390. break;
  391. case "S7F17":
  392. Handle_S7F17(e);
  393. break;
  394. case "S7F19":
  395. Handle_S7F19(e);
  396. break;
  397. case "S7F25":
  398. Handle_S7F25(e);
  399. break;
  400. case "S10F3"://Single terminal message
  401. Handle_S10F3(e);
  402. break;
  403. case "S10F5"://Multiple terminal message
  404. Handle_S10F5(e);
  405. break;
  406. }
  407. switch (e.EventId)
  408. {
  409. case PrimaryEventType.ProcessProgramLoadInquire: //S7F1
  410. break;
  411. }
  412. }
  413. /// <summary>
  414. /// Host requests the equipment to delete the Process Program
  415. /// L,n (Number of process programs to be deleted)
  416. /// 1. <PPID1>
  417. /// .
  418. /// .
  419. /// n. <PPIDn>
  420. /// Exception: If n=0, then delete all.
  421. /// </summary>
  422. /// <param name="e"></param>
  423. private void Handle_S7F17(SECsPrimaryInEventArgs e)
  424. {
  425. try
  426. {
  427. string reason = string.Empty;
  428. if (e.Inputs.DataItem[0].Count == 0)
  429. {
  430. LOG.Write("Handle_S7F17, delete all recipes");
  431. DeleteAllRecipes(out reason);
  432. }
  433. else // Delete the list of selected Process Program
  434. {
  435. List<string> deleteRecipes = new List<string>();
  436. for (int i = 0; i < e.Inputs.DataItem[0].Count; i++)
  437. {
  438. string ppid = e.Inputs.DataItem[0][i].ToString();
  439. deleteRecipes.Add(ppid);
  440. LOG.Write("Handle_S7F17, delete recipe:" + ppid);
  441. }
  442. DeleteRecipe(deleteRecipes, out reason);
  443. }
  444. //give reply to host
  445. SECsMessage messageToReply = _gem.Services.ProcessProgram.DeleteProcessProgramAcknowledge(0);
  446. _gem.SendReply(messageToReply, e.TransactionID);
  447. }
  448. catch (Exception ex)
  449. {
  450. LOG.Write("Handle_S7F17 Exception: " + ex.Message);
  451. //give reply to host
  452. SECsMessage messageToReply = _gem.Services.ProcessProgram.DeleteProcessProgramAcknowledge(4/*error*/);
  453. _gem.SendReply(messageToReply, e.TransactionID);
  454. }
  455. }
  456. protected void DeleteAllRecipes(out string reason)
  457. {
  458. reason = string.Empty;
  459. var recipes = RecipeFileManager.Instance.GetSequenceNameList();
  460. foreach (var name in recipes)
  461. {
  462. if (!RecipeFileManager.Instance.DeleteSequence(name))
  463. {
  464. EV.PostWarningLog("System", $"Can not delete {name}, delete all failed.");
  465. return;
  466. }
  467. }
  468. EV.PostInfoLog("System", "All recipe deleted");
  469. }
  470. protected void DeleteRecipe(List<string> recipeFiles, out string reason)
  471. {
  472. reason = string.Empty;
  473. foreach (var name in recipeFiles)
  474. {
  475. if (!RecipeFileManager.Instance.DeleteSequence(name))
  476. {
  477. EV.PostWarningLog("System", $"Can not delete {name}.");
  478. return;
  479. }
  480. else
  481. {
  482. EV.PostWarningLog("System", $"Delete recipe {name}.");
  483. }
  484. }
  485. }
  486. private void Handle_S7F3(SECsPrimaryInEventArgs e)
  487. {
  488. try
  489. {
  490. LOG.Write("Handle_S7F4, Request down load recipe");
  491. string ppid = e.Inputs.DataItem[0][0].Value.ToString();
  492. string reason = string.Empty;
  493. // Get the format of PPBODY
  494. SECsFormat bodyType = e.Inputs.DataItem[0][1].Format;
  495. bool recipeSuccess = false;
  496. if (bodyType == SECsFormat.Binary)
  497. {
  498. recipeSuccess = DownLoadRecipeInByte(ppid, (byte[])e.Inputs.DataItem[0][1].Value, out reason);
  499. }
  500. else
  501. {
  502. recipeSuccess = DownLoadRecipe(ppid, e.Inputs.DataItem[0][1].ToString(), out reason);
  503. }
  504. if (recipeSuccess)
  505. {
  506. SECsMessage acknowledge = _gem.Services.ProcessProgram.ProcessProgramAcknowledge(0);
  507. _gem.SendReply(acknowledge, e.TransactionID);
  508. }
  509. else
  510. {
  511. //1:download recipe body fail:Permission Not Granted
  512. //2:download recipe body fail:Length Error
  513. //3:download recipe body fail:Matrix Overflow
  514. //4:download recipe body fail:PPID Not Found
  515. //5:download recipe body fail:Mode Unsupported
  516. SECsMessage acknowledge = _gem.Services.ProcessProgram.ProcessProgramAcknowledge(5);
  517. _gem.SendReply(acknowledge, e.TransactionID);
  518. }
  519. }
  520. catch (Exception ex)
  521. {
  522. LOG.Write("Handle_S7F4 exception:" + ex.Message);
  523. SECsMessage acknowledge = _gem.Services.ProcessProgram.ProcessProgramAcknowledge(1);
  524. _gem.SendReply(acknowledge, e.TransactionID);
  525. }
  526. }
  527. protected bool DownLoadRecipe(string name, string content, out string reason)
  528. {
  529. bool ret = false;
  530. reason = string.Empty;
  531. ret = RecipeFileManager.Instance.SaveSequence(name, content, false);
  532. if (!ret)
  533. {
  534. reason = string.Format("save recipe content failed,recipeName:{0}", name);
  535. LOG.Write(reason);
  536. }
  537. return ret;
  538. }
  539. protected bool DownLoadRecipeInByte(string name, byte[] content, out string reason)
  540. {
  541. bool ret = false;
  542. reason = string.Empty;
  543. ret = RecipeFileManager.Instance.SaveSequence(name, System.Text.Encoding.UTF8.GetString(content), false);
  544. if (!ret)
  545. {
  546. reason = string.Format("save recipe content failed,recipeName:{0}", name);
  547. LOG.Write(reason);
  548. }
  549. return ret;
  550. }
  551. /// <summary>
  552. /* 0 = OK
  553. 1 = Already have
  554. 2 = No space
  555. 3 = Invalid PPID
  556. 4 = Busy, try later
  557. 5 = Will not accept
  558. >5 = Other error
  559. 6-63 Reserved
  560. */
  561. ///</summary>
  562. /// <param name="e"></param>
  563. private void Handle_S7F1(SECsPrimaryInEventArgs e)
  564. {
  565. try
  566. {
  567. LOG.Write("Handle_S7F1, Process Program Load Inquire");
  568. string ppid = e.Inputs.DataItem[0][0].Value.ToString();
  569. var recipeList = RecipeFileManager.Instance.GetSequenceNameList();
  570. int ppGrant = 0;
  571. if (!recipeList.Contains(ppid))
  572. ppGrant = 3;
  573. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(7, 2, false);
  574. reply.DataItem.Add("PPGNT", ppGrant, SECsFormat.Binary);
  575. _gem.SendReply(reply, e.TransactionID);
  576. }
  577. catch (Exception ex)
  578. {
  579. LOG.Write("Handle_S7F1 exception:" + ex.Message);
  580. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(7, 0, false);
  581. _gem.SendReply(reply, e.TransactionID);
  582. }
  583. }
  584. private void Handle_S7F5(SECsPrimaryInEventArgs e)
  585. {
  586. try
  587. {
  588. LOG.Write("Handle_S7F5,Used to request the transfer of a process program");
  589. string ppid = e.Inputs.DataItem[0].ToString();
  590. string reason = string.Empty;
  591. string data = RecipeFileManager.Instance.GetSequence(ppid, false);
  592. if (!string.IsNullOrEmpty(data))
  593. {
  594. byte[] ppbody = System.Text.Encoding.UTF8.GetBytes(data);
  595. SECsMessage recipetToReply = _gem.Services.ProcessProgram.ProcessProgramData(ppid, ppbody);
  596. _gem.SendReply(recipetToReply, e.TransactionID);
  597. }
  598. else
  599. {
  600. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(7, 6, false);
  601. reply.DataItem.AddList();
  602. reply.DataItem[0].Add("RVIACK", 0x01/*abnormal*/, SECsFormat.Binary);
  603. reply.DataItem[0].Add("CPVALUE", reason, SECsFormat.Ascii);
  604. _gem.SendReply(reply, e.TransactionID);
  605. }
  606. }
  607. catch (Exception ex)
  608. {
  609. LOG.Write("Handle_S7F6 exception:" + ex.Message);
  610. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(7, 6, false);
  611. reply.DataItem.AddList();
  612. _gem.SendReply(reply, e.TransactionID);
  613. }
  614. }
  615. private void Handle_S7F19(SECsPrimaryInEventArgs e)
  616. {
  617. try
  618. {
  619. string reason = string.Empty;
  620. LOG.Write("Handle_S7F19, Request the transmission of the current equipment process program directory");
  621. var recipeList = RecipeFileManager.Instance.GetSequenceNameList();
  622. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(7, 20, false);
  623. reply.DataItem.AddList();
  624. for (int rNum = 0; rNum < recipeList.Count; rNum++)
  625. {
  626. reply.DataItem[0].Add("PPID", recipeList[rNum], SECsFormat.Ascii);
  627. }
  628. _gem.SendReply(reply, e.TransactionID);
  629. }
  630. catch (Exception ex)
  631. {
  632. LOG.Write("Handle_S7F19 exception:" + ex.Message);
  633. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(7, 0, false);
  634. _gem.SendReply(reply, e.TransactionID);
  635. }
  636. }
  637. private void Handle_S7F25(SECsPrimaryInEventArgs e)
  638. {
  639. try
  640. {
  641. var ppid = e.Inputs.DataItem[0].Value.ToString();
  642. LOG.Write("Handle_S7F25, request a particular process program from the other");
  643. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(7, 26, false);
  644. reply.DataItem.AddList();
  645. var parameters = GetRecipe(ppid, out string reason);
  646. if (parameters != null)
  647. {
  648. reply.DataItem[0].Add("PPID", ppid, SECsFormat.Ascii);
  649. reply.DataItem[0].Add("MDLN", _gem.EquipmentModel.Nameable.model, SECsFormat.Ascii);
  650. reply.DataItem[0].Add("SOFTREV", _gem.EquipmentModel.Nameable.softwareRev, SECsFormat.Ascii);
  651. reply.DataItem[0].AddList();
  652. reply.DataItem[0][3].AddList();
  653. reply.DataItem[0][3][0].Add("CCODE", 1, SECsFormat.U1);
  654. reply.DataItem[0][3][0].AddList();
  655. for (int i = 0; i < parameters.Count; i++)
  656. {
  657. reply.DataItem[0][3][0][1].Add($"PPARM{i + 1}", parameters[i], SECsFormat.Ascii);
  658. }
  659. }
  660. else
  661. {
  662. EV.PostWarningLog("FA", $"Request {ppid} failed, {reason}");
  663. }
  664. _gem.SendReply(reply, e.TransactionID);
  665. }
  666. catch (Exception ex)
  667. {
  668. LOG.Write("Handle_S7F25 exception:" + ex.Message);
  669. SECsMessage reply = _gem.Services.CustomMessage.CreateMessage(7, 0, false);
  670. _gem.SendReply(reply, e.TransactionID);
  671. }
  672. }
  673. public List<string> GetRecipe(string pathName, out string reason)
  674. {
  675. List<string> result = new List<string>();
  676. reason = string.Empty;
  677. try
  678. {
  679. string content = string.Empty;
  680. if (RecipeFileManager.Instance.CheckSequenceFileExist(pathName))
  681. content = RecipeFileManager.Instance.GetSequence(pathName, false);
  682. if (string.IsNullOrEmpty(content))
  683. {
  684. bool enableFolder = SC.GetValue<bool>("System.RecipeFolderByType");
  685. if (enableFolder)
  686. {
  687. if (pathName.StartsWith("PMA") && !pathName.StartsWith("PMA\\Process") &&
  688. !pathName.StartsWith("PMA\\Clean"))
  689. pathName = pathName.Replace("PMA", "PMA\\Process");
  690. if (pathName.StartsWith("PMB") && !pathName.StartsWith("PMB\\Process") &&
  691. !pathName.StartsWith("PMB\\Clean"))
  692. pathName = pathName.Replace("PMB", "PMB\\Process");
  693. }
  694. content = RecipeFileManager.Instance.LoadRecipe("", pathName, false);
  695. }
  696. result.Add(content);
  697. }
  698. catch (Exception ex)
  699. {
  700. LOG.Write(ex);
  701. reason = ex.Message;
  702. }
  703. return result;
  704. }
  705. public List<string> GetFormattedSequence(string sequenceName, out string reason)
  706. {
  707. List<string> result = new List<string>();
  708. try
  709. {
  710. string sequenceData = RecipeFileManager.Instance.GetSequence(sequenceName, false);
  711. XmlDocument recipeDoc = new XmlDocument();
  712. recipeDoc.LoadXml(sequenceData);
  713. XmlNodeList stepNodeList = recipeDoc.SelectNodes("/Aitex/TableSequenceData/Step");
  714. for (int i = 0; i < stepNodeList.Count; i++)
  715. {
  716. XmlElement stepNode = stepNodeList[i] as XmlElement;
  717. Dictionary<string, string> dic = new Dictionary<string, string>();
  718. //遍历Step节点
  719. foreach (XmlAttribute att in stepNode.Attributes)
  720. {
  721. result.Add($"STEP{i + 1}/{att.Name}:{att.Value}");
  722. }
  723. }
  724. reason = string.Empty;
  725. }
  726. catch (Exception ex)
  727. {
  728. LOG.Write(ex);
  729. reason = ex.Message;
  730. }
  731. return result;
  732. }
  733. public List<string> GetFormattedRecipe(string recipeName, out string reason)
  734. {
  735. List<string> result = new List<string>();
  736. try
  737. {
  738. string sequenceData = RecipeFileManager.Instance.LoadRecipe("", recipeName, false);
  739. XmlDocument recipeDoc = new XmlDocument();
  740. recipeDoc.LoadXml(sequenceData);
  741. XmlNodeList stepNodeList = recipeDoc.SelectNodes("/TableRecipeData/Step");
  742. for (int i = 0; i < stepNodeList.Count; i++)
  743. {
  744. XmlElement stepNode = stepNodeList[i] as XmlElement;
  745. Dictionary<string, string> dic = new Dictionary<string, string>();
  746. //遍历Step节点
  747. foreach (XmlAttribute att in stepNode.Attributes)
  748. {
  749. result.Add($"STEP{i + 1}/{att.Name}:{att.Value}");
  750. }
  751. //遍历Step子节点中所有的attribute属性节点
  752. foreach (XmlElement subStepNode in stepNode.ChildNodes)
  753. {
  754. foreach (XmlAttribute att in subStepNode.Attributes)
  755. {
  756. result.Add($"STEP{i + 1}/{subStepNode.Name}/{att.Name}:{att.Value}");
  757. }
  758. //遍历Step子节点的子节点中所有的attribute属性节点
  759. foreach (XmlElement subsubStepNode in subStepNode.ChildNodes)
  760. {
  761. foreach (XmlAttribute att in subsubStepNode.Attributes)
  762. {
  763. result.Add($"STEP{i + 1}/{subStepNode.Name}/{subsubStepNode.Name}/{att.Name}:{att.Value}");
  764. }
  765. }
  766. }
  767. }
  768. reason = string.Empty;
  769. }
  770. catch (Exception ex)
  771. {
  772. LOG.Write(ex);
  773. reason = ex.Message;
  774. }
  775. return result;
  776. }
  777. /// <summary>
  778. /// Single terminal message process
  779. /// S10F3 Format
  780. /// L,2
  781. /// 1. <TID>
  782. /// 2. <TEXT>
  783. /// </summary>
  784. /// <param name="e"></param>
  785. private void Handle_S10F3(SECsPrimaryInEventArgs e)
  786. {
  787. try
  788. {
  789. LOG.Write("Process host single terminal message");
  790. string terminalMessage = e.Inputs.DataItem["Ln"]["TEXT"].ToString();
  791. // notify equipment to show terminal message
  792. OnReceivedSingleTerminalMessage(terminalMessage);
  793. // acknowledge Host
  794. SECsMessage reply = _gem.Services.TerminalDisplay.TerminalDisplayAcknowledge(0);
  795. reply.Function = 4;
  796. _gem.SendReply(reply, e.TransactionID);
  797. }
  798. catch (Exception ex)
  799. {
  800. LOG.Write("Handle_S10F3 Exception: " + ex.Message);
  801. SECsMessage reply = _gem.Services.TerminalDisplay.TerminalDisplayAcknowledge(1/*will not display*/);
  802. reply.Function = 4;
  803. _gem.SendReply(reply, e.TransactionID);
  804. }
  805. }
  806. /// <summary>
  807. /// Multiple terminal message process
  808. /// S10F5 Format
  809. /// L,2
  810. /// 1. <TID>
  811. /// 2. L,N
  812. /// 1. <TEXT1>
  813. /// .
  814. /// .
  815. /// n.<TEXTn>
  816. /// </summary>
  817. /// <param name="e"></param>
  818. private void Handle_S10F5(SECsPrimaryInEventArgs e)
  819. {
  820. try
  821. {
  822. LOG.Write("Process host multiple terminal message");
  823. List<string> receivedMultipleMessages = new List<string>();
  824. string message = string.Empty;
  825. for (int i = 0; i < e.Inputs.DataItem[0][1].Count; i++)
  826. {
  827. receivedMultipleMessages.Add((string)e.Inputs.DataItem[0][1][i].Value);
  828. }
  829. // notify equipment to show terminal message
  830. OnReceivedMultipleTerminalMessage(receivedMultipleMessages);
  831. // acknowledge Host
  832. SECsMessage reply = _gem.Services.TerminalDisplay.TerminalDisplayAcknowledge(0);
  833. reply.Function = 6;
  834. _gem.SendReply(reply, e.TransactionID);
  835. }
  836. catch (Exception ex)
  837. {
  838. LOG.Write("Handle_S10F5 Exception: " + ex.Message);
  839. SECsMessage reply = _gem.Services.TerminalDisplay.TerminalDisplayAcknowledge(1/*will not display*/);
  840. reply.Function = 6;
  841. _gem.SendReply(reply, e.TransactionID);
  842. }
  843. }
  844. /// <summary>
  845. /// On single terminal message received
  846. /// </summary>
  847. /// <param name="terminalMessage"></param>
  848. protected virtual void OnReceivedSingleTerminalMessage(string terminalMessage)
  849. {
  850. EV.Notify("Host", EventTerminalMessage, terminalMessage);
  851. }
  852. /// <summary>
  853. /// On multiple terminal message received
  854. /// </summary>
  855. /// <param name="terminalMessage"></param>
  856. protected virtual void OnReceivedMultipleTerminalMessage(List<string> terminalMessage)
  857. {
  858. foreach (var message in terminalMessage)
  859. {
  860. EV.Notify("Host", EventTerminalMessage, message);
  861. }
  862. }
  863. public void Terminate()
  864. {
  865. _faMonitorThread.Stop();
  866. _logCleaner.Stop();
  867. }
  868. public void Enable()
  869. {
  870. _gem.SetEnable();
  871. }
  872. public void Disable()
  873. {
  874. _gem.SetDisable();
  875. }
  876. public void NotifyEvent(string eventName, Dictionary<string, string> dvid, Dictionary<string, object> objDvid)
  877. {
  878. _lstEvent.Enqueue(new FaEventItem() { dvid = dvid, objDvid = objDvid, EventName = eventName, IsAlarm = false });
  879. }
  880. public void NotifyAlarm(string alarmName, Dictionary<string, string> dvid, Dictionary<string, object> objDvid, string text)
  881. {
  882. _lstEvent.Enqueue(new FaEventItem() { dvid = dvid, objDvid = objDvid, EventName = alarmName, IsAlarm = true, Text = text});
  883. }
  884. public void NotifyEvent(string eventName, Dictionary<string, string> dvid)
  885. {
  886. _lstEvent.Enqueue(new FaEventItem() { dvid = dvid, EventName = eventName, IsAlarm = false });
  887. }
  888. public void NotifyAlarm(string alarmName, Dictionary<string, string> dvid, string text)
  889. {
  890. _lstEvent.Enqueue(new FaEventItem() { dvid = dvid, EventName = alarmName, IsAlarm = true, Text = text});
  891. }
  892. public void SetLocalControl()
  893. {
  894. Task.Factory.StartNew(() =>
  895. {
  896. _gem.SetLocal();
  897. });
  898. }
  899. public void SetRemoteControl()
  900. {
  901. Task.Factory.StartNew(() =>
  902. {
  903. _gem.SetRemote();
  904. });
  905. }
  906. public void SetEnableSpooling()
  907. {
  908. Task.Factory.StartNew(() =>
  909. {
  910. _gem.SetAttribute(GEMVariables.SpoolEnabled, AttributeType.EC, "true");
  911. });
  912. }
  913. public void SetDisableSpooling()
  914. {
  915. Task.Factory.StartNew(() =>
  916. {
  917. _gem.SetAttribute(GEMVariables.SpoolEnabled, AttributeType.EC, "false");
  918. });
  919. }
  920. public bool MonitorFaTask()
  921. {
  922. try
  923. {
  924. SynchronizeSVIDValue();
  925. FaEventItem ev;
  926. while (_lstEvent.TryDequeue(out ev))
  927. {
  928. if (ev.dvid != null)
  929. {
  930. foreach (var dvid in ev.dvid)
  931. {
  932. SetDVIDValue(dvid.Key, dvid.Value);
  933. }
  934. }
  935. if (ev.objDvid != null)
  936. {
  937. foreach (var dvid in ev.objDvid)
  938. {
  939. SetDVIDValue(dvid.Key, dvid.Value);
  940. }
  941. }
  942. SetDVIDValue(DVIDName.EventName, ev.EventName);
  943. if (ev.IsAlarm)
  944. {
  945. SetAlarm(ev.EventName, ev.Text);
  946. }
  947. else
  948. {
  949. SendEvent(ev.EventName);
  950. }
  951. //Thread.Sleep(500);
  952. }
  953. }
  954. catch (Exception ex)
  955. {
  956. System.Diagnostics.Trace.WriteLine(ex);
  957. }
  958. return true;
  959. }
  960. private void OnCommunicationStateChanged(object sender, SECsEventArgs e)
  961. {
  962. if (_gem.CommunicationState == CommunicationState.EnabledCommunicating)
  963. {
  964. if (SC.ContainsItem("System.FA.DefaultToOnline") && SC.GetValue<bool>("System.FA.DefaultToOnline"))
  965. _gem.SetOnline();
  966. if (SC.ContainsItem("System.FA.DefaultToRemote") && SC.GetValue<bool>("System.FA.DefaultToRemote"))
  967. _gem.SetRemote();
  968. }
  969. }
  970. /// <summary>
  971. /// Send terminal message to host
  972. /// </summary>
  973. /// <param name="message"></param>
  974. public void SendTerminalMessageToHost(string message)
  975. {
  976. if (!_gem.IsConnected || _gem.CommunicationState == CommunicationState.Disabled
  977. || _gem.CommunicationState == CommunicationState.WaitDelay
  978. || _gem.CommunicationState == CommunicationState.EnabledNotCommunicating)
  979. {
  980. EV.PostWarningLog("FA", "Host not connected, send terminal message failed.");
  981. return;
  982. }
  983. LOG.Write("Send terminal message to host:" + message);
  984. Task.Factory.StartNew(() =>
  985. {
  986. SECsMessage secsMsg = _gem.Services.TerminalDisplay.TerminalRequest(message);
  987. _gem.Send(secsMsg);
  988. });
  989. }
  990. public void SynchronizeSVIDValue()
  991. {
  992. try
  993. {
  994. foreach (SVID sv in _gem.EquipmentModel.StatusVariables.SVIDCollection)
  995. {
  996. if (sv != null && !_systemBuildInVariables.Contains(sv.logicalName))
  997. {
  998. if (sv.valueType == SECSFormats.List)
  999. {
  1000. List<string> svData = _equipment.GetListSvidValue(sv.logicalName);
  1001. if (svData != null && svData.Count > 0)
  1002. {
  1003. SECsDataItem data = new SECsDataItem(SECsFormat.List);
  1004. foreach (var item in svData)
  1005. {
  1006. data.Add(item, item);
  1007. }
  1008. _gem.SetListAttribute(sv.logicalName, AttributeType.SV, data);
  1009. }
  1010. else
  1011. {
  1012. SECsDataItem data = new SECsDataItem(SECsFormat.List);
  1013. data.Clear();
  1014. _gem.SetListAttribute(sv.logicalName, AttributeType.SV, data);
  1015. }
  1016. }
  1017. else
  1018. {
  1019. string svDataValue = _equipment.GetSvidValue(sv.logicalName);
  1020. if (!string.IsNullOrEmpty(svDataValue))
  1021. {
  1022. if (sv.valueType == SECSFormats.Boolean) svDataValue = ConvertToBoolean(svDataValue).ToString();
  1023. _gem.SetAttribute(sv.logicalName, AttributeType.SV, svDataValue);
  1024. }
  1025. }
  1026. }
  1027. }
  1028. }
  1029. catch (Exception ex)
  1030. {
  1031. LOG.Write("Synchronize FA Model Data exception:" + ex.Message);
  1032. }
  1033. }
  1034. private bool SetDVIDValue(string localName, object value)
  1035. {
  1036. if (value == null) return false;
  1037. if (_gem.EquipmentModel == null || !_gem.EquipmentModel.DataVariables.DVIDCollection.IsExistLogicalName(localName))
  1038. return false;
  1039. foreach (VariableType dv in _gem.EquipmentModel.DataVariables.DVIDCollection)
  1040. {
  1041. if (dv.logicalName == localName)
  1042. {
  1043. if (localName == "RecipeStepEndDataSummary")
  1044. {
  1045. List<FdcDataItem> lwsdata = (List<FdcDataItem>)value;
  1046. SECsDataItem ldata = new SECsDataItem(SECsFormat.List);
  1047. foreach (FdcDataItem wsd in lwsdata)
  1048. {
  1049. SECsDataItem data = new SECsDataItem(SECsFormat.List);
  1050. data.Add("Process item", wsd.Name);
  1051. data.Add("Min", wsd.MinValue.ToString());
  1052. data.Add("Max", wsd.MaxValue.ToString());
  1053. data.Add("Mean", wsd.MeanValue.ToString());
  1054. data.Add("SetPoint", wsd.SetPoint.ToString());
  1055. data.Add("Std", wsd.StdValue.ToString());
  1056. data.Add("SampleCount", wsd.SampleCount.ToString());
  1057. ldata.Add(data);
  1058. }
  1059. _gem.SetListAttribute(localName, AttributeType.DV, ldata);
  1060. return true;
  1061. }
  1062. if (dv.valueType == SECSFormats.Boolean)
  1063. {
  1064. value = ConvertToBoolean(Convert.ToString(value)).ToString();
  1065. }
  1066. break;
  1067. }
  1068. }
  1069. _gem.SetAttribute(localName, AttributeType.DV, Convert.ToString(value));
  1070. return true;
  1071. }
  1072. private bool SetDVIDValue(string localName, string value)
  1073. {
  1074. if (value == null) return false;
  1075. //if (!string.IsNullOrEmpty(value))
  1076. //{
  1077. if (_gem.EquipmentModel == null || !_gem.EquipmentModel.DataVariables.DVIDCollection.IsExistLogicalName(localName))
  1078. return false;
  1079. foreach (VariableType dv in _gem.EquipmentModel.DataVariables.DVIDCollection)
  1080. {
  1081. if (dv.logicalName == localName)
  1082. {
  1083. if (dv.valueType == SECSFormats.Boolean)
  1084. {
  1085. value = ConvertToBoolean(value).ToString();
  1086. }
  1087. break;
  1088. }
  1089. }
  1090. _gem.SetAttribute(localName, AttributeType.DV, value);
  1091. //}
  1092. return true;
  1093. }
  1094. private bool ConvertToBoolean(string value)
  1095. {
  1096. if (value == "0" || value.ToLower() == "false") return false;
  1097. else return true;
  1098. }
  1099. private void SendEvent(string eventName)
  1100. {
  1101. try
  1102. {
  1103. if (_gem.EquipmentModel != null)
  1104. {
  1105. var allEvents = _gem.GetAllEnabledEvents();
  1106. if (allEvents.Contains(eventName))
  1107. {
  1108. _gem.SendCollectionEvent(eventName);
  1109. }
  1110. else
  1111. {
  1112. //LOG.Write(string.Format("sendEvent failed,not find:", eventName));
  1113. }
  1114. //LOG.Write(string.Format("【FA2SendEvent--{0}】", eventName));
  1115. }
  1116. }
  1117. catch (Exception ex)
  1118. {
  1119. LOG.Write("SendEvent Error:" + ex.Message);
  1120. }
  1121. }
  1122. public void SetAlarm(string alarmTag, string text)
  1123. {
  1124. Task.Factory.StartNew(() =>
  1125. {
  1126. //if (_gem.IsAlarmSet(alarmTag))
  1127. //{
  1128. // _gem.ClearAlarm(alarmTag);
  1129. //}
  1130. var allAlarms = _gem.GetAllEnabledAlarms();
  1131. if (allAlarms.Contains(alarmTag))
  1132. {
  1133. _gem.EquipmentModel.Alarms[alarmTag].description = text;
  1134. _gem.SetAlarm(alarmTag);
  1135. }
  1136. else
  1137. {
  1138. //WriteLog(string.Format("sendAlarm failed,not find:", alarmTag));
  1139. }
  1140. //WriteLog(string.Format("【FA3SetAlarm--{0}】", alarmTag));
  1141. });
  1142. }
  1143. public void ClearAlarm(string alarmTag)
  1144. {
  1145. try
  1146. {
  1147. var allsetalarms = _gem.GetAllSetAlarms();
  1148. if (allsetalarms != null && allsetalarms.Count > 0 && allsetalarms.Contains(alarmTag))
  1149. _gem.ClearAlarm(alarmTag);
  1150. if (string.IsNullOrEmpty(alarmTag))
  1151. {
  1152. foreach (var allsetalarm in allsetalarms)
  1153. {
  1154. _gem.ClearAlarm(allsetalarm.ToString());
  1155. }
  1156. }
  1157. }
  1158. catch (Exception ex)
  1159. {
  1160. LOG.Write($"Clear Alarm Error : {ex.Message}");
  1161. }
  1162. }
  1163. }
  1164. }