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:
@@ -180,13 +180,15 @@ public sealed class S7ArrayReadTests
|
||||
var opts = new S7DriverOptions
|
||||
{
|
||||
Host = "192.0.2.1",
|
||||
Tags =
|
||||
[
|
||||
new("Scalar", "DB1.DBW0", S7DataType.Int16),
|
||||
new("Arr", "DB1.DBW10", S7DataType.Int16, ArrayCount: 8),
|
||||
],
|
||||
Probe = new S7ProbeOptions { Enabled = false },
|
||||
// Array tags are read-only this phase (writable arrays are rejected by the init guard).
|
||||
RawTags = S7RawTags.Entries(
|
||||
new S7TagDefinition("Scalar", "DB1.DBW0", S7DataType.Int16),
|
||||
new S7TagDefinition("Arr", "DB1.DBW10", S7DataType.Int16, Writable: false, ArrayCount: 8)),
|
||||
};
|
||||
using var drv = new S7Driver(opts, "s7-arr-disco");
|
||||
// v3: DiscoverAsync projects the table built at Initialize — initialize with a fake PLC first.
|
||||
using var drv = new S7Driver(opts, "s7-arr-disco", new ConnectingFakeS7PlcFactory());
|
||||
await drv.InitializeAsync("{}", TestContext.Current.CancellationToken);
|
||||
|
||||
var builder = new RecordingAddressSpaceBuilder();
|
||||
await drv.DiscoverAsync(builder, TestContext.Current.CancellationToken);
|
||||
@@ -209,9 +211,12 @@ public sealed class S7ArrayReadTests
|
||||
var opts = new S7DriverOptions
|
||||
{
|
||||
Host = "192.0.2.1",
|
||||
Tags = [new("One", "DB1.DBW0", S7DataType.Int16, ArrayCount: 1)],
|
||||
Probe = new S7ProbeOptions { Enabled = false },
|
||||
RawTags = S7RawTags.Entries(new S7TagDefinition("One", "DB1.DBW0", S7DataType.Int16, Writable: false, ArrayCount: 1)),
|
||||
};
|
||||
using var drv = new S7Driver(opts, "s7-arr-one");
|
||||
// v3: DiscoverAsync projects the table built at Initialize — initialize with a fake PLC first.
|
||||
using var drv = new S7Driver(opts, "s7-arr-one", new ConnectingFakeS7PlcFactory());
|
||||
await drv.InitializeAsync("{}", TestContext.Current.CancellationToken);
|
||||
|
||||
var builder = new RecordingAddressSpaceBuilder();
|
||||
await drv.DiscoverAsync(builder, TestContext.Current.CancellationToken);
|
||||
@@ -228,9 +233,12 @@ public sealed class S7ArrayReadTests
|
||||
var opts = new S7DriverOptions
|
||||
{
|
||||
Host = "192.0.2.1",
|
||||
Tags = [new("Scalar", "DB1.DBW0", S7DataType.Int16, ArrayCount: null)],
|
||||
Probe = new S7ProbeOptions { Enabled = false },
|
||||
RawTags = S7RawTags.Entries(new S7TagDefinition("Scalar", "DB1.DBW0", S7DataType.Int16, ArrayCount: null)),
|
||||
};
|
||||
using var drv = new S7Driver(opts, "s7-arr-null");
|
||||
// v3: DiscoverAsync projects the table built at Initialize — initialize with a fake PLC first.
|
||||
using var drv = new S7Driver(opts, "s7-arr-null", new ConnectingFakeS7PlcFactory());
|
||||
await drv.InitializeAsync("{}", TestContext.Current.CancellationToken);
|
||||
|
||||
var builder = new RecordingAddressSpaceBuilder();
|
||||
await drv.DiscoverAsync(builder, TestContext.Current.CancellationToken);
|
||||
@@ -253,32 +261,33 @@ public sealed class S7ArrayReadTests
|
||||
arr[0].ShouldBe((short)100);
|
||||
}
|
||||
|
||||
// ── Equipment-tag resolver threads arrayLength → ArrayCount ───────────────────────────
|
||||
// ── Tag-definition factory threads arrayLength → ArrayCount ───────────────────────────
|
||||
|
||||
/// <summary>Verifies the equipment-tag parser threads isArray/arrayLength into ArrayCount.</summary>
|
||||
/// <summary>Verifies the tag-definition factory threads isArray/arrayLength into ArrayCount.</summary>
|
||||
[Fact]
|
||||
public void EquipmentTagParser_threads_array_length_into_ArrayCount()
|
||||
public void TagDefinitionFactory_threads_array_length_into_ArrayCount()
|
||||
{
|
||||
var json = """{"address":"DB1.DBW0","dataType":"Int16","isArray":true,"arrayLength":16}""";
|
||||
S7EquipmentTagParser.TryParse(json, out var def).ShouldBeTrue();
|
||||
def!.ArrayCount.ShouldBe(16);
|
||||
S7TagDefinitionFactory.FromTagConfig(json, "line/eq/arr", out var def).ShouldBeTrue();
|
||||
def!.Name.ShouldBe("line/eq/arr", "the definition's identity is the RawPath");
|
||||
def.ArrayCount.ShouldBe(16);
|
||||
}
|
||||
|
||||
/// <summary>Verifies arrayLength is ignored when isArray is false (mirrors the sink foundation).</summary>
|
||||
[Fact]
|
||||
public void EquipmentTagParser_ignores_arrayLength_when_isArray_false()
|
||||
public void TagDefinitionFactory_ignores_arrayLength_when_isArray_false()
|
||||
{
|
||||
var json = """{"address":"DB1.DBW0","dataType":"Int16","isArray":false,"arrayLength":16}""";
|
||||
S7EquipmentTagParser.TryParse(json, out var def).ShouldBeTrue();
|
||||
S7TagDefinitionFactory.FromTagConfig(json, "line/eq/arr", out var def).ShouldBeTrue();
|
||||
def!.ArrayCount.ShouldBeNull("arrayLength is honoured only when isArray is true");
|
||||
}
|
||||
|
||||
/// <summary>Verifies a scalar equipment tag (no array keys) has a null ArrayCount.</summary>
|
||||
/// <summary>Verifies a scalar tag config (no array keys) has a null ArrayCount.</summary>
|
||||
[Fact]
|
||||
public void EquipmentTagParser_scalar_has_null_ArrayCount()
|
||||
public void TagDefinitionFactory_scalar_has_null_ArrayCount()
|
||||
{
|
||||
var json = """{"address":"DB1.DBW0","dataType":"Int16"}""";
|
||||
S7EquipmentTagParser.TryParse(json, out var def).ShouldBeTrue();
|
||||
S7TagDefinitionFactory.FromTagConfig(json, "line/eq/scalar", out var def).ShouldBeTrue();
|
||||
def!.ArrayCount.ShouldBeNull();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user