Midas Alarm Functions (al_xxx)


Functions

INT al_trigger_alarm (const char *alarm_name, const char *alarm_message, const char *default_class, const char *cond_str, INT type)
INT al_reset_alarm (const char *alarm_name)
INT al_check ()


Function Documentation

INT al_check (  ) 

Scan ODB for alarms.

Returns:
AL_SUCCESS

Definition at line 508 of file alarm.c.

Referenced by cm_yield(), and rpc_server_dispatch().

00509 {
00510    if (rpc_is_remote())
00511       return rpc_call(RPC_AL_CHECK);
00512 
00513 #ifdef LOCAL_ROUTINES
00514    {
00515       INT i, status, size, semaphore;
00516       HNDLE hDB, hkeyroot, hkey;
00517       KEY key;
00518       ALARM a;
00519       char str[256], value[256];
00520       time_t now;
00521       PROGRAM_INFO program_info;
00522       BOOL flag;
00523 
00524       ALARM_CLASS_STR(alarm_class_str);
00525       ALARM_ODB_STR(alarm_odb_str);
00526       ALARM_PERIODIC_STR(alarm_periodic_str);
00527 
00528       cm_get_experiment_database(&hDB, NULL);
00529 
00530       if (hDB == 0)
00531          return AL_SUCCESS;     /* called from server not yet connected */
00532 
00533       /* check online mode */
00534       flag = TRUE;
00535       size = sizeof(flag);
00536       db_get_value(hDB, 0, "/Runinfo/Online Mode", &flag, &size, TID_INT, TRUE);
00537       if (!flag)
00538          return AL_SUCCESS;
00539 
00540       /* check global alarm flag */
00541       flag = TRUE;
00542       size = sizeof(flag);
00543       db_get_value(hDB, 0, "/Alarms/Alarm system active", &flag, &size, TID_BOOL, TRUE);
00544       if (!flag)
00545          return AL_SUCCESS;
00546 
00547       /* request semaphore */
00548       cm_get_experiment_semaphore(&semaphore, NULL, NULL, NULL);
00549       status = ss_semaphore_wait_for(semaphore, 100);
00550       if (status != SS_SUCCESS)
00551          return SUCCESS;        /* someone else is doing alarm business */
00552 
00553       /* check ODB alarms */
00554       db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
00555       if (!hkeyroot) {
00556          /* create default ODB alarm */
00557          status = db_create_record(hDB, 0, "/Alarms/Alarms/Demo ODB", strcomb(alarm_odb_str));
00558          db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
00559          if (!hkeyroot) {
00560             ss_semaphore_release(semaphore);
00561             return SUCCESS;
00562          }
00563 
00564          status = db_create_record(hDB, 0, "/Alarms/Alarms/Demo periodic", strcomb(alarm_periodic_str));
00565          db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
00566          if (!hkeyroot) {
00567             ss_semaphore_release(semaphore);
00568             return SUCCESS;
00569          }
00570 
00571          /* create default alarm classes */
00572          status = db_create_record(hDB, 0, "/Alarms/Classes/Alarm", strcomb(alarm_class_str));
00573          status = db_create_record(hDB, 0, "/Alarms/Classes/Warning", strcomb(alarm_class_str));
00574          if (status != DB_SUCCESS) {
00575             ss_semaphore_release(semaphore);
00576             return SUCCESS;
00577          }
00578       }
00579 
00580       for (i = 0;; i++) {
00581          status = db_enum_key(hDB, hkeyroot, i, &hkey);
00582          if (status == DB_NO_MORE_SUBKEYS)
00583             break;
00584 
00585          db_get_key(hDB, hkey, &key);
00586 
00587          size = sizeof(a);
00588          status = db_get_record(hDB, hkey, &a, &size, 0);
00589          if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
00590             /* make sure alarm record has right structure */
00591             db_check_record(hDB, hkey, "", strcomb(alarm_odb_str), TRUE);
00592             size = sizeof(a);
00593             status = db_get_record(hDB, hkey, &a, &size, 0);
00594             if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
00595                cm_msg(MERROR, "al_check", "Cannot get alarm record");
00596                continue;
00597             }
00598          }
00599 
00600          /* check periodic alarm only when active */
00601          if (a.active &&
00602              a.type == AT_PERIODIC &&
00603              a.check_interval > 0 && (INT) ss_time() - (INT) a.checked_last > a.check_interval) {
00604             /* if checked_last has not been set, set it to current time */
00605             if (a.checked_last == 0) {
00606                a.checked_last = ss_time();
00607                db_set_record(hDB, hkey, &a, size, 0);
00608             } else
00609                al_trigger_alarm(key.name, a.alarm_message, a.alarm_class, "", AT_PERIODIC);
00610          }
00611 
00612          /* check alarm only when active and not internal */
00613          if (a.active &&
00614              a.type == AT_EVALUATED &&
00615              a.check_interval > 0 && (INT) ss_time() - (INT) a.checked_last > a.check_interval) {
00616             /* if condition is true, trigger alarm */
00617             if (al_evaluate_condition(a.condition, value)) {
00618                sprintf(str, a.alarm_message, value);
00619                al_trigger_alarm(key.name, str, a.alarm_class, "", AT_EVALUATED);
00620             } else {
00621                a.checked_last = ss_time();
00622                status = db_set_record(hDB, hkey, &a, sizeof(a), 0);
00623                if (status != DB_SUCCESS) {
00624                   cm_msg(MERROR, "al_check", "Cannot write back alarm record");
00625                   continue;
00626                }
00627             }
00628          }
00629       }
00630 
00631       /* check /programs alarms */
00632       db_find_key(hDB, 0, "/Programs", &hkeyroot);
00633       if (hkeyroot) {
00634          for (i = 0;; i++) {
00635             status = db_enum_key(hDB, hkeyroot, i, &hkey);
00636             if (status == DB_NO_MORE_SUBKEYS)
00637                break;
00638 
00639             db_get_key(hDB, hkey, &key);
00640 
00641             /* don't check "execute on xxx" */
00642             if (key.type != TID_KEY)
00643                continue;
00644 
00645             size = sizeof(program_info);
00646             status = db_get_record(hDB, hkey, &program_info, &size, 0);
00647             if (status != DB_SUCCESS) {
00648                cm_msg(MERROR, "al_check", "Cannot get program info record");
00649                continue;
00650             }
00651 
00652             now = ss_time();
00653 
00654             rpc_get_name(str);
00655             str[strlen(key.name)] = 0;
00656             if (!equal_ustring(str, key.name) && cm_exist(key.name, FALSE) == CM_NO_CLIENT) {
00657                if (program_info.first_failed == 0)
00658                   program_info.first_failed = (DWORD) now;
00659 
00660                /* fire alarm when not running for more than what specified in check interval */
00661                if (now - program_info.first_failed >= program_info.check_interval / 1000) {
00662                   /* if not running and alarm calss defined, trigger alarm */
00663                   if (program_info.alarm_class[0]) {
00664                      sprintf(str, "Program %s is not running", key.name);
00665                      al_trigger_alarm(key.name, str, program_info.alarm_class,
00666                                       "Program not running", AT_PROGRAM);
00667                   }
00668 
00669                   /* auto restart program */
00670                   if (program_info.auto_restart && program_info.start_command[0]) {
00671                      ss_system(program_info.start_command);
00672                      program_info.first_failed = 0;
00673                      cm_msg(MTALK, "al_check", "Program %s restarted", key.name);
00674                   }
00675                }
00676             } else
00677                program_info.first_failed = 0;
00678 
00679             db_set_record(hDB, hkey, &program_info, sizeof(program_info), 0);
00680          }
00681       }
00682 
00683       ss_semaphore_release(semaphore);
00684    }
00685 #endif                          /* LOCAL_COUTINES */
00686 
00687    return SUCCESS;
00688 }

