Auto: ablegacy-7 — array contiguous block addressing

Closes #250
This commit is contained in:
Joseph Doherty
2026-04-25 23:36:01 -04:00
parent 05528bf71c
commit c689ac58b1
14 changed files with 779 additions and 15 deletions
@@ -32,6 +32,11 @@ internal sealed class LibplctagLegacyTagRuntime : IAbLegacyTagRuntime
Name = p.TagName,
Timeout = p.Timeout,
};
// PR 7 — array contiguous-block reads. Setting ElementCount tells libplctag to allocate
// a buffer covering N consecutive PCCC words (one frame, up to ~120 elements). The
// driver decodes element-by-element through DecodeArrayElement after a single ReadAsync.
if (p.ElementCount > 1)
_tag.ElementCount = p.ElementCount;
}
public Task InitializeAsync(CancellationToken cancellationToken) => _tag.InitializeAsync(cancellationToken);
@@ -127,6 +132,32 @@ internal sealed class LibplctagLegacyTagRuntime : IAbLegacyTagRuntime
}
}
/// <summary>
/// PR 7 — decode element <paramref name="elementIndex"/> of an N-element contiguous
/// PCCC block read. Element width is fixed per data type: Int / AnalogInt / Bit-as-word
/// are 16-bit (2 bytes/element), Long / Float are 32-bit (4 bytes/element). Mirrors the
/// non-array decoder shape but at byte offset <c>elementIndex × elementBytes</c>.
/// </summary>
public object? DecodeArrayElement(AbLegacyDataType type, int elementIndex)
{
if (elementIndex < 0) throw new ArgumentOutOfRangeException(nameof(elementIndex));
return type switch
{
// Bit / N-array reads — Rockwell convention is one BOOL per word (e.g. `B3:0,10`
// returns 10 BOOLs, not 160 individual bits). Each word is non-zero → true.
AbLegacyDataType.Bit => _tag.GetInt16(elementIndex * 2) != 0,
AbLegacyDataType.Int or AbLegacyDataType.AnalogInt => (int)_tag.GetInt16(elementIndex * 2),
AbLegacyDataType.Long => _tag.GetInt32(elementIndex * 4),
AbLegacyDataType.Float => _tag.GetFloat32(elementIndex * 4),
// String + element types are out-of-scope for PR 7 array reads — the PCCC layer's
// 240-byte frame ceiling means an ST array would only fit a couple of strings, and
// sub-element arrays (`T4:0,5.ACC`) are rejected at parse time. Surface a clear
// error if the driver mis-routes us here.
_ => throw new NotSupportedException(
$"AbLegacyDataType {type} cannot be decoded as a contiguous array element."),
};
}
public void Dispose() => _tag.Dispose();
private static PlcType MapPlcType(string attribute) => attribute switch