using HslCommunication; using HslCommunication.Profinet.Siemens; using System.Net.NetworkInformation; using WIDESEA_Comm.DataHandle; using WIDESEA_Comm.LogInfo; using static FreeSql.Internal.GlobalFilter; namespace WIDESEA_WCS.WCSClient { /// /// 西门子协议PLC /// public class SiemensPLCClient : PLCClient { private readonly object _lockWrite = new object(); public SiemensS7Net siemensPLCClient { get; set; } public SiemensPLCClient(string model) { if (model == "S300") siemensPLCClient = new SiemensS7Net(SiemensPLCS.S300); else siemensPLCClient = new SiemensS7Net(SiemensPLCS.S1500); base.siemensPLCClient = this.siemensPLCClient; } /// /// 自定义西门子类型 /// /// public SiemensPLCClient(SiemensPLCS types) { siemensPLCClient = new SiemensS7Net(types); base.siemensPLCClient = this.siemensPLCClient; } /// /// 连接PLC,长链接 /// /// public override string Connect() { var res = new Ping().Send(Ip, 1000); if (res.Status != IPStatus.Success) { string msg = $"{PLCName},{Ip}网络异常。"; WriteLog.Write_Log(PLCName, $"{PLCName}_CoonInfo", msg); return msg; } siemensPLCClient.IpAddress = Ip; siemensPLCClient.Port = Port; siemensPLCClient.Slot = (byte)Slot; siemensPLCClient.ConnectTimeOut = 1000 * 3;//超时时间 siemensPLCClient.ReceiveTimeOut = 1000 * 3; siemensPLCClient.ConnectClose(); var coonRes = siemensPLCClient.ConnectServer(); IsConnected = coonRes.IsSuccess; //日志记录 string coonMsg = string.Empty; if (coonRes.IsSuccess) { coonMsg = PLCName + "连接成功"; } else { coonMsg = PLCName + "连接失败," + coonRes.Message; } Console.WriteLine(coonMsg); WriteLog.Write_Log(PLCName, $"{PLCName}_CoonInfo", coonMsg); return coonMsg; } /// /// 断开PLC长链接 /// /// public override bool DisConnect() { var res = siemensPLCClient.ConnectClose(); IsConnected = false; if (res.IsSuccess) { WriteLog.Write_Log(PLCName, $"{PLCName}_CoonInfo", PLCName + "断开连接成功!"); } else { WriteLog.Write_Log(PLCName, $"{PLCName}_CoonInfo", PLCName + "断开连接失败," + res.Message); } return res.IsSuccess; } /// /// 读取数据,直接写地址 /// /// 数据类型 /// DB地址 /// 读取场地 /// /// public override DataType Read(string dbAddress, int len = 1) { if (typeof(DataType) == typeof(int))//4字节,有符号类型 { return (DataType)GetContent(siemensPLCClient.ReadInt32(dbAddress), dbAddress); } else if (typeof(DataType) == typeof(uint))//4字节,无符号类型 { return (DataType)GetContent(siemensPLCClient.ReadUInt32(dbAddress), dbAddress); } else if (typeof(DataType) == typeof(short))//2字节,有符号类型,最常用 { return (DataType)GetContent(siemensPLCClient.ReadInt16(dbAddress), dbAddress); } else if (typeof(DataType) == typeof(ushort))//2字节,无符号类型 { return (DataType)GetContent(siemensPLCClient.ReadUInt16(dbAddress), dbAddress); } else if (typeof(DataType) == typeof(float))//浮点型 { return (DataType)GetContent(siemensPLCClient.ReadFloat(dbAddress), dbAddress); } else if (typeof(DataType) == typeof(bool)) { return (DataType)GetContent(siemensPLCClient.ReadBool(dbAddress), dbAddress); } else if (typeof(DataType) == typeof(byte))//字节 { return (DataType)GetContent(siemensPLCClient.ReadByte(dbAddress), dbAddress); } else if (typeof(DataType) == typeof(byte[]))//字节数组 { return (DataType)GetContent(siemensPLCClient.Read(dbAddress, (ushort)len), dbAddress); } else if (typeof(DataType) == typeof(string))//字符串 { //var bytes = (byte[])GetContent(siemensPLCClient.Read(dbAddress, (ushort)len), dbAddress); //string str = DataParse.GetStr(bytes, 0); //return (DataType)(str as object); var str = GetContent(siemensPLCClient.ReadString(dbAddress, (ushort)len), dbAddress).ToString(); str = str.Replace("\0", "")?.Replace("\\", "")?.Replace("\u0014", "")?.Replace("?\u0006", "")?.Replace("\u000e\u000e", "")?.Replace("\n", "")?.Replace("?", "")?.Trim(); return (DataType)(str as object); } else { throw new Exception($"【{PLCName}】,DB地址{dbAddress},未定义数据类型{typeof(DataType).Name}"); } } /// /// 读取数据,根据数据库指令来 /// /// IO点名称 /// public override DataType ReadByOrder(string orderName, string Method = null) { var item = itemGroups.Where(t => t.name.Equals(orderName)).FirstOrDefault(); if (Method != null) { item = itemGroups.Where(t => t.name.Equals(orderName) && t.Methods.Equals(Method)).FirstOrDefault(); } if (item == null) { throw new Exception($"PLC{PLCName},未定义指令{orderName}"); } if (typeof(DataType) == typeof(int))//4字节,有符号类型 { return (DataType)GetContent(siemensPLCClient.ReadInt32(item.dbAddress), item); } else if (typeof(DataType) == typeof(uint))//4字节,无符号类型 { return (DataType)GetContent(siemensPLCClient.ReadUInt32(item.dbAddress), item); } else if (typeof(DataType) == typeof(short))//2字节,有符号类型,最常用 { return (DataType)GetContent(siemensPLCClient.ReadInt16(item.dbAddress), item); } else if (typeof(DataType) == typeof(ushort))//2字节,无符号类型 { return (DataType)GetContent(siemensPLCClient.ReadUInt16(item.dbAddress), item); } else if (typeof(DataType) == typeof(float))//浮点型 { return (DataType)GetContent(siemensPLCClient.ReadFloat(item.dbAddress), item); } else if (typeof(DataType) == typeof(bool)) { return (DataType)GetContent(siemensPLCClient.ReadBool(item.dbAddress), item); } else if (typeof(DataType) == typeof(byte))//字节 { return (DataType)GetContent(siemensPLCClient.ReadByte(item.dbAddress), item); } else if (typeof(DataType) == typeof(byte[]))//字节数组 { return (DataType)GetContent(siemensPLCClient.Read(item.dbAddress, (ushort)item.dataLen), item); } else if (typeof(DataType) == typeof(string))//字符串 { var str = GetContent(siemensPLCClient.ReadString(item.dbAddress, (ushort)item.dataLen), item).ToString(); str = str.Replace("\0", "")?.Replace("\\", "")?.Replace("\u0014", "")?.Replace("?\u0006", "")?.Replace("\n", "")?.Replace("?", "")?.Trim(); return (DataType)(str as object); } else { throw new Exception($"【Error】,指令{orderName},未定义数据类型{typeof(DataType).Name}"); } } /// /// 写入数据 /// /// /// public override bool Write(string dbAddress, object value) { lock (_lockWrite) { Type dataType = value.GetType(); OperateResult result; if (dataType == typeof(int)) { result = siemensPLCClient.Write(dbAddress, Convert.ToInt32(value));//4字节,有符号 } else if (dataType == typeof(uint)) { result = siemensPLCClient.Write(dbAddress, Convert.ToUInt32(value));//4字节,无符号 } else if (dataType == typeof(short)) { result = siemensPLCClient.Write(dbAddress, Convert.ToInt16(value));//2字节,有符号,最常用 } else if (dataType == typeof(ushort)) { result = siemensPLCClient.Write(dbAddress, Convert.ToUInt16(value));//2字节,无符号,最常用 } else if (dataType == typeof(float)) { result = siemensPLCClient.Write(dbAddress, (float)value);//4字节浮点型 } else if (dataType == typeof(bool)) { result = siemensPLCClient.Write(dbAddress, Convert.ToBoolean(value)); } else if (dataType == typeof(byte)) { result = siemensPLCClient.Write(dbAddress, (byte)value); } else if (dataType == typeof(byte[])) { result = siemensPLCClient.Write(dbAddress, (byte[])value); } else if (dataType == typeof(string)) { result = siemensPLCClient.Write(dbAddress, (string)value); } else { throw new Exception($"【Error】DB地址{dbAddress},未定义数据类型{dataType.Name}"); } if (!result.IsSuccess) { IsConnected = false; WriteLog.Write_Log(PLCName, $"{PLCName}_Write", $"{dbAddress}写入失败," + result.Message); throw new Exception($"{dbAddress}写入失败," + result.Message); } return result.IsSuccess; } } /// /// 写入数据,根据数据库指令 /// /// /// public override bool WriteByOrder(string orderName, object value, string Method = null) { lock (_lockWrite) { var item = itemGroups.Where(t => t.name.Equals(orderName)).FirstOrDefault(); if (Method != null) { item = itemGroups.Where(t => t.name.Equals(orderName) && t.Methods.Equals(Method)).FirstOrDefault(); } if (item == null) { throw new Exception($"PLC{PLCName},未定义指令{orderName}"); } Type dataType = value.GetType(); OperateResult result; if (dataType == typeof(int)) { result = siemensPLCClient.Write(item.dbAddress, Convert.ToInt32(value));//4字节,有符号 } else if (dataType == typeof(uint)) { result = siemensPLCClient.Write(item.dbAddress, Convert.ToUInt32(value));//4字节,无符号 } else if (dataType == typeof(short)) { result = siemensPLCClient.Write(item.dbAddress, Convert.ToInt16(value));//2字节,有符号,最常用 } else if (dataType == typeof(ushort)) { result = siemensPLCClient.Write(item.dbAddress, Convert.ToUInt16(value));//2字节,无符号,最常用 } else if (dataType == typeof(float)) { result = siemensPLCClient.Write(item.dbAddress, (float)value);//4字节浮点型 } else if (dataType == typeof(bool)) { result = siemensPLCClient.Write(item.dbAddress, Convert.ToBoolean(value)); } else if (dataType == typeof(byte)) { result = siemensPLCClient.Write(item.dbAddress, (byte)value); } else if (dataType == typeof(byte[])) { result = siemensPLCClient.Write(item.dbAddress, (byte[])value); } else if (dataType == typeof(string)) { result = siemensPLCClient.Write(item.dbAddress, (string)value); } else { throw new Exception($"【Error】指令{item.name},DB地址{item.dbAddress},未定义数据类型{dataType.Name}"); } if (!result.IsSuccess) { IsConnected = false; WriteLog.Write_Log(PLCName, $"{PLCName}_Write", $"{orderName}写入失败," + result.Message, item); throw new Exception($"{PLCName},{orderName}写入失败," + result.Message); } return result.IsSuccess; } } } }