新增信号交互进程插件

This commit is contained in:
ykkokluo
2026-08-17 15:20:27 +08:00
parent 12c7c1d518
commit cacc5fea5c
25 changed files with 937 additions and 369 deletions
+24 -1
View File
@@ -5,9 +5,17 @@ using IoTClient.Common.Enums;
namespace StandardScene.Signal.Plc
{
/// <summary>西门子 S7 长连接。地址兼容 Hsl 的 DB1.0 与 IoTClient 的 DB1.DBB0。</summary>
/// <summary>
/// 西门子 S7 长连接封装(IoTClient)。一个机构一个实例,由对应 Worker 独占。
/// </summary>
/// <remarks>
/// 字节地址兼容老 Hsl 写法 <c>DB1.0</c> 与 IoTClient 写法 <c>DB1.DBB0</c>
/// 心跳位地址保持原样(如 <c>DB1.DBX2.0</c>),不做 DBB 转换。
/// 连接失败时读/写返回 false,由 Worker 标断线,不在这里抛给扫车线程。
/// </remarks>
public sealed class SiemensPlcSession : IDisposable
{
/// <summary>匹配 Hsl 风格「DB块号.字节偏移」,捕获组 1=DB2=偏移。</summary>
private static readonly Regex BareDbByte = new Regex(@"^DB(\d+)\.(\d+)$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private readonly SiemensVersion _version;
@@ -17,6 +25,10 @@ namespace StandardScene.Signal.Plc
private SiemensClient _client;
private readonly object _sync = new object();
/// <param name="version">进程字段 PlcVersion,如 S7_1500。</param>
/// <param name="ip">机构 IP。</param>
/// <param name="port">S7 端口,通常 102。</param>
/// <param name="slot">机架槽号,S7-1500 常见 1。</param>
public SiemensPlcSession(string version, string ip, int port, int slot)
{
_version = ParseVersion(version);
@@ -25,6 +37,7 @@ namespace StandardScene.Signal.Plc
_slot = (byte)Math.Max(0, slot);
}
/// <summary>当前客户端是否已 Open 成功。未创建客户端时为 false。</summary>
public bool Connected
{
get
@@ -33,6 +46,7 @@ namespace StandardScene.Signal.Plc
}
}
/// <summary>惰性创建客户端并 Open。已连接则直接 true;失败返回 false 不抛。</summary>
public bool EnsureOpen()
{
lock (_sync)
@@ -53,6 +67,7 @@ namespace StandardScene.Signal.Plc
}
}
/// <summary>读一字节。地址会先规范化;未连接或失败时 value=0 且返回 false。</summary>
public bool TryReadByte(string address, out byte value)
{
value = 0;
@@ -72,6 +87,7 @@ namespace StandardScene.Signal.Plc
}
}
/// <summary>写一字节(进入中/到位等)。失败返回 false。</summary>
public bool TryWriteByte(string address, byte value)
{
if (string.IsNullOrWhiteSpace(address) || !EnsureOpen())
@@ -87,6 +103,7 @@ namespace StandardScene.Signal.Plc
}
}
/// <summary>读心跳位。地址不做 DBB 转换。</summary>
public bool TryReadBool(string address, out bool value)
{
value = false;
@@ -106,6 +123,7 @@ namespace StandardScene.Signal.Plc
}
}
/// <summary>写心跳位(通常写当前值的反码,让 PLC 看到翻转)。</summary>
public bool TryWriteBool(string address, bool value)
{
if (string.IsNullOrWhiteSpace(address) || !EnsureOpen())
@@ -121,6 +139,7 @@ namespace StandardScene.Signal.Plc
}
}
/// <summary>关闭并丢弃客户端,下次 EnsureOpen 会新建。</summary>
public void Close()
{
lock (_sync)
@@ -133,6 +152,9 @@ namespace StandardScene.Signal.Plc
public void Dispose() => Close();
/// <summary>
/// <c>DB1.0</c> → <c>DB1.DBB0</c>;已是 DBB/DBW/DBX 的地址原样返回。
/// </summary>
internal static string NormalizeByteAddress(string address)
{
var addr = address.Trim();
@@ -140,6 +162,7 @@ namespace StandardScene.Signal.Plc
return m.Success ? $"DB{m.Groups[1].Value}.DBB{m.Groups[2].Value}" : addr;
}
/// <summary>空或无法解析时默认 S7_1500。允许把 S7-1500 写成带连字符。</summary>
internal static SiemensVersion ParseVersion(string version)
{
if (string.IsNullOrWhiteSpace(version))