fix(modbus): enforce region/type compatibility at the tag factory
P6: Coils/DiscreteInputs carry only Bool and register regions never Bool; the factory (and so the deploy-gate Inspect and the AdminUI parse consult) refuses a mismatch, and an absent dataType defaults per region (Bool for a bit region). A HoldingRegisters+Bool tag used to throw out of the coalescing planner and stall every tag of the subscription; the planner also skips any incompatible pair defensively. The tag editor keeps the type compatible when the region changes; the CLI refuses the pair up front. The array-write parity test records the Coils divergence from DriverArrayWriteSupport (owned outside this lane) as follow-up F1. Refs #741 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col-md-4"><label class="form-label">Region</label>
|
||||
<select class="form-select form-select-sm" value="@_m.Region" @onchange="@(e => Update(() => _m.Region = ParseEnum(e.Value, ModbusRegion.HoldingRegisters)))">
|
||||
<select class="form-select form-select-sm" value="@_m.Region" @onchange="@(e => Update(() => _m.SetRegion(ParseEnum(e.Value, ModbusRegion.HoldingRegisters))))">
|
||||
@foreach (var v in Enum.GetValues<ModbusRegion>()) { <option value="@v">@v</option> }
|
||||
</select></div>
|
||||
<div class="col-md-2"><label class="form-label">Address</label>
|
||||
|
||||
@@ -30,6 +30,19 @@ public sealed class ModbusTagConfigModel
|
||||
/// key stays absent.</summary>
|
||||
public bool? Writable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Changes the region and keeps the data type compatible with it (the driver refuses a bit region
|
||||
/// with a non-Bool type, and a register region with Bool): switching to Coils / DiscreteInputs selects
|
||||
/// Bool, switching from them back to a register region selects Int16.
|
||||
/// </summary>
|
||||
/// <param name="region">The newly selected region.</param>
|
||||
public void SetRegion(ModbusRegion region)
|
||||
{
|
||||
Region = region;
|
||||
if (!ModbusTagDefinitionFactory.IsRegionTypeCompatible(region, DataType))
|
||||
DataType = ModbusTagDefinitionFactory.DefaultDataType(region);
|
||||
}
|
||||
|
||||
private JsonObject _bag = new();
|
||||
|
||||
// The blob this model was LOADED FROM, or null when it was built by object initialiser rather than
|
||||
@@ -49,7 +62,9 @@ public sealed class ModbusTagConfigModel
|
||||
_source = json ?? "",
|
||||
Region = TagConfigJson.GetEnum(o, "region", ModbusRegion.HoldingRegisters),
|
||||
Address = TagConfigJson.GetInt(o, "address"),
|
||||
DataType = TagConfigJson.GetEnum(o, "dataType", ModbusDataType.Int16),
|
||||
// Absent dataType defaults per region, exactly as the driver's factory does (Bool for a bit region).
|
||||
DataType = TagConfigJson.GetEnum(o, "dataType",
|
||||
ModbusTagDefinitionFactory.DefaultDataType(TagConfigJson.GetEnum(o, "region", ModbusRegion.HoldingRegisters))),
|
||||
ByteOrder = TagConfigJson.GetEnum(o, "byteOrder", ModbusByteOrder.BigEndian),
|
||||
BitIndex = TagConfigJson.GetInt(o, "bitIndex"),
|
||||
StringLength = TagConfigJson.GetInt(o, "stringLength"),
|
||||
|
||||
Reference in New Issue
Block a user