feat(modbus): String + BitInRegister array decode + equipment-tag arrayLength
- DecodeRegisterArray: add String and BitInRegister cases replacing the default:throw; each element decoded by reusing DecodeRegister on its contiguous register slice → string[] / bool[] - ModbusEquipmentTagParser.TryParse: read optional arrayLength key from TagConfig JSON and thread it into ModbusTagDefinition.ArrayCount (null when absent or zero, preserving scalar behaviour) - ModbusArrayTests: 8 new tests covering the two decode cases and the equipment-tag parser/resolver path; 285/285 green
This commit is contained in:
@@ -34,9 +34,14 @@ public static class ModbusEquipmentTagParser
|
||||
var byteOrder = ReadEnum(root, "byteOrder", ModbusByteOrder.BigEndian);
|
||||
var bitIndex = (byte)ReadInt(root, "bitIndex");
|
||||
var stringLength = (ushort)ReadInt(root, "stringLength");
|
||||
// isArray / arrayLength — optional keys authored by the typed Modbus tag editor.
|
||||
// When arrayLength > 0 we expose an array tag of that count; otherwise scalar.
|
||||
var arrayLength = ReadInt(root, "arrayLength");
|
||||
int? arrayCount = arrayLength > 0 ? arrayLength : null;
|
||||
def = new ModbusTagDefinition(
|
||||
Name: reference, Region: region, Address: (ushort)address, DataType: dataType,
|
||||
Writable: true, ByteOrder: byteOrder, BitIndex: bitIndex, StringLength: stringLength);
|
||||
Writable: true, ByteOrder: byteOrder, BitIndex: bitIndex, StringLength: stringLength,
|
||||
ArrayCount: arrayCount);
|
||||
return true;
|
||||
}
|
||||
catch (JsonException) { return false; }
|
||||
|
||||
@@ -479,6 +479,25 @@ public sealed class ModbusDriver
|
||||
arr[i] = (double)DecodeRegister(data.AsSpan(i * elementBytes, elementBytes), tag);
|
||||
return arr;
|
||||
}
|
||||
case ModbusDataType.String:
|
||||
{
|
||||
// Each element occupies elementRegs registers = elementBytes bytes, encoding
|
||||
// StringLength chars packed high-byte-first or low-byte-first per tag.StringByteOrder.
|
||||
// DecodeRegister handles the per-element slice identically to the scalar path.
|
||||
var arr = new string[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
arr[i] = (string)DecodeRegister(data.AsSpan(i * elementBytes, elementBytes), tag);
|
||||
return arr;
|
||||
}
|
||||
case ModbusDataType.BitInRegister:
|
||||
{
|
||||
// Each element is 1 holding register (2 bytes). The same BitIndex is applied to
|
||||
// every element. DecodeRegister returns bool for BitInRegister scalar slices.
|
||||
var arr = new bool[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
arr[i] = (bool)DecodeRegister(data.AsSpan(i * elementBytes, elementBytes), tag);
|
||||
return arr;
|
||||
}
|
||||
default:
|
||||
throw new InvalidOperationException(
|
||||
$"Array decode not supported for {tag.DataType} (use scalar tags or split by element)");
|
||||
|
||||
Reference in New Issue
Block a user