添加配置连接窗口已经相关S7与ModbusTCP连接功能
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using S7.Net;
|
||||
using S7.Net;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
@@ -9,7 +9,6 @@ namespace DeviceCommand.Base
|
||||
{
|
||||
public class S7Device : IS7Device
|
||||
{
|
||||
// 保持和你一致的连接参数命名属性
|
||||
public string IPAddress { get; private set; } = "127.0.0.1";
|
||||
public CpuType CpuType { get; private set; } = CpuType.S71200;
|
||||
public short Rack { get; private set; } = 0;
|
||||
@@ -20,21 +19,15 @@ namespace DeviceCommand.Base
|
||||
private Plc _plc;
|
||||
public Plc PlcContext => _plc;
|
||||
|
||||
// S7.Net 的 Plc.IsConnected 属性内部会通过 Socket 状态进行判断
|
||||
public bool IsConnected => _plc?.IsConnected ?? false;
|
||||
|
||||
// 统一线程锁
|
||||
protected readonly SemaphoreSlim _commLock = new(1, 1);
|
||||
|
||||
public S7Device()
|
||||
{
|
||||
// 初始化默认配置
|
||||
_plc = new Plc(CpuType, IPAddress, Rack, Slot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备参数配置(符合你的命名风格)
|
||||
/// </summary>
|
||||
public void ConfigureDevice(string ipAddress, CpuType cpuType, short rack = 0, short slot = 1, int sendTimeout = 3000, int receiveTimeout = 3000)
|
||||
{
|
||||
IPAddress = ipAddress;
|
||||
@@ -50,32 +43,30 @@ namespace DeviceCommand.Base
|
||||
await _commLock.WaitAsync(ct);
|
||||
try
|
||||
{
|
||||
// 如果已经连接,检查当前的 IP 和 CPU 类型是否一致,一致则直接复用
|
||||
if (_plc != null && _plc.IsConnected)
|
||||
{
|
||||
if (_plc.IP == IPAddress && _plc.CPU == CpuType && _plc.Rack == Rack && _plc.Slot == Slot)
|
||||
return true;
|
||||
}
|
||||
|
||||
// 修复:释放并彻底清空旧连接实例
|
||||
if (_plc != null)
|
||||
{
|
||||
_plc.Close();
|
||||
}
|
||||
|
||||
// 重新实例化 Plc 对象并配置超时
|
||||
_plc = new Plc(CpuType, IPAddress, Rack, Slot)
|
||||
{
|
||||
ReadTimeout = ReceiveTimeout,
|
||||
WriteTimeout = SendTimeout
|
||||
};
|
||||
|
||||
// 部分版本 S7.Net 的 OpenAsync 本身不接受 CancellationToken,我们通过 WaitAsync 实现超时
|
||||
await _plc.OpenAsync().WaitAsync(TimeSpan.FromMilliseconds(SendTimeout), ct);
|
||||
await _plc.OpenAsync();
|
||||
return _plc.IsConnected;
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[S7Device] 连接异常: IP={IPAddress}, CPU={CpuType}, Error={ex.Message}");
|
||||
System.Diagnostics.Debug.WriteLine($"[S7Device] 异常堆栈: {ex.StackTrace}");
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
@@ -125,7 +116,22 @@ namespace DeviceCommand.Base
|
||||
public async Task<T> ReadAsync<T>(string address, CancellationToken ct = default)
|
||||
{
|
||||
var result = await ReadAsync(address, ct);
|
||||
return (T)result;
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"[S7Device.ReadAsync<T>] 地址={address}, 返回类型={result?.GetType().Name ?? "null"}, 值={result}");
|
||||
|
||||
try
|
||||
{
|
||||
if (result is IConvertible convertible)
|
||||
{
|
||||
return (T)Convert.ChangeType(convertible, typeof(T));
|
||||
}
|
||||
return (T)result;
|
||||
}
|
||||
catch (InvalidCastException ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[S7Device.ReadAsync<T>] 类型转换失败: 目标类型={typeof(T).Name}, 实际类型={result.GetType().Name}, 值={result}, 异常={ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<byte[]> ReadBytesAsync(DataType dataType, int db, int startByteAdr, int count, CancellationToken ct = default)
|
||||
|
||||
Reference in New Issue
Block a user