INT al_reset_alarm ( const char *  alarm_name  ) 

Reset (acknoledge) alarm.

Parameters:
alarm_name Alarm name, defined in /alarms/alarms
Returns:
AL_SUCCESS, AL_RESETE, AL_INVALID_NAME

Definition at line 420 of file alarm.c.

Referenced by command_loop(), SqlODBC::Connect(), interprete(), lazy_main(), and lazy_maintain_free_space().

00421 {
00422    int status, size, i;
00423    HNDLE hDB, hkeyalarm, hkeyclass, hsubkey;
00424    KEY key;
00425    char str[256];
00426    ALARM a;
00427    ALARM_CLASS ac;
00428 
00429    cm_get_experiment_database(&hDB, NULL);
00430 
00431    if (alarm_name == NULL) {
00432       /* reset all alarms */
00433       db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyalarm);
00434       if (hkeyalarm) {
00435          for (i = 0;; i++) {
00436             db_enum_link(hDB, hkeyalarm, i, &hsubkey);
00437 
00438             if (!hsubkey)
00439                break;
00440 
00441             db_get_key(hDB, hsubkey, &key);
00442             al_reset_alarm(key.name);
00443          }
00444       }
00445       return AL_SUCCESS;
00446    }
00447 
00448    /* find alarm and alarm class */
00449    sprintf(str, "/Alarms/Alarms/%s", alarm_name);
00450    db_find_key(hDB, 0, str, &hkeyalarm);
00451    if (!hkeyalarm) {
00452       /*cm_msg(MERROR, "al_reset_alarm", "Alarm %s not found in ODB", alarm_name);*/
00453       return AL_INVALID_NAME;
00454    }
00455 
00456    size = sizeof(a);
00457    status = db_get_record(hDB, hkeyalarm, &a, &size, 0);
00458    if (status != DB_SUCCESS) {
00459       cm_msg(MERROR, "al_reset_alarm", "Cannot get alarm record");
00460       return AL_ERROR_ODB;
00461    }
00462 
00463    sprintf(str, "/Alarms/Classes/%s", a.alarm_class);
00464    db_find_key(hDB, 0, str, &hkeyclass);
00465    if (!hkeyclass) {
00466       cm_msg(MERROR, "al_reset_alarm", "Alarm class %s not found in ODB", a.alarm_class);
00467       return AL_INVALID_NAME;
00468    }
00469 
00470    size = sizeof(ac);
00471    status = db_get_record(hDB, hkeyclass, &ac, &size, 0);
00472    if (status != DB_SUCCESS) {
00473       cm_msg(MERROR, "al_reset_alarm", "Cannot get alarm class record");
00474       return AL_ERROR_ODB;
00475    }
00476 
00477    if (a.triggered) {
00478       a.triggered = 0;
00479       a.time_triggered_first[0] = 0;
00480       a.time_triggered_last[0] = 0;
00481       a.checked_last = 0;
00482 
00483       ac.system_message_last = 0;
00484       ac.execute_last = 0;
00485 
00486       status = db_set_record(hDB, hkeyalarm, &a, sizeof(a), 0);
00487       if (status != DB_SUCCESS) {
00488          cm_msg(MERROR, "al_reset_alarm", "Cannot update alarm record");
00489          return AL_ERROR_ODB;
00490       }
00491       status = db_set_record(hDB, hkeyclass, &ac, sizeof(ac), 0);
00492       if (status != DB_SUCCESS) {
00493          cm_msg(MERROR, "al_reset_alarm", "Cannot update alarm class record");
00494          return AL_ERROR_ODB;
00495       }
00496       return AL_RESET;
00497    }
00498 
00499    return AL_SUCCESS;
00500 }

