CalibrationCore.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. using HslCommunication;
  2. using HslCommunication.Core;
  3. using HslCommunication.ModBus;
  4. using HslCommunication.Profinet.Siemens;
  5. using SWRIS.Enums;
  6. using SWRIS.Models;
  7. using System;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace SWRIS.Core
  11. {
  12. public class CalibrationCore : IDisposable
  13. {
  14. private IReadWriteNet moduleDevice;
  15. private readonly CalibrationSettings config;
  16. private readonly ModuleStateModel moduleState;
  17. private readonly CancellationTokenSource ctsToken = new CancellationTokenSource();
  18. public bool IsConnected { get; set; }
  19. public event EventHandler<LimitData> LimitStateChanged;
  20. public event EventHandler<bool> ConnectionStateChanged;
  21. public CalibrationCore(CalibrationSettings config)
  22. {
  23. this.config = config;
  24. moduleState = new ModuleStateModel(false);
  25. InitializeModule();
  26. ConnectServer();
  27. ThreadPool.QueueUserWorkItem(o => ReadLimitData(ctsToken.Token));
  28. }
  29. private void InitializeModule()
  30. {
  31. // 根据模块类型创建相应的设备实例
  32. switch (config.ModuleType)
  33. {
  34. case ModuleType.S1200:
  35. moduleDevice = new SiemensS7Net(SiemensPLCS.S1200)
  36. {
  37. IpAddress = config.Tcp.IpAddress,
  38. Port = config.Tcp.Port,
  39. ConnectTimeOut = 3000,
  40. ReceiveTimeOut = 2000
  41. };
  42. break;
  43. case ModuleType.S1500:
  44. moduleDevice = new SiemensS7Net(SiemensPLCS.S1500)
  45. {
  46. IpAddress = config.Tcp.IpAddress,
  47. Port = config.Tcp.Port,
  48. ConnectTimeOut = 3000,
  49. ReceiveTimeOut = 2000
  50. };
  51. break;
  52. case ModuleType.S300:
  53. moduleDevice = new SiemensS7Net(SiemensPLCS.S300)
  54. {
  55. IpAddress = config.Tcp.IpAddress,
  56. Port = config.Tcp.Port,
  57. ConnectTimeOut = 3000,
  58. ReceiveTimeOut = 2000
  59. };
  60. break;
  61. case ModuleType.S400:
  62. moduleDevice = new SiemensS7Net(SiemensPLCS.S400)
  63. {
  64. IpAddress = config.Tcp.IpAddress,
  65. Port = config.Tcp.Port,
  66. ConnectTimeOut = 3000,
  67. ReceiveTimeOut = 2000
  68. };
  69. break;
  70. case ModuleType.S200:
  71. moduleDevice = new SiemensS7Net(SiemensPLCS.S200)
  72. {
  73. IpAddress = config.Tcp.IpAddress,
  74. Port = config.Tcp.Port,
  75. ConnectTimeOut = 3000,
  76. ReceiveTimeOut = 2000
  77. };
  78. break;
  79. case ModuleType.S200Smart:
  80. moduleDevice = new SiemensS7Net(SiemensPLCS.S200Smart)
  81. {
  82. IpAddress = config.Tcp.IpAddress,
  83. Port = config.Tcp.Port,
  84. ConnectTimeOut = 3000,
  85. ReceiveTimeOut = 2000
  86. };
  87. break;
  88. case ModuleType.ModbusTcp:
  89. moduleDevice = new ModbusTcpNet(config.Tcp.IpAddress, config.Tcp.Port, config.Tcp.Station)
  90. {
  91. ConnectTimeOut = 3000,
  92. ReceiveTimeOut = 2000
  93. };
  94. break;
  95. case ModuleType.ModbusRtu:
  96. moduleDevice = new ModbusRtu(config.Serial.Station);
  97. (moduleDevice as ModbusRtu).SerialPortInni(config.Serial.PortName,
  98. config.Serial.BaudRate,
  99. config.Serial.DataBits,
  100. config.Serial.StopBits,
  101. config.Serial.Parity);
  102. break;
  103. default:
  104. throw new NotSupportedException($"不支持的模块类型: {config.ModuleType}");
  105. }
  106. }
  107. private async void ReadLimitData(CancellationToken token)
  108. {
  109. OperateResult<bool> readLimitResult;
  110. while (!token.IsCancellationRequested)
  111. {
  112. try
  113. {
  114. if (IsConnected)
  115. {
  116. foreach (var limit in config.Limits)
  117. {
  118. if (!limit.IsEnable)
  119. continue;
  120. readLimitResult = await moduleDevice.ReadBoolAsync(limit.Address);
  121. if (StateMonitor(readLimitResult))
  122. {
  123. var limitState = (limit.IsReverse ? !readLimitResult.Content : readLimitResult.Content) ? LimitState.AtLimit : LimitState.NotInLimit;
  124. if (limit.State != limitState)
  125. {
  126. limit.State = limitState;
  127. LimitStateChanged?.Invoke(this, limit);
  128. }
  129. }
  130. await Task.Delay(50);
  131. }
  132. }
  133. }
  134. catch (Exception ex)
  135. {
  136. LogHelper.Error("读取限位信号时发生错误:" + ex.Message, ex);
  137. }
  138. finally
  139. {
  140. Thread.Sleep(200);
  141. }
  142. }
  143. }
  144. private bool StateMonitor(OperateResult<bool> readLimitResult)
  145. {
  146. if (readLimitResult.IsSuccess)
  147. {
  148. moduleState.Depth = moduleState.Depth < 0 ? 1 : moduleState.Depth > 20 ? 20 : moduleState.Depth + 1;
  149. if (!moduleState.IsOnline && moduleState.Depth >= 3)
  150. {
  151. ChangeModuleState(true);
  152. }
  153. return true;
  154. }
  155. else
  156. {
  157. moduleState.Depth = moduleState.Depth > 0 ? -1 : moduleState.Depth < -20 ? -20 : moduleState.Depth - 1;
  158. if (moduleState.IsOnline && moduleState.Depth <= -3)
  159. {
  160. ChangeModuleState(false);
  161. }
  162. return false;
  163. }
  164. }
  165. private void ChangeModuleState(bool isOnline)
  166. {
  167. moduleState.IsOnline = isOnline;
  168. moduleState.Depth = 0;
  169. ConnectionStateChanged?.Invoke(this, isOnline);
  170. }
  171. private bool ConnectDevice()
  172. {
  173. try
  174. {
  175. if (moduleDevice is SiemensS7Net siemensDevice)
  176. {
  177. return siemensDevice.ConnectServer().IsSuccess;
  178. }
  179. else if (moduleDevice is ModbusTcpNet modbusTcpDevice)
  180. {
  181. return modbusTcpDevice.ConnectServer().IsSuccess;
  182. }
  183. else if (moduleDevice is ModbusRtu modbusRtuDevice)
  184. {
  185. return modbusRtuDevice.Open().IsSuccess;
  186. }
  187. return false;
  188. }
  189. catch (Exception ex)
  190. {
  191. LogHelper.Error($"设备连接异常: {ex.Message}", ex);
  192. return false;
  193. }
  194. }
  195. private void CloseDeviceConnection()
  196. {
  197. try
  198. {
  199. if (moduleDevice is SiemensS7Net siemensDevice)
  200. {
  201. siemensDevice.ConnectClose();
  202. }
  203. else if (moduleDevice is ModbusTcpNet modbusTcpDevice)
  204. {
  205. modbusTcpDevice.ConnectClose();
  206. }
  207. else if (moduleDevice is ModbusRtu modbusRtuDevice)
  208. {
  209. modbusRtuDevice.Close();
  210. }
  211. if (moduleDevice is IDisposable disposable)
  212. {
  213. disposable.Dispose();
  214. }
  215. }
  216. catch (Exception ex)
  217. {
  218. LogHelper.Error($"关闭设备连接异常: {ex.Message}", ex);
  219. }
  220. finally
  221. {
  222. moduleDevice = null;
  223. IsConnected = false;
  224. }
  225. }
  226. public void ConnectServer()
  227. {
  228. ThreadPool.QueueUserWorkItem(action =>
  229. {
  230. while (!ctsToken.IsCancellationRequested)
  231. {
  232. if (!IsConnected)
  233. {
  234. try
  235. {
  236. if (ConnectDevice())
  237. {
  238. IsConnected = true;
  239. LogHelper.Info($"连接成功: {config.ModuleType} - {config.Tcp.IpAddress}:{config.Tcp.Port}");
  240. }
  241. }
  242. catch (Exception ex)
  243. {
  244. LogHelper.Error($"连接异常: {ex.Message}", ex);
  245. }
  246. }
  247. Thread.Sleep(5000);
  248. }
  249. });
  250. }
  251. public void CloseServer()
  252. {
  253. CloseDeviceConnection();
  254. }
  255. public void Dispose()
  256. {
  257. ctsToken?.Cancel();
  258. ctsToken?.Dispose();
  259. CloseDeviceConnection();
  260. }
  261. }
  262. }