namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
///
/// Abstraction over the OPC UA SDK's address space. OpcUaPublishActor consumes this
/// so the Runtime project doesn't reference Opc.Ua.Server directly — production
/// binds a real SDK-backed sink in the fused Host's wiring, dev/Mac binds the
/// no-op.
///
public interface IOpcUaAddressSpaceSink
{
/// Write a Variable node's current value + quality + source timestamp.
void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc);
/// Write an alarm-condition Variable's active/acknowledged state.
void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc);
///
/// Ensure a folder node exists under the given parent. Used by Phase7Applier to
/// materialise the UNS Area/Line/Equipment hierarchy in the address space. When
/// is null the folder is parented under the namespace
/// root. Idempotent: calling twice with the same id is safe.
///
void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName);
///
/// Ensure a Variable node exists at , parented under
/// (or the namespace root when null). Created with
/// Bad quality + null value; subsequent calls update both.
/// Used by Phase7Applier to materialise Galaxy / SystemPlatform tags ahead of any
/// driver-side subscribe so OPC UA clients can browse them. Idempotent.
///
/// OPC UA built-in type name ("Boolean" / "Int32" / "Float" / etc.).
void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType);
///
/// Tear down + repopulate the address space. Called by OpcUaPublishActor after a
/// successful deployment apply so the node manager reflects the new config. Idempotent.
///
void RebuildAddressSpace();
}
/// OPC UA status code projection — Good / Uncertain / Bad. Real SDK has finer-grained
/// codes; the engine actors only need this 3-state classification.
public enum OpcUaQuality { Good, Uncertain, Bad }
/// No-op sink. Bound by default so the actors are safe to run in dev / Mac /
/// integration tests without a real SDK behind them.
public sealed class NullOpcUaAddressSpaceSink : IOpcUaAddressSpaceSink
{
public static readonly NullOpcUaAddressSpaceSink Instance = new();
private NullOpcUaAddressSpaceSink() { }
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc) { }
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc) { }
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName) { }
public void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType) { }
public void RebuildAddressSpace() { }
}