CognexOcrReader.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Imaging;
  5. using System.Globalization;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Text.RegularExpressions;
  10. using System.Threading;
  11. using Aitex.Common.Util;
  12. using Aitex.Core.RT.DataCenter;
  13. using Aitex.Core.RT.Device;
  14. using Aitex.Core.RT.Event;
  15. using Aitex.Core.RT.IOCore;
  16. using Aitex.Core.RT.OperationCenter;
  17. using Aitex.Core.RT.SCCore;
  18. using Aitex.Core.Util;
  19. using Aitex.Sorter.Common;
  20. using MECF.Framework.Common.Communications;
  21. using MECF.Framework.Common.Equipment;
  22. using MECF.Framework.Common.SubstrateTrackings;
  23. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  24. using ErrorEventArgs = MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.ErrorEventArgs;
  25. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.OcrReaders
  26. {
  27. public class CognexOcrReader : BaseDevice, IDevice, IConnection
  28. {
  29. public const string delimiter = "\r\n";
  30. private static readonly object _locker = new object();
  31. private readonly string _addr;
  32. private IHandler _foregroundHandler; //current handler
  33. private readonly Queue<IHandler> _handlers = new Queue<IHandler>();
  34. public bool IsLogined { get; set; } = false;
  35. public bool IsOnline { get; set; } = false;
  36. public string ImageFileName => _imageFileName;
  37. public string ImageStorePath => _imageStorePath;
  38. private AsyncSocket _socket;
  39. private string _imageStorePath;
  40. private string _imageFileName;
  41. private string _imageString; //Read image in BMP format
  42. //private int _imageLength; //Read image in BMP format
  43. //private StringBuilder _stringBuilder;
  44. //private bool _readStart;
  45. public CongnexHandlerType CurrentHandlerType { get; set; } = CongnexHandlerType.None;
  46. public CongnexHandlerState CurrentHandlerState { get; set; } = CongnexHandlerState.None;
  47. public Guid OCRGuid { get; set; }
  48. public bool CurrentHandlerExcuteResult { get; set; } = true;
  49. public bool CurrentHandlerExcuteComplete { get; set; } = true;
  50. public string CurrentWaferID { get; set; }
  51. private const string EventCMDFail = "CongnexCommandFailed";
  52. private DeviceTimer _timer = new DeviceTimer();
  53. private int _ts;
  54. public bool NeedSocketLog
  55. {
  56. get;set;
  57. }
  58. public string Address => _addr;
  59. public bool IsConnected => _socket.IsConnected;
  60. public CognexOcrReader(string module, string name, string display, string deviceId, string address)
  61. : base(module, name, display, deviceId)
  62. {
  63. _addr = address;
  64. _socket = new AsyncSocket(address,524288, "");
  65. _socket.OnDataChanged += OnDataChanged;
  66. _socket.OnErrorHappened += OnErrorHandler;
  67. //IsReadImage = false;
  68. Initalized = false;
  69. _imageString = "";
  70. }
  71. public DeviceState State
  72. {
  73. get
  74. {
  75. if (!Initalized) return DeviceState.Unknown;
  76. if (Error) return DeviceState.Error;
  77. if (Busy)
  78. return DeviceState.Busy;
  79. return DeviceState.Idle;
  80. }
  81. }
  82. public bool Initalized { get; set; }
  83. public bool Busy => _handlers.Count > 0 || _foregroundHandler != null;
  84. public bool Error { get; set; }
  85. public bool ReadLaserMaker { get; set; }
  86. public string CurrentJobName { get; set; }
  87. public string LaserMark1 { get; set; }
  88. public double LaserMark1Score { get; set; }
  89. public string LaserMark1ReadTime { get; set; } = string.Empty;
  90. public string LaserMark2 { get; set; }
  91. public double LaserMark2Score { get; set; }
  92. public string LaserMark2ReadTime { get; set; } = string.Empty;
  93. public string CurrentLaserMark { get;set; }
  94. public List<string> JobFileList { get; set; }
  95. public bool ReadOK { get; set; }
  96. public string LaserMark1ReadResult { get; set; }
  97. public string LaserMark2ReadResult { get; set; }
  98. public string ImageString => _imageString;
  99. public bool Connect()
  100. {
  101. _socket.Connect(_addr);
  102. return true;
  103. }
  104. public bool Disconnect()
  105. {
  106. _socket.Dispose();
  107. return true;
  108. }
  109. public bool Initialize()
  110. {
  111. ConnectionManager.Instance.Subscribe(Name, this);
  112. JobFileList = new List<string>();
  113. int retry = 0;
  114. while (!_socket.IsConnected && retry<5)
  115. {
  116. _socket.Connect(_addr);
  117. Thread.Sleep(1000);
  118. retry++;
  119. }
  120. //DEVICE.Register(string.Format("{0}.{1}", Name, "ReadWaferID"),//DeviceOperationName.ReadWaferID),
  121. // (out string reason, int time, object[] param) =>
  122. // {
  123. // var bLaser = bool.Parse((string) param[0]);
  124. // var jobName = (string) param[1];
  125. // var ret = Read(bLaser, jobName, out reason);
  126. // if (ret)
  127. // {
  128. // reason = string.Format("{0}", Name, "Read Laser Mark.");
  129. // return true;
  130. // }
  131. // return false;
  132. // });
  133. //DEVICE.Register(string.Format("{0}.{1}", Name, "ReadLM1"),//DeviceOperationName.ReadWaferID),
  134. // (out string reason, int time, object[] param) =>
  135. // {
  136. // var bLaser =true;
  137. // var jobName = (string)param[0];
  138. // var ret = Read(bLaser, jobName, out reason);
  139. // if (ret)
  140. // {
  141. // reason = string.Format("{0}", Name, "Read Laser Mark.");
  142. // return true;
  143. // }
  144. // return false;
  145. // });
  146. //DEVICE.Register(string.Format("{0}.{1}", Name, "ReadLM2"),//DeviceOperationName.ReadWaferID),
  147. // (out string reason, int time, object[] param) =>
  148. // {
  149. // var bLaser = false;
  150. // var jobName = (string)param[0];
  151. // var ret = Read(bLaser, jobName, out reason);
  152. // if (ret)
  153. // {
  154. // reason = string.Format("{0}", Name, "Read Laser Mark.");
  155. // return true;
  156. // }
  157. // return false;
  158. // });
  159. //DEVICE.Register($"{Name}.RefreshJobList", (out string reason, int time, object[] param) =>
  160. //{
  161. // GetJobList(out reason);
  162. // return true;
  163. //});
  164. DATA.Subscribe(Name, "WRIDReaderState", () => State);
  165. DATA.Subscribe(Name, "WRIDReaderBusy", () => Busy);
  166. DATA.Subscribe(Name, "LaserMaker1", () => LaserMark1);
  167. DATA.Subscribe(Name, "LaserMaker2", () => LaserMark2);
  168. DATA.Subscribe(Name, "LaserMark1Result", () => LaserMark1ReadResult);
  169. DATA.Subscribe(Name, "LaserMark2Result", () => LaserMark2ReadResult);
  170. DATA.Subscribe(Name, "JobFileList", () => JobFileList);
  171. DATA.Subscribe(Name, "CurrentLaserMark", () => CurrentLaserMark);
  172. EV.Subscribe(new EventItem("Event", EventCMDFail, "Congnex command execution failed.", EventLevel.Alarm, Aitex.Core.RT.Event.EventType.HostNotification));
  173. _ts = SC.ContainsItem("OcrReader.TimeLimitForWID") ? SC.GetValue<int>("OcrReader.TimeLimitForWID") : 5;
  174. var fileInfo = new FileInfo(PathManager.GetDirectory($"Logs\\{DeviceID}"));
  175. if (fileInfo.Directory != null && !fileInfo.Directory.Exists)
  176. fileInfo.Directory.Create();
  177. if (fileInfo.Directory != null)
  178. _imageStorePath = fileInfo.FullName;
  179. _handlers.Clear();
  180. Initalized = true;
  181. if(_socket.IsConnected)
  182. Login(out _);
  183. return true;
  184. }
  185. public void Terminate()
  186. {
  187. _socket.Dispose();
  188. }
  189. public void Monitor()
  190. {
  191. var wafer = WaferManager.Instance.GetWafers(ModuleName.Aligner)[0];
  192. if(wafer.IsEmpty) CurrentLaserMark = string.Empty;
  193. //if (IO.DI["DI_PreAlignerWaferOn"].Value) CurrentLaserMark = string.Empty;
  194. }
  195. public void Reset()
  196. {
  197. lock (_locker)
  198. {
  199. _foregroundHandler = null;
  200. _handlers.Clear();
  201. }
  202. if (Error)
  203. {
  204. Error = false;
  205. _socket.Connect(_addr);
  206. }
  207. }
  208. private string[] GetJobName(bool bLaserMark1)
  209. {
  210. var jobs = string.Empty;
  211. if (bLaserMark1)
  212. jobs = SC.GetStringValue("OcrReader.ReaderJob1Main");
  213. else
  214. jobs = SC.GetStringValue("OcrReader.ReaderJob2Main");
  215. return jobs.Split(';');
  216. }
  217. private bool execute(IHandler handler, out string reason)
  218. {
  219. reason = string.Empty;
  220. NeedSocketLog = true;
  221. lock (_locker)
  222. {
  223. CurrentHandlerExcuteComplete = false;
  224. CurrentHandlerExcuteResult = false;
  225. CurrentHandlerState = CongnexHandlerState.CMDSend;
  226. _foregroundHandler = handler;
  227. if (!handler.Execute(ref _socket))
  228. {
  229. EV.Notify(EventCMDFail);
  230. reason = "Communication failed, please recovery it.";
  231. CurrentHandlerState = CongnexHandlerState.CMDFail;
  232. return false;
  233. }
  234. }
  235. return true;
  236. }
  237. private bool execute(out string reason)
  238. {
  239. reason = string.Empty;
  240. NeedSocketLog = true;
  241. lock (_locker)
  242. {
  243. if (_handlers.Count > 0)
  244. {
  245. _foregroundHandler = _handlers.Dequeue();
  246. CurrentHandlerExcuteComplete = false;
  247. CurrentHandlerExcuteResult = false;
  248. CurrentHandlerState = CongnexHandlerState.CMDSend;
  249. if (!_foregroundHandler.Execute(ref _socket))
  250. {
  251. EV.Notify(EventCMDFail);
  252. reason = " communication failed, please recovery it.";
  253. //LOG.Error(reason);
  254. EV.PostMessage(Name, EventEnum.DefaultWarning, "【Reader】" + reason);
  255. CurrentHandlerState = CongnexHandlerState.CMDFail;
  256. return false;
  257. }
  258. }
  259. }
  260. return true;
  261. }
  262. private void OnDataChanged(string package)
  263. {
  264. try
  265. {
  266. if(package.Contains("User:"))
  267. {
  268. _foregroundHandler = null;
  269. _handlers.Clear();
  270. Login(out _);
  271. return;
  272. }
  273. if (_foregroundHandler == null) return;
  274. if (package.Trim() == "") return;
  275. bool completed = false;
  276. lock (_locker)
  277. {
  278. if (_foregroundHandler != null && _foregroundHandler.OnMessage(ref _socket, package.Trim(), out completed))
  279. {
  280. if (CurrentHandlerState == CongnexHandlerState.ExecuteComplete)
  281. {
  282. _foregroundHandler = null;
  283. var reason = string.Empty;
  284. execute(out reason);
  285. }
  286. if (CurrentHandlerState == CongnexHandlerState.CMDFail)
  287. {
  288. EV.Notify(EventCMDFail);
  289. _foregroundHandler = null;
  290. _handlers.Clear();
  291. }
  292. }
  293. }
  294. }
  295. catch (ExcuteFailedException ex)
  296. {
  297. EV.PostMessage(DeviceID, EventEnum.DefaultWarning, ex.Message);
  298. }
  299. catch (InvalidPackageException ex)
  300. {
  301. EV.PostMessage(DeviceID, EventEnum.DefaultWarning, ex.Message);
  302. }
  303. catch (Exception ex)
  304. {
  305. EV.PostMessage(Name, EventEnum.DefaultWarning, "【Reader】has exception:" + ex);
  306. }
  307. }
  308. private void OnErrorHandler(ErrorEventArgs args)
  309. {
  310. Error = true;
  311. Initalized = false;
  312. EV.PostMessage(Module, EventEnum.CommunicationError, Display, args.Reason);
  313. //EV.PostMessage(Name, EventEnum.DefaultWarning, string.Format("{0} Communication failed,please check it.{1}", Name, args.Reason));
  314. }
  315. private string ConvertJobName(string name)
  316. {
  317. name = name.Substring(name.LastIndexOf("\\") + 1); //remove dir
  318. name = name.Substring(0, name.LastIndexOf(".")); //remove expand
  319. return name;
  320. }
  321. public void SaveImage(string imgString)
  322. {
  323. DeleteEarlyImageFile();
  324. var byBitmap = HexStringToBytes(imgString);
  325. var bmp = new Bitmap(new MemoryStream(byBitmap));
  326. _imageFileName = CurrentWaferID + DateTime.Now.ToString("G").Replace('/','_').Replace(':','_');
  327. bmp.Save($"{_imageStorePath}{_imageFileName}.bmp",ImageFormat.Bmp);
  328. EV.PostInfoLog("WIDReader",$"Picture saved, file name is {_imageFileName}.bmp");
  329. bmp.Dispose();
  330. }
  331. private void DeleteEarlyImageFile()
  332. {
  333. string[] fpath = Directory.GetFiles(_imageStorePath, "*.bmp", SearchOption.TopDirectoryOnly);
  334. Dictionary<string, DateTime> fCreateDate = new Dictionary<string, DateTime>();
  335. for (int i = 0; i < fpath.Length; i++)
  336. {
  337. FileInfo fi = new FileInfo(fpath[i]);
  338. fCreateDate[fpath[i]] = fi.CreationTime;
  339. }
  340. fCreateDate = fCreateDate.OrderBy(f => f.Value).ToDictionary(f => f.Key, f => f.Value);
  341. int fCount = fCreateDate.Count;
  342. while (fCount > 99)
  343. {
  344. string strFile = fCreateDate.First().Key;
  345. File.Delete(strFile);
  346. fCreateDate.Remove(strFile);
  347. fCount = fCreateDate.Count;
  348. }
  349. }
  350. private static byte[] HexStringToBytes(string hex)
  351. {
  352. byte[] data = new byte[hex.Length /2];
  353. int j = 0;
  354. for (int i = 0; i < hex.Length; i+=2)
  355. {
  356. data[ j ] = Convert.ToByte(hex.Substring(i, 2), 16);
  357. ++j;
  358. }
  359. return data;
  360. }
  361. private string ConvetJobName(string name)
  362. {
  363. name = name.Substring(name.LastIndexOf("\\") + 1); //remove dir
  364. name = name.Substring(0, name.LastIndexOf(".")); //remove expand
  365. return name;
  366. }
  367. #region Command
  368. public bool Login(out string reason)
  369. {
  370. _handlers.Clear();
  371. _handlers.Enqueue(new CongexHandler(new CognexUserNameHandler(this))); //UserName
  372. _handlers.Enqueue(new CongexHandler(new CognexPasswordHandler(this))); //Password
  373. return execute(out reason);
  374. }
  375. public bool ReadOnHostMode(bool bLaserMaker, string[] jobnames, out string reason)
  376. {
  377. _handlers.Clear();
  378. string[] jobs = jobnames;
  379. if (jobs.Length == 0 || string.IsNullOrEmpty(jobs[0]))
  380. {
  381. reason = "Job is undefine";
  382. return false;
  383. }
  384. string jobName = ConvetJobName(jobs[0]).Replace(".job","");
  385. if (CurrentJobName != jobName)
  386. {
  387. _handlers.Enqueue(new CongexHandler(new CognexOnlineHandler(this), false)); //offline
  388. _handlers.Enqueue(new CongexHandler(new CognexLoadJobHandler(this), jobName)); //LoadJob
  389. }
  390. _handlers.Enqueue(new CongexHandler(new CognexOnlineHandler(this), true)); //online
  391. _handlers.Enqueue(new CongexHandler(new CognexReadHandler(this))); //Read
  392. //if (jobs.Length > 1)
  393. //{
  394. // for (int i = 1; i < jobs.Length; i++)
  395. // {
  396. // jobName = ConvetJobName(jobs[i]);
  397. // _handlers.Enqueue(new handler(new CognexOnlineHandler(this), false)); //offline
  398. // _handlers.Enqueue(new handler(new CognexLoadJobHandler(this), jobName)); //LoadJob
  399. // _handlers.Enqueue(new handler(new CognexOnlineHandler(this), true)); //online
  400. // _handlers.Enqueue(new handler(new CognexReadHandler(this))); //Read
  401. // }
  402. //}
  403. ReadOK = false;
  404. ReadLaserMaker = bLaserMaker;
  405. return execute(out reason);
  406. }
  407. public bool Read(out string reason)
  408. {
  409. _handlers.Clear();
  410. string[] jobs = GetJobName(true);
  411. if (jobs.Length == 0 || string.IsNullOrEmpty(jobs[0]))
  412. {
  413. reason = "Job is undefine";
  414. return false;
  415. }
  416. string jobName = ConvetJobName(jobs[0]);
  417. if (CurrentJobName != jobName)
  418. {
  419. _handlers.Enqueue(new CongexHandler(new CognexOnlineHandler(this), false)); //offline
  420. _handlers.Enqueue(new CongexHandler(new CognexLoadJobHandler(this), jobName)); //LoadJob
  421. }
  422. _handlers.Enqueue(new CongexHandler(new CognexOnlineHandler(this), true)); //online
  423. _handlers.Enqueue(new CongexHandler(new CognexReadHandler(this))); //Read
  424. //if (jobs.Length > 1)
  425. //{
  426. // for (int i = 1; i < jobs.Length; i++)
  427. // {
  428. // jobName = ConvetJobName(jobs[i]);
  429. // _handlers.Enqueue(new handler(new CognexOnlineHandler(this), false)); //offline
  430. // _handlers.Enqueue(new handler(new CognexLoadJobHandler(this), jobName)); //LoadJob
  431. // _handlers.Enqueue(new handler(new CognexOnlineHandler(this), true)); //online
  432. // _handlers.Enqueue(new handler(new CognexReadHandler(this))); //Read
  433. // }
  434. //}
  435. ReadOK = false;
  436. ReadLaserMaker = true;
  437. return execute(out reason);
  438. }
  439. public bool Read(bool bLaserMaker, out string reason)
  440. {
  441. _handlers.Clear();
  442. string[] jobs = GetJobName(bLaserMaker);
  443. if (jobs.Length == 0 || string.IsNullOrEmpty(jobs[0]))
  444. {
  445. reason = "Job is undefine";
  446. return false;
  447. }
  448. string jobName = ConvetJobName(jobs[0]);
  449. if (CurrentJobName != jobName)
  450. {
  451. _handlers.Enqueue(new CongexHandler(new CognexOnlineHandler(this), false)); //offline
  452. _handlers.Enqueue(new CongexHandler(new CognexLoadJobHandler(this), jobName)); //LoadJob
  453. }
  454. _handlers.Enqueue(new CongexHandler(new CognexOnlineHandler(this), true)); //online
  455. _handlers.Enqueue(new CongexHandler(new CognexReadHandler(this))); //Read
  456. //if (jobs.Length > 1)
  457. //{
  458. // for (int i = 1; i < jobs.Length; i++)
  459. // {
  460. // jobName = ConvetJobName(jobs[i]);
  461. // _handlers.Enqueue(new handler(new CognexOnlineHandler(this), false)); //offline
  462. // _handlers.Enqueue(new handler(new CognexLoadJobHandler(this), jobName)); //LoadJob
  463. // _handlers.Enqueue(new handler(new CognexOnlineHandler(this), true)); //online
  464. // _handlers.Enqueue(new handler(new CognexReadHandler(this))); //Read
  465. // }
  466. //}
  467. ReadOK = false;
  468. ReadLaserMaker = bLaserMaker;
  469. return execute(out reason);
  470. }
  471. public bool Read(bool bLaserMaker, string jobName, out string reason)
  472. {
  473. _handlers.Clear();
  474. if (string.IsNullOrEmpty(jobName))
  475. {
  476. reason = "Job is undefine.";
  477. return false;
  478. }
  479. jobName = ConvertJobName(jobName);
  480. if (CurrentJobName != jobName)
  481. {
  482. _handlers.Enqueue(new CongexHandler(new CognexOnlineHandler(this), false)); //offline
  483. _handlers.Enqueue(new CongexHandler(new CognexLoadJobHandler(this), jobName)); //LoadJob
  484. }
  485. ReadOK = false;
  486. ReadLaserMaker = bLaserMaker;
  487. _handlers.Enqueue(new CongexHandler(new CognexOnlineHandler(this), true)); //online
  488. _handlers.Enqueue(new CongexHandler(new CognexReadHandler(this))); //Read
  489. return execute(out reason);
  490. }
  491. public bool ReadImage(string waferid,out string reason)
  492. {
  493. _handlers.Clear();
  494. this.CurrentWaferID = waferid;
  495. reason = string.Empty;
  496. _handlers.Enqueue(new CongexHandler(new CognexReadImageHandler(this))); //Read
  497. return execute(out reason);
  498. }
  499. public bool ReadJobName(out string reason)
  500. {
  501. reason = string.Empty;
  502. return execute(new CongexHandler(new CognexGetJobHandler(this)), out reason);
  503. }
  504. public bool GetJobList(out string reason)
  505. {
  506. reason = string.Empty;
  507. return execute(new CongexHandler(new CognexGetJobListHandler(this)), out reason);
  508. }
  509. public bool Online(bool online, out string reason)
  510. {
  511. reason = string.Empty;
  512. return execute(new CongexHandler(new CognexOnlineHandler(this), online), out reason);
  513. }
  514. public bool LoadJob(string jobName, out string reason)
  515. {
  516. reason = string.Empty;
  517. return execute(new CongexHandler(new CognexLoadJobHandler(this), jobName), out reason);
  518. }
  519. #endregion
  520. }
  521. }