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:
Joseph Doherty
2026-06-16 21:51:55 -04:00
parent c2006dfb57
commit 8d3dc32148
3 changed files with 197 additions and 1 deletions
@@ -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; }