using Shouldly; using Xunit; namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205; /// /// Verifies the driver's Modbus-exception → OPC UA StatusCode translation end-to-end /// against the dl205.json pymodbus profile. pymodbus returns exception 02 (Illegal Data /// Address) for reads outside the configured register ranges, matching real DL205/DL260 /// firmware behavior per docs/v2/dl205.md §exception-codes. The driver must surface /// that as BadOutOfRange (0x803C0000) — not BadInternalError — so the /// operator sees a tag-config diagnosis instead of a generic driver-fault message. /// [Collection(ModbusSimulatorCollection.Name)] [Trait("Category", "Integration")] [Trait("Device", "DL205")] public sealed class DL205ExceptionCodeTests(ModbusSimulatorFixture sim) { [Fact] public async Task DL205_FC03_at_unmapped_register_returns_BadOutOfRange() { if (sim.SkipReason is not null) Assert.Skip(sim.SkipReason); if (!string.Equals(Environment.GetEnvironmentVariable("MODBUS_SIM_PROFILE"), "dl205", StringComparison.OrdinalIgnoreCase)) { Assert.Skip("MODBUS_SIM_PROFILE != dl205 — skipping."); } // Address 16383 is the last cell of hr-size=16384 in dl205.json; address 16384 is // beyond the configured HR range. pymodbus validates and returns exception 02 // (Illegal Data Address). var options = new ModbusDriverOptions { Host = sim.Host, Port = sim.Port, UnitId = 1, Timeout = TimeSpan.FromSeconds(2), Tags = [ 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"); await driver.InitializeAsync("{}", TestContext.Current.CancellationToken); var results = await driver.ReadAsync(["Unmapped"], TestContext.Current.CancellationToken); results[0].StatusCode.ShouldBe(0x803C0000u, "DL205 returns exception 02 for an FC03 at an unmapped register; driver must translate to BadOutOfRange (not BadInternalError)"); } }