MyRfidReaderModbusTcp.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. using Aitex.Core.RT.Event;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.SCCore;
  4. using Aitex.Core.Util;
  5. using HslCommunication;
  6. using HslCommunication.ModBus;
  7. using MECF.Framework.Common.Communications;
  8. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.CarrierIdReaders.CarrierIDReaderBase;
  9. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.CarrierIdReaders.MyModbus
  17. {
  18. public class MyRfidReaderModbusTcp : CIDReaderBaseDevice, IConnection
  19. {
  20. public MyRfidReaderModbusTcp(string module, string name, string scRoot, LoadPortBaseDevice lp = null, int offset = 0, int length = 16, int readerIndex = 1)
  21. : base(module, name, lp, readerIndex)
  22. {
  23. _scRoot = scRoot;
  24. _address = SC.GetStringValue($"{_scRoot}.{Name}.Address").Split(':').FirstOrDefault();
  25. Offset = offset;
  26. Length = length;
  27. _readerClient = new ModbusTcpNet(_address);
  28. _isConnected = false;
  29. Reset();
  30. _thread = new PeriodicJob(5000, OnTimerMonitor, $"{_scRoot}.{Name} MonitorHandler", true);
  31. }
  32. private bool OnTimerMonitor()
  33. {
  34. if (!IsConnected) return true;
  35. lock (_locker)
  36. {
  37. try
  38. {
  39. Testlink();
  40. }
  41. catch (Exception ex)
  42. {
  43. }
  44. return true;
  45. }
  46. }
  47. private object _locker = new object();
  48. private PeriodicJob _thread;
  49. private ModbusTcpNet _readerClient;
  50. private string _scRoot;
  51. private string _address;
  52. private int Offset;
  53. private int Length;
  54. private DateTime _startTime;
  55. private int _retryTime;
  56. private bool _isConnected;
  57. public string Address => _address;
  58. public bool IsConnected => _isConnected;
  59. public bool Connect()
  60. {
  61. lock (_locker)
  62. {
  63. _address = SC.GetStringValue($"{_scRoot}.{Name}.Address");
  64. _address = _address.Split(':').FirstOrDefault();
  65. _readerClient.IpAddress = _address;
  66. _isConnected = _readerClient.ConnectServer().IsSuccess;
  67. return true;
  68. }
  69. }
  70. public bool Disconnect()
  71. {
  72. lock (_locker)
  73. {
  74. _readerClient.ConnectClose();
  75. _isConnected = false;
  76. return true;
  77. }
  78. }
  79. private int _linktestFailTime = 0;
  80. private bool Testlink()
  81. {
  82. var result = _readerClient?.Read("2", 1);
  83. if (!result.IsSuccess)
  84. {
  85. _linktestFailTime++;
  86. if(_linktestFailTime >10)
  87. {
  88. LOG.Write($"{Name} link test continue failed times reach 10,content:{result.Content},message:{result.Message}.");
  89. _linktestFailTime = 0;
  90. }
  91. }
  92. else
  93. _linktestFailTime = 0;
  94. return result.IsSuccess;
  95. }
  96. protected override bool fStartReset(object[] param)
  97. {
  98. lock (_locker)
  99. {
  100. _address = SC.GetStringValue($"{_scRoot}.{Name}.Address");
  101. if (!_isConnected)
  102. {
  103. _isConnected = _readerClient.ConnectServer().IsSuccess;
  104. if(_isConnected)
  105. EV.PostInfoLog("RFIDReader", $"{Name} success to connect RFID reader.");
  106. }
  107. _isConnected = Testlink();
  108. _retryTime = 0;
  109. while (!_isConnected)
  110. {
  111. EV.PostInfoLog("RFIDReader", $"{Name} start to re-connect RFID reader.");
  112. _readerClient.IpAddress = SC.GetStringValue($"{_scRoot}.{Name}.Address").Split(':').FirstOrDefault();
  113. _readerClient.ConnectClose();
  114. Thread.Sleep(1000);
  115. _isConnected = _readerClient.ConnectServer().IsSuccess;
  116. if (_isConnected)
  117. EV.PostInfoLog("RFIDReader", $"{Name} success to re-connect RFID reader.");
  118. _retryTime++;
  119. if (_retryTime > 5)
  120. {
  121. EV.PostWarningLog("RFIDReader", $"{Name} failed to re-connect RFID reader.");
  122. break;
  123. }
  124. }
  125. if (_isConnected)
  126. {
  127. LOG.Write($"Success to connect to {Name} on address:{_address}.");
  128. }
  129. else
  130. {
  131. LOG.Write($"Failed to connect to {Name} on address:{_address}.");
  132. }
  133. return true;
  134. }
  135. }
  136. protected override bool fStartReadCarrierID(object[] param)
  137. {
  138. int offset = 0;
  139. int length = 16;
  140. if (param != null)
  141. {
  142. offset = (int)param[0];
  143. length = (int)param[1];
  144. }
  145. _startTime = DateTime.Now;
  146. _retryTime = 0;
  147. CarrierIDStartPage = offset + 1;
  148. CarrierIDPageLength = length;
  149. EV.PostInfoLog(Module, $"{Name} Start to read RFID from startpage:{CarrierIDStartPage}.with length:{CarrierIDPageLength}");
  150. return true;
  151. }
  152. protected override bool fMonitorReadCarrierID(object[] param)
  153. {
  154. if (DateTime.Now - _startTime > TimeSpan.FromSeconds(30))
  155. {
  156. OnCarrierIDReadFailed("Timeout");
  157. return true;
  158. }
  159. lock (_locker)
  160. {
  161. if (_retryTime < 10)
  162. {
  163. EV.PostInfoLog(Module, $"{Name} read the {_retryTime + 1}st time RFID from startpage:{CarrierIDStartPage}.with length:{CarrierIDPageLength}");
  164. ushort startaddress = (ushort)(5 + (CarrierIDStartPage - 1) * 4);
  165. ushort datalength = (ushort)(CarrierIDPageLength * 4);
  166. if (datalength > 64) datalength = 64;
  167. OperateResult<string> ret1;
  168. OperateResult<string> ret2;
  169. if (datalength > 32)
  170. {
  171. ret1 = _readerClient.ReadString(startaddress.ToString(), 32);
  172. ret2 = _readerClient.ReadString((startaddress + 32).ToString(), Convert.ToUInt16(datalength - 32));
  173. if (!ret1.IsSuccess || !ret2.IsSuccess)
  174. {
  175. EV.PostInfoLog(Module, $"{Name} Start to retry {_retryTime + 1} RFID read from startpage:{CarrierIDStartPage}.with length:{CarrierIDPageLength}");
  176. _retryTime++;
  177. _startTime = DateTime.Now;
  178. if (ret1.Message.Contains("连接") && ret1.Message.Contains("失败"))
  179. {
  180. _readerClient.IpAddress = _address;
  181. _readerClient.ConnectClose();
  182. Thread.Sleep(500);
  183. _isConnected = _readerClient.ConnectServer().IsSuccess;
  184. if (_isConnected)
  185. {
  186. EV.PostInfoLog("CarrierIDReader", $"Success to connect to {Name} on address:{_address}.");
  187. }
  188. else
  189. {
  190. EV.PostInfoLog("CarrierIDReader", $"Failed to connect to {Name} on address:{_address}.");
  191. }
  192. }
  193. return false;
  194. }
  195. string rawcid = ret1.Content + ret2.Content;
  196. string cid = rawcid.Trim('\0').Split('\0').FirstOrDefault().Trim();
  197. OnCarrierIDRead(cid);
  198. return true;
  199. }
  200. var ret = _readerClient.ReadString(startaddress.ToString(), datalength);
  201. if (ret.IsSuccess)
  202. {
  203. string cid = ret.Content.Trim('\0').Split('\0').FirstOrDefault().Trim();
  204. OnCarrierIDRead(cid);
  205. return true;
  206. }
  207. EV.PostInfoLog(Module, $"{Name} Start to retry {_retryTime + 1} RFID read from startpage:{CarrierIDStartPage}.with length:{CarrierIDPageLength}");
  208. _retryTime++;
  209. _startTime = DateTime.Now;
  210. if (ret.Message.Contains("连接") && ret.Message.Contains("失败"))
  211. {
  212. _readerClient.IpAddress = _address;
  213. _readerClient.ConnectClose();
  214. Thread.Sleep(500);
  215. _isConnected = _readerClient.ConnectServer().IsSuccess;
  216. if (_isConnected)
  217. {
  218. EV.PostInfoLog("CarrierIDReader", $"Success to connect to {Name} on address:{_address}.");
  219. }
  220. else
  221. {
  222. EV.PostInfoLog("CarrierIDReader", $"Failed to connect to {Name} on address:{_address}.");
  223. }
  224. }
  225. return false;
  226. }
  227. }
  228. OnCarrierIDReadFailed("RetryTimeOut");
  229. return true;
  230. }
  231. protected override bool fStartWriteCarrierID(object[] param)
  232. {
  233. try
  234. {
  235. _startTime = DateTime.Now;
  236. _retryTime = 0;
  237. CarrierIDToBeWriten = param[0].ToString();
  238. int offset = 0;
  239. int length = 16;
  240. if (param.Length == 3)
  241. {
  242. offset = (int)param[1];
  243. length = (int)param[2];
  244. }
  245. CarrierIDStartPage = offset + 1;
  246. CarrierIDPageLength = length;
  247. EV.PostInfoLog(Module, $"{Name} start to write RFID:{CarrierIDToBeWriten} from startpage:{CarrierIDStartPage}.with length:{CarrierIDPageLength}");
  248. return true;
  249. }
  250. catch (Exception ex)
  251. {
  252. LOG.Write(ex);
  253. return false;
  254. }
  255. }
  256. protected override bool fMonitorWriteCarrierID(object[] param)
  257. {
  258. if (DateTime.Now - _startTime > TimeSpan.FromSeconds(30))
  259. {
  260. OnCarrierIDWriteFailed("Timeout");
  261. return true;
  262. }
  263. lock (_locker)
  264. {
  265. if (_retryTime < 5)
  266. {
  267. EV.PostInfoLog(Module, $"{Name} write the {_retryTime + 1}st time RFID from startpage:{CarrierIDStartPage}.with length:{CarrierIDPageLength}");
  268. ushort startaddress = (ushort)(5 + (CarrierIDStartPage - 1) * 4);
  269. OperateResult ret1;
  270. OperateResult ret2;
  271. if (CarrierIDToBeWriten.Length >= 64)
  272. {
  273. string cidpart1 = CarrierIDToBeWriten.Substring(0, 64);
  274. ret1 = _readerClient.Write(startaddress.ToString(), cidpart1);
  275. string cidpart2 = CarrierIDToBeWriten.Length >= 128 ?
  276. CarrierIDToBeWriten.Substring(64, 64) : (CarrierIDToBeWriten.Substring(64) + "\0");
  277. ret2 = _readerClient.Write((startaddress + 32).ToString(), cidpart2);
  278. if (ret1.IsSuccess && ret2.IsSuccess)
  279. {
  280. OnCarrierIDWrite();
  281. return true;
  282. }
  283. EV.PostInfoLog(Module, $"{Name} Start to retry {_retryTime + 1} RFID write from startpage:{CarrierIDStartPage}.with length:{CarrierIDPageLength}");
  284. _address = SC.GetStringValue($"{_scRoot}.{Name}.Address");
  285. if (ret1.Message.Contains("连接") && ret1.Message.Contains("失败"))
  286. {
  287. _readerClient.IpAddress = _address;
  288. _readerClient.ConnectClose();
  289. Thread.Sleep(500);
  290. _isConnected = _readerClient.ConnectServer().IsSuccess;
  291. if (_isConnected)
  292. {
  293. EV.PostInfoLog("CarrierIDReader", $"Success to connect to {Name} on address:{_address}.");
  294. }
  295. else
  296. {
  297. EV.PostInfoLog("CarrierIDReader", $"Failed to connect to {Name} on address:{_address}.");
  298. }
  299. }
  300. _retryTime++;
  301. _startTime = DateTime.Now;
  302. return false;
  303. }
  304. CarrierIDToBeWriten += "\0";
  305. var ret = _readerClient.Write(startaddress.ToString(), CarrierIDToBeWriten);
  306. if (ret.IsSuccess)
  307. {
  308. OnCarrierIDWrite();
  309. return true;
  310. }
  311. _address = SC.GetStringValue($"{_scRoot}.{Name}.Address");
  312. if (ret.Message.Contains("连接") && ret.Message.Contains("失败"))
  313. {
  314. _readerClient.IpAddress = _address;
  315. _readerClient.ConnectClose();
  316. Thread.Sleep(500);
  317. _isConnected = _readerClient.ConnectServer().IsSuccess;
  318. if (_isConnected)
  319. {
  320. EV.PostInfoLog("CarrierIDReader", $"Success to connect to {Name} on address:{_address}.");
  321. }
  322. else
  323. {
  324. EV.PostInfoLog("CarrierIDReader", $"Failed to connect to {Name} on address:{_address}.");
  325. }
  326. }
  327. EV.PostInfoLog(Module, $"{Name} Start to retry {_retryTime + 1} RFID write from startpage:{CarrierIDStartPage}.with length:{CarrierIDPageLength}");
  328. _retryTime++;
  329. _startTime = DateTime.Now;
  330. return false;
  331. }
  332. }
  333. OnCarrierIDWriteFailed("RetryTimeOut");
  334. return true;
  335. }
  336. public override void Terminate()
  337. {
  338. _readerClient.ConnectClose();
  339. LOG.Write($"{Name} close connection succefully.");
  340. }
  341. }
  342. }