Per ADR-002, adds the Driver/Virtual/ScriptedAlarm discriminator to DriverAttributeInfo
so the DriverNodeManager's dispatch layer can route Read/Write/Subscribe to the right
runtime subsystem — drivers (unchanged), VirtualTagEngine (Phase 7 Stream B), or
ScriptedAlarmEngine (Phase 7 Stream C).
## Changes
- NodeSourceKind enum added to Core.Abstractions (Driver=0/Virtual=1/ScriptedAlarm=2).
- DriverAttributeInfo gains Source / VirtualTagId / ScriptedAlarmId parameters — all
default so existing call sites (every driver) compile unchanged.
- EquipmentNamespaceContent gains VirtualTags + ScriptedAlarms optional collections.
- EquipmentNodeWalker emits:
- Virtual-tag variables — Source=Virtual, VirtualTagId set, Historize flag honored
- Scripted-alarm variables — Source=ScriptedAlarm, ScriptedAlarmId set, IsAlarm=true
(triggers node-manager AlarmConditionState materialization)
- Skips disabled virtual tags + scripted alarms
## Tests — 13/13 in EquipmentNodeWalkerTests (5 new)
- Virtual-tag variables carry Source=Virtual + VirtualTagId + Historize flag
- Scripted-alarm variables carry Source=ScriptedAlarm + IsAlarm=true + Boolean type
- Disabled rows skipped
- Null VirtualTags/ScriptedAlarms collections safe (back-compat for non-Phase-7 callers)
- Driver tags default Source=Driver (ensures no discriminator regression)
## Next
Stream G follow-up: DriverNodeManager dispatch (Read/Write/Subscribe routing by
NodeSourceKind), SealedBootstrap wiring of VirtualTagEngine + ScriptedAlarmEngine,
end-to-end integration test.
74 lines
3.7 KiB
C#
74 lines
3.7 KiB
C#
namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Per <c>docs/v2/plan.md</c> §5a (LmxNodeManager reusability) — <c>DriverAttributeInfo</c>
|
|
/// replaces the v1 Galaxy-specific <c>GalaxyAttributeInfo</c> in the generic node-manager
|
|
/// so the same node-manager class works against every driver.
|
|
/// </remarks>
|
|
/// <param name="FullName">
|
|
/// Driver-side full reference for read/write addressing
|
|
/// (e.g. for Galaxy: <c>"DelmiaReceiver_001.DownloadPath"</c>).
|
|
/// </param>
|
|
/// <param name="DriverDataType">Driver-agnostic data type; maps to OPC UA built-in type at build time.</param>
|
|
/// <param name="IsArray">True when this attribute is a 1-D array.</param>
|
|
/// <param name="ArrayDim">Declared array length when <see cref="IsArray"/> is true; null otherwise.</param>
|
|
/// <param name="SecurityClass">Write-authorization tier for this attribute.</param>
|
|
/// <param name="IsHistorized">True when this attribute is expected to feed historian / HistoryRead.</param>
|
|
/// <param name="IsAlarm">
|
|
/// True when this attribute represents an alarm condition (Galaxy: has an
|
|
/// <c>AlarmExtension</c> primitive). The generic node-manager enriches the variable with an
|
|
/// OPC UA <c>AlarmConditionState</c> when true. Defaults to false so existing non-Galaxy
|
|
/// drivers aren't forced to flow a flag they don't produce.
|
|
/// </param>
|
|
/// <param name="WriteIdempotent">
|
|
/// True when a timed-out or failed write to this attribute is safe to replay. Per
|
|
/// <c>docs/v2/plan.md</c> decisions #44, #45, #143 — 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.
|
|
/// </param>
|
|
/// <param name="Source">
|
|
/// Per ADR-002 — discriminates which runtime subsystem owns this node's dispatch.
|
|
/// Defaults to <see cref="NodeSourceKind.Driver"/> so existing callers are unchanged.
|
|
/// </param>
|
|
/// <param name="VirtualTagId">
|
|
/// Set when <paramref name="Source"/> is <see cref="NodeSourceKind.Virtual"/> — stable
|
|
/// logical id the VirtualTagEngine addresses by. Null otherwise.
|
|
/// </param>
|
|
/// <param name="ScriptedAlarmId">
|
|
/// Set when <paramref name="Source"/> is <see cref="NodeSourceKind.ScriptedAlarm"/> —
|
|
/// stable logical id the ScriptedAlarmEngine addresses by. Null otherwise.
|
|
/// </param>
|
|
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);
|
|
|
|
/// <summary>
|
|
/// Per ADR-002 — discriminates which runtime subsystem owns this node's Read/Write/
|
|
/// Subscribe dispatch. <c>Driver</c> = a real IDriver capability surface;
|
|
/// <c>Virtual</c> = a Phase 7 <see cref="DriverAttributeInfo"/>.VirtualTagId'd tag
|
|
/// computed by the VirtualTagEngine; <c>ScriptedAlarm</c> = a scripted Part 9 alarm
|
|
/// materialized by the ScriptedAlarmEngine.
|
|
/// </summary>
|
|
public enum NodeSourceKind
|
|
{
|
|
Driver = 0,
|
|
Virtual = 1,
|
|
ScriptedAlarm = 2,
|
|
}
|