feat(otopcua): OpcUaPublishActor handles discovered-node materialisation

This commit is contained in:
Joseph Doherty
2026-06-26 07:24:22 -04:00
parent 598cdfad5a
commit ccf93fc029
2 changed files with 67 additions and 6 deletions
@@ -56,6 +56,13 @@ public sealed class OpcUaPublishActor : ReceiveActor, IWithTimers
/// fall back to the latest sealed deployment (lags a not-yet-sealed apply by one revision).
/// </summary>
public sealed record RebuildAddressSpace(CorrelationId Correlation, DeploymentId? DeploymentId = null);
/// <summary>Inject driver-discovered nodes (FixedTree) under an equipment at runtime (post-connect).</summary>
public sealed record MaterialiseDiscoveredNodes(
string EquipmentRootNodeId,
IReadOnlyList<DiscoveredFolder> Folders,
IReadOnlyList<DiscoveredVariable> Variables);
public sealed record ServiceLevelChanged(byte ServiceLevel);
private readonly IOpcUaAddressSpaceSink _sink;
@@ -217,6 +224,7 @@ public sealed class OpcUaPublishActor : ReceiveActor, IWithTimers
Receive<AttributeValueUpdate>(HandleAttributeUpdate);
Receive<AlarmStateUpdate>(HandleAlarmUpdate);
Receive<RebuildAddressSpace>(HandleRebuild);
Receive<MaterialiseDiscoveredNodes>(HandleMaterialiseDiscovered);
Receive<ServiceLevelChanged>(HandleServiceLevelChanged);
Receive<RedundancyStateChanged>(HandleRedundancyStateChanged);
Receive<DbHealthProbeActor.DbHealthStatus>(HandleDbHealthStatus);
@@ -390,6 +398,12 @@ public sealed class OpcUaPublishActor : ReceiveActor, IWithTimers
}
}
/// <summary>Forwards driver-discovered (FixedTree) nodes to the applier so they are injected under
/// the equipment at runtime. No-op when no applier is wired (dev/Mac/legacy seam), matching the
/// optional-applier tolerance of <see cref="HandleRebuild"/>.</summary>
private void HandleMaterialiseDiscovered(MaterialiseDiscoveredNodes msg)
=> _applier?.MaterialiseDiscoveredNodes(msg.EquipmentRootNodeId, msg.Folders, msg.Variables);
private void HandleServiceLevelChanged(ServiceLevelChanged msg)
{
// Always publish the FIRST computed level, even if it equals the byte-default 0. Otherwise a