6affbd57ea
ci / nightly-windev (push) Has been skipped
ci / windows-x86 (push) Successful in 1m19s
ci / java (push) Successful in 2m8s
ci / portable (push) Failing after 2m23s
ci / nightly-windev (pull_request) Has been skipped
ci / windows-x86 (pull_request) Successful in 1m18s
ci / java (pull_request) Successful in 2m3s
ci / portable (pull_request) Failing after 2m17s
Adds a managed acknowledge path over AVEVA's modern alarm client so GUID acks carry full operator identity (domain + full name) and work on builds where the wnwrap COM AlarmAckByGUID is E_NOTIMPL. Default off; opt in with MXGATEWAY_USE_MANAGED_ALARM_ACK=1 (wnwrap behavior unchanged otherwise). - AaManagedAlarmAckConsumer: reflection wrapper over aaAlarmManagedClient.AlarmClient (InitializeConsumer/RegisterConsumer/ Subscribe/AlarmAckByGUID); EnvGatedFactory degrades to null (wnwrap) if the DLL can't load, so alarm reads never break. - IManagedAlarmAckClient seam. AlarmDispatcher takes an optional client and routes GUID acks to it (subscribing + disposing it alongside the reader). - AlarmCommandHandler gains an optional managedAckFactory; WorkerPipeSession wires AaManagedAlarmAckConsumer.EnvGatedFactory at the production sites. - WnalNativeAckConsumer: confirmed native alarmlst.dll WNAL submit layer (WNALalarmReqSetText / WNALUserRequest / WNALUserRequestEx + lpAlmAck layout). List acquisition is intentionally not hand-rolled: the alarm-record layout and selection semantics are provider-defined and not recoverable from alarmlst.dll, so inferring them risks acking the wrong alarm. - AlarmManagedGuidAckLiveSmokeTests: skip-gated live smoke that pulls a real (non-degraded) alarm GUID and asserts the ack APPLIES (Acknowledge transition / acked snapshot), not merely rc=0. By-name acks stay on wnwrap (AlarmClient has no AlarmAckByName). Grounded in static RE of alarmlst.dll, aaAlarmManagedClient.dll and alarmmgr.exe. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
45 lines
2.0 KiB
C#
45 lines
2.0 KiB
C#
using System;
|
|
|
|
namespace ZB.MOM.WW.MxGateway.Worker.MxAccess;
|
|
|
|
/// <summary>
|
|
/// Optional ack-only seam over AVEVA's modern managed alarm client
|
|
/// (<c>aaAlarmManagedClient.AlarmClient</c>). When supplied to an
|
|
/// <see cref="AlarmDispatcher"/>, GUID-keyed acknowledges route here
|
|
/// instead of the wnwrap COM consumer's <c>AlarmAckByGUID</c> (which is
|
|
/// <c>E_NOTIMPL</c> on current builds) — carrying full operator identity
|
|
/// (domain + full name) that the wnwrap 6-arg <c>AlarmAckByName</c> drops.
|
|
/// The production implementation is <see cref="AaManagedAlarmAckConsumer"/>.
|
|
/// </summary>
|
|
public interface IManagedAlarmAckClient : IDisposable
|
|
{
|
|
/// <summary>
|
|
/// Run the client's Initialize → Register → Subscribe lifecycle against
|
|
/// the same subscription expression the read consumer uses
|
|
/// (<c>\\<node>\Galaxy!<area></c>). Must be called once,
|
|
/// on the worker STA, before <see cref="AcknowledgeByGuid"/>.
|
|
/// </summary>
|
|
/// <param name="subscription">The subscription expression.</param>
|
|
void Subscribe(string subscription);
|
|
|
|
/// <summary>
|
|
/// Acknowledge a single alarm by GUID with full operator identity.
|
|
/// Returns AVEVA's native status (0 = success; 0 means accepted, not
|
|
/// necessarily applied — verify the alarm's acked state / Historian row).
|
|
/// </summary>
|
|
/// <param name="alarmGuid">The alarm GUID.</param>
|
|
/// <param name="comment">The acknowledgment comment.</param>
|
|
/// <param name="operatorName">The operator name.</param>
|
|
/// <param name="operatorNode">The operator node.</param>
|
|
/// <param name="operatorDomain">The operator domain.</param>
|
|
/// <param name="operatorFullName">The operator full name.</param>
|
|
/// <returns>The AVEVA-native status code.</returns>
|
|
int AcknowledgeByGuid(
|
|
Guid alarmGuid,
|
|
string comment,
|
|
string operatorName,
|
|
string operatorNode,
|
|
string operatorDomain,
|
|
string operatorFullName);
|
|
}
|