MelsecA1EAsciiHsl.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Dongke.IBOSS.PRD.Basics.Library;
  5. using HslCommunication;
  6. using HslCommunication.Profinet.Melsec;
  7. namespace PCLCommunication
  8. {
  9. public class MelsecA1EAsciiHsl : IDisposable
  10. {
  11. private bool _always = false;
  12. //[NonSerialized]
  13. //public Socket _socket = null;
  14. //[NonSerialized]
  15. private StringBuilder _command = null;
  16. //[NonSerialized]
  17. private string _receive = null;
  18. [NonSerialized]
  19. public MelsecA1EAsciiNet _MelsecA1EAsciiNet = null;
  20. public string Command
  21. {
  22. get
  23. {
  24. return this._command?.ToString();
  25. }
  26. }
  27. public string Receive
  28. {
  29. get
  30. {
  31. return this._receive;
  32. }
  33. }
  34. /// <summary>
  35. /// 是:长连接;否:短连接
  36. /// </summary>
  37. public bool Always
  38. {
  39. get
  40. {
  41. return this._always;
  42. }
  43. set
  44. {
  45. this._always = value;
  46. if (!this._always)
  47. {
  48. this.CloseSocket();
  49. }
  50. else
  51. {
  52. this.ConnectSocket();
  53. }
  54. }
  55. }
  56. ///// <summary>
  57. ///// Socket
  58. ///// </summary>
  59. //[System.Xml.Serialization.XmlIgnore]
  60. //[System.Web.Script.Serialization.ScriptIgnore]
  61. //public Socket Socket
  62. //{
  63. // get
  64. // {
  65. // return this._socket;
  66. // }
  67. //}
  68. /// <summary>
  69. /// 通信超时(3s)
  70. /// </summary>
  71. public int Timeout
  72. {
  73. get;
  74. set;
  75. } = 10000;//3000;
  76. /// <summary>
  77. /// 关闭连接
  78. /// </summary>
  79. public void CloseSocket()
  80. {
  81. try
  82. {
  83. //_socket?.Close();
  84. this._MelsecA1EAsciiNet?.ConnectClose();
  85. }
  86. catch (Exception ex)
  87. {
  88. // TODO log
  89. string j = JsonHelper.ToJson(this);
  90. LogOut.Error(null, ex, j);
  91. //throw ex;
  92. }
  93. finally
  94. {
  95. //_socket = null;
  96. //this._MelsecA1EAsciiNet = null;
  97. }
  98. }
  99. /// <summary>
  100. /// 打开连接
  101. /// </summary>
  102. public void ConnectSocket()
  103. {
  104. try
  105. {
  106. //_socket?.Close();
  107. //this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  108. //this._socket.Connect(IPAddress.Parse(this.IP), this.Port);
  109. //this._socket.SendTimeout = this.Timeout;
  110. //this._socket.ReceiveTimeout = this.Timeout;
  111. this._MelsecA1EAsciiNet?.ConnectClose();
  112. if (this._MelsecA1EAsciiNet == null)
  113. {
  114. this._MelsecA1EAsciiNet = new MelsecA1EAsciiNet(this.IP, this.Port);
  115. }
  116. this._MelsecA1EAsciiNet.ConnectTimeOut = this.Timeout;
  117. this._MelsecA1EAsciiNet.ReceiveTimeOut = this.Timeout;
  118. this._MelsecA1EAsciiNet.ConnectServer();
  119. }
  120. catch (Exception ex)
  121. {
  122. // TODO log
  123. throw ex;
  124. }
  125. finally
  126. {
  127. if (!this._always)
  128. {
  129. CloseSocket();
  130. }
  131. }
  132. }
  133. /// <summary>
  134. /// PLC IP
  135. /// </summary>
  136. public string IP
  137. {
  138. get
  139. {
  140. return this._MelsecA1EAsciiNet.IpAddress;
  141. }
  142. set
  143. {
  144. this._MelsecA1EAsciiNet.IpAddress = value;
  145. }
  146. }
  147. /// <summary>
  148. /// PLC Port
  149. /// </summary>
  150. public int Port
  151. {
  152. get
  153. {
  154. return this._MelsecA1EAsciiNet.Port;
  155. }
  156. set
  157. {
  158. this._MelsecA1EAsciiNet.Port = value;
  159. }
  160. }
  161. public MelsecA1EAsciiHsl(string ip, int port)
  162. {
  163. this._MelsecA1EAsciiNet = new MelsecA1EAsciiNet(ip, port);
  164. this._MelsecA1EAsciiNet.ConnectTimeOut = this.Timeout;
  165. this._MelsecA1EAsciiNet.ReceiveTimeOut = this.Timeout;
  166. //this.IP = ip;
  167. //this.Port = port;
  168. }
  169. /// <summary>
  170. /// 读取PLC
  171. /// </summary>
  172. /// <param name="type"></param>
  173. /// <param name="begin"></param>
  174. /// <param name="length"></param>
  175. /// <returns></returns>
  176. public string GetHexData(string type, int begin, int length)
  177. {
  178. this._command = null;
  179. this._receive = null;
  180. string mm = "\r\ntype:" + type + "\r\nbegin:" + begin + "\r\nlength:" + length;
  181. try
  182. {
  183. //if (this._socket == null || !this._always)
  184. //{
  185. // this.CloseSocket();
  186. // this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  187. // this._socket.Connect(IPAddress.Parse(this.IP), this.Port);
  188. // this._socket.SendTimeout = this.Timeout;
  189. // this._socket.ReceiveTimeout = this.Timeout;
  190. //}
  191. // 副标题: 01 【命令:字单位读取】
  192. // PC号: FF 【固定】
  193. // 监视定时器:00 0C 【3秒(单位250毫秒)】
  194. this._command = new StringBuilder("01FF000C");
  195. // 起始软元件编码 D100 => 4420 0000 0064
  196. // 软元件代码
  197. if (type.Length == 1)
  198. {
  199. this._command.Append(MelsecA1EAscii.GetHexAscii(type) + "20");
  200. }
  201. else
  202. {
  203. this._command.Append(MelsecA1EAscii.GetHexAscii(type));
  204. }
  205. // 软元件编码
  206. this._command.Append(begin.ToString("X8"));
  207. // 软元件点数
  208. this._command.Append(length.ToString("X2"));
  209. // 命令结束
  210. this._command.Append("00");
  211. byte[] cmdBytes = Encoding.ASCII.GetBytes(this._command.ToString());
  212. //int cmdResult = this._socket.Send(cmdBytes);
  213. //byte[] receiveBytes = new byte[length * 4 + 4];
  214. //int receiveResult = this._socket.Receive(receiveBytes);
  215. //this._receive = Encoding.ASCII.GetString(receiveBytes, 0, receiveResult);
  216. //if (!this._receive.StartsWith("8100"))
  217. //{
  218. // // TODO log ip port command receive
  219. // string j = JsonHelperForPC.ToJson(this) + mm;
  220. // LogOut.Error(null, null, j);
  221. // return null;
  222. //}
  223. OperateResult<byte[]> result = this._MelsecA1EAsciiNet.ReadFromCoreServer(cmdBytes);
  224. if (result.IsSuccess)
  225. {
  226. this._receive = Encoding.ASCII.GetString(result.Content);
  227. if (!this._receive.StartsWith("8100"))
  228. {
  229. // TODO log ip port command receive
  230. string j = JsonHelper.ToJson(this) + mm;
  231. LogOut.Error(null, null, j);
  232. return null;
  233. }
  234. }
  235. else
  236. {
  237. // TODO log ip port command receive
  238. string j = JsonHelper.ToJson(this) + mm + "\r\nError:" + result.ToMessageShowString();
  239. LogOut.Error(null, null, j);
  240. return null;
  241. }
  242. //return receive.Substring(4);
  243. return this._receive;
  244. }
  245. catch (Exception ex)
  246. {
  247. // TODO log
  248. string j = JsonHelper.ToJson(this) + mm;
  249. LogOut.Error(null, ex, j);
  250. return null;
  251. }
  252. finally
  253. {
  254. if (!this._always)
  255. {
  256. this.CloseSocket();
  257. }
  258. }
  259. }
  260. /// <summary>
  261. /// 读取PLC
  262. /// </summary>
  263. /// <param name="type"></param>
  264. /// <param name="begin"></param>
  265. /// <param name="length"></param>
  266. /// <returns></returns>
  267. public byte[] GetByteData(string type, int begin, int length)
  268. {
  269. string mm = "\r\ntype:" + type + "\r\nbegin:" + begin + "\r\nlength:" + length;
  270. try
  271. {
  272. string str = this.GetHexData(type, begin, length);
  273. if (string.IsNullOrEmpty(str))
  274. {
  275. return null;
  276. }
  277. List<byte> list = new List<byte>();
  278. for (int i = 4; i < str.Length; i = i + 2)
  279. {
  280. list.Add(Convert.ToByte(str.Substring(i, 2), 16));
  281. }
  282. return list.ToArray();
  283. }
  284. catch (Exception ex)
  285. {
  286. // TODO log
  287. string j = JsonHelper.ToJson(this) + mm;
  288. LogOut.Error(null, ex, j);
  289. return null;
  290. }
  291. finally
  292. {
  293. }
  294. }
  295. /// <summary>
  296. /// 写入PLC
  297. /// </summary>
  298. /// <param name="type"></param>
  299. /// <param name="begin"></param>
  300. /// <param name="length"></param>
  301. /// <returns></returns>
  302. public bool SetData(string type, int begin, int length, string hexData)
  303. {
  304. this._command = null;
  305. this._receive = null;
  306. string mm = "\r\ntype:" + type + "\r\nbegin:" + begin + "\r\nlength:" + length + "\r\nhexData:" + hexData;
  307. try
  308. {
  309. //if (this._socket == null || !this._always)
  310. //{
  311. // this.CloseSocket();
  312. // this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  313. // this._socket.Connect(IPAddress.Parse(this.IP), this.Port);
  314. // this._socket.SendTimeout = this.Timeout;
  315. // this._socket.ReceiveTimeout = this.Timeout;
  316. //}
  317. // 副标题: 03 【命令:字单位写入】
  318. // PC号: FF 【固定】
  319. // 监视定时器:00 0C 【3秒(单位250毫秒)】
  320. this._command = new StringBuilder("03FF000C");
  321. // 起始软元件编码 D100 => 4420 0000 0064
  322. // 软元件代码
  323. if (type.Length == 1)
  324. {
  325. this._command.Append(MelsecA1EAscii.GetHexAscii(type) + "20");
  326. }
  327. else
  328. {
  329. this._command.Append(MelsecA1EAscii.GetHexAscii(type));
  330. }
  331. // 软元件编码
  332. this._command.Append(begin.ToString("X8"));
  333. // 软元件点数
  334. this._command.Append(length.ToString("X2"));
  335. // 命令结束
  336. this._command.Append("00");
  337. // 写入补齐
  338. int count = length * 4;
  339. if (hexData.Length < count)
  340. {
  341. hexData = hexData.PadRight(count, '0');
  342. }
  343. //if (hexData.Length > count)
  344. //{
  345. // hexData = hexData.Substring(0, count);
  346. //}
  347. // 写入
  348. this._command.Append(hexData);
  349. byte[] cmdBytes = Encoding.ASCII.GetBytes(this._command.ToString());
  350. //int cmdResult = this._socket.Send(cmdBytes);
  351. //byte[] receiveBytes = new byte[1024];
  352. //int receiveResult = this._socket.Receive(receiveBytes);
  353. //this._receive = Encoding.ASCII.GetString(receiveBytes, 0, receiveResult);
  354. //if (!this._receive.StartsWith("8300"))
  355. //{
  356. // // TODO log ip port command receive
  357. // string j = JsonHelperForPC.ToJson(this) + mm;
  358. // LogOut.Error(null, null, j);
  359. // return false;
  360. //}
  361. OperateResult<byte[]> result = this._MelsecA1EAsciiNet.ReadFromCoreServer(cmdBytes);
  362. if (result.IsSuccess)
  363. {
  364. this._receive = Encoding.ASCII.GetString(result.Content);
  365. if (!this._receive.StartsWith("8300"))
  366. {
  367. // TODO log ip port command receive
  368. string j = JsonHelper.ToJson(this) + mm;
  369. LogOut.Error(null, null, j);
  370. return false;
  371. }
  372. }
  373. else
  374. {
  375. // TODO log ip port command receive
  376. string j = JsonHelper.ToJson(this) + mm + "\r\nError:" + result.ToMessageShowString();
  377. LogOut.Error(null, null, j);
  378. return false;
  379. }
  380. return true;
  381. }
  382. catch (Exception ex)
  383. {
  384. // TODO log
  385. string j = JsonHelper.ToJson(this) + mm;
  386. LogOut.Error(null, ex, j);
  387. return false;
  388. }
  389. finally
  390. {
  391. if (!this._always)
  392. {
  393. this.CloseSocket();
  394. }
  395. }
  396. }
  397. /// <summary>
  398. /// 写入PLC
  399. /// </summary>
  400. /// <param name="type"></param>
  401. /// <param name="begin"></param>
  402. /// <param name="hexData"></param>
  403. /// <returns></returns>
  404. public bool SetData(string type, int begin, string hexData)
  405. {
  406. int length = (int)(hexData.Length / 4.0 + 0.5);
  407. return this.SetData(type, begin, length, hexData);
  408. }
  409. /// <summary>
  410. /// 写入PLC
  411. /// </summary>
  412. /// <param name="type"></param>
  413. /// <param name="begin"></param>
  414. /// <returns></returns>
  415. public bool SetData(string type, int begin, byte[] data)
  416. {
  417. try
  418. {
  419. StringBuilder sb = new StringBuilder();
  420. foreach (byte item in data)
  421. {
  422. sb.Append(item.ToString("X2"));
  423. }
  424. return SetData(type, begin, sb.ToString());
  425. }
  426. catch (Exception ex)
  427. {
  428. // TODO log
  429. LogOut.Error(null, ex);
  430. return false;
  431. }
  432. finally
  433. {
  434. }
  435. }
  436. /// <summary>
  437. /// 写入PLC
  438. /// </summary>
  439. /// <param name="type"></param>
  440. /// <param name="begin"></param>
  441. /// <param name="length"></param>
  442. /// <returns></returns>
  443. public bool SetData(string type, int begin, int length, byte[] data)
  444. {
  445. try
  446. {
  447. StringBuilder sb = new StringBuilder();
  448. foreach (byte item in data)
  449. {
  450. sb.Append(item.ToString("X2"));
  451. }
  452. return SetData(type, begin, length, sb.ToString());
  453. }
  454. catch (Exception ex)
  455. {
  456. // TODO log
  457. LogOut.Error(null, ex);
  458. return false;
  459. }
  460. finally
  461. {
  462. if (!this._always)
  463. {
  464. this.CloseSocket();
  465. }
  466. }
  467. }
  468. public void Do(string command)
  469. {
  470. this._command = null;
  471. this._receive = null;
  472. try
  473. {
  474. //if (this._socket == null || !this._always)
  475. //{
  476. // this.CloseSocket();
  477. // this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  478. // this._socket.Connect(IPAddress.Parse(this.IP), this.Port);
  479. // this._socket.SendTimeout = this.Timeout;
  480. // this._socket.ReceiveTimeout = this.Timeout;
  481. //}
  482. this._command = new StringBuilder(command);
  483. byte[] cmdBytes = Encoding.ASCII.GetBytes(command);
  484. //int cmdResult = this._socket.Send(cmdBytes);
  485. //byte[] receiveBytes = new byte[4096];
  486. //int receiveResult = this._socket.Receive(receiveBytes);
  487. //this._receive = Encoding.ASCII.GetString(receiveBytes, 0, receiveResult);
  488. OperateResult<byte[]> result = this._MelsecA1EAsciiNet.ReadFromCoreServer(cmdBytes);
  489. if (result.IsSuccess)
  490. {
  491. this._receive = Encoding.ASCII.GetString(result.Content);
  492. }
  493. else
  494. {
  495. // TODO log ip port command receive
  496. string j = JsonHelper.ToJson(this) + "\r\nError:" + result.ToMessageShowString();
  497. LogOut.Error(null, null, j);
  498. }
  499. }
  500. catch (Exception ex)
  501. {
  502. // TODO log
  503. string j = JsonHelper.ToJson(this);
  504. LogOut.Error(null, ex, j);
  505. }
  506. finally
  507. {
  508. if (!this._always)
  509. {
  510. this.CloseSocket();
  511. }
  512. }
  513. }
  514. /// <summary>
  515. /// 获取字符串对应的2进制Ascii码(字符=>命令)
  516. /// </summary>
  517. /// <param name="value"></param>
  518. /// <returns></returns>
  519. public static string GetHexAscii(string value)
  520. {
  521. if (string.IsNullOrEmpty(value))
  522. {
  523. return "";
  524. }
  525. byte[] bs = Encoding.ASCII.GetBytes(value);
  526. if (bs.Length > 1)
  527. {
  528. StringBuilder sb = new StringBuilder();
  529. foreach (byte item in bs)
  530. {
  531. sb.Append(item.ToString("X2"));
  532. }
  533. return sb.ToString();
  534. }
  535. else
  536. {
  537. return bs[0].ToString("X2");
  538. }
  539. }
  540. /// <summary>
  541. /// 获取2进制Ascii码对应的字符串(命令=>字符)
  542. /// </summary>
  543. /// <param name="value"></param>
  544. /// <returns></returns>
  545. public static string GetByHexAscii(string value)
  546. {
  547. if (string.IsNullOrWhiteSpace(value))
  548. {
  549. return null;
  550. }
  551. List<byte> list = new List<byte>();
  552. for (int i = 0; i < value.Length; i = i + 2)
  553. {
  554. list.Add(Convert.ToByte(value.Substring(i, 2), 16));
  555. }
  556. return Encoding.ASCII.GetString(list.ToArray());
  557. }
  558. /// <summary>
  559. /// 销毁
  560. /// </summary>
  561. public void Dispose()
  562. {
  563. try
  564. {
  565. this.CloseSocket();
  566. }
  567. catch
  568. {
  569. }
  570. }
  571. }
  572. }