using Shouldly; using Xunit; namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205; /// /// Verifies DL205/DL260 binary-coded-decimal register handling against the /// dl205.json pymodbus profile. HR[1072] = 0x1234 on the profile represents /// decimal 1234 (BCD nibbles). Reading it as would /// return 0x1234 = 4660; the path decodes 1234. /// [Collection(ModbusSimulatorCollection.Name)] [Trait("Category", "Integration")] [Trait("Device", "DL205")] public sealed class DL205BcdQuirkTests(ModbusSimulatorFixture sim) { [Fact] public async Task DL205_BCD16_decodes_HR1072_as_decimal_1234() { 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 (standard profile does not seed HR[1072])."); } var options = new ModbusDriverOptions { Host = sim.Host, Port = sim.Port, UnitId = 1, Timeout = TimeSpan.FromSeconds(2), Tags = [ 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"); await driver.InitializeAsync("{}", TestContext.Current.CancellationToken); var results = await driver.ReadAsync(["DL205_Count_Bcd", "DL205_Count_Int16"], TestContext.Current.CancellationToken); results[0].StatusCode.ShouldBe(0u); results[0].Value.ShouldBe(1234, "DL205 BCD register 0x1234 represents decimal 1234 per the DirectLOGIC convention"); results[1].StatusCode.ShouldBe(0u); results[1].Value.ShouldBe((short)0x1234, "same register read as Int16 returns the raw 0x1234 = 4660 value — proves BCD path is distinct"); } }