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
|
{
|
/// <summary>
|
/// 西门子协议PLC
|
/// </summary>
|
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;
|
}
|
|
/// <summary>
|
/// 自定义西门子类型
|
/// </summary>
|
/// <param name="types"></param>
|
public SiemensPLCClient(SiemensPLCS types)
|
{
|
siemensPLCClient = new SiemensS7Net(types);
|
base.siemensPLCClient = this.siemensPLCClient;
|
}
|
|
/// <summary>
|
/// 连接PLC,长链接
|
/// </summary>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 断开PLC长链接
|
/// </summary>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 读取数据,直接写地址
|
/// </summary>
|
/// <typeparam name="DataType">数据类型</typeparam>
|
/// <param name="dbAddress">DB地址</param>
|
/// <param name="len">读取场地</param>
|
/// <returns></returns>
|
/// <exception cref="Exception"></exception>
|
public override DataType Read<DataType>(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}");
|
}
|
}
|
|
/// <summary>
|
/// 读取数据,根据数据库指令来
|
/// </summary>
|
/// <param name="orderName">IO点名称</param>
|
/// <returns></returns>
|
public override DataType ReadByOrder<DataType>(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}");
|
}
|
}
|
|
|
/// <summary>
|
/// 写入数据
|
/// </summary>
|
/// <param name="dbAddress"></param>
|
/// <param name="value"></param>
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 写入数据,根据数据库指令
|
/// </summary>
|
/// <param name="orderName"></param>
|
/// <exception cref="Exception"></exception>
|
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;
|
}
|
}
|
}
|
}
|