namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions; /// /// Driver-agnostic per-attribute (tag) descriptor used by the generic node-manager /// to build OPC UA address-space variables. Every driver maps its native attribute /// metadata into this DTO during discovery. /// /// /// Per docs/v2/plan.md §5a (LmxNodeManager reusability) — DriverAttributeInfo /// replaces the v1 Galaxy-specific GalaxyAttributeInfo in the generic node-manager /// so the same node-manager class works against every driver. /// /// /// Driver-side full reference for read/write addressing /// (e.g. for Galaxy: "DelmiaReceiver_001.DownloadPath"). /// /// Driver-agnostic data type; maps to OPC UA built-in type at build time. /// True when this attribute is a 1-D array. /// Declared array length when is true; null otherwise. /// Write-authorization tier for this attribute. /// True when this attribute is expected to feed historian / HistoryRead. /// /// True when this attribute represents an alarm condition (Galaxy: has an /// AlarmExtension primitive). The generic node-manager enriches the variable with an /// OPC UA AlarmConditionState when true. Defaults to false so existing non-Galaxy /// drivers aren't forced to flow a flag they don't produce. /// /// /// True when a timed-out or failed write to this attribute is safe to replay. Per /// docs/v2/plan.md, writes are NOT auto-retried by default /// because replaying a pulse / alarm-ack / counter-increment / recipe-step advance can /// duplicate field actions. Drivers flag only tags whose semantics make retry safe /// (holding registers with level-set values, set-point writes to analog tags) — the /// capability invoker respects this flag when deciding whether to apply Polly retry. /// /// /// Discriminates which runtime subsystem owns this node's dispatch. /// Defaults to so existing callers are unchanged. /// /// /// Set when is — stable /// logical id the VirtualTagEngine addresses by. Null otherwise. /// /// /// Set when is — /// stable logical id the ScriptedAlarmEngine addresses by. Null otherwise. /// /// /// The driver's OWN type name for this attribute (e.g. "Real" for an /// AbCipDataType, "Int16" for a TwinCATDataType) when the driver binds /// by a driver-specific type enum in its TagConfig; null for a driver whose tag config /// carries no type (OPC UA Client, Galaxy) or which takes the type from the wire (MQTT /// Sparkplug births, MTConnect probe inference). /// /// It exists because is lossy in exactly the direction a /// browse-commit needs (Gitea #536): AbCipDataType.SInt, .Int and .DInt /// all map to , so a commit that reverse-mapped the /// driver-agnostic type would bind a 16-bit INT as a 32-bit DINT. Nothing downstream of the /// address-space build reads this — it is authoring metadata carried alongside the type the /// node manager actually uses. /// /// public sealed record DriverAttributeInfo( string FullName, DriverDataType DriverDataType, bool IsArray, uint? ArrayDim, SecurityClassification SecurityClass, bool IsHistorized, bool IsAlarm = false, bool WriteIdempotent = false, NodeSourceKind Source = NodeSourceKind.Driver, string? VirtualTagId = null, string? ScriptedAlarmId = null, string? NativeDataType = null); /// /// Discriminates which runtime subsystem owns this node's Read/Write/ /// Subscribe dispatch. Driver = a real IDriver capability surface; /// Virtual = a Phase 7 .VirtualTagId'd tag /// computed by the VirtualTagEngine; ScriptedAlarm = a scripted Part 9 alarm /// materialized by the ScriptedAlarmEngine. /// public enum NodeSourceKind { Driver = 0, Virtual = 1, ScriptedAlarm = 2, }