FaHost.cs 51 KB

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