feat(modbus-rtu): add Transport selector to the AdminUI Modbus driver form
Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
This commit is contained in:
+15
@@ -27,6 +27,16 @@
|
|||||||
}
|
}
|
||||||
</InputSelect>
|
</InputSelect>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Transport</label>
|
||||||
|
<InputSelect @bind-Value="_form.Transport" @bind-Value:after="EmitAsync" class="form-select form-select-sm">
|
||||||
|
@foreach (var e in Enum.GetValues<ModbusTransportMode>())
|
||||||
|
{
|
||||||
|
<option value="@e">@e</option>
|
||||||
|
}
|
||||||
|
</InputSelect>
|
||||||
|
<div class="form-text">RtuOverTcp = talk raw RTU frames to a serial→Ethernet gateway; must match the gateway's mode.</div>
|
||||||
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<label class="form-label">MELSEC sub-family</label>
|
<label class="form-label">MELSEC sub-family</label>
|
||||||
<InputSelect @bind-Value="_form.MelsecSubFamily" @bind-Value:after="EmitAsync" class="form-select form-select-sm">
|
<InputSelect @bind-Value="_form.MelsecSubFamily" @bind-Value:after="EmitAsync" class="form-select form-select-sm">
|
||||||
@@ -290,6 +300,9 @@
|
|||||||
public ModbusFamily Family { get; set; } = ModbusFamily.Generic;
|
public ModbusFamily Family { get; set; } = ModbusFamily.Generic;
|
||||||
public MelsecFamily MelsecSubFamily { get; set; } = MelsecFamily.Q_L_iQR;
|
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
|
// Transport flags
|
||||||
public bool AutoReconnect { get; set; } = true;
|
public bool AutoReconnect { get; set; } = true;
|
||||||
public int IdleDisconnectTimeoutSeconds { get; set; } = 0;
|
public int IdleDisconnectTimeoutSeconds { get; set; } = 0;
|
||||||
@@ -337,6 +350,7 @@
|
|||||||
TimeoutSeconds = (int)o.Timeout.TotalSeconds,
|
TimeoutSeconds = (int)o.Timeout.TotalSeconds,
|
||||||
Family = o.Family,
|
Family = o.Family,
|
||||||
MelsecSubFamily = o.MelsecSubFamily,
|
MelsecSubFamily = o.MelsecSubFamily,
|
||||||
|
Transport = o.Transport,
|
||||||
AutoReconnect = o.AutoReconnect,
|
AutoReconnect = o.AutoReconnect,
|
||||||
IdleDisconnectTimeoutSeconds = o.IdleDisconnectTimeout.HasValue ? (int)o.IdleDisconnectTimeout.Value.TotalSeconds : 0,
|
IdleDisconnectTimeoutSeconds = o.IdleDisconnectTimeout.HasValue ? (int)o.IdleDisconnectTimeout.Value.TotalSeconds : 0,
|
||||||
MaxRegistersPerRead = o.MaxRegistersPerRead,
|
MaxRegistersPerRead = o.MaxRegistersPerRead,
|
||||||
@@ -387,6 +401,7 @@
|
|||||||
MaxReadGap = (ushort)Math.Clamp(MaxReadGap, 0, 65535),
|
MaxReadGap = (ushort)Math.Clamp(MaxReadGap, 0, 65535),
|
||||||
Family = Family,
|
Family = Family,
|
||||||
MelsecSubFamily = MelsecSubFamily,
|
MelsecSubFamily = MelsecSubFamily,
|
||||||
|
Transport = Transport,
|
||||||
WriteOnChangeOnly = WriteOnChangeOnly,
|
WriteOnChangeOnly = WriteOnChangeOnly,
|
||||||
AutoReconnect = AutoReconnect,
|
AutoReconnect = AutoReconnect,
|
||||||
KeepAlive = new ModbusKeepAliveOptions
|
KeepAlive = new ModbusKeepAliveOptions
|
||||||
|
|||||||
@@ -61,4 +61,15 @@ public sealed class ModbusDriverFormModelTests
|
|||||||
json.ShouldContain("\"family\":\"MELSEC\""); // enum-as-name (not a number), camelCase key
|
json.ShouldContain("\"family\":\"MELSEC\""); // enum-as-name (not a number), camelCase key
|
||||||
json.ShouldNotContain("\"family\":0", Case.Sensitive); // never the numeric enum form
|
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<ModbusDriverOptions>(json, JsonOpts)!);
|
||||||
|
back.Transport.ShouldBe(ModbusTransportMode.RtuOverTcp);
|
||||||
|
json.ShouldContain("\"transport\":\"RtuOverTcp\""); // name string, never a number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user