feat(historian): honor per-alarm HistorizeToAveva opt-out at the durable write
This commit is contained in:
@@ -22,14 +22,16 @@ public sealed class ScriptedAlarmEngineTests
|
||||
}
|
||||
|
||||
private static ScriptedAlarmDefinition Alarm(string id, string predicate,
|
||||
string msg = "condition", AlarmSeverity sev = AlarmSeverity.High) =>
|
||||
string msg = "condition", AlarmSeverity sev = AlarmSeverity.High,
|
||||
bool historizeToAveva = true) =>
|
||||
new(AlarmId: id,
|
||||
EquipmentPath: "Plant/Line1/Reactor",
|
||||
AlarmName: id,
|
||||
Kind: AlarmKind.AlarmCondition,
|
||||
Severity: sev,
|
||||
MessageTemplate: msg,
|
||||
PredicateScriptSource: predicate);
|
||||
PredicateScriptSource: predicate,
|
||||
HistorizeToAveva: historizeToAveva);
|
||||
|
||||
/// <summary>Verifies that LoadAsync compiles the alarm predicate and subscribes to all referenced upstream tags.</summary>
|
||||
[Fact]
|
||||
@@ -479,6 +481,38 @@ public sealed class ScriptedAlarmEngineTests
|
||||
events.First(e => e.Emission == EmissionKind.CommentAdded).Comment.ShouldBe("second look");
|
||||
}
|
||||
|
||||
/// <summary>Verifies the emitted <see cref="ScriptedAlarmEvent.HistorizeToAveva"/> carries the
|
||||
/// per-alarm opt-out flag from the <see cref="ScriptedAlarmDefinition"/> through to the event so the
|
||||
/// historian adapter can suppress the durable write while the live alerts fan-out is unaffected.
|
||||
/// An alarm defined <c>HistorizeToAveva: false</c> emits <c>false</c>; the default (<c>true</c>)
|
||||
/// emits <c>true</c>.</summary>
|
||||
[Fact]
|
||||
public async Task Emission_carries_HistorizeToAveva_flag_from_definition()
|
||||
{
|
||||
var up = new FakeUpstream();
|
||||
up.Set("Temp", 50);
|
||||
using var eng = Build(up, out _);
|
||||
await eng.LoadAsync(
|
||||
[
|
||||
Alarm("OptOut", """return (int)ctx.GetTag("Temp").Value > 100;""", historizeToAveva: false),
|
||||
Alarm("OptIn", """return (int)ctx.GetTag("Temp").Value > 100;""" /* default true */),
|
||||
],
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
var events = new List<ScriptedAlarmEvent>();
|
||||
eng.OnEvent += (_, e) => events.Add(e);
|
||||
|
||||
up.Push("Temp", 150);
|
||||
await WaitForAsync(() =>
|
||||
events.Any(e => e.AlarmId == "OptOut" && e.Emission == EmissionKind.Activated) &&
|
||||
events.Any(e => e.AlarmId == "OptIn" && e.Emission == EmissionKind.Activated));
|
||||
|
||||
events.First(e => e.AlarmId == "OptOut" && e.Emission == EmissionKind.Activated)
|
||||
.HistorizeToAveva.ShouldBeFalse("opt-out alarm carries HistorizeToAveva=false on its emission");
|
||||
events.First(e => e.AlarmId == "OptIn" && e.Emission == EmissionKind.Activated)
|
||||
.HistorizeToAveva.ShouldBeTrue("opt-in (default) alarm carries HistorizeToAveva=true on its emission");
|
||||
}
|
||||
|
||||
// (2b) TimedShelveAsync / UnshelveAsync end-to-end through the engine.
|
||||
/// <summary>Verifies that TimedShelveAsync shelves with a deadline and UnshelveAsync removes the shelve before the timer expires.</summary>
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user