Auto: abcip-2.6 — AOI input/output handling
AOI-aware browse paths: AOI instances now fan out under directional sub-folders (Inputs/, Outputs/, InOut/) instead of a flat layout. The sub-folders only appear when at least one member carries a non-Local AoiQualifier, so plain UDT tags keep the pre-2.6 flat structure. - Add AoiQualifier enum (Local / Input / Output / InOut) + new property on AbCipStructureMember (defaults to Local). - L5K parser learns ADD_ON_INSTRUCTION_DEFINITION blocks; PARAMETER entries' Usage attribute flows through L5kMember.Usage. - L5X parser captures the Usage attribute on <Parameter> elements. - L5kIngest maps Usage strings (Input/Output/InOut) to AoiQualifier; null + unknown values map to Local. - AbCipDriver.DiscoverAsync groups directional members under Inputs / Outputs / InOut sub-folders when any member is non-Local. - Tests for L5K AOI block parsing, L5X Usage capture, ingest mapping (both formats), and AOI-vs-plain UDT discovery fan-out. Closes #234
This commit is contained in:
@@ -1025,10 +1025,31 @@ public sealed class AbCipDriver : IDriver, IReadable, IWritable, ITagDiscovery,
|
||||
if (tag.DataType == AbCipDataType.Structure && tag.Members is { Count: > 0 })
|
||||
{
|
||||
var udtFolder = deviceFolder.Folder(tag.Name, tag.Name);
|
||||
// PR abcip-2.6 — AOI-aware fan-out. When any member carries a non-Local
|
||||
// AoiQualifier the tag is treated as an AOI instance: Input / Output / InOut
|
||||
// members get grouped under sub-folders (Inputs/, Outputs/, InOut/) so the
|
||||
// browse tree visually matches Studio 5000's AOI parameter tabs. Plain UDT
|
||||
// tags (every member Local) retain the pre-2.6 flat layout under the parent
|
||||
// folder so existing browse paths stay stable.
|
||||
var hasDirectional = tag.Members.Any(m => m.AoiQualifier != AoiQualifier.Local);
|
||||
IAddressSpaceBuilder? inputsFolder = null;
|
||||
IAddressSpaceBuilder? outputsFolder = null;
|
||||
IAddressSpaceBuilder? inOutFolder = null;
|
||||
foreach (var member in tag.Members)
|
||||
{
|
||||
var parentFolder = udtFolder;
|
||||
if (hasDirectional)
|
||||
{
|
||||
parentFolder = member.AoiQualifier switch
|
||||
{
|
||||
AoiQualifier.Input => inputsFolder ??= udtFolder.Folder("Inputs", "Inputs"),
|
||||
AoiQualifier.Output => outputsFolder ??= udtFolder.Folder("Outputs", "Outputs"),
|
||||
AoiQualifier.InOut => inOutFolder ??= udtFolder.Folder("InOut", "InOut"),
|
||||
_ => udtFolder, // Local stays at the AOI root
|
||||
};
|
||||
}
|
||||
var memberFullName = $"{tag.Name}.{member.Name}";
|
||||
udtFolder.Variable(member.Name, member.Name, new DriverAttributeInfo(
|
||||
parentFolder.Variable(member.Name, member.Name, new DriverAttributeInfo(
|
||||
FullName: memberFullName,
|
||||
DriverDataType: member.DataType.ToDriverDataType(),
|
||||
IsArray: false,
|
||||
|
||||
Reference in New Issue
Block a user