v3(s7): apply Modbus RawTags exemplar to the S7 driver

Rename S7EquipmentTagParser -> S7TagDefinitionFactory; TryParse(reference)
-> FromTagConfig(tagConfig, rawPath, out def) (drops the leading-{ heuristic,
keys the def by RawPath, adds inverse ToTagConfig). Replace S7DriverOptions.Tags
(pre-declared S7TagDefinition list) with RawTags (IReadOnlyList<RawTagEntry>);
the driver builds its RawPath->def table from RawTags at Initialize via the
factory (skip+log on miss), resolver is byName-only, DiscoverAsync + init guards
+ address pre-parse now run off that table. Factory retires the pre-declared DTO
tag path (RawTags binding only). Cli BuildOptions serialises typed defs to
RawTagEntry. Tests migrated to a S7RawTags helper + FromTagConfig; parser test
files renamed. Coordinator's EquipmentTagConfigInspector S7 rename left to Wave-B
coordinator; Driver.S7.IntegrationTests (Docker-gated) left red per scope.

Driver.S7 + Cli build green; Driver.S7.Tests 264/264, S7.Cli.Tests 49/49.
This commit is contained in:
Joseph Doherty
2026-07-15 20:11:04 -04:00
parent c379e246d0
commit 1e26b9ab58
21 changed files with 425 additions and 251 deletions
@@ -22,7 +22,7 @@ public sealed class S7DriverReconnectTests
// Probe off — these tests drive reconnect through the read path deterministically; a
// background probe would race the created-connection assertions.
Probe = new S7ProbeOptions { Enabled = false },
Tags = [new S7TagDefinition("W0", "DB1.DBW0", S7DataType.UInt16, Writable: false)],
RawTags = S7RawTags.Entries(new S7TagDefinition("W0", "DB1.DBW0", S7DataType.UInt16, Writable: false)),
};
/// <summary>
@@ -265,7 +265,7 @@ public sealed class S7DriverReconnectTests
Host = "192.0.2.1",
Timeout = TimeSpan.FromSeconds(5), // long, so the CALLER token fires first, not the internal timeout
Probe = new S7ProbeOptions { Enabled = false },
Tags = [new S7TagDefinition("W0", "DB1.DBW0", S7DataType.UInt16, Writable: false)],
RawTags = S7RawTags.Entries(new S7TagDefinition("W0", "DB1.DBW0", S7DataType.UInt16, Writable: false)),
};
var factory = new FakeS7PlcFactory();
using var drv = new S7Driver(opts, "s7-caller-cancel", factory);
@@ -367,7 +367,7 @@ public sealed class S7DriverReconnectTests
Host = "192.0.2.1",
Timeout = TimeSpan.FromMilliseconds(250),
Probe = new S7ProbeOptions { Enabled = false },
Tags = [new S7TagDefinition("WW0", "DB1.DBW0", S7DataType.UInt16, Writable: true)],
RawTags = S7RawTags.Entries(new S7TagDefinition("WW0", "DB1.DBW0", S7DataType.UInt16, Writable: true)),
};
var factory = new FakeS7PlcFactory();
using var drv = new S7Driver(opts, "s7-cancel-write", factory);
@@ -448,7 +448,7 @@ public sealed class S7DriverReconnectTests
Interval = TimeSpan.FromMilliseconds(50),
Timeout = TimeSpan.FromMilliseconds(250),
},
Tags = [new S7TagDefinition("W0", "DB1.DBW0", S7DataType.UInt16, Writable: false)],
RawTags = S7RawTags.Entries(new S7TagDefinition("W0", "DB1.DBW0", S7DataType.UInt16, Writable: false)),
};
/// <summary>Polls <paramref name="condition"/> until it holds or <paramref name="timeout"/> elapses (returns either way).</summary>