feat(runtime): carry DriverInstanceId on AttributeValuePublished (live-value routing key)
This commit is contained in:
@@ -62,7 +62,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
|||||||
public sealed record ForceReconnect;
|
public sealed record ForceReconnect;
|
||||||
/// <summary>Published to the actor's parent whenever the subscribed IDriver fires
|
/// <summary>Published to the actor's parent whenever the subscribed IDriver fires
|
||||||
/// <see cref="ISubscribable.OnDataChange"/>. The parent forwards to OpcUaPublishActor.</summary>
|
/// <see cref="ISubscribable.OnDataChange"/>. The parent forwards to OpcUaPublishActor.</summary>
|
||||||
public sealed record AttributeValuePublished(string FullReference, object? Value, OpcUaQuality Quality, DateTime TimestampUtc);
|
public sealed record AttributeValuePublished(string DriverInstanceId, string FullReference, object? Value, OpcUaQuality Quality, DateTime TimestampUtc);
|
||||||
private sealed record DataChangeForward(string FullReference, DataValueSnapshot Snapshot);
|
private sealed record DataChangeForward(string FullReference, DataValueSnapshot Snapshot);
|
||||||
public sealed class RetryConnect
|
public sealed class RetryConnect
|
||||||
{
|
{
|
||||||
@@ -446,7 +446,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
|||||||
{
|
{
|
||||||
var quality = QualityFromStatus(msg.Snapshot.StatusCode);
|
var quality = QualityFromStatus(msg.Snapshot.StatusCode);
|
||||||
var ts = msg.Snapshot.SourceTimestampUtc ?? msg.Snapshot.ServerTimestampUtc;
|
var ts = msg.Snapshot.SourceTimestampUtc ?? msg.Snapshot.ServerTimestampUtc;
|
||||||
Context.Parent.Tell(new AttributeValuePublished(msg.FullReference, msg.Snapshot.Value, quality, ts));
|
Context.Parent.Tell(new AttributeValuePublished(_driverInstanceId, msg.FullReference, msg.Snapshot.Value, quality, ts));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Translate an OPC UA status code to the 3-state <see cref="OpcUaQuality"/> projection
|
/// <summary>Translate an OPC UA status code to the 3-state <see cref="OpcUaQuality"/> projection
|
||||||
|
|||||||
+12
-12
@@ -21,9 +21,9 @@ public sealed class DependencyMuxActorTests : RuntimeActorTestBase
|
|||||||
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-1", "tag-2" }, subA.Ref));
|
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-1", "tag-2" }, subA.Ref));
|
||||||
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-2", "tag-3" }, subB.Ref));
|
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-2", "tag-3" }, subB.Ref));
|
||||||
|
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished("tag-1", 10, OpcUaQuality.Good, DateTime.UtcNow));
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished("driver-1", "tag-1", 10, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished("tag-3", 30, OpcUaQuality.Good, DateTime.UtcNow));
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished("driver-1", "tag-3", 30, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished("tag-2", 20, OpcUaQuality.Good, DateTime.UtcNow));
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished("driver-1", "tag-2", 20, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
|
|
||||||
// subA hears tag-1 + tag-2.
|
// subA hears tag-1 + tag-2.
|
||||||
var aMsgs = new[]
|
var aMsgs = new[]
|
||||||
@@ -53,7 +53,7 @@ public sealed class DependencyMuxActorTests : RuntimeActorTestBase
|
|||||||
var sub = CreateTestProbe();
|
var sub = CreateTestProbe();
|
||||||
|
|
||||||
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-1" }, sub.Ref));
|
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-1" }, sub.Ref));
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished("nobody-cares", 99, OpcUaQuality.Good, DateTime.UtcNow));
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished("driver-1", "nobody-cares", 99, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
|
|
||||||
sub.ExpectNoMsg(TimeSpan.FromMilliseconds(200));
|
sub.ExpectNoMsg(TimeSpan.FromMilliseconds(200));
|
||||||
}
|
}
|
||||||
@@ -66,11 +66,11 @@ public sealed class DependencyMuxActorTests : RuntimeActorTestBase
|
|||||||
var sub = CreateTestProbe();
|
var sub = CreateTestProbe();
|
||||||
|
|
||||||
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-1" }, sub.Ref));
|
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-1" }, sub.Ref));
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished("tag-1", 10, OpcUaQuality.Good, DateTime.UtcNow));
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished("driver-1", "tag-1", 10, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
sub.ExpectMsg<VirtualTagActor.DependencyValueChanged>();
|
sub.ExpectMsg<VirtualTagActor.DependencyValueChanged>();
|
||||||
|
|
||||||
mux.Tell(new DependencyMuxActor.UnregisterInterest(sub.Ref));
|
mux.Tell(new DependencyMuxActor.UnregisterInterest(sub.Ref));
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished("tag-1", 20, OpcUaQuality.Good, DateTime.UtcNow));
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished("driver-1", "tag-1", 20, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
sub.ExpectNoMsg(TimeSpan.FromMilliseconds(200));
|
sub.ExpectNoMsg(TimeSpan.FromMilliseconds(200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,10 +84,10 @@ public sealed class DependencyMuxActorTests : RuntimeActorTestBase
|
|||||||
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-1" }, sub.Ref));
|
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-1" }, sub.Ref));
|
||||||
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-2" }, sub.Ref)); // replaces tag-1
|
mux.Tell(new DependencyMuxActor.RegisterInterest(new[] { "tag-2" }, sub.Ref)); // replaces tag-1
|
||||||
|
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished("tag-1", 10, OpcUaQuality.Good, DateTime.UtcNow));
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished("driver-1", "tag-1", 10, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
sub.ExpectNoMsg(TimeSpan.FromMilliseconds(200));
|
sub.ExpectNoMsg(TimeSpan.FromMilliseconds(200));
|
||||||
|
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished("tag-2", 20, OpcUaQuality.Good, DateTime.UtcNow));
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished("driver-1", "tag-2", 20, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
sub.ExpectMsg<VirtualTagActor.DependencyValueChanged>().TagId.ShouldBe("tag-2");
|
sub.ExpectMsg<VirtualTagActor.DependencyValueChanged>().TagId.ShouldBe("tag-2");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,17 +110,17 @@ public sealed class DependencyMuxActorTests : RuntimeActorTestBase
|
|||||||
AwaitAssert(() =>
|
AwaitAssert(() =>
|
||||||
{
|
{
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished(
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished(
|
||||||
"ref-a", 10, OpcUaQuality.Good, DateTime.UtcNow));
|
"driver-1", "ref-a", 10, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
parent.ExpectMsg<VirtualTagActor.EvaluationResult>(TimeSpan.FromMilliseconds(200))
|
parent.ExpectMsg<VirtualTagActor.EvaluationResult>(TimeSpan.FromMilliseconds(200))
|
||||||
.Value.ShouldBe(10);
|
.Value.ShouldBe(10);
|
||||||
}, duration: TimeSpan.FromSeconds(3));
|
}, duration: TimeSpan.FromSeconds(3));
|
||||||
|
|
||||||
// From here the actor is wired — second publish drives the sum.
|
// From here the actor is wired — second publish drives the sum.
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished("ref-b", 32, OpcUaQuality.Good, DateTime.UtcNow));
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished("driver-1", "ref-b", 32, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
parent.ExpectMsg<VirtualTagActor.EvaluationResult>(TimeSpan.FromSeconds(2)).Value.ShouldBe(42);
|
parent.ExpectMsg<VirtualTagActor.EvaluationResult>(TimeSpan.FromSeconds(2)).Value.ShouldBe(42);
|
||||||
|
|
||||||
// Unrelated ref shouldn't fire eval.
|
// Unrelated ref shouldn't fire eval.
|
||||||
mux.Tell(new DriverInstanceActor.AttributeValuePublished("ref-unrelated", 99, OpcUaQuality.Good, DateTime.UtcNow));
|
mux.Tell(new DriverInstanceActor.AttributeValuePublished("driver-1", "ref-unrelated", 99, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
parent.ExpectNoMsg(TimeSpan.FromMilliseconds(200));
|
parent.ExpectNoMsg(TimeSpan.FromMilliseconds(200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ public sealed class DependencyMuxActorTests : RuntimeActorTestBase
|
|||||||
|
|
||||||
// Tell the host an AttributeValuePublished — it should fan out to the mux + subscriber.
|
// Tell the host an AttributeValuePublished — it should fan out to the mux + subscriber.
|
||||||
hostActor.Tell(new DriverInstanceActor.AttributeValuePublished(
|
hostActor.Tell(new DriverInstanceActor.AttributeValuePublished(
|
||||||
"ref-1", 42, OpcUaQuality.Good, DateTime.UtcNow));
|
"driver-1", "ref-1", 42, OpcUaQuality.Good, DateTime.UtcNow));
|
||||||
|
|
||||||
subscriber.ExpectMsg<VirtualTagActor.DependencyValueChanged>().TagId.ShouldBe("ref-1");
|
subscriber.ExpectMsg<VirtualTagActor.DependencyValueChanged>().TagId.ShouldBe("ref-1");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user