diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/AbCipRawTags.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/AbCipRawTags.cs
new file mode 100644
index 00000000..9fed1d68
--- /dev/null
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/AbCipRawTags.cs
@@ -0,0 +1,27 @@
+using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests;
+
+///
+/// Test helper bridging the pre-v3 pre-declared-tag authoring style (a typed
+/// ) to the v3 RawPath seam the driver now consumes
+/// (). Each typed def is serialised to its TagConfig blob via
+/// , and the def's identity (Name → RawPath),
+/// device routing key (DeviceHostAddress → ) and
+/// write-idempotence travel on the entry — exactly the shape the deploy artifact delivers. Lets the
+/// driver's integration smoke tests keep expressing fixtures as typed definitions while exercising the
+/// v3 RawTags → FromTagConfig table-build path. Mirrors the unit-test project's helper of
+/// the same name.
+///
+internal static class AbCipRawTags
+{
+ /// Projects typed definitions to the driver's RawTags option shape.
+ /// The typed definitions to project.
+ /// The equivalent list.
+ public static IReadOnlyList From(params AbCipTagDefinition[] defs) =>
+ [.. defs.Select(d => new RawTagEntry(
+ RawPath: d.Name,
+ TagConfig: AbCipTagDefinitionFactory.ToTagConfig(d),
+ WriteIdempotent: d.WriteIdempotent,
+ DeviceName: d.DeviceHostAddress))];
+}
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/AbCipReadSmokeTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/AbCipReadSmokeTests.cs
index a6b57fa5..51168dfb 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/AbCipReadSmokeTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/AbCipReadSmokeTests.cs
@@ -37,7 +37,7 @@ public sealed class AbCipReadSmokeTests
var drv = new AbCipDriver(new AbCipDriverOptions
{
Devices = [new AbCipDeviceOptions(deviceUri, profile.Family)],
- Tags = [new AbCipTagDefinition("Counter", deviceUri, "TestDINT", AbCipDataType.DInt)],
+ RawTags = AbCipRawTags.From(new AbCipTagDefinition("Counter", deviceUri, "TestDINT", AbCipDataType.DInt)),
Timeout = TimeSpan.FromSeconds(5),
}, $"drv-smoke-{profile.Family}");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/Emulate/AbCipEmulateAlmdTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/Emulate/AbCipEmulateAlmdTests.cs
index 193c475d..d33b464d 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/Emulate/AbCipEmulateAlmdTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/Emulate/AbCipEmulateAlmdTests.cs
@@ -54,7 +54,7 @@ public sealed class AbCipEmulateAlmdTests
Devices = [new AbCipDeviceOptions($"ab://{endpoint}/1,0")],
EnableAlarmProjection = true,
AlarmPollInterval = TimeSpan.FromMilliseconds(200),
- Tags = [
+ RawTags = AbCipRawTags.From(
new AbCipTagDefinition(
Name: "HighTempAlarm",
DeviceHostAddress: $"ab://{endpoint}/1,0",
@@ -72,8 +72,7 @@ public sealed class AbCipEmulateAlmdTests
DeviceHostAddress: $"ab://{endpoint}/1,0",
TagPath: "SimulateAlarm",
DataType: AbCipDataType.Bool,
- Writable: true),
- ],
+ Writable: true)),
};
await using var drv = new AbCipDriver(options, driverInstanceId: "emulate-almd");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/Emulate/AbCipEmulateUdtReadTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/Emulate/AbCipEmulateUdtReadTests.cs
index e36919bd..a6018c02 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/Emulate/AbCipEmulateUdtReadTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/Emulate/AbCipEmulateUdtReadTests.cs
@@ -51,7 +51,7 @@ public sealed class AbCipEmulateUdtReadTests
var options = new AbCipDriverOptions
{
Devices = [new AbCipDeviceOptions($"ab://{endpoint}/1,0")],
- Tags = [
+ RawTags = AbCipRawTags.From(
new AbCipTagDefinition(
Name: "Motor1",
DeviceHostAddress: $"ab://{endpoint}/1,0",
@@ -61,8 +61,7 @@ public sealed class AbCipEmulateUdtReadTests
new AbCipStructureMember("Speed", AbCipDataType.DInt),
new AbCipStructureMember("Torque", AbCipDataType.Real),
new AbCipStructureMember("Status", AbCipDataType.DInt),
- ]),
- ],
+ ])),
Timeout = TimeSpan.FromSeconds(5),
};
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyRawTags.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyRawTags.cs
new file mode 100644
index 00000000..ba0babd1
--- /dev/null
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyRawTags.cs
@@ -0,0 +1,32 @@
+using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests;
+
+///
+/// Test helper bridging the v2 authoring shape (a typed ) to the v3
+/// delivery shape (). Under v3 the driver no longer takes pre-declared
+/// definitions — the deploy artifact hands it authored raw tags (RawPath + TagConfig blob + owning
+/// DeviceName), and the driver rebuilds the typed definitions via
+/// . These integration smoke tests keep expressing their
+/// intent as typed definitions; this helper serialises each back to its TagConfig blob (via
+/// ) and packages it as a
+/// whose RawPath is the def's Name and whose is the def's
+/// DeviceHostAddress — so the round-trip through the real mapper reproduces the same definition
+/// the test authored, keyed by the same name the read/write/subscribe call sites use and routed to the
+/// same device (the driver matches DeviceName against a configured device's Name or HostAddress).
+/// Mirrors the unit-test project's helper of the same name.
+///
+internal static class AbLegacyRawTags
+{
+ /// Serialises one typed definition into its (RawPath = def.Name, DeviceName = def.DeviceHostAddress).
+ /// The typed definition to convert.
+ /// The equivalent .
+ public static RawTagEntry Entry(AbLegacyTagDefinition def)
+ => new(def.Name, AbLegacyTagDefinitionFactory.ToTagConfig(def), def.WriteIdempotent, DeviceName: def.DeviceHostAddress);
+
+ /// Serialises typed definitions into records.
+ /// The typed definitions to convert (array, params, or a collection expression).
+ /// The equivalent raw-tag entries.
+ public static IReadOnlyList Entries(params AbLegacyTagDefinition[] defs)
+ => [.. defs.Select(Entry)];
+}
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyReadSmokeTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyReadSmokeTests.cs
index 0aa29fc6..313892ce 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyReadSmokeTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyReadSmokeTests.cs
@@ -51,13 +51,12 @@ public sealed class AbLegacyReadSmokeTests(AbLegacyServerFixture sim)
await using var drv = new AbLegacyDriver(new AbLegacyDriverOptions
{
Devices = [new AbLegacyDeviceOptions(deviceUri, profile.Family)],
- Tags = [
+ RawTags = AbLegacyRawTags.Entries(
new AbLegacyTagDefinition(
Name: "IntCounter",
DeviceHostAddress: deviceUri,
Address: "N7:0",
- DataType: AbLegacyDataType.Int),
- ],
+ DataType: AbLegacyDataType.Int)),
Timeout = TimeSpan.FromSeconds(5),
Probe = new AbLegacyProbeOptions { Enabled = false },
}, driverInstanceId: $"ablegacy-smoke-{profile.Family}");
@@ -96,14 +95,13 @@ public sealed class AbLegacyReadSmokeTests(AbLegacyServerFixture sim)
await using var drv = new AbLegacyDriver(new AbLegacyDriverOptions
{
Devices = [new AbLegacyDeviceOptions(deviceUri, AbLegacyPlcFamily.Slc500)],
- Tags = [
+ RawTags = AbLegacyRawTags.Entries(
new AbLegacyTagDefinition(
Name: "Scratch",
DeviceHostAddress: deviceUri,
Address: "N7:5",
DataType: AbLegacyDataType.Int,
- Writable: true),
- ],
+ Writable: true)),
Timeout = TimeSpan.FromSeconds(5),
Probe = new AbLegacyProbeOptions { Enabled = false },
}, driverInstanceId: "ablegacy-smoke-rw");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/FocasRawTags.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/FocasRawTags.cs
new file mode 100644
index 00000000..200d5c6b
--- /dev/null
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/FocasRawTags.cs
@@ -0,0 +1,31 @@
+using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests;
+
+///
+/// Test helper bridging the v2 authoring shape (a typed ) to the v3
+/// delivery shape (). Under v3 the driver no longer takes pre-declared
+/// definitions — the deploy artifact hands it authored raw tags (RawPath + TagConfig blob + DeviceName),
+/// and the driver rebuilds the typed definitions via and routes
+/// each to its device by . These integration wire tests keep
+/// expressing their intent as typed definitions; this helper serialises each back to its TagConfig blob
+/// (via ) and packages it as a
+/// whose RawPath is the def's Name and whose DeviceName is the def's DeviceHostAddress — so
+/// the round-trip through the real mapper + device match reproduces the same definition the test authored,
+/// keyed by the same name the read/write/subscribe call sites use. Mirrors the unit-test project's helper
+/// of the same name.
+///
+internal static class FocasRawTags
+{
+ /// Serialises one typed definition into its (RawPath = def.Name, DeviceName = def.DeviceHostAddress).
+ /// The typed definition to convert.
+ /// The equivalent .
+ public static RawTagEntry Entry(FocasTagDefinition def)
+ => new(def.Name, FocasTagDefinitionFactory.ToTagConfig(def), def.WriteIdempotent, def.DeviceHostAddress);
+
+ /// Serialises typed definitions into records.
+ /// The typed definitions to convert (array, params, or a collection expression).
+ /// The equivalent raw-tag entries.
+ public static IReadOnlyList Entries(params FocasTagDefinition[] defs)
+ => [.. defs.Select(Entry)];
+}
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/Series/WireBackendCoverageTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/Series/WireBackendCoverageTests.cs
index 1da9f2c6..f09d7e39 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/Series/WireBackendCoverageTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/Series/WireBackendCoverageTests.cs
@@ -54,12 +54,10 @@ public sealed class WireBackendCoverageTests
var drv = new FocasDriver(new FocasDriverOptions
{
Devices = [new FocasDeviceOptions(DeviceHost)],
- Tags =
- [
+ RawTags = FocasRawTags.Entries(
new FocasTagDefinition("Param6711", DeviceHost, "PARAM:6711", FocasDataType.Int32, Writable: false),
new FocasTagDefinition("Macro500", DeviceHost, "MACRO:500", FocasDataType.Float64, Writable: false),
- new FocasTagDefinition("R100", DeviceHost, "R100", FocasDataType.Byte, Writable: false),
- ],
+ new FocasTagDefinition("R100", DeviceHost, "R100", FocasDataType.Byte, Writable: false)),
Probe = new FocasProbeOptions { Enabled = false },
}, driverInstanceId: "wire-usertags", clientFactory: new WireFocasClientFactory());
@@ -86,11 +84,9 @@ public sealed class WireBackendCoverageTests
var drv = new FocasDriver(new FocasDriverOptions
{
Devices = [new FocasDeviceOptions(DeviceHost, DeviceName: "Lathe-1")],
- Tags =
- [
+ RawTags = FocasRawTags.Entries(
new FocasTagDefinition("Run", DeviceHost, "R100", FocasDataType.Byte, Writable: false),
- new FocasTagDefinition("Speed", DeviceHost, "MACRO:500", FocasDataType.Float64, Writable: false),
- ],
+ new FocasTagDefinition("Speed", DeviceHost, "MACRO:500", FocasDataType.Float64, Writable: false)),
Probe = new FocasProbeOptions { Enabled = false },
}, driverInstanceId: "wire-discover", clientFactory: new WireFocasClientFactory());
@@ -127,7 +123,7 @@ public sealed class WireBackendCoverageTests
var drv = new FocasDriver(new FocasDriverOptions
{
Devices = [new FocasDeviceOptions(DeviceHost)],
- Tags = [new FocasTagDefinition("Run", DeviceHost, "R100", FocasDataType.Byte, Writable: false)],
+ RawTags = FocasRawTags.Entries(new FocasTagDefinition("Run", DeviceHost, "R100", FocasDataType.Byte, Writable: false)),
Probe = new FocasProbeOptions { Enabled = false },
}, driverInstanceId: "wire-subscribe", clientFactory: new WireFocasClientFactory());
@@ -172,7 +168,7 @@ public sealed class WireBackendCoverageTests
var drv = new FocasDriver(new FocasDriverOptions
{
Devices = [new FocasDeviceOptions(DeviceHost)],
- Tags = [],
+ RawTags = [],
Probe = new FocasProbeOptions { Enabled = false },
AlarmProjection = new FocasAlarmProjectionOptions
{
@@ -275,7 +271,7 @@ public sealed class WireBackendCoverageTests
var driver = new FocasDriver(new FocasDriverOptions
{
Devices = [new FocasDeviceOptions(DeviceHost, PositionDecimalPlaces: 1)],
- Tags = [],
+ RawTags = [],
Probe = new FocasProbeOptions { Enabled = false },
FixedTree = new FocasFixedTreeOptions
{
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/Series/WireBackendTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/Series/WireBackendTests.cs
index ec373748..6eff4b42 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/Series/WireBackendTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.IntegrationTests/Series/WireBackendTests.cs
@@ -57,7 +57,7 @@ public sealed class WireBackendTests
var driver = new FocasDriver(new FocasDriverOptions
{
Devices = [new FocasDeviceOptions(DeviceHost)],
- Tags = [],
+ RawTags = [],
Probe = new FocasProbeOptions { Enabled = false },
FixedTree = new FocasFixedTreeOptions
{
@@ -120,7 +120,7 @@ public sealed class WireBackendTests
var driver = new FocasDriver(new FocasDriverOptions
{
Devices = [new FocasDeviceOptions(DeviceHost)],
- Tags = [],
+ RawTags = [],
Probe = new FocasProbeOptions { Enabled = false },
FixedTree = new FocasFixedTreeOptions
{
@@ -175,7 +175,7 @@ public sealed class WireBackendTests
var driver = new FocasDriver(new FocasDriverOptions
{
Devices = [new FocasDeviceOptions(DeviceHost)],
- Tags = [],
+ RawTags = [],
Probe = new FocasProbeOptions { Enabled = false },
FixedTree = new FocasFixedTreeOptions
{
@@ -242,7 +242,7 @@ public sealed class WireBackendTests
var driver = new FocasDriver(new FocasDriverOptions
{
Devices = [new FocasDeviceOptions(DeviceHost)],
- Tags = [],
+ RawTags = [],
Probe = new FocasProbeOptions { Enabled = false },
FixedTree = new FocasFixedTreeOptions
{
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/AddressingGrammarTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/AddressingGrammarTests.cs
index a53ccfb2..2d372eba 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/AddressingGrammarTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/AddressingGrammarTests.cs
@@ -27,7 +27,7 @@ public sealed class AddressingGrammarTests
{
var opts = new ModbusDriverOptions
{
- Host = _sim.Host, Port = _sim.Port, Tags = tags,
+ Host = _sim.Host, Port = _sim.Port, RawTags = ModbusRawTags.Entries(tags),
Probe = new ModbusProbeOptions { Enabled = false },
};
var drv = new ModbusDriver(opts, "addressing-e2e");
@@ -108,7 +108,7 @@ public sealed class AddressingGrammarTests
var t3 = new ModbusTagDefinition("T3", ModbusRegion.HoldingRegisters, 204, ModbusDataType.Int16);
var opts = new ModbusDriverOptions
{
- Host = _sim.Host, Port = _sim.Port, Tags = [t1, t2, t3], MaxReadGap = 5,
+ Host = _sim.Host, Port = _sim.Port, RawTags = ModbusRawTags.Entries([t1, t2, t3]), MaxReadGap = 5,
Probe = new ModbusProbeOptions { Enabled = false },
};
var drv = new ModbusDriver(opts, "addressing-e2e");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205BcdQuirkTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205BcdQuirkTests.cs
index 8fbf8e40..b3ae07e1 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205BcdQuirkTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205BcdQuirkTests.cs
@@ -31,15 +31,14 @@ public sealed class DL205BcdQuirkTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition("DL205_Count_Bcd",
ModbusRegion.HoldingRegisters, Address: 1072,
DataType: ModbusDataType.Bcd16, Writable: false),
new ModbusTagDefinition("DL205_Count_Int16",
ModbusRegion.HoldingRegisters, Address: 1072,
DataType: ModbusDataType.Int16, Writable: false),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(options, driverInstanceId: "dl205-bcd");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205CoilMappingTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205CoilMappingTests.cs
index b77b635f..3b5019b6 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205CoilMappingTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205CoilMappingTests.cs
@@ -106,7 +106,7 @@ public sealed class DL205CoilMappingTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags = tags,
+ RawTags = ModbusRawTags.Entries(tags),
Probe = new ModbusProbeOptions { Enabled = false },
};
}
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205ExceptionCodeTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205ExceptionCodeTests.cs
index 4a7e166f..e7a3773f 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205ExceptionCodeTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205ExceptionCodeTests.cs
@@ -36,12 +36,11 @@ public sealed class DL205ExceptionCodeTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition("Unmapped",
ModbusRegion.HoldingRegisters, Address: 16383,
DataType: ModbusDataType.UInt16, Writable: false),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(options, driverInstanceId: "dl205-exc");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205FloatCdabQuirkTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205FloatCdabQuirkTests.cs
index fecfce23..a90fa677 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205FloatCdabQuirkTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205FloatCdabQuirkTests.cs
@@ -33,8 +33,7 @@ public sealed class DL205FloatCdabQuirkTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition("DL205_Float_CDAB",
ModbusRegion.HoldingRegisters, Address: 1056,
DataType: ModbusDataType.Float32, Writable: false,
@@ -44,7 +43,7 @@ public sealed class DL205FloatCdabQuirkTests(ModbusSimulatorFixture sim)
ModbusRegion.HoldingRegisters, Address: 1056,
DataType: ModbusDataType.Float32, Writable: false,
ByteOrder: ModbusByteOrder.BigEndian),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(options, driverInstanceId: "dl205-cdab");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205Profile.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205Profile.cs
index 80b0c08f..5f635de1 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205Profile.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205Profile.cs
@@ -37,15 +37,14 @@ public static class DL205Profile
Port = port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition(
Name: "Smoke_HReg200",
Region: ModbusRegion.HoldingRegisters,
Address: SmokeHoldingRegister,
DataType: ModbusDataType.Int16,
Writable: true),
- ],
+ ]),
// Disable the background probe loop — integration tests drive reads explicitly and
// the probe would race with assertions.
Probe = new ModbusProbeOptions { Enabled = false },
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205StringQuirkTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205StringQuirkTests.cs
index 3614de57..0ff12dbf 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205StringQuirkTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205StringQuirkTests.cs
@@ -40,8 +40,7 @@ public sealed class DL205StringQuirkTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition(
Name: "DL205_Hello_Low",
Region: ModbusRegion.HoldingRegisters,
@@ -60,7 +59,7 @@ public sealed class DL205StringQuirkTests(ModbusSimulatorFixture sim)
Writable: false,
StringLength: 5,
StringByteOrder: ModbusStringByteOrder.HighByteFirst),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(options, driverInstanceId: "dl205-string");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205VMemoryQuirkTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205VMemoryQuirkTests.cs
index 7242d680..01c679ef 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205VMemoryQuirkTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205VMemoryQuirkTests.cs
@@ -36,12 +36,11 @@ public sealed class DL205VMemoryQuirkTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition("DL205_V2000",
ModbusRegion.HoldingRegisters, Address: pdu,
DataType: ModbusDataType.UInt16, Writable: false),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(options, driverInstanceId: "dl205-vmem");
@@ -75,12 +74,11 @@ public sealed class DL205VMemoryQuirkTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition("DL205_V40400",
ModbusRegion.HoldingRegisters, Address: pdu,
DataType: ModbusDataType.UInt16, Writable: false),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(options, driverInstanceId: "dl205-sysv");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205XInputTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205XInputTests.cs
index 201a46a8..41cfa428 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205XInputTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/DL205/DL205XInputTests.cs
@@ -66,7 +66,7 @@ public sealed class DL205XInputTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags = tags,
+ RawTags = ModbusRawTags.Entries(tags),
Probe = new ModbusProbeOptions { Enabled = false },
};
}
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/ExceptionInjectionTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/ExceptionInjectionTests.cs
index 05dee5be..0cb5d767 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/ExceptionInjectionTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/ExceptionInjectionTests.cs
@@ -47,12 +47,11 @@ public sealed class ExceptionInjectionTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition(tagName,
ModbusRegion.HoldingRegisters, Address: (ushort)address,
DataType: ModbusDataType.UInt16, Writable: false),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(opts, driverInstanceId: "modbus-exc");
@@ -112,12 +111,11 @@ public sealed class ExceptionInjectionTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition(tag,
ModbusRegion.HoldingRegisters, Address: (ushort)address,
DataType: ModbusDataType.UInt16, Writable: true),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(opts, driverInstanceId: "modbus-exc-write");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/Mitsubishi/MitsubishiProfile.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/Mitsubishi/MitsubishiProfile.cs
index f831e5e0..e60ef47d 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/Mitsubishi/MitsubishiProfile.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/Mitsubishi/MitsubishiProfile.cs
@@ -32,15 +32,14 @@ public static class MitsubishiProfile
Port = port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition(
Name: "Smoke_HReg200",
Region: ModbusRegion.HoldingRegisters,
Address: SmokeHoldingRegister,
DataType: ModbusDataType.Int16,
Writable: true),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
}
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/Mitsubishi/MitsubishiQuirkTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/Mitsubishi/MitsubishiQuirkTests.cs
index 8d28ecbc..6b2f1712 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/Mitsubishi/MitsubishiQuirkTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/Mitsubishi/MitsubishiQuirkTests.cs
@@ -176,7 +176,7 @@ public sealed class MitsubishiQuirkTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags = tags,
+ RawTags = ModbusRawTags.Entries(tags),
Probe = new ModbusProbeOptions { Enabled = false },
},
driverInstanceId: "melsec-quirk");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/ModbusRawTags.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/ModbusRawTags.cs
new file mode 100644
index 00000000..265ed4bf
--- /dev/null
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/ModbusRawTags.cs
@@ -0,0 +1,29 @@
+using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests;
+
+///
+/// Test helper bridging the v2 authoring shape (a typed ) to the v3
+/// delivery shape (). Under v3 the driver no longer takes pre-declared
+/// definitions — the deploy artifact hands it authored raw tags (RawPath + TagConfig blob), and the
+/// driver rebuilds the typed definitions via . These integration
+/// profiles + quirk tests keep expressing their intent as typed definitions; this helper serialises each
+/// back to its TagConfig blob (via ) and packages it
+/// as a whose RawPath is the def's Name — so the round-trip through the
+/// real mapper reproduces the same definition the test authored, keyed by the same name the
+/// read/write/subscribe call sites use. Mirrors the unit-test project's helper of the same name.
+///
+internal static class ModbusRawTags
+{
+ /// Serialises one typed definition into its (RawPath = def.Name).
+ /// The typed definition to convert.
+ /// The equivalent .
+ public static RawTagEntry Entry(ModbusTagDefinition def)
+ => new(def.Name, ModbusTagDefinitionFactory.ToTagConfig(def), def.WriteIdempotent);
+
+ /// Serialises a sequence of typed definitions into records.
+ /// The typed definitions to convert.
+ /// The equivalent raw-tag entries.
+ public static IReadOnlyList Entries(IEnumerable defs)
+ => [.. defs.Select(Entry)];
+}
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/S7/S7_1500Profile.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/S7/S7_1500Profile.cs
index adfcdac3..0cb75b0a 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/S7/S7_1500Profile.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/S7/S7_1500Profile.cs
@@ -32,15 +32,14 @@ public static class S7_1500Profile
Port = port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition(
Name: "Smoke_HReg200",
Region: ModbusRegion.HoldingRegisters,
Address: SmokeHoldingRegister,
DataType: ModbusDataType.Int16,
Writable: true),
- ],
+ ]),
// Disable the background probe loop — integration tests drive reads explicitly and
// the probe would race with assertions.
Probe = new ModbusProbeOptions { Enabled = false },
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/S7/S7_ByteOrderTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/S7/S7_ByteOrderTests.cs
index f604dbf3..2d3c6c4c 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/S7/S7_ByteOrderTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/S7/S7_ByteOrderTests.cs
@@ -33,8 +33,7 @@ public sealed class S7_ByteOrderTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition("S7_Float_ABCD",
ModbusRegion.HoldingRegisters, Address: 100,
DataType: ModbusDataType.Float32, Writable: false,
@@ -45,7 +44,7 @@ public sealed class S7_ByteOrderTests(ModbusSimulatorFixture sim)
ModbusRegion.HoldingRegisters, Address: 100,
DataType: ModbusDataType.Float32, Writable: false,
ByteOrder: ModbusByteOrder.WordSwap),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(options, driverInstanceId: "s7-float-abcd");
@@ -79,13 +78,12 @@ public sealed class S7_ByteOrderTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition("S7_Int32_ABCD",
ModbusRegion.HoldingRegisters, Address: 300,
DataType: ModbusDataType.Int32, Writable: false,
ByteOrder: ModbusByteOrder.BigEndian),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(options, driverInstanceId: "s7-int-abcd");
@@ -117,12 +115,11 @@ public sealed class S7_ByteOrderTests(ModbusSimulatorFixture sim)
Port = sim.Port,
UnitId = 1,
Timeout = TimeSpan.FromSeconds(2),
- Tags =
- [
+ RawTags = ModbusRawTags.Entries([
new ModbusTagDefinition("S7_Fingerprint",
ModbusRegion.HoldingRegisters, Address: 0,
DataType: ModbusDataType.UInt16, Writable: false),
- ],
+ ]),
Probe = new ModbusProbeOptions { Enabled = false },
};
await using var driver = new ModbusDriver(options, driverInstanceId: "s7-fingerprint");
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests/S7RawTags.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests/S7RawTags.cs
new file mode 100644
index 00000000..aba103da
--- /dev/null
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests/S7RawTags.cs
@@ -0,0 +1,29 @@
+using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests;
+
+///
+/// Test helper bridging the v2 authoring shape (a typed ) to the v3
+/// delivery shape (). Under v3 the driver no longer takes pre-declared
+/// definitions — the deploy artifact hands it authored raw tags (RawPath + TagConfig blob), and the
+/// driver rebuilds the typed definitions via . These integration
+/// profiles keep expressing their intent as typed definitions; this helper serialises each back to its
+/// TagConfig blob (via ) and packages it as a
+/// whose RawPath is the def's Name — so the round-trip through the real
+/// mapper reproduces the same definition the profile authored, keyed by the same name the
+/// read/write/subscribe call sites use. Mirrors the unit-test project's helper of the same name.
+///
+internal static class S7RawTags
+{
+ /// Serialises one typed definition into its (RawPath = def.Name).
+ /// The typed definition to convert.
+ /// The equivalent .
+ public static RawTagEntry Entry(S7TagDefinition def)
+ => new(def.Name, S7TagDefinitionFactory.ToTagConfig(def), def.WriteIdempotent);
+
+ /// Serialises a sequence of typed definitions into records.
+ /// The typed definitions to convert.
+ /// The equivalent raw-tag entries.
+ public static IReadOnlyList Entries(params S7TagDefinition[] defs)
+ => [.. defs.Select(Entry)];
+}
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests/S7_1500/S7_1500Profile.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests/S7_1500/S7_1500Profile.cs
index c329e472..f840686e 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests/S7_1500/S7_1500Profile.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests/S7_1500/S7_1500Profile.cs
@@ -41,14 +41,12 @@ public static class S7_1500Profile
// gate, injecting flakiness that has nothing to do with the code
// under test.
Probe = new S7ProbeOptions { Enabled = false },
- Tags =
- [
+ RawTags = S7RawTags.Entries(
new S7TagDefinition(ProbeTag, "DB1.DBW0", S7DataType.UInt16),
new S7TagDefinition(SmokeI16Tag, "DB1.DBW10", S7DataType.Int16),
new S7TagDefinition(SmokeI32Tag, "DB1.DBD20", S7DataType.Int32),
new S7TagDefinition(SmokeF32Tag, "DB1.DBD30", S7DataType.Float32),
new S7TagDefinition(SmokeBoolTag, "DB1.DBX50.3", S7DataType.Bool),
- new S7TagDefinition(WriteScratchTag, "DB1.DBW100", S7DataType.UInt16),
- ],
+ new S7TagDefinition(WriteScratchTag, "DB1.DBW100", S7DataType.UInt16)),
};
}
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.IntegrationTests/TwinCAT3SmokeTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.IntegrationTests/TwinCAT3SmokeTests.cs
index a5f46f30..f6510e01 100644
--- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.IntegrationTests/TwinCAT3SmokeTests.cs
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.IntegrationTests/TwinCAT3SmokeTests.cs
@@ -246,14 +246,12 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
var options = new TwinCATDriverOptions
{
Devices = [new TwinCATDeviceOptions($"ads://{sim.TargetNetId}:{sim.AmsPort}", "XAR-VM")],
- Tags =
- [
+ RawTags = TwinCATRawTags.Entries(
new TwinCATTagDefinition(
Name: "Primitive",
DeviceHostAddress: $"ads://{sim.TargetNetId}:{sim.AmsPort}",
SymbolPath: symbolPath,
- DataType: type),
- ],
+ DataType: type)),
Timeout = TimeSpan.FromSeconds(5),
Probe = new TwinCATProbeOptions { Enabled = false },
};
@@ -307,8 +305,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
var options = new TwinCATDriverOptions
{
Devices = [new TwinCATDeviceOptions($"ads://{sim.TargetNetId}:{sim.AmsPort}", "XAR-VM")],
- Tags =
- [
+ RawTags = TwinCATRawTags.Entries(
new TwinCATTagDefinition(
Name: "WordBit3",
DeviceHostAddress: $"ads://{sim.TargetNetId}:{sim.AmsPort}",
@@ -318,8 +315,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
Name: "WordBit4",
DeviceHostAddress: $"ads://{sim.TargetNetId}:{sim.AmsPort}",
SymbolPath: "GVL_Primitives.vWord.4",
- DataType: TwinCATDataType.Bool),
- ],
+ DataType: TwinCATDataType.Bool)),
Timeout = TimeSpan.FromSeconds(5),
Probe = new TwinCATProbeOptions { Enabled = false },
};
@@ -345,8 +341,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
var options = new TwinCATDriverOptions
{
Devices = [new TwinCATDeviceOptions($"ads://{sim.TargetNetId}:{sim.AmsPort}", "XAR-VM")],
- Tags =
- [
+ RawTags = TwinCATRawTags.Entries(
new TwinCATTagDefinition(
Name: "MotorTemp",
DeviceHostAddress: $"ads://{sim.TargetNetId}:{sim.AmsPort}",
@@ -356,8 +351,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
Name: "MotorRunning",
DeviceHostAddress: $"ads://{sim.TargetNetId}:{sim.AmsPort}",
SymbolPath: "GVL_Plant.Line1.Stations[1].Axes[1].Motor.Running",
- DataType: TwinCATDataType.Bool),
- ],
+ DataType: TwinCATDataType.Bool)),
Timeout = TimeSpan.FromSeconds(5),
Probe = new TwinCATProbeOptions { Enabled = false },
};
@@ -386,8 +380,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
var options = new TwinCATDriverOptions
{
Devices = [new TwinCATDeviceOptions($"ads://{sim.TargetNetId}:{sim.AmsPort}", "XAR-VM")],
- Tags =
- [
+ RawTags = TwinCATRawTags.Entries(
new TwinCATTagDefinition(
Name: "NonexistentSymbol",
DeviceHostAddress: $"ads://{sim.TargetNetId}:{sim.AmsPort}",
@@ -398,8 +391,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
DeviceHostAddress: $"ads://{sim.TargetNetId}:{sim.AmsPort}",
SymbolPath: "GVL_Fixture.nCounter",
DataType: TwinCATDataType.DInt,
- Writable: false),
- ],
+ Writable: false)),
Timeout = TimeSpan.FromSeconds(5),
Probe = new TwinCATProbeOptions { Enabled = false },
};
@@ -442,8 +434,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
new TwinCATDeviceOptions(realHost, "Real-VM"),
new TwinCATDeviceOptions(ghostHost, "Ghost-VM"),
],
- Tags =
- [
+ RawTags = TwinCATRawTags.Entries(
new TwinCATTagDefinition(
Name: "RealCounter",
DeviceHostAddress: realHost,
@@ -453,8 +444,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
Name: "GhostCounter",
DeviceHostAddress: ghostHost,
SymbolPath: "GVL_Fixture.nCounter",
- DataType: TwinCATDataType.DInt),
- ],
+ DataType: TwinCATDataType.DInt)),
// Shorter timeout so the bogus device fails fast rather than dragging the whole
// test; the healthy read shouldn't be slowed down by a peer timeout.
Timeout = TimeSpan.FromSeconds(2),
@@ -488,7 +478,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
var options = new TwinCATDriverOptions
{
Devices = [new TwinCATDeviceOptions($"ads://{sim.TargetNetId}:{sim.AmsPort}", "XAR-VM")],
- Tags = [],
+ RawTags = [],
Timeout = TimeSpan.FromSeconds(5),
Probe = new TwinCATProbeOptions
{
@@ -532,7 +522,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
var options = new TwinCATDriverOptions
{
Devices = baseOptions.Devices,
- Tags = baseOptions.Tags,
+ RawTags = baseOptions.RawTags,
UseNativeNotifications = baseOptions.UseNativeNotifications,
Timeout = baseOptions.Timeout,
Probe = baseOptions.Probe,
@@ -565,7 +555,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
HostAddress: $"ads://{sim.TargetNetId}:{sim.AmsPort}",
DeviceName: "XAR-VM"),
],
- Tags = [
+ RawTags = TwinCATRawTags.Entries(
new TwinCATTagDefinition(
Name: "Counter",
DeviceHostAddress: $"ads://{sim.TargetNetId}:{sim.AmsPort}",
@@ -582,8 +572,7 @@ public sealed class TwinCAT3SmokeTests(TwinCATXarFixture sim)
DeviceHostAddress: $"ads://{sim.TargetNetId}:{sim.AmsPort}",
SymbolPath: "GVL_Arrays.aReal1D[5]",
DataType: TwinCATDataType.Real,
- Writable: true),
- ],
+ Writable: true)),
UseNativeNotifications = true,
Timeout = TimeSpan.FromSeconds(5),
// Disable the probe loop — the smoke tests run their own reads; a background
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.IntegrationTests/TwinCATRawTags.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.IntegrationTests/TwinCATRawTags.cs
new file mode 100644
index 00000000..0e01eaa8
--- /dev/null
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.IntegrationTests/TwinCATRawTags.cs
@@ -0,0 +1,32 @@
+using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.IntegrationTests;
+
+///
+/// Test helper bridging the v2 authoring shape (a typed ) to the v3
+/// delivery shape (). Under v3 the driver no longer takes pre-declared
+/// definitions — the deploy artifact hands it authored raw tags (RawPath + TagConfig blob + owning
+/// DeviceName), and the driver rebuilds the typed definitions via .
+/// These integration smoke tests keep expressing their intent as typed definitions; this helper serialises
+/// each back to its TagConfig blob (via ) and packages
+/// it as a whose RawPath is the def's Name and whose
+/// is the def's DeviceHostAddress — so the round-trip through
+/// the real mapper + the driver's device resolution (which matches DeviceName against the configured
+/// devices by host) reproduces the same definition + device routing the test authored, keyed by the same
+/// name the read/write/subscribe call sites use. Mirrors the unit-test project's helper of the same name.
+///
+internal static class TwinCATRawTags
+{
+ /// Serialises one typed definition into its
+ /// (RawPath = def.Name, DeviceName = def.DeviceHostAddress).
+ /// The typed definition to convert.
+ /// The equivalent .
+ public static RawTagEntry Entry(TwinCATTagDefinition def)
+ => new(def.Name, TwinCATTagDefinitionFactory.ToTagConfig(def), def.WriteIdempotent, def.DeviceHostAddress);
+
+ /// Serialises typed definitions into records.
+ /// The typed definitions to convert (array, params, or a collection expression).
+ /// The equivalent raw-tag entries.
+ public static IReadOnlyList Entries(params TwinCATTagDefinition[] defs)
+ => [.. defs.Select(Entry)];
+}