INT al_trigger_alarm ( const char *  alarm_name,
const char *  alarm_message,
const char *  default_class,
const char *  cond_str,
INT  type 
)

Trigger a certain alarm.

 ...
  lazy.alarm[0] = 0;
  size = sizeof(lazy.alarm);
  db_get_value(hDB, pLch->hKey, "Settings/Alarm Class", lazy.alarm, &size, TID_STRING, TRUE);

  // trigger alarm if defined
  if (lazy.alarm[0])
    al_trigger_alarm("Tape", "Tape full...load new one!", lazy.alarm, "Tape full", AT_INTERNAL);
  ...
Parameters:
alarm_name Alarm name, defined in /alarms/alarms
alarm_message Optional message which goes with alarm
default_class If alarm is not yet defined under /alarms/alarms/<alarm_name>, a new one is created and this default class is used.
cond_str String displayed in alarm condition
type Alarm type, one of AT_xxx
Returns:
AL_SUCCESS, AL_INVALID_NAME

Definition at line 203 of file alarm.c.

Referenced by al_check(), SqlODBC::Disconnect(), hs_define_event_odbc(), hs_get_tags_odbc(), hs_read_odbc(), hs_write_event_odbc(), lazy_main(), lazy_maintain_free_space(), and rpc_server_dispatch().

