HuaRui/SiemensPLCTCPDriver.cs

395 lines
12 KiB
C#
Raw Permalink Normal View History

2024-08-17 14:06:39 +08:00

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");
//}
/// <summary>
/// 写单独地址
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
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");
}
/// <summary>
/// 写单独地址
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
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");
}
/// <summary>
/// 写单独地址 string值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
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");
}
/// <summary>
/// 写单独地址 float值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
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<int> GetMonitorValues(int startAddress, int length)
{
List<int> res = new List<int>();
// 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<int>(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<int> 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)
{
}
}
}
});
}
}
}