feat: data-sourced attributes start with uncertain quality before first DCL value
Attributes bound to data connections now initialize with "Uncertain" quality, distinguishing "never received a value" from "known good" or "connection lost." Quality is tracked per attribute and included in GetAttributeResponse.
This commit is contained in:
@@ -11,7 +11,9 @@ public record GetAttributeRequest(
|
||||
DateTimeOffset Timestamp);
|
||||
|
||||
/// <summary>
|
||||
/// Response containing the current value of an attribute.
|
||||
/// Response containing the current value and quality of an attribute.
|
||||
/// Quality is "Good", "Bad", or "Uncertain".
|
||||
/// Data-sourced attributes start at "Uncertain" until the first DCL value update arrives.
|
||||
/// </summary>
|
||||
public record GetAttributeResponse(
|
||||
string CorrelationId,
|
||||
@@ -19,4 +21,5 @@ public record GetAttributeResponse(
|
||||
string AttributeName,
|
||||
object? Value,
|
||||
bool Found,
|
||||
string Quality,
|
||||
DateTimeOffset Timestamp);
|
||||
|
||||
@@ -38,6 +38,7 @@ public class InstanceActor : ReceiveActor
|
||||
private readonly SiteRuntimeOptions _options;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Dictionary<string, object?> _attributes = new();
|
||||
private readonly Dictionary<string, string> _attributeQualities = new();
|
||||
private readonly Dictionary<string, AlarmState> _alarmStates = new();
|
||||
private readonly Dictionary<string, IActorRef> _scriptActors = new();
|
||||
private readonly Dictionary<string, IActorRef> _alarmActors = new();
|
||||
@@ -75,11 +76,15 @@ public class InstanceActor : ReceiveActor
|
||||
_configuration = JsonSerializer.Deserialize<FlattenedConfiguration>(configJson);
|
||||
|
||||
// Load default attribute values from the flattened configuration
|
||||
// Data-sourced attributes start with Uncertain quality until the first DCL value arrives.
|
||||
// Static attributes start with Good quality.
|
||||
if (_configuration != null)
|
||||
{
|
||||
foreach (var attr in _configuration.Attributes)
|
||||
{
|
||||
_attributes[attr.CanonicalName] = attr.Value;
|
||||
_attributeQualities[attr.CanonicalName] =
|
||||
string.IsNullOrEmpty(attr.DataSourceReference) ? "Good" : "Uncertain";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,12 +174,14 @@ public class InstanceActor : ReceiveActor
|
||||
private void HandleGetAttribute(GetAttributeRequest request)
|
||||
{
|
||||
var found = _attributes.TryGetValue(request.AttributeName, out var value);
|
||||
_attributeQualities.TryGetValue(request.AttributeName, out var quality);
|
||||
Sender.Tell(new GetAttributeResponse(
|
||||
request.CorrelationId,
|
||||
_instanceUniqueName,
|
||||
request.AttributeName,
|
||||
value,
|
||||
found,
|
||||
quality ?? "Good",
|
||||
DateTimeOffset.UtcNow));
|
||||
}
|
||||
|
||||
@@ -249,6 +256,7 @@ public class InstanceActor : ReceiveActor
|
||||
{
|
||||
// WP-24: State mutation serialized through this actor
|
||||
_attributes[changed.AttributeName] = changed.Value;
|
||||
_attributeQualities[changed.AttributeName] = changed.Quality;
|
||||
|
||||
PublishAndNotifyChildren(changed);
|
||||
}
|
||||
@@ -345,7 +353,7 @@ public class InstanceActor : ReceiveActor
|
||||
kvp.Key,
|
||||
kvp.Key,
|
||||
kvp.Value,
|
||||
"Good",
|
||||
_attributeQualities.GetValueOrDefault(kvp.Key, "Good"),
|
||||
DateTimeOffset.UtcNow)).ToList();
|
||||
|
||||
var alarmStates = _alarmStates.Select(kvp => new AlarmStateChanged(
|
||||
|
||||
Reference in New Issue
Block a user