using HslCommunication; using HslCommunication.Core; using HslCommunication.ModBus; using HslCommunication.Profinet.Siemens; using SWRIS.Enums; using SWRIS.Models; using System; using System.Threading; using System.Threading.Tasks; namespace SWRIS.Core { public class CalibrationCore : IDisposable { private IReadWriteNet moduleDevice; private readonly CalibrationSettings config; private readonly ModuleStateModel moduleState; private readonly CancellationTokenSource ctsToken = new CancellationTokenSource(); public bool IsConnected { get; set; } public event EventHandler LimitStateChanged; public event EventHandler ConnectionStateChanged; public CalibrationCore(CalibrationSettings config) { this.config = config; moduleState = new ModuleStateModel(false); InitializeModule(); ConnectServer(); ThreadPool.QueueUserWorkItem(o => ReadLimitData(ctsToken.Token)); } private void InitializeModule() { // 根据模块类型创建相应的设备实例 switch (config.ModuleType) { case ModuleType.S1200: moduleDevice = new SiemensS7Net(SiemensPLCS.S1200) { IpAddress = config.Tcp.IpAddress, Port = config.Tcp.Port, ConnectTimeOut = 3000, ReceiveTimeOut = 2000 }; break; case ModuleType.S1500: moduleDevice = new SiemensS7Net(SiemensPLCS.S1500) { IpAddress = config.Tcp.IpAddress, Port = config.Tcp.Port, ConnectTimeOut = 3000, ReceiveTimeOut = 2000 }; break; case ModuleType.S300: moduleDevice = new SiemensS7Net(SiemensPLCS.S300) { IpAddress = config.Tcp.IpAddress, Port = config.Tcp.Port, ConnectTimeOut = 3000, ReceiveTimeOut = 2000 }; break; case ModuleType.S400: moduleDevice = new SiemensS7Net(SiemensPLCS.S400) { IpAddress = config.Tcp.IpAddress, Port = config.Tcp.Port, ConnectTimeOut = 3000, ReceiveTimeOut = 2000 }; break; case ModuleType.S200: moduleDevice = new SiemensS7Net(SiemensPLCS.S200) { IpAddress = config.Tcp.IpAddress, Port = config.Tcp.Port, ConnectTimeOut = 3000, ReceiveTimeOut = 2000 }; break; case ModuleType.S200Smart: moduleDevice = new SiemensS7Net(SiemensPLCS.S200Smart) { IpAddress = config.Tcp.IpAddress, Port = config.Tcp.Port, ConnectTimeOut = 3000, ReceiveTimeOut = 2000 }; break; case ModuleType.ModbusTcp: moduleDevice = new ModbusTcpNet(config.Tcp.IpAddress, config.Tcp.Port, config.Tcp.Station) { ConnectTimeOut = 3000, ReceiveTimeOut = 2000 }; break; case ModuleType.ModbusRtu: moduleDevice = new ModbusRtu(config.Serial.Station); (moduleDevice as ModbusRtu).SerialPortInni(config.Serial.PortName, config.Serial.BaudRate, config.Serial.DataBits, config.Serial.StopBits, config.Serial.Parity); break; default: throw new NotSupportedException($"不支持的模块类型: {config.ModuleType}"); } } private async void ReadLimitData(CancellationToken token) { OperateResult readLimitResult; while (!token.IsCancellationRequested) { try { if (IsConnected) { foreach (var limit in config.Limits) { if (!limit.IsEnable) continue; readLimitResult = await moduleDevice.ReadBoolAsync(limit.Address); if (StateMonitor(readLimitResult)) { var limitState = (limit.IsReverse ? !readLimitResult.Content : readLimitResult.Content) ? LimitState.AtLimit : LimitState.NotInLimit; if (limit.State != limitState) { limit.State = limitState; LimitStateChanged?.Invoke(this, limit); } } await Task.Delay(50); } } } catch (Exception ex) { LogHelper.Error("读取限位信号时发生错误:" + ex.Message, ex); } finally { Thread.Sleep(200); } } } private bool StateMonitor(OperateResult readLimitResult) { if (readLimitResult.IsSuccess) { moduleState.Depth = moduleState.Depth < 0 ? 1 : moduleState.Depth > 20 ? 20 : moduleState.Depth + 1; if (!moduleState.IsOnline && moduleState.Depth >= 3) { ChangeModuleState(true); } return true; } else { moduleState.Depth = moduleState.Depth > 0 ? -1 : moduleState.Depth < -20 ? -20 : moduleState.Depth - 1; if (moduleState.IsOnline && moduleState.Depth <= -3) { ChangeModuleState(false); } return false; } } private void ChangeModuleState(bool isOnline) { moduleState.IsOnline = isOnline; moduleState.Depth = 0; ConnectionStateChanged?.Invoke(this, isOnline); } private bool ConnectDevice() { try { if (moduleDevice is SiemensS7Net siemensDevice) { return siemensDevice.ConnectServer().IsSuccess; } else if (moduleDevice is ModbusTcpNet modbusTcpDevice) { return modbusTcpDevice.ConnectServer().IsSuccess; } else if (moduleDevice is ModbusRtu modbusRtuDevice) { return modbusRtuDevice.Open().IsSuccess; } return false; } catch (Exception ex) { LogHelper.Error($"设备连接异常: {ex.Message}", ex); return false; } } private void CloseDeviceConnection() { try { if (moduleDevice is SiemensS7Net siemensDevice) { siemensDevice.ConnectClose(); } else if (moduleDevice is ModbusTcpNet modbusTcpDevice) { modbusTcpDevice.ConnectClose(); } else if (moduleDevice is ModbusRtu modbusRtuDevice) { modbusRtuDevice.Close(); } if (moduleDevice is IDisposable disposable) { disposable.Dispose(); } } catch (Exception ex) { LogHelper.Error($"关闭设备连接异常: {ex.Message}", ex); } finally { moduleDevice = null; IsConnected = false; } } public void ConnectServer() { ThreadPool.QueueUserWorkItem(action => { while (!ctsToken.IsCancellationRequested) { if (!IsConnected) { try { if (ConnectDevice()) { IsConnected = true; LogHelper.Info($"连接成功: {config.ModuleType} - {config.Tcp.IpAddress}:{config.Tcp.Port}"); } } catch (Exception ex) { LogHelper.Error($"连接异常: {ex.Message}", ex); } } Thread.Sleep(5000); } }); } public void CloseServer() { CloseDeviceConnection(); } public void Dispose() { ctsToken?.Cancel(); ctsToken?.Dispose(); CloseDeviceConnection(); } } }