a1325299ce
OpcUaPublishActor now routes through pluggable seams instead of just incrementing a counter: - IOpcUaAddressSpaceSink (Commons.OpcUa) — WriteValue / WriteAlarmState / RebuildAddressSpace. OpcUaQuality enum moved here from the actor's nested type so producers don't have to reference the actor itself. - IServiceLevelPublisher — Publish(byte). NullServiceLevelPublisher retains the last level for inspection. - The actor subscribes to the redundancy-state DPS topic in PreStart and maps the local node's NodeRedundancyState to a coarse ServiceLevel (Primary+leader=240, Primary=200, Secondary=100, Detached=0). This keeps the local SDK's ServiceLevel node honest without round-tripping back through the admin-singleton calculator. - ServiceLevelChanged dedupes identical levels so the SDK doesn't see redundant writes. - Sink + publisher exceptions are caught and logged; the actor never crashes its own dispatcher. - PropsForTests gets optional sink/publisher/localNode params and skips the DPS subscribe so unit tests stay on a vanilla TestKit cluster. Production binding to a real SDK NodeManager + Variable nodes is the remaining residual — split as F10b. Task 60 still blocked on F10b. Tests: Runtime 40 -> 46 (+6): - AttributeValueUpdate routes to sink - AlarmStateUpdate routes to sink - RebuildAddressSpace calls sink.Rebuild - ServiceLevelChanged dedupes - RedundancyStateChanged for primary-leader publishes 240 - RedundancyStateChanged for secondary publishes 100 All 6 v2 test suites green: 132 tests passing.
23 lines
922 B
C#
23 lines
922 B
C#
namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
|
||
|
||
/// <summary>
|
||
/// Writes the OPC UA Server object's <c>ServiceLevel</c> Variable (0–255). Production binds
|
||
/// a sink that pokes the SDK's ServiceLevel node; tests + dev mode bind
|
||
/// <see cref="NullServiceLevelPublisher"/> which just records the most recently set level
|
||
/// for inspection.
|
||
/// </summary>
|
||
public interface IServiceLevelPublisher
|
||
{
|
||
void Publish(byte serviceLevel);
|
||
}
|
||
|
||
/// <summary>No-op default that retains the last-written ServiceLevel in
|
||
/// <see cref="LastPublished"/>. Used by dev mode + verified by tests.</summary>
|
||
public sealed class NullServiceLevelPublisher : IServiceLevelPublisher
|
||
{
|
||
public static readonly NullServiceLevelPublisher Instance = new();
|
||
private NullServiceLevelPublisher() { }
|
||
public byte LastPublished { get; private set; }
|
||
public void Publish(byte serviceLevel) => LastPublished = serviceLevel;
|
||
}
|