In the following examples the continuous alert handling will be compared with the discrete alert handling. For every example configuration the curve of the original value will be shown in a trend diagram.

## Example of an continuous alert handling

In this example an alert will be triggered, when the filling level of a tank is too low. It is specified that there is no upper limit, because the tank is filled wit a defined refill capacity as soon as a specific bottom range will be reached. The maximum filling level of the tank is 100 litre and the minimum is 0 litre.

In the following figure a continuous alert handling with 4 ranges has been configured.

The limiting values have been set as follows:

• range 4: good range - 40-100 litre

• range 3: information range - 39-21 litre

• range 2: warning range - 20-11 litre

• range 1: alerts range - 10-0 litre

The hysteresis of [-2,2] between the ranges 4 and 3 effects that the information alert will be returned only then, if the filling level goes below 38 litre. Just as well the information alert goes only then, if the filling level of 43 litre will be exceeded. The hysteresis shall avoid that the fluctuation in the 40 litre area always triggers a information alert.

In the following diagram the filling level of the tank reaches the following states:

1. Filling level sinks: 100..75..55..45..40..37..20..10

2. The tank will be filled automatically -> during the fill a defect occurs. The filling level fluctuates, because the draining process did not stop and the tank is tried to be filled: 11..21..35..45..43..41..37..55..37..20

3. Defect eliminated -> filling level raises till 100 litre again: 21..30..50..70..90..100

Diagram: Curve in the trend

Abbreviations:

IC - information came

WC - warning came

WW - warning went

## Example of a discrete alerts handling

This example describes the water temperature in a tank. The water is heated continuously, but must not exceed the temperature of 100°C. The current temperature of the water is detected and returned every 5 seconds.

The following figure shows an example configuration for this description above.

The limiting values have been set as follows:

• range 1: good range - 20, 40, 60°C

• range 2: information range - <0, 0-19, 21-39, 41-59, 61-69, >100°C

• range 3: warning range - 70-89°C

• range 4: alerts range - 90-100°C

The following water temperatures (states) are reached:

1. Water is heated to a temperature of 60°C (optimal temperature): 5, 9, 20, 29, 40, 53, 60°C.

2. The automatized measurement equipment has a defect -> the heating process continuous: 65, 75, 85, 92°C

3. Coolant is added, what has the effect that the temperature rapidly sinks: 90, 75, 60, 50, 40, 25°C

4. Tank with the coolant is empty -> the temperature is raising again: 35, 40, 55, 65, 80°C

5. The defect on the equipment could be eliminated -> temperature goes back to 60°C (optimal temperature)

Diagram: Curve in the trend

Abbreviations:

IC - information came

IW - information gone (no went text defined, so it is not visible in the event screen)

WC - warning came

WW - warning went

The range values are always scanned from the highest to the lowest range for a match. That means that in this example the alarm range is checked firstly. If the value is not in the range/range value, so the warning range will be checked, etc. In this example is the information range the most interesting one. This alert shall be returned every time (see configuration) when the value is unequal 20, 40 or 60. This means that in continuous value changes an information will be always returned, after one of these three ranges is exceeded. This can be useful for a better controlling of processes.

If the value matches the alert range, the lower ranges will not the checked anymore.

## Example of how to set an alert handling for multiinstance alerts by using CTRL function calls

In the following example a message is sent to the Event-Manager using alertSet(). This sets the corresponding attributes the already existing data point "MI_Demo" with configured multiinstance alert handling. Next, an SQL query dpQuery() is called to search for matches in the set attributes of the data point. The matches give then the information about the count when they are called as parameters in getACount().If the count is known the function alertGet() can be used, for example, to synchronize multiinstance alerts on redundant systems.

``````main()
{
dyn_anytype addVal = makeDynAnytype(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32);
time t;
dyn_dyn_anytype attr;
//The current time is stored in a local variable
t = getCurrentTime();
//set an alert on the data point 'MI_Demo.',
//with the _add_values we declared above
//Now we query a config from the data point where the came time and
//the alert id are same as ours
while (dynlen(attr) <= 1)
{
delay(0, 200);
}

//        => ALERT COUNT: 1 (at next call)
//        => ALERT COUNT: 2 (at next call)
//        ...
}``````

``````int _alertSet(string dpe)
{
time t = getCurrentTime();
/* Add the strsplit to one row. In this example, the example contains a line break for demonstration purposes */
\n17c\n18c\n19c\n20c\n21c\n22c\n23c\n24c\n25c\n26c\n27c\n28c\n29c\n30c\n31c\n32c",
"\n");
,t, 0, dpe + ":_alert_hdl.2._class"     , "information."
}``````

## Example of how to set a binary alert from CAME to WENT

