mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-17 05:11:13 +08:00
2f72239a72
Every Enable call on a reference-server alarm produced **two** condition
events (different EventIds, same Time); Disable produced one.
## Cause
`ConditionTypeHolder.OnEnableDisableAlarm` is registered as the
condition's `OnEnableDisable` hook, which
`ConditionState.ProcessBeforeEnableDisable` calls *before*
`OnEnableCalled`/`OnDisableCalled` change the `EnabledState`. The hook
switched the state (`SetEnableState`) and called `ReportEvent()` itself;
the core then ran `UpdateStateAfterEnable` and `ReportStateChange` for
the same change, because every concrete holder sets
`AutoReportStateChanges` (`AcknowledgeableConditionTypeHolder`). On
Disable the hook's `ReportEvent` is skipped (the condition is already
disabled), so only Enable doubled.
Part 9 §5.5.2: a change of `EnabledState` causes a ConditionType Event
Notification — one per change. The duplicate also made the CTT's *A and
C Enable Test_002* flaky: it took the second notification as the answer
to its next call (worked around in the CTT scripts).
## Fix
The hook keeps setting the `Message` ("Enabling" / "Disabling alarm …",
carried by the core's event) and leaves the state change and its event
to the core. For a condition without `AutoReportStateChanges` it still
changes the state and reports, as before.
## Tests
`AlarmsAndConditionsEnableTests.DisableEnableViaTypeAndInstanceMethodNoEventsDuringDisabledAsync`
now asserts exactly one condition event in the Enable call window —
fails on master (`Expected: 1 But was: 2`), passes with the fix. All A&C
history tests (152, 3 runs) and client alarm tests (55) pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>