How is it possible to enforce acknowledge of a Multiinstance alarm?
Acknowledge of a Multiinstance alarm in WinCC OA is only possible when the same alarm exists in a connected device. Every acknowledge message in WinCC OA to an alarm from a disconnected device returns a FALSE from isAckable().
This is a security functionality to prevent the system from inconsistencies.
But there could be some exception where it is necessary to enforce the acknowledge message of a Multiinstance alarm even if the device is not connected with the WinCC OA system.
In this case it is necessary to trigger an alertSet() at the _alert_hdl.._event attribute with value 4 (DPATTR_ALERTEVENT_SINGLE_ACK) at the same time where the come or went event occurred.
It is necessary to implement this alertSet() functionality in an own CTRL-Script to acknowledge the pending alarm. Below there is an example code with a function that needs two input parameters:
1. name of the data point with the pending alarm
2. System name of the data point
ackAlert(string dpName, string systemName)
{
string sqlAlert;
dyn_dyn_anytype tab;
time alertTimeCame, alertTimeGone;
string dpeAlert;
time ackTime;
bool direction;
int indexCame, indexGone;
sqlAlert = "SELECT ALERT '_alert_hdl.._came_time', '_alert_hdl.._gone_time', '_alert_hdl.._ack_time', '_alert_hdl.._direction', '_alert_hdl.._came_time_idx', '_alert_hdl.._gone_time_idx' FROM '" + dpName + "' REMOTE '" + systemName + "'";
dpQuery(sqlAlert, tab);
for(int i = 2; i<=dynlen(tab); i++)
{
ackTime = tab[i][5];
if (ackTime != 0)
{
//nothing to do
continue;
}
direction = tab[i][6]; //check for alarm direction 1: CAME; 2: WENT
indexCame = tab[i][7]; //readIndex Came Alarm
indexGone = tab[i][8]; //readIndex Went Alarm
dpeAlert = tab[i][1];
dpeAlert = strltrim( dpeAlert, dpSubStr(dpeAlert, DPSUB_SYS_DP));
alertTimeCame = tab[i][3];
alertTimeGone = tab[i][4];
if(direction)
{
DebugTN("execute alertSet Came: ", alertTimeCame, indexCame, systemName + dpName + dpeAlert + ":_alert_hdl.._event", DPATTR_ALERTEVENT_SINGLE_ACK);
alertSet(alertTimeCame, indexCame, systemName + dpName + dpeAlert + ":_alert_hdl.._event", DPATTR_ALERTEVENT_SINGLE_ACK);
}
else
{
DebugTN("execute alertSet Went: ", alertTimeGone, indexGone, systemName + dpName + dpeAlert + ":_alert_hdl.._event", DPATTR_ALERTEVENT_SINGLE_ACK);
alertSet(alertTimeGone, indexGone, systemName + dpName + dpeAlert + ":_alert_hdl.._event", DPATTR_ALERTEVENT_SINGLE_ACK);
}
}
}