diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/Forms/ModbusDriverForm.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/Forms/ModbusDriverForm.razor
index f0959d1a..0c34a768 100644
--- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/Forms/ModbusDriverForm.razor
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Drivers/Forms/ModbusDriverForm.razor
@@ -27,6 +27,16 @@
}
+
+
+
+ @foreach (var e in Enum.GetValues())
+ {
+
+ }
+
+
RtuOverTcp = talk raw RTU frames to a serial→Ethernet gateway; must match the gateway's mode.
+
@@ -290,6 +300,9 @@
public ModbusFamily Family { get; set; } = ModbusFamily.Generic;
public MelsecFamily MelsecSubFamily { get; set; } = MelsecFamily.Q_L_iQR;
+ // Wire transport (Tcp = Modbus/TCP MBAP; RtuOverTcp = RTU framing over a serial→Ethernet gateway)
+ public ModbusTransportMode Transport { get; set; } = ModbusTransportMode.Tcp;
+
// Transport flags
public bool AutoReconnect { get; set; } = true;
public int IdleDisconnectTimeoutSeconds { get; set; } = 0;
@@ -337,6 +350,7 @@
TimeoutSeconds = (int)o.Timeout.TotalSeconds,
Family = o.Family,
MelsecSubFamily = o.MelsecSubFamily,
+ Transport = o.Transport,
AutoReconnect = o.AutoReconnect,
IdleDisconnectTimeoutSeconds = o.IdleDisconnectTimeout.HasValue ? (int)o.IdleDisconnectTimeout.Value.TotalSeconds : 0,
MaxRegistersPerRead = o.MaxRegistersPerRead,
@@ -387,6 +401,7 @@
MaxReadGap = (ushort)Math.Clamp(MaxReadGap, 0, 65535),
Family = Family,
MelsecSubFamily = MelsecSubFamily,
+ Transport = Transport,
WriteOnChangeOnly = WriteOnChangeOnly,
AutoReconnect = AutoReconnect,
KeepAlive = new ModbusKeepAliveOptions
diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/ModbusDriverFormModelTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/ModbusDriverFormModelTests.cs
index c7e47597..59c90bc2 100644
--- a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/ModbusDriverFormModelTests.cs
+++ b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/ModbusDriverFormModelTests.cs
@@ -61,4 +61,15 @@ public sealed class ModbusDriverFormModelTests
json.ShouldContain("\"family\":\"MELSEC\""); // enum-as-name (not a number), camelCase key
json.ShouldNotContain("\"family\":0", Case.Sensitive); // never the numeric enum form
}
+
+ [Fact]
+ public void Round_trip_preserves_Transport_mode()
+ {
+ var form = new ModbusDriverForm.FormModel { Transport = ModbusTransportMode.RtuOverTcp };
+ var json = JsonSerializer.Serialize(form.ToOptions(), JsonOpts);
+ var back = ModbusDriverForm.FormModel.FromOptions(
+ JsonSerializer.Deserialize(json, JsonOpts)!);
+ back.Transport.ShouldBe(ModbusTransportMode.RtuOverTcp);
+ json.ShouldContain("\"transport\":\"RtuOverTcp\""); // name string, never a number
+ }
}