GalilTcpDevice.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. using Aitex.Core.RT.Log;
  2. using Aitex.Core.Util;
  3. using MECF.Framework.Common.Device.Festo;
  4. using MECF.Framework.Common.Net;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. namespace MECF.Framework.Common.Device.Galil
  12. {
  13. public class GalilTcpDevice : JetMessageTcpClient<GalilMessage, GalilCommand>
  14. {
  15. #region 内部变量
  16. /// <summary>
  17. /// 名称
  18. /// </summary>
  19. private string _module;
  20. /// <summary>
  21. /// 上一次错误信息
  22. /// </summary>
  23. private string _lastErrorMsg = "";
  24. /// <summary>
  25. /// IP地址
  26. /// </summary>
  27. private string _ip = "";
  28. /// <summary>
  29. /// 端口号
  30. /// </summary>
  31. private int _port = 502;
  32. /// <summary>
  33. /// 定时器
  34. /// </summary>
  35. private PeriodicJob _periodicJob;
  36. /// <summary>
  37. /// 共享锁
  38. /// </summary>
  39. private object _locker = new object();
  40. /// <summary>
  41. /// 共享锁时长
  42. /// </summary>
  43. private int _lockerTime = 2000;
  44. #endregion
  45. /// <summary>
  46. /// 构造函数
  47. /// </summary>
  48. /// <param name="ip"></param>
  49. /// <param name="port"></param>
  50. public GalilTcpDevice(string module, string ip, int port) : base(ip, port)
  51. {
  52. ReceiveTimeout = 1000;
  53. SendTimeout = 1000;
  54. ConnectTimeout = 1000;
  55. _module = module;
  56. _ip = ip;
  57. _port = port;
  58. _periodicJob = new PeriodicJob(20, OnTimer, $"Galil {_module} timer", false, true);
  59. }
  60. /// <summary>
  61. /// 定时器执行
  62. /// </summary>
  63. /// <returns></returns>
  64. private bool OnTimer()
  65. {
  66. if (Monitor.TryEnter(_locker, _lockerTime))
  67. {
  68. ApplyAllDatas();
  69. Monitor.Exit(_locker);
  70. }
  71. return true;
  72. }
  73. /// <summary>
  74. /// 更新地址数量
  75. /// </summary>
  76. /// <param name="addressCount"></param>
  77. public void Initialize()
  78. {
  79. NetResult result = Connect();
  80. if (result.IsSuccess)
  81. {
  82. ApplyAllDatas();
  83. LOG.WriteLog(eEvent.INFO_GALIL, _module, $"connect {_ip}:{_port} success");
  84. }
  85. else
  86. {
  87. LOG.WriteLog(eEvent.INFO_GALIL, _module, $"connect {_ip}:{_port} failed");
  88. }
  89. _periodicJob.Start();
  90. }
  91. /// <summary>
  92. /// 设置Galil数值
  93. /// </summary>
  94. /// <param name="address"></param>
  95. /// <param name="value"></param>
  96. /// <returns></returns>
  97. public bool SetGalilCommand(string command)
  98. {
  99. GalilCommand galiCommand = new GalilCommand();
  100. galiCommand.CommandCode = 0x06;
  101. galiCommand.SetData = command;
  102. if (Monitor.TryEnter(_locker, _lockerTime))
  103. {
  104. bool result = SetOperation(galiCommand);
  105. Monitor.Exit(_locker);
  106. return result;
  107. }
  108. else
  109. {
  110. WriteErrMsg($"Write apply locker over {_lockerTime}");
  111. return false;
  112. }
  113. }
  114. /// <summary>
  115. /// 设置操作
  116. /// </summary>
  117. /// <param name="command"></param>
  118. /// <returns></returns>
  119. private bool SetOperation(GalilCommand command)
  120. {
  121. if (Connected)
  122. {
  123. return WriteCommand(command);
  124. }
  125. else
  126. {
  127. NetResult netResult = Connect();
  128. if (netResult.IsSuccess)
  129. {
  130. return WriteCommand(command);
  131. }
  132. else
  133. {
  134. WriteErrMsg("connect failed");
  135. return false;
  136. }
  137. }
  138. }
  139. /// <summary>
  140. /// 写指令
  141. /// </summary>
  142. /// <param name="command"></param>
  143. /// <returns></returns>
  144. private bool WriteCommand(GalilCommand command)
  145. {
  146. NetResult netResult = SetData(command);
  147. if (!netResult.IsSuccess)
  148. {
  149. WriteErrMsg($"write value {command.SetData} failed,{netResult.Message}");
  150. return false;
  151. }
  152. else
  153. {
  154. LOG.WriteLog(eEvent.INFO_GALIL, _module, $"write value {command.SetData} success");
  155. }
  156. return true;
  157. }
  158. /// <summary>
  159. /// 申请所有数据
  160. /// </summary>
  161. public void ApplyAllDatas()
  162. {
  163. GalilCommand command = new GalilCommand();
  164. command.CommandCode = 0x03;
  165. command.SetData = "QR;";
  166. ApplyDataOperation(command);
  167. }
  168. /// <summary>
  169. /// 申请数据操作
  170. /// </summary>
  171. /// <param name="command"></param>
  172. private void ApplyDataOperation(GalilCommand command)
  173. {
  174. if (!Connected)
  175. {
  176. NetResult connectResult = Connect();
  177. if (!connectResult.IsSuccess)
  178. {
  179. WriteErrMsg("connect failed");
  180. return;
  181. }
  182. }
  183. NetResult<GalilCommand> netResult = ApplyData(command);
  184. if (!netResult.IsSuccess)
  185. {
  186. WriteErrMsg($"apply data failed,{netResult.Message}");
  187. return;
  188. }
  189. else
  190. {
  191. GalilControllerCfgManager.Instance.UpdateModuleData(_module, netResult.Data.ControllerData);
  192. }
  193. }
  194. /// <summary>
  195. /// 写错误日志
  196. /// </summary>
  197. /// <param name="msg"></param>
  198. private void WriteErrMsg(string msg)
  199. {
  200. if (msg != _lastErrorMsg)
  201. {
  202. _lastErrorMsg = msg;
  203. LOG.WriteLog(eEvent.ERR_GALIL, _module, msg);
  204. }
  205. }
  206. }
  207. }