namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip; /// /// AB CIP / EtherNet-IP driver configuration, bound from the driver's DriverConfig /// JSON at DriverHost.RegisterAsync. One instance supports N devices (PLCs) behind /// the same driver; per-device routing is keyed on /// via IPerCallHostResolver. /// /// /// Per v2 plan decisions #11 (libplctag), #41 (AbCip vs AbLegacy split), #143–144 (per-call /// host resolver + resilience keys), #144 (bulkhead keyed on (DriverInstanceId, HostName)). /// public sealed class AbCipDriverOptions { /// /// PLCs this driver instance talks to. Each device contributes its own /// string as the hostName key used by resilience pipelines and the Admin UI. /// public IReadOnlyList Devices { get; init; } = []; /// Pre-declared tag map across all devices — AB discovery lands in PR 5. public IReadOnlyList Tags { get; init; } = []; /// Per-device probe settings. Falls back to defaults when omitted. public AbCipProbeOptions Probe { get; init; } = new(); /// /// Default libplctag call timeout applied to reads/writes/discovery when the caller does /// not pass a more specific value. Matches the Modbus driver's 2-second default. /// public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(2); } /// /// One PLC endpoint. must parse via /// ; misconfigured devices fail driver /// initialization rather than silently connecting to nothing. /// /// Canonical ab://gateway[:port]/cip-path string. /// Which per-family profile to apply. Determines ConnectionSize, /// request-packing support, unconnected-only hint, and other quirks. /// Optional display label for Admin UI. Falls back to . public sealed record AbCipDeviceOptions( string HostAddress, AbCipPlcFamily PlcFamily = AbCipPlcFamily.ControlLogix, string? DeviceName = null); /// /// One AB-backed OPC UA variable. Mirrors the ModbusTagDefinition shape. /// /// Tag name; becomes the OPC UA browse name and full reference. /// Which device () this tag lives on. /// Logix symbolic path (controller or program scope). /// Logix atomic type, or for UDT-typed tags. /// When true and the tag's ExternalAccess permits writes, IWritable routes writes here. /// Per plan decisions #44–#45, #143 — safe to replay on write timeout. Default false. /// For -typed tags, the declared UDT /// member layout. When supplied, discovery fans out the UDT into a folder + one Variable per /// member (member TagPath = {tag.TagPath}.{member.Name}). When null on a Structure /// tag, the driver treats it as a black-box and relies on downstream configuration to address /// members individually via dotted syntax. Ignored for atomic types. /// GuardLogix safety-partition tag hint. When true, the driver /// forces SecurityClassification.ViewOnly on discovery regardless of /// — safety tags can only be written from the safety task of a /// GuardLogix controller; non-safety writes violate the safety-partition isolation and are /// rejected by the PLC anyway. Surfaces the intent explicitly instead of relying on the /// write attempt failing at runtime. public sealed record AbCipTagDefinition( string Name, string DeviceHostAddress, string TagPath, AbCipDataType DataType, bool Writable = true, bool WriteIdempotent = false, IReadOnlyList? Members = null, bool SafetyTag = false); /// /// One declared member of a UDT tag. Name is the member identifier on the PLC (e.g. Speed, /// Status), DataType is the atomic Logix type, Writable/WriteIdempotent mirror /// . Declaration-driven — the real CIP Template Object reader /// (class 0x6C) that would auto-discover member layouts lands as a follow-up PR. /// public sealed record AbCipStructureMember( string Name, AbCipDataType DataType, bool Writable = true, bool WriteIdempotent = false); /// Which AB PLC family the device is — selects the profile applied to connection params. public enum AbCipPlcFamily { ControlLogix, CompactLogix, Micro800, GuardLogix, } /// /// Background connectivity-probe settings. Enabled by default; the probe reads a cheap tag /// on the PLC at the configured interval to drive /// state transitions + Admin UI health status. /// public sealed class AbCipProbeOptions { public bool Enabled { get; init; } = true; public TimeSpan Interval { get; init; } = TimeSpan.FromSeconds(5); public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(2); /// /// Tag path used for the probe. If null, the driver attempts to read a default /// system tag (PR 8 wires this up — the choice is family-dependent, e.g. /// @raw_cpu_type on ControlLogix or a user-configured probe tag on Micro800). /// public string? ProbeTagPath { get; init; } }