feat(ablegacy): PCCC multi-element file array read + IsArray discovery
This commit is contained in:
@@ -41,13 +41,31 @@ public sealed record AbLegacyDeviceOptions(
|
||||
/// One PCCC-backed OPC UA variable. <paramref name="Address"/> is the canonical PCCC
|
||||
/// file-address string that parses via <c>AbLegacyAddress.TryParse</c>.
|
||||
/// </summary>
|
||||
/// <param name="ArrayLength">
|
||||
/// Element count when the tag addresses a multi-element span of a PCCC data file (e.g. an
|
||||
/// <c>N7</c> integer file is inherently up to 256 words); <see langword="null"/> for a scalar.
|
||||
/// A PCCC data file holds at most <see cref="AbLegacyArray.MaxElements"/> (256) elements, so a
|
||||
/// value above that is clamped where it is materialised/read. <c>1</c> reads as a scalar.
|
||||
/// </param>
|
||||
public sealed record AbLegacyTagDefinition(
|
||||
string Name,
|
||||
string DeviceHostAddress,
|
||||
string Address,
|
||||
AbLegacyDataType DataType,
|
||||
bool Writable = true,
|
||||
bool WriteIdempotent = false);
|
||||
bool WriteIdempotent = false,
|
||||
int? ArrayLength = null);
|
||||
|
||||
/// <summary>PCCC array-tag constants shared by the parser, discovery, and read paths.</summary>
|
||||
public static class AbLegacyArray
|
||||
{
|
||||
/// <summary>
|
||||
/// Maximum element count for a single PCCC data file. The PCCC/DF1 protocol addresses a
|
||||
/// data file element with a single byte sub-element offset, so a file holds at most 256
|
||||
/// elements (words for N/B/I/O/S/A, 32-bit elements for L/F). Array tags clamp to this.
|
||||
/// </summary>
|
||||
public const int MaxElements = 256;
|
||||
}
|
||||
|
||||
public sealed class AbLegacyProbeOptions
|
||||
{
|
||||
|
||||
+14
-1
@@ -29,9 +29,18 @@ public static class AbLegacyEquipmentTagParser
|
||||
if (string.IsNullOrWhiteSpace(address)) return false;
|
||||
var dataType = ReadEnum(root, "dataType", AbLegacyDataType.Int);
|
||||
var deviceHostAddress = ReadString(root, "deviceHostAddress");
|
||||
// Phase 4c #137 — thread the equipment tag's array element count. arrayLength is the
|
||||
// authoritative count; isArray is the AdminUI's boolean toggle. A positive arrayLength
|
||||
// (regardless of isArray) makes this an array tag. Clamp to the PCCC file maximum
|
||||
// (AbLegacyArray.MaxElements = 256) so a fat-fingered count can never request a span
|
||||
// larger than a single data file holds. Absent / non-positive → null (scalar).
|
||||
int? arrayLength = null;
|
||||
var rawLength = ReadInt(root, "arrayLength");
|
||||
if (rawLength > 0)
|
||||
arrayLength = Math.Min(rawLength, AbLegacyArray.MaxElements);
|
||||
def = new AbLegacyTagDefinition(
|
||||
Name: reference, DeviceHostAddress: deviceHostAddress, Address: address,
|
||||
DataType: dataType, Writable: true);
|
||||
DataType: dataType, Writable: true, ArrayLength: arrayLength);
|
||||
return true;
|
||||
}
|
||||
catch (JsonException) { return false; }
|
||||
@@ -46,4 +55,8 @@ public static class AbLegacyEquipmentTagParser
|
||||
private static string ReadString(JsonElement o, string name)
|
||||
=> o.TryGetProperty(name, out var e) && e.ValueKind == JsonValueKind.String
|
||||
? e.GetString() ?? "" : "";
|
||||
|
||||
private static int ReadInt(JsonElement o, string name)
|
||||
=> o.TryGetProperty(name, out var e) && e.ValueKind == JsonValueKind.Number
|
||||
&& e.TryGetInt32(out var v) ? v : 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user