Files
2025-09-11 16:22:12 +08:00

161 lines
5.4 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
};
}
/// <summary>
/// 尝试连接到PLC
/// </summary>
/// <returns>连接成功返回true失败返回false</returns>
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;
}
}
/// <summary>
/// 检查PLC连接状态
/// </summary>
/// <returns>连接正常返回true否则返回false</returns>
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;
}
}
/// <summary>
/// 重连PLC
/// </summary>
/// <returns>重连成功返回true失败返回false</returns>
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);
}
}
/// <summary>
/// 向PLC写入单个bit值
/// </summary>
/// <param name="addr">PLC地址</param>
/// <param name="value">要写入的bool值</param>
/// <returns>写入成功返回true失败返回false</returns>
public bool WriteBit(string addr, bool value)
{
var write = siemensTcpNet.Write(addr, value);
return write.IsSuccess;
}
/// <summary>
/// 从PLC读取单个bit值
/// </summary>
/// <param name="addr">PLC地址</param>
/// <returns>读取到的bool值</returns>
public bool ReadBit(string addr)
{
return siemensTcpNet.ReadBool(addr).Content;
}
/// <summary>
/// 从PLC读取多个连续的二进制数据并转为字节数组
/// </summary>
/// <param name="addr">起始PLC地址默认为"VB100"</param>
/// <param name="length">要读取的字节数默认为12</param>
/// <returns>读取到的字节数组如果失败返回null</returns>
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;
}
}
/// <summary>
/// 关闭与PLC的连接
/// </summary>
public void ConnectClose()
{
siemensTcpNet.ConnectClose();
}
}
}