In the following example all alert couples (CAME time and WENT time) of the data point MI_Demo are inserted into a variable. Each alert time is of the type atime, the internal time format including count and data point identifier. In the Log Viewer it looks like this:

[2012.12.22 12:12:12.000 (7 ) System1:MI_Demo. (Type: 41 Sys: 1 Dp: 508 El: 1 : 0..0)]

With the function getACount() you get the count of the given alert time (in this case the count would be 7). In order to address multiinstance alerts you need the alert time and the count.

With the status bits (direction, obsolete, visible) you can check whether it's a valid CAME alert and must be set to WENT.

This example is only working for binary multiinstance alerts. If you want to use it for nonbinary multiinstance alerts, you have to specify the details. For example "MI_Demo.:_alert_hdl.2._event" in order to set an WENT action for this alert range. See the second example below.

``````main()
{
dyn_anytype alarm;
bit32 state;
//All alert couples (CAME time & WENT time) of DP MI_Demo are inserted into the
//variable
//Then all alerts of the _alerts attribute will be checked whether they are
//CAME actions and must be set to WENT.

for(int j = 1; j <=dynlen(alarm); j++)
{
//The status bits of each alert are needed for checking.
DebugN("pending alarms:", rc, alarm[j], getACount(alarm[j]), "MI_Demo.:_alert_hdl.._state",
state, state[1], state[4], state[0], state[31]);
//It's checked if the alerts are still valid and if its direction is CAME with
//the status bits "obsolete", "visible" and "direction"
if (rc != 0 || state[1] == 1 /*obsolete*/ || state[4] == 0 /* visible */ || state[0] == 0 /* went */)
continue;
//and the alert will be set to WENT with the constant DPATTR_ALERTEVENT_WENT
DebugN(rc);
}
}``````

EXAMPLE

Multiinstance alerts can be triggered via Control. The following two Control examples show how to set multiinstance alerts to CAME and WENT.

``````main()
{
int retVal;
time t = makeTime(2016,04,20,15,44,00,000);

/* Note that when you want to set an alert to WENT, the time must correspond to the
CAME time and you have to specify the exact time including the milliseconds. In addition,
the ID (meaning the alert count)of the alert must correspond to the count of the
CAME alert. In this example the alert count is 0. See the second parameter in the
DebugN("RetVal:", retVal);
}``````

In order to set the alert to WENT, use the constant "DPATTR_ALERTEVENT_WENT".

``````main()
{
int retVal;
time t = makeTime(2016,04,20,15,44,00,000);
DebugN("RetVal:", retVal);
}``````

``````main()
{
bit32 state;

for(int j = 1; j<=dynlen(alert); j++)
{
/* The attribute _alert_hdl.._state contains the status bits for an alert in a bit32.
getACount returns the count that is needed for the alertSet, see example above */

}
}``````

The output of the code:

WCCOAui1: ["dpGet of the alert:"][dyn_anytype 2 items

``````WCCOAui1:
1: 2016.04.20 16:25:40.591 (0 ) :_alert_hdl.3 (Type: 0 Sys: 0 Dp: 0 El: 0 : _alert_hdl.3.0)``````
``````WCCOAui1:
2: 2016.04.20 16:27:59.869 (1 ) :_alert_hdl.3 (Type: 0 Sys: 0 Dp: 0 El: 0 : _alert_hdl.3.0)``````
``````WCCOAui1:
]``````
``````WCCOAui1:
``````WCCOAui1:

EXAMPLE

``````main()
{
int retVal;
time t = makeTime(2019,05,13,9,54,00,000);
/* Note that when you want to set the alert to WENT, the time must correspond
to the CAME time (including milliseconds)
count of the CAME alert. In this example the alert count is 0.
See the second parameter in the alertSet function call */
DebugN("RetVal:", retVal);
}``````

## Example of how to acknowledge a multi instance alert via a driver

External alerts of peripheral devices (S7, BACnet, OPC) must be written on the internal data point elements _Driver.AL.AckDps and _Driver.AL.AckData to be acknowledged via the respective driver (refer to Multiinstance alerts for further information). This can be realized by acknowledging the alert via the alert screen or using the function isAckable(). Following example shows how an alert can be passed to the isAckable() function in order to be acknowledged.

``````main()
{
int ret;
//time, count and DPE must correspond to an unacknowledged alert
//The attribute of the DPE (in our case _abbr) does not matter
time t = makeTime(2016,4,12,14,30,23, 608, true);
atime a = makeATime(t, 14, "System1:ClientAlarm_2.boolean:_alert_hdl.2._abbr");
dyn_atime dps = makeDynATime(a);
isAckable(2, dps, ret);
DebugN(ret);
}``````