00204 {
00205    if (rpc_is_remote())
00206       return rpc_call(RPC_AL_TRIGGER_ALARM, alarm_name, alarm_message, default_class, cond_str, type);
00207 
00208 #ifdef LOCAL_ROUTINES
00209    {
00210       int status, size;
00211       HNDLE hDB, hkeyalarm;
00212       char str[256];
00213       ALARM a;
00214       BOOL flag;
00215       ALARM_ODB_STR(alarm_odb_str);
00216 
00217       cm_get_experiment_database(&hDB, NULL);
00218 
00219       /* check online mode */
00220       flag = TRUE;
00221       size = sizeof(flag);
00222       db_get_value(hDB, 0, "/Runinfo/Online Mode", &flag, &size, TID_INT, TRUE);
00223       if (!flag)
00224          return AL_SUCCESS;
00225 
00226       /* find alarm */
00227       sprintf(str, "/Alarms/Alarms/%s", alarm_name);
00228       db_find_key(hDB, 0, str, &hkeyalarm);
00229       if (!hkeyalarm) {
00230          /* alarm must be an internal analyzer alarm, so create a default alarm */
00231          status = db_create_record(hDB, 0, str, strcomb(alarm_odb_str));
00232          db_find_key(hDB, 0, str, &hkeyalarm);
00233          if (!hkeyalarm) {
00234             cm_msg(MERROR, "al_trigger_alarm", "Cannot create alarm record");
00235             return AL_ERROR_ODB;
00236          }
00237 
00238          if (default_class && default_class[0])
00239             db_set_value(hDB, hkeyalarm, "Alarm Class", default_class, 32, 1, TID_STRING);
00240          status = TRUE;
00241          db_set_value(hDB, hkeyalarm, "Active", &status, sizeof(status), 1, TID_BOOL);
00242       }
00243 
00244       /* set parameters for internal alarms */
00245       if (type != AT_EVALUATED && type != AT_PERIODIC) {
00246          db_set_value(hDB, hkeyalarm, "Type", &type, sizeof(INT), 1, TID_INT);
00247          strcpy(str, cond_str);
00248          db_set_value(hDB, hkeyalarm, "Condition", str, 256, 1, TID_STRING);
00249       }
00250 
00251       size = sizeof(a);
00252       status = db_get_record(hDB, hkeyalarm, &a, &size, 0);
00253       if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
00254          /* make sure alarm record has right structure */
00255          db_check_record(hDB, hkeyalarm, "", strcomb(alarm_odb_str), TRUE);
00256 
00257          size = sizeof(a);
00258          status = db_get_record(hDB, hkeyalarm, &a, &size, 0);
00259          if (status != DB_SUCCESS) {
00260             cm_msg(MERROR, "al_trigger_alarm", "Cannot get alarm record");
00261             return AL_ERROR_ODB;
00262          }
00263       }
00264 
00265       /* if internal alarm, check if active and check interval */
00266       if (a.type != AT_EVALUATED && a.type != AT_PERIODIC) {
00267          /* check global alarm flag */
00268          flag = TRUE;
00269          size = sizeof(flag);
00270          db_get_value(hDB, 0, "/Alarms/Alarm system active", &flag, &size, TID_BOOL, TRUE);
00271          if (!flag)
00272             return AL_SUCCESS;
00273 
00274          if (!a.active)
00275             return AL_SUCCESS;
00276 
00277          if ((INT) ss_time() - (INT) a.checked_last < a.check_interval)
00278             return AL_SUCCESS;
00279 
00280          /* now the alarm will be triggered, so save time */
00281          a.checked_last = ss_time();
00282       }
00283 
00284       /* write back alarm message for internal alarms */
00285       if (a.type != AT_EVALUATED && a.type != AT_PERIODIC) {
00286          strncpy(a.alarm_message, alarm_message, 79);
00287          a.alarm_message[79] = 0;
00288       }
00289 
00290       /* now trigger alarm class defined in this alarm */
00291       if (a.alarm_class[0])
00292          al_trigger_class(a.alarm_class, alarm_message, a.triggered > 0);
00293 
00294       /* signal alarm being triggered */
00295       cm_asctime(str, sizeof(str));
00296 
00297       if (!a.triggered)
00298          strcpy(a.time_triggered_first, str);
00299 
00300       a.triggered++;
00301       strcpy(a.time_triggered_last, str);
00302 
00303       a.checked_last = ss_time();
00304 
00305       status = db_set_record(hDB, hkeyalarm, &a, sizeof(a), 0);
00306       if (status != DB_SUCCESS) {
00307          cm_msg(MERROR, "al_trigger_alarm", "Cannot update alarm record");
00308          return AL_ERROR_ODB;
00309       }
00310 
00311    }
00312 #endif                          /* LOCAL_ROUTINES */
00313 
00314    return AL_SUCCESS;
00315 }


Midas DOC Version 3.0.0 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - Greg Hackman - Gertjan Hofman - Paul Knowles - Exaos Lee - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk