using HslCommunication.Profinet.Siemens; using Infrastructure; using MiniExcelLibs; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DOAN.Infrastructure.PLC { public class PLCTool { // 私有连接对象 private SiemensS7Net siemensTcpNet = null; private readonly string plcAddress; private const int ReconnectDelayMs = 5000; public PLCTool() { plcAddress = AppSettings.GetConfig("PLCConfig:Address"); this.siemensTcpNet = new SiemensS7Net(SiemensPLCS.S200Smart, plcAddress) { ConnectTimeOut = 5000 }; } /// /// 尝试连接到PLC /// /// 连接成功返回true,失败返回false public bool ConnectPLC() { try { var connect = siemensTcpNet.ConnectServer(); if (connect.IsSuccess) { Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] PLC连接成功,地址{plcAddress}"); return true; } else { Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] PLC连接失败,地址{plcAddress}: {connect.Message}"); return false; } } catch (Exception e) { Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] PLC连接失败,地址{plcAddress}: {e.Message}"); return false; } } /// /// 检查PLC连接状态 /// /// 连接正常返回true,否则返回false public bool IsConnected() { try { // 尝试读取一个字节来检查连接状态 var result = siemensTcpNet.Read("VB100", 1); if (!result.IsSuccess) { Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] PLC连接状态检查失败: {result.Message}"); } return result.IsSuccess; } catch (Exception ex) { Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] PLC连接状态检查异常: {ex.Message}"); return false; } } /// /// 重连PLC /// /// 重连成功返回true,失败返回false public bool ReconnectPLC() { Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 尝试重新连接PLC..."); // 先关闭现有连接 ConnectClose(); // 重新创建PLC对象 this.siemensTcpNet = new SiemensS7Net(SiemensPLCS.S200Smart, plcAddress) { ConnectTimeOut = 5000 }; // 持续尝试重新连接,直到成功 int attempt = 0; while (true) { attempt++; if (ConnectPLC()) { Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] PLC重连成功,尝试次数: {attempt}"); return true; } Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] PLC重连失败,尝试次数: {attempt}"); System.Threading.Thread.Sleep(ReconnectDelayMs); } } /// /// 向PLC写入单个bit值 /// /// PLC地址 /// 要写入的bool值 /// 写入成功返回true,失败返回false public bool WriteBit(string addr, bool value) { var write = siemensTcpNet.Write(addr, value); return write.IsSuccess; } /// /// 从PLC读取单个bit值 /// /// PLC地址 /// 读取到的bool值 public bool ReadBit(string addr) { return siemensTcpNet.ReadBool(addr).Content; } /// /// 从PLC读取多个连续的二进制数据并转为字节数组 /// /// 起始PLC地址,默认为"VB100" /// 要读取的字节数,默认为12 /// 读取到的字节数组,如果失败返回null public byte[] ReadAllValue(string addr = "VB100", ushort length = 12) { var result = siemensTcpNet.Read(addr, length); if (result.IsSuccess) { return result.Content; } else { Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] PLC IO 取值失败,PLC地址{plcAddress},访问地址为{addr},地址个数为{length}"); return null; } } /// /// 关闭与PLC的连接 /// public void ConnectClose() { siemensTcpNet.ConnectClose(); } } }