using HslCommunication; using HslCommunication.Profinet.Melsec; using HslCommunication.Profinet.Siemens; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using System.Xml.Linq; using static OpenCvSharp.FileStorage; namespace YSDetection { public class SiemensPLCTCPDriver { private SiemensS7Net siemensTcpNet = null; private SiemensPLCS siemensPLCSelected = SiemensPLCS.S200Smart; private MelsecMcNet melsecMc = new MelsecMcNet(); // private HslCommunication.ModBus.ModbusTcpNet melsecMc = new HslCommunication.ModBus.ModbusTcpNet(); //HslCommunication.Profinet.Melsec.MelsecMcServer melsecMc = new HslCommunication.Profinet.Melsec.MelsecMcServer(); #region PLCBase public int ReadInt(string address) { try { // 读取Int变量 var result = siemensTcpNet.ReadInt32(address); if (result.IsSuccess) { return result.Content; } else { // LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + address + ";提示:" + result.Message); return -1; } } catch (Exception ex) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage()); return -1; } } public int ReadBool(string address) { try { int value = -1; // 读取Int变量 var result = siemensTcpNet.ReadBool(address); if (result.IsSuccess) { if(result.Content) value = 1; else value = 0; return value; } else { value = -1; // LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + address + ";提示:" + result.Message); return value; } } catch (Exception ex) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage()); return -1; } } //public void WriteItem(PLCItem item, bool waitForReply = true) //{ // item.PLCOpType = PLCOpType.Write; // if (item.ItemValues == null || item.ItemValues.Count < 1) // { // // LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入值不能为空"); // return; // } // int repeatTime = 3; // Stopwatch sw = new Stopwatch(); // do // { // try // { // var result = siemensTcpNet.Write(item.Address, item.ItemValues.First()); // if (result.IsSuccess) // { // repeatTime = 0; // } // } // catch (Exception ex) // { // if (repeatTime < 0) // { // //LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}"); // } // } // } while (repeatTime > 0); // sw.Stop(); // // LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} WriteItem:{item.GetDisplayText()},写入 {item.ItemValues.First()}完成,耗时:{sw.ElapsedMilliseconds} ms"); //} /// /// 写单独地址 /// /// 地址 /// /// public void WriteBool(string address, bool writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address)) { // LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!"); return; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); do { try { var result = siemensTcpNet.Write(address, writeValue); if (result.IsSuccess) { repeatTime = 0; } } catch (Exception ex) { if (repeatTime < 0) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}"); } } } while (repeatTime > 0); sw.Stop(); // LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入 {writeValue} 完成,耗时:{sw.ElapsedMilliseconds} ms"); } /// /// 写单独地址 /// /// 地址 /// /// public void WriteInt(string address, int writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address)) { // LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!"); return; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); do { try { var result = siemensTcpNet.Write("M"+address, writeValue); if (result.IsSuccess) { repeatTime = 0; } } catch (Exception ex) { if (repeatTime < 0) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}"); } } } while (repeatTime > 0); sw.Stop(); // LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入 {writeValue} 完成,耗时:{sw.ElapsedMilliseconds} ms"); } /// /// 写单独地址 string值 /// /// 地址 /// /// public void WriteString(string address, string writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address) || string.IsNullOrEmpty(writeValue)) { // LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!"); return; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); do { try { var result = siemensTcpNet.Write(address, writeValue); if (result.IsSuccess) { repeatTime = 0; } } catch (Exception ex) { if (repeatTime < 0) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}"); } } } while (repeatTime > 0); sw.Stop(); // LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入{writeValue}完成,耗时:{sw.ElapsedMilliseconds} ms"); } /// /// 写单独地址 float值 /// /// 地址 /// /// public void WriteFloat(string address, float writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address)) { //LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!"); return; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); do { try { var result = siemensTcpNet.Write(address, writeValue); if (result.IsSuccess) { repeatTime = 0; } } catch (Exception ex) { if (repeatTime < 0) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}"); } } } while (repeatTime > 0); sw.Stop(); // LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入{writeValue}完成,耗时:{sw.ElapsedMilliseconds} ms"); } #endregion #region DeviceBase public void Start() { // IConfig.ip siemensTcpNet = new SiemensS7Net(siemensPLCSelected, "192.168.2.1"); // 如果网络不太理想,配置了两个端口,一个有问题,立即切换另一个的话,可以配置如下的代码 // melsecMc.GetPipeSocket().SetMultiPorts(new int[] { 6000, 6001 }); //melsecMc = new HslCommunication.ModBus.ModbusTcpNet(); //melsecMc.IpAddress = "192.168.3.39"; //melsecMc.Port = 502; //melsecMc.ConnectTimeOut = 10000; // 连接超时,单位毫秒 //melsecMc.ReceiveTimeOut = 5000; // 接收超时,单位毫秒 //melsecMc.Station = 1; //melsecMc.AddressStartWithZero = true; //melsecMc.IsStringReverse = false; //melsecMc.DataFormat = HslCommunication.Core.DataFormat.CDAB; // melsecMc.ServerStart(6000); // 连接对象 OperateResult connect = siemensTcpNet.ConnectServer(); if (connect.IsSuccess) { Task.Run(() => { // HeartbeatMonitor(); }); } else { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}已开启异常:{connect.Message}"); } } protected void Stop() { try { // 断开连接 // melsecMc.RemoteStop(); siemensTcpNet.ConnectClose(); } catch (Exception ex) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}关闭异常:{ex.GetExceptionMessage()}"); } } #endregion #region IMonitor readonly byte[] scanBuffer = new byte[2048]; public List GetMonitorValues(int startAddress, int length) { List res = new List(); // var result = melsecMc.ReadUInt16(startAddress.ToString(), (ushort)length); // var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length); var result = siemensTcpNet.ReadInt32("" + startAddress, (ushort)length); if (result.IsSuccess) { res = new List(result.Content); } else { //LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:W" + startAddress + ";长度:" + length + ";提示:" + result.Message); } return res; } #endregion int HeartbeatCycle = 2; string HeartbeatAddress = "M12.0"; bool CurrentState = false; public event Action Heartbeat; public async void HeartbeatMonitor() { if (HeartbeatCycle <= 0) { return; } await Task.Run(async () => { if (!string.IsNullOrEmpty(HeartbeatAddress) && HeartbeatCycle > 0) { while (CurrentState != false) { if (HeartbeatCycle <= 0) { return; } try { await Task.Delay(HeartbeatCycle * 1000); var result = siemensTcpNet.Write(HeartbeatAddress, true); if (!result.IsSuccess) { Heartbeat?.Invoke(1); //LogAsync(DateTime.Now, LogLevel.Error, $"{this.Name} 心跳监听失败"); } } catch (Exception ex) { } } } }); } } }