diff --git a/ZB.MOM.WW.OtOpcUa.slnx b/ZB.MOM.WW.OtOpcUa.slnx
index 6c2b4cc..670153c 100644
--- a/ZB.MOM.WW.OtOpcUa.slnx
+++ b/ZB.MOM.WW.OtOpcUa.slnx
@@ -41,6 +41,7 @@
+
diff --git a/docs/drivers/OpcUaClient-Test-Fixture.md b/docs/drivers/OpcUaClient-Test-Fixture.md
index f179fd7..83393a5 100644
--- a/docs/drivers/OpcUaClient-Test-Fixture.md
+++ b/docs/drivers/OpcUaClient-Test-Fixture.md
@@ -3,24 +3,55 @@
Coverage map + gap inventory for the OPC UA Client (gateway / aggregation)
driver.
-**TL;DR: there is no integration fixture.** Tests mock the OPC UA SDK's
-`Session` + `Subscription` types directly; there is no upstream OPC UA
-server standup in CI. The irony is not lost — this repo *is* an OPC UA
-server, and the integration fixtures for `OpcUaApplicationHost`
-(`tests/ZB.MOM.WW.OtOpcUa.Server.Tests/OpcUaServerIntegrationTests.cs` +
-`OpcUaEquipmentWalkerIntegrationTests.cs`) stand up the server-side stack
-end-to-end. The client-side driver could in principle wire against one of
-those, but doesn't today.
+**TL;DR:** Wire-level coverage now exists via
+[opc-plc](https://github.com/Azure-Samples/iot-edge-opc-plc) — Microsoft
+Industrial IoT's OPC UA PLC simulator running in Docker (task #215). Real
+Secure Channel, real Session, real MonitoredItem exchange against an
+independent server implementation. Unit tests still carry the exhaustive
+capability matrix (cert auth / security policies / reconnect / failover /
+attribute mapping). Gaps remaining: upstream-server-specific quirks
+(historian aggregates, typed ConditionType events, SDK-publish-queue edge
+behavior under load) — opc-plc uses the same OPCFoundation stack internally
+so fully-independent-stack coverage needs `open62541/open62541` as a second
+image (follow-up).
## What the fixture is
-Nothing at the integration layer.
-`tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests/` is unit-only. Tests
-inject fakes through the driver's construction path; the
+**Integration layer** (task #215):
+`tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/` stands up
+`mcr.microsoft.com/iotedge/opc-plc:2.14.10` via `Docker/docker-compose.yml`
+on `opc.tcp://localhost:50000`. `OpcPlcFixture` probes the port at
+collection init + skips tests with a clear message when the container's
+not running (matches the Modbus/pymodbus + S7/python-snap7 skip pattern).
+Docker is the launcher — no PowerShell wrapper needed because opc-plc
+ships pre-containerized. Compose-file flags: `--ut` (unsecured transport
+advertised), `--aa` (auto-accept client certs — opc-plc's cert trust store
+resets on each spin-up), `--alm` (alarm simulation for IAlarmSource
+follow-up coverage), `--pn=50000` (port).
+
+**Unit layer**:
+`tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests/` is still the primary
+coverage. Tests inject fakes through the driver's construction path; the
OPCFoundation.NetStandard `Session` surface is wrapped behind an interface
the tests mock.
-## What it actually covers (unit only)
+## What it actually covers
+
+### Integration (opc-plc Docker, task #215)
+
+- `OpcUaClientSmokeTests.Client_connects_and_reads_StepUp_node_through_real_OPC_UA_stack` —
+ full Secure Channel + Session + `ns=3;s=StepUp` Read round-trip
+- `OpcUaClientSmokeTests.Client_reads_batch_of_varied_types_from_live_simulator` —
+ batch Read of UInt32 / Int32 / Boolean; asserts `bool`-specific Variant
+ decoding to catch a common attribute-mapping regression
+- `OpcUaClientSmokeTests.Client_subscribe_receives_StepUp_data_changes_from_live_server` —
+ real `MonitoredItem` subscription against `ns=3;s=FastUInt1` (ticks every
+ 100 ms); asserts `OnDataChange` fires within 3 s of subscribe
+
+Wire-level surfaces verified: `IDriver` + `IReadable` + `ISubscribable` +
+`IHostConnectivityProbe` (via the Secure Channel exchange).
+
+### Unit
The surface is broad because `OpcUaClientDriver` is the richest-capability
driver in the fleet (it's a gateway for another OPC UA server, so it
diff --git a/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/Docker/README.md b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/Docker/README.md
new file mode 100644
index 0000000..cb7059d
--- /dev/null
+++ b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/Docker/README.md
@@ -0,0 +1,103 @@
+# opc-plc Docker fixture
+
+[Microsoft Industrial IoT's opc-plc](https://github.com/Azure-Samples/iot-edge-opc-plc)
+— pinned Docker image that stands up an OPC UA server at
+`opc.tcp://localhost:50000` with step-up counters, random nodes, alarm
+simulation, and other canonical simulated shapes. Replaces the PowerShell
+launcher pattern used by the Modbus / S7 fixtures — Docker is the launcher
+here since opc-plc ships pre-containerized.
+
+| File | Purpose |
+|---|---|
+| [`docker-compose.yml`](docker-compose.yml) | Service definition for `otopcua-opc-plc` — image pin, port map, command flags. |
+| (this file) | How to run it. |
+
+## Install
+
+Docker Desktop (Windows) or the docker CLI + daemon (Linux/macOS). Per
+`CLAUDE.md` Phase 1 decision #134 the dev box already has Docker Desktop
+configured with the WSL 2 backend — nothing new to install.
+
+## Run
+
+From the repo root:
+
+```powershell
+docker compose -f tests\ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests\Docker\docker-compose.yml up
+```
+
+Or from this folder:
+
+```powershell
+docker compose up
+```
+
+First run pulls the image (~250 MB). Startup takes ~5-10 seconds; the
+healthcheck in the compose file surfaces ready state in `docker ps`.
+
+To run detached (CI pattern):
+
+```powershell
+docker compose up -d
+```
+
+Stop with `docker compose down` (removes the container) or `docker compose stop`
+(keeps it for fast restart).
+
+## Endpoint
+
+- Default: `opc.tcp://localhost:50000`
+- Override by setting `OPCUA_SIM_ENDPOINT` before `dotnet test` — e.g. point
+ at a real OPC UA server in the lab, or at a different Docker host.
+
+## What opc-plc advertises
+
+Command flags in `docker-compose.yml` enable:
+
+- `--pn=50000` — OPC UA endpoint on port 50000
+- `--ut` — unsecured transport endpoint advertised (SecurityPolicy=None).
+ Secured policies are still on the endpoint list; `--ut` just adds an
+ unsecured option.
+- `--aa` — auto-accept client certs (opc-plc's cert trust store lives
+ inside the container + resets each spin-up, so without this the driver's
+ first contact would be rejected).
+- `--alm` — alarm simulation enabled; opc-plc publishes
+ `TripAlarmType`, `ExclusiveDeviationAlarmType`,
+ `NonExclusiveLevelAlarmType`, and `DialogConditionType` events.
+
+Not turned on (but available via compose-file tweaks):
+
+- `--daa` — disable anonymous auth; forces username or cert tokens. Flip
+ on when username-auth / cert-auth smoke tests land.
+- `--fn` / `--fr` / `--ft` — fast-node variants (100 / 1 000 / 10 000 Hz
+ update rates) for subscription-stress coverage. Not needed for smoke.
+- `--sn` / `--sr` — slow-node / special-shape coverage.
+
+## Run the integration tests
+
+In a separate shell, with the simulator running:
+
+```powershell
+cd C:\Users\dohertj2\Desktop\lmxopcua
+dotnet test tests\ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests
+```
+
+Tests auto-skip with a clear `SkipReason` when `localhost:50000` isn't
+reachable within 2 seconds (`OpcPlcFixture`).
+
+## Known limitations
+
+opc-plc uses the OPCFoundation.NetStandard stack internally — same as
+our driver. That means bugs common to the stack itself are **not** caught
+by this fixture; the follow-up to add `open62541/open62541` as a second
+independent-stack image (task tracked in #215's follow-ups) would close
+that.
+
+See [`docs/drivers/OpcUaClient-Test-Fixture.md`](../../../docs/drivers/OpcUaClient-Test-Fixture.md)
+for the full coverage map + what's still trusted from field deployments.
+
+## References
+
+- [opc-plc GitHub](https://github.com/Azure-Samples/iot-edge-opc-plc)
+- [mcr.microsoft.com/iotedge/opc-plc tags](https://mcr.microsoft.com/v2/iotedge/opc-plc/tags/list)
+- [`docs/drivers/OpcUaClient-Test-Fixture.md`](../../../docs/drivers/OpcUaClient-Test-Fixture.md)
diff --git a/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/Docker/docker-compose.yml b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/Docker/docker-compose.yml
new file mode 100644
index 0000000..18849ce
--- /dev/null
+++ b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/Docker/docker-compose.yml
@@ -0,0 +1,45 @@
+# opc-plc — OPC UA PLC simulator from Microsoft Industrial IoT.
+# https://github.com/Azure-Samples/iot-edge-opc-plc
+#
+# Why pinned: MCR tags only go forward; keeping the suite reproducible means
+# we test against a known feature surface. Bump deliberately alongside a
+# driver-side change that needs the newer image.
+services:
+ opc-plc:
+ image: mcr.microsoft.com/iotedge/opc-plc:2.14.10
+ container_name: otopcua-opc-plc
+ restart: "no"
+ ports:
+ - "50000:50000"
+ command:
+ # --pn: Bind port 50000 (opc-plc default; matches fixture default)
+ # --ut: Advertise an Unsecured transport endpoint (SecurityPolicy=None).
+ # Tests that need signed/encrypted endpoints pick those off the
+ # negotiated endpoint list separately — opc-plc always advertises
+ # the secure policies even with --ut on.
+ # --aa: Auto-accept client certs. Tests wouldn't otherwise survive the
+ # first contact because opc-plc's cert trust store lives inside
+ # the container + resets each spin-up.
+ # --daa: Disable anonymous auth — forces the driver to go through the
+ # Anonymous user-token policy negotiation rather than opc-plc's
+ # "no auth required" short-circuit. Would flip to username/cert
+ # if we needed that coverage.
+ # Commented out for first-pass smoke; flip on when the cert-auth
+ # and username-auth smoke tests land.
+ # --alm: Turn on alarm simulation (TripAlarm / ExclusiveDeviation /
+ # NonExclusiveLevel / DialogCondition). Closes the IAlarmSource
+ # gap the OpcUaClient-Test-Fixture doc calls out.
+ - "--pn=50000"
+ - "--ut"
+ - "--aa"
+ - "--alm"
+ # - "--daa"
+ healthcheck:
+ # opc-plc doesn't expose an HTTP health endpoint by default; use a TCP
+ # probe via a shell the base image ships with. The fixture does its own
+ # TCP probe but healthcheck surfaces status in `docker ps` for humans.
+ test: ["CMD-SHELL", "netstat -an | grep -q ':50000.*LISTEN' || exit 1"]
+ interval: 5s
+ timeout: 2s
+ retries: 10
+ start_period: 10s
diff --git a/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcPlcFixture.cs b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcPlcFixture.cs
new file mode 100644
index 0000000..856a12a
--- /dev/null
+++ b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcPlcFixture.cs
@@ -0,0 +1,97 @@
+using System.Net.Sockets;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests;
+
+///
+/// Reachability probe for an opc-plc simulator (Microsoft Industrial IoT's
+/// OPC UA PLC from mcr.microsoft.com/iotedge/opc-plc) or any real OPC UA
+/// server the OPCUA_SIM_ENDPOINT env var points at. Parses
+/// OPCUA_SIM_ENDPOINT (default opc.tcp://localhost:50000),
+/// TCP-connects to the resolved host:port at collection init, and records a
+/// on failure. Tests call Assert.Skip on that, so
+/// `dotnet test` stays green when Docker isn't running the simulator — mirrors the
+/// / Snap7ServerFixture pattern.
+///
+///
+///
+/// Why opc-plc over loopback against our own server — (1) independent
+/// cert chain + user-token handling catches interop bugs loopback can't;
+/// (2) built-in alarm ConditionType + history simulation gives
+/// +
+/// coverage without a custom
+/// driver fake; (3) pinned image tag fixes the test surface in a way our own
+/// evolving server wouldn't. Follow-up: add open62541/open62541 as a
+/// second image once this lands, for fully-independent-stack interop.
+///
+///
+/// Endpoint URL contract: parser strips the opc.tcp:// scheme + resolves
+/// host + port for the liveness probe only. The real test session always
+/// dials the full endpoint URL via
+/// so cert negotiation + security-policy selection run end-to-end.
+///
+///
+public sealed class OpcPlcFixture : IAsyncDisposable
+{
+ private const string DefaultEndpoint = "opc.tcp://localhost:50000";
+ private const string EndpointEnvVar = "OPCUA_SIM_ENDPOINT";
+
+ /// Full opc.tcp://host:port URL the driver session should connect to.
+ public string EndpointUrl { get; }
+ public string Host { get; }
+ public int Port { get; }
+ public string? SkipReason { get; }
+
+ public OpcPlcFixture()
+ {
+ EndpointUrl = Environment.GetEnvironmentVariable(EndpointEnvVar) ?? DefaultEndpoint;
+
+ (Host, Port) = ParseHostPort(EndpointUrl);
+
+ try
+ {
+ using var client = new TcpClient(AddressFamily.InterNetwork);
+ var task = client.ConnectAsync(
+ System.Net.Dns.GetHostAddresses(Host)
+ .FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork)
+ ?? System.Net.IPAddress.Loopback,
+ Port);
+ if (!task.Wait(TimeSpan.FromSeconds(2)) || !client.Connected)
+ {
+ SkipReason = $"opc-plc simulator at {Host}:{Port} did not accept a TCP connection within 2s. " +
+ $"Start it (`docker compose -f Docker/docker-compose.yml up`) or override {EndpointEnvVar}.";
+ }
+ }
+ catch (Exception ex)
+ {
+ SkipReason = $"opc-plc simulator at {Host}:{Port} unreachable: {ex.GetType().Name}: {ex.Message}. " +
+ $"Start it (`docker compose -f Docker/docker-compose.yml up`) or override {EndpointEnvVar}.";
+ }
+ }
+
+ ///
+ /// Parse "opc.tcp://host:port[/path]" → (host, port). Defaults to port 4840
+ /// (OPC UA standard) when the URL omits the port, but opc-plc's default is
+ /// 50000 so DefaultEndpoint carries it explicitly.
+ ///
+ private static (string Host, int Port) ParseHostPort(string endpointUrl)
+ {
+ const string scheme = "opc.tcp://";
+ var body = endpointUrl.StartsWith(scheme, StringComparison.OrdinalIgnoreCase)
+ ? endpointUrl[scheme.Length..]
+ : endpointUrl;
+ var slash = body.IndexOf('/');
+ if (slash >= 0) body = body[..slash];
+ var colon = body.IndexOf(':');
+ if (colon < 0) return (body, 4840);
+ var host = body[..colon];
+ return int.TryParse(body[(colon + 1)..], out var p) ? (host, p) : (host, 4840);
+ }
+
+ public ValueTask DisposeAsync() => ValueTask.CompletedTask;
+}
+
+[Xunit.CollectionDefinition(Name)]
+public sealed class OpcPlcCollection : Xunit.ICollectionFixture
+{
+ public const string Name = "OpcPlc";
+}
diff --git a/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcPlcProfile.cs b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcPlcProfile.cs
new file mode 100644
index 0000000..d57b07d
--- /dev/null
+++ b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcPlcProfile.cs
@@ -0,0 +1,38 @@
+using ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests;
+
+///
+/// Driver-side configuration + well-known opc-plc node identifiers that the smoke
+/// tests address. Node IDs are stable across opc-plc releases — the simulator
+/// guarantees the same ns=3;s=... names shipped since v1.0. If a release
+/// bump breaks these, the fixture's pinned image tag needs a coordinated bump.
+///
+public static class OpcPlcProfile
+{
+ /// opc-plc monotonically-increasing UInt32; ticks once per second under default opts.
+ public const string StepUp = "ns=3;s=StepUp";
+
+ /// opc-plc random Int32 node; new value ~every 100ms.
+ public const string RandomSignedInt32 = "ns=3;s=RandomSignedInt32";
+
+ /// opc-plc alternating boolean; flips every second.
+ public const string AlternatingBoolean = "ns=3;s=AlternatingBoolean";
+
+ /// opc-plc fast uint node — ticks every 100ms. Used for subscription-cadence tests.
+ public const string FastUInt1 = "ns=3;s=FastUInt1";
+
+ public static OpcUaClientDriverOptions BuildOptions(string endpointUrl) => new()
+ {
+ EndpointUrl = endpointUrl,
+ SecurityPolicy = OpcUaSecurityPolicy.None,
+ SecurityMode = OpcUaSecurityMode.None,
+ AuthType = OpcUaAuthType.Anonymous,
+ // opc-plc auto-accepts client certs (--aa) but we still present one; trust the
+ // server's cert back since the simulator regenerates it each container spin-up
+ // and there's no meaningful chain to validate against.
+ AutoAcceptCertificates = true,
+ Timeout = TimeSpan.FromSeconds(10),
+ SessionTimeout = TimeSpan.FromSeconds(30),
+ };
+}
diff --git a/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcUaClientSmokeTests.cs b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcUaClientSmokeTests.cs
new file mode 100644
index 0000000..ab11c64
--- /dev/null
+++ b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcUaClientSmokeTests.cs
@@ -0,0 +1,92 @@
+using Shouldly;
+using Xunit;
+using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests;
+
+///
+/// End-to-end smoke against a live opc-plc (task #215). Drives the real
+/// OPC UA Secure Channel + Session + MonitoredItem exchange — no mocks. Every
+/// test here proves a capability surface that loopback against our own server
+/// couldn't exercise cleanly: real cert negotiation, real endpoint descriptions,
+/// real simulated nodes that change without a write.
+///
+[Collection(OpcPlcCollection.Name)]
+[Trait("Category", "Integration")]
+[Trait("Simulator", "opc-plc")]
+public sealed class OpcUaClientSmokeTests(OpcPlcFixture sim)
+{
+ [Fact]
+ public async Task Client_connects_and_reads_StepUp_node_through_real_OPC_UA_stack()
+ {
+ if (sim.SkipReason is not null) Assert.Skip(sim.SkipReason);
+
+ var options = OpcPlcProfile.BuildOptions(sim.EndpointUrl);
+ await using var drv = new OpcUaClientDriver(options, driverInstanceId: "opcua-smoke-read");
+ await drv.InitializeAsync("{}", TestContext.Current.CancellationToken);
+
+ var snapshots = await drv.ReadAsync(
+ [OpcPlcProfile.StepUp], TestContext.Current.CancellationToken);
+
+ snapshots.Count.ShouldBe(1);
+ snapshots[0].StatusCode.ShouldBe(0u, "opc-plc StepUp read must succeed end-to-end");
+ snapshots[0].Value.ShouldNotBeNull("StepUp always has a current value");
+ }
+
+ [Fact]
+ public async Task Client_reads_batch_of_varied_types_from_live_simulator()
+ {
+ if (sim.SkipReason is not null) Assert.Skip(sim.SkipReason);
+
+ var options = OpcPlcProfile.BuildOptions(sim.EndpointUrl);
+ await using var drv = new OpcUaClientDriver(options, driverInstanceId: "opcua-smoke-batch");
+ await drv.InitializeAsync("{}", TestContext.Current.CancellationToken);
+
+ var snapshots = await drv.ReadAsync(
+ [OpcPlcProfile.StepUp, OpcPlcProfile.RandomSignedInt32, OpcPlcProfile.AlternatingBoolean],
+ TestContext.Current.CancellationToken);
+
+ snapshots.Count.ShouldBe(3);
+ foreach (var s in snapshots)
+ {
+ s.StatusCode.ShouldBe(0u);
+ s.Value.ShouldNotBeNull();
+ }
+ // AlternatingBoolean should decode as a bool specifically — catches a common
+ // attribute-mapping regression where the driver stringifies variant values.
+ snapshots[2].Value.ShouldBeOfType();
+ }
+
+ [Fact]
+ public async Task Client_subscribe_receives_StepUp_data_changes_from_live_server()
+ {
+ if (sim.SkipReason is not null) Assert.Skip(sim.SkipReason);
+
+ var options = OpcPlcProfile.BuildOptions(sim.EndpointUrl);
+ await using var drv = new OpcUaClientDriver(options, driverInstanceId: "opcua-smoke-sub");
+ await drv.InitializeAsync("{}", TestContext.Current.CancellationToken);
+
+ var observed = new List();
+ var gate = new SemaphoreSlim(0);
+ drv.OnDataChange += (_, e) =>
+ {
+ lock (observed) observed.Add(e);
+ gate.Release();
+ };
+
+ var handle = await drv.SubscribeAsync(
+ [OpcPlcProfile.FastUInt1], TimeSpan.FromMilliseconds(250),
+ TestContext.Current.CancellationToken);
+
+ // FastUInt1 ticks every 100 ms — one publishing interval (250 ms) should deliver.
+ // Wait up to 3 s to tolerate container warm-up + first-publish delay.
+ var got = await gate.WaitAsync(TimeSpan.FromSeconds(3), TestContext.Current.CancellationToken);
+ got.ShouldBeTrue("opc-plc FastUInt1 must publish at least one data change within 3s");
+
+ int observedCount;
+ lock (observed) observedCount = observed.Count;
+ observedCount.ShouldBeGreaterThan(0);
+
+ await drv.UnsubscribeAsync(handle, TestContext.Current.CancellationToken);
+ }
+}
diff --git a/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests.csproj b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests.csproj
new file mode 100644
index 0000000..c2e5bd7
--- /dev/null
+++ b/tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests.csproj
@@ -0,0 +1,35 @@
+
+
+
+ net10.0
+ enable
+ enable
+ false
+ true
+ ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+