IF IS_ARRAY(#"DB Alarms") THEN // Calculate the maximum number of alarms (array size minus 1) #"Max Num of Alarms" := CountOfElements(#"DB Alarms") - 1; // Initialize timing variables for performance monitoring #Aux."Elapsed Time s" := LREAL_TO_REAL(RUNTIME(#Aux.TimeRecorded)); #Aux."Added Time" := 0.0; #Aux."alarms analysed for call" := 0; // Main processing loop - continues until 0.5 seconds have elapsed WHILE #Aux."Added Time" < 0.5 DO // Reset index and clear section data when all alarms have been processed IF #Aux.index >= #"Max Num of Alarms" THEN #Aux.index := 0; // Reset section data for alarms and warnings FOR #s := 1 TO "Numero_Sezioni" DO IF NOT #"Sections Data"[#s]."Check Alarm" THEN #"Sections Data"[#s]."Actual Alarm" := 0; #"Sections Data"[#s]."Priority Alarm" := -1; END_IF; IF NOT #"Sections Data"[#s]."Check Warning" THEN #"Sections Data"[#s]."Actual Warning" := 0; #"Sections Data"[#s]."Priority Warning" := -1; END_IF; #"Sections Data"[#s]."Check Alarm" := FALSE; #"Sections Data"[#s]."Check Warning" := FALSE; END_FOR; END_IF; // Move current alarm data to a temporary variable for processing #Result := MOVE_BLK_VARIANT(SRC := #"DB Alarms", COUNT := 1, SRC_INDEX := #Aux.index, DEST_INDEX := 0, DEST => #Alarm); // Process the alarm if it's valid and enabled IF #Alarm.DB > 0 AND NOT #Alarm.Disable THEN // Store the previous state and read the current state #Alarm.Ons := #Alarm.Value; #Alarm.Value := PEEK_BOOL(area := #DB, dbNumber := #Alarm.DB, byteOffset := #Alarm."Byte", bitOffset := #Alarm.Bit); // Check each section for this alarm FOR #s := 1 TO "Numero_Sezioni" DO IF #Alarm.Section[#s] THEN IF #Alarm.Value THEN // Process warnings IF #Alarm."Is Warning" AND (#"Sections Data"[#s]."Priority Warning" < #Alarm.Priority OR #Alarm.AlarmNum = #"Sections Data"[#s]."Actual Warning") THEN #"Sections Data"[#s]."Actual Warning" := #Alarm.AlarmNum; #"Sections Data"[#s]."Priority Warning" := #Alarm.Priority; #"Sections Data"[#s]."Check Warning" := TRUE; END_IF; // Process alarms IF NOT #Alarm."Is Warning" AND (#"Sections Data"[#s]."Priority Alarm" < #Alarm.Priority OR #Alarm.AlarmNum = #"Sections Data"[#s]."Actual Alarm") THEN #"Sections Data"[#s]."Actual Alarm" := #Alarm.AlarmNum; #"Sections Data"[#s]."Priority Alarm" := #Alarm.Priority; #"Sections Data"[#s]."Check Alarm" := TRUE; END_IF; END_IF; END_IF; END_FOR; END_IF; // Write back the processed alarm data #Result := MOVE_BLK_VARIANT(SRC := #Alarm, COUNT := 1, SRC_INDEX := 0, DEST_INDEX := #Aux.index, DEST => #"DB Alarms"); // Update counters and timing information #Aux.index := #Aux.index + 1; #Aux."alarms analysed for call" := #Aux."alarms analysed for call" + 1; #Aux."Elapsed Time s" := LREAL_TO_REAL(RUNTIME(#Aux.TimeRecorded)); #Aux."Added Time" := #Aux."Added Time" + #Aux."Elapsed Time s" * 1000.0; END_WHILE; END_IF;