MIDAS
Midas Alarm Functions (al_xxx)

Functions

BOOL al_evaluate_condition (const char *condition, char *value)
 
INT al_trigger_alarm (const char *alarm_name, const char *alarm_message, const char *default_class, const char *cond_str, INT type)
 
INT al_trigger_class (const char *alarm_class, const char *alarm_message, BOOL first)
 
INT al_reset_alarm (const char *alarm_name)
 
INT al_check ()
 
INT al_get_alarms (char *result, int result_size)
 
INT EXPRT al_define_odb_alarm (const char *name, const char *condition, const char *aclass, const char *message)
 

Detailed Description

dox


Function Documentation

◆ al_check()

INT al_check ( void  )

Scan ODB for alarms.

Returns
AL_SUCCESS

Definition at line 561 of file alarm.cxx.

561  {
562  if (rpc_is_remote())
563  return rpc_call(RPC_AL_CHECK);
564 
565 #ifdef LOCAL_ROUTINES
566  {
567  INT i, status, size, semaphore;
568  HNDLE hDB, hkeyroot, hkey;
569  KEY key;
570  char str[256], value[256];
571  PROGRAM_INFO_STR(program_info_str);
572  PROGRAM_INFO program_info;
573  BOOL flag;
574 
575  ALARM_CLASS_STR(alarm_class_str);
576  ALARM_ODB_STR(alarm_odb_str);
577  ALARM_PERIODIC_STR(alarm_periodic_str);
578 
580 
581  if (hDB == 0)
582  return AL_SUCCESS; /* called from server not yet connected */
583 
584  /* check online mode */
585  flag = TRUE;
586  size = sizeof(flag);
587  db_get_value(hDB, 0, "/Runinfo/Online Mode", &flag, &size, TID_INT, TRUE);
588  if (!flag)
589  return AL_SUCCESS;
590 
591  /* check global alarm flag */
592  flag = TRUE;
593  size = sizeof(flag);
594  db_get_value(hDB, 0, "/Alarms/Alarm system active", &flag, &size, TID_BOOL, TRUE);
595  if (!flag)
596  return AL_SUCCESS;
597 
598  /* request semaphore */
599  cm_get_experiment_semaphore(&semaphore, NULL, NULL, NULL);
600  status = ss_semaphore_wait_for(semaphore, 100);
601  if (status == SS_TIMEOUT)
602  return AL_SUCCESS; /* someone else is doing alarm business */
603  if (status != SS_SUCCESS) {
604  printf("al_check: Something is wrong with our semaphore, ss_semaphore_wait_for() returned %d, aborting.\n",
605  status);
606  // abort(); // DOES NOT RETURN
607  printf("al_check: Cannot abort - this will lock you out of odb. From this point, MIDAS will not work "
608  "correctly. Please read the discussion at https://midas.triumf.ca/elog/Midas/945\n");
609  // NOT REACHED
610  return AL_SUCCESS;
611  }
612 
613  /* check ODB alarms */
614  db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
615  if (!hkeyroot) {
616  /* create default ODB alarm */
617  status = db_create_record(hDB, 0, "/Alarms/Alarms/Demo ODB", strcomb1(alarm_odb_str).c_str());
618  db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
619  if (!hkeyroot) {
620  ss_semaphore_release(semaphore);
621  return AL_SUCCESS;
622  }
623 
624  status = db_create_record(hDB, 0, "/Alarms/Alarms/Demo periodic", strcomb1(alarm_periodic_str).c_str());
625  db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
626  if (!hkeyroot) {
627  ss_semaphore_release(semaphore);
628  return AL_SUCCESS;
629  }
630 
631  /* create default alarm classes */
632  status = db_create_record(hDB, 0, "/Alarms/Classes/Alarm", strcomb1(alarm_class_str).c_str());
633  status = db_create_record(hDB, 0, "/Alarms/Classes/Warning", strcomb1(alarm_class_str).c_str());
634  if (status != DB_SUCCESS) {
635  ss_semaphore_release(semaphore);
636  return AL_SUCCESS;
637  }
638  }
639 
640  for (i = 0;; i++) {
641  ALARM a;
642 
643  status = db_enum_key(hDB, hkeyroot, i, &hkey);
644  if (status == DB_NO_MORE_SUBKEYS)
645  break;
646 
647  db_get_key(hDB, hkey, &key);
648 
649  size = sizeof(a);
650  status = db_get_record1(hDB, hkey, &a, &size, 0, strcomb1(alarm_odb_str).c_str());
651  if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
652  /* make sure alarm record has right structure */
653  db_check_record(hDB, hkey, "", strcomb1(alarm_odb_str).c_str(), TRUE);
654  size = sizeof(a);
655  status = db_get_record1(hDB, hkey, &a, &size, 0, strcomb1(alarm_odb_str).c_str());
656  if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
657  cm_msg(MERROR, "al_check", "Cannot get alarm record");
658  continue;
659  }
660  }
661 
662  /* check periodic alarm only when active */
663  if (a.active && a.type == AT_PERIODIC && a.check_interval > 0 && (INT) ss_time() - (INT) a.checked_last > a.check_interval) {
664  /* if checked_last has not been set, set it to current time */
665  if (a.checked_last == 0) {
666  a.checked_last = ss_time();
667  db_set_record(hDB, hkey, &a, size, 0);
668  } else
670  }
671 
672  /* check alarm only when active and not internal */
673  if (a.active && a.type == AT_EVALUATED && a.check_interval > 0 && (INT) ss_time() - (INT) a.checked_last > a.check_interval) {
674  /* if condition is true, trigger alarm */
676  sprintf(str, a.alarm_message, value);
678  } else {
679  a.checked_last = ss_time();
680  status = db_set_value(hDB, hkey, "Checked last", &a.checked_last, sizeof(DWORD), 1, TID_DWORD);
681  if (status != DB_SUCCESS) {
682  cm_msg(MERROR, "al_check", "Cannot change alarm record");
683  continue;
684  }
685  }
686  }
687  }
688 
689  /* check /programs alarms */
690  db_find_key(hDB, 0, "/Programs", &hkeyroot);
691  if (hkeyroot) {
692  for (i = 0;; i++) {
693  status = db_enum_key(hDB, hkeyroot, i, &hkey);
694  if (status == DB_NO_MORE_SUBKEYS)
695  break;
696 
697  db_get_key(hDB, hkey, &key);
698 
699  /* don't check "execute on xxx" */
700  if (key.type != TID_KEY)
701  continue;
702 
703  size = sizeof(program_info);
704  status = db_get_record1(hDB, hkey, &program_info, &size, 0, strcomb1(program_info_str).c_str());
705  if (status != DB_SUCCESS) {
706  cm_msg(MERROR, "al_check",
707  "Cannot get program info record for program \"%s\", db_get_record1() status %d", key.name,
708  status);
709  continue;
710  }
711 
712  time_t now = ss_time();
713 
714  // get name of this client
715  std::string name = rpc_get_name();
716  strlcpy(str, name.c_str(), sizeof(str));
717 
718  // truncate name of this client to the length of program name in /Programs/xxx
719  // to get rid if "odbedit1", "odbedit2", etc.
720  str[strlen(key.name)] = 0;
721 
722  // printf("str [%s], key.name [%s]\n", str, key.name);
724  if (program_info.first_failed == 0) {
725  program_info.first_failed = (DWORD) now;
726  db_set_record(hDB, hkey, &program_info, sizeof(program_info), 0);
727  }
728 
729  // printf("check %d-%d = %d >= %d\n", now, program_info.first_failed, now - program_info.first_failed,
730  // program_info.check_interval / 1000);
731 
732  /* fire alarm when not running for more than what specified in check interval */
733  if (now - program_info.first_failed >= program_info.check_interval / 1000) {
734  /* if not running and alarm class defined, trigger alarm */
735  if (program_info.alarm_class[0]) {
736  sprintf(str, "Program %s is not running", key.name);
737  al_trigger_alarm(key.name, str, program_info.alarm_class, "Program not running", AT_PROGRAM);
738  }
739 
740  /* auto restart program */
741  if (program_info.auto_restart && program_info.start_command[0]) {
742  ss_system(program_info.start_command);
743  program_info.first_failed = 0;
744  cm_msg(MTALK, "al_check", "Program %s restarted", key.name);
745  }
746  }
747  } else {
748  if (program_info.first_failed != 0) {
749  program_info.first_failed = 0;
750  db_set_record(hDB, hkey, &program_info, sizeof(program_info), 0);
751  }
752  }
753  }
754  }
755 
756  ss_semaphore_release(semaphore);
757  }
758 #endif /* LOCAL_COUTINES */
759 
760  return SUCCESS;
761 }
#define FALSE
Definition: cfortran.h:309
BOOL al_evaluate_condition(const char *condition, char *value)
Definition: alarm.cxx:42
INT al_trigger_alarm(const char *alarm_name, const char *alarm_message, const char *default_class, const char *cond_str, INT type)
Definition: alarm.cxx:225
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition: midas.cxx:3005
INT cm_get_experiment_semaphore(INT *semaphore_alarm, INT *semaphore_elog, INT *semaphore_history, INT *semaphore_msg)
Definition: midas.cxx:3027
INT cm_exist(const char *name, BOOL bUnique)
Definition: midas.cxx:7484
#define CM_NO_CLIENT
Definition: midas.h:590
#define DB_SUCCESS
Definition: midas.h:637
#define DB_NO_MORE_SUBKEYS
Definition: midas.h:652
#define SS_SUCCESS
Definition: midas.h:669
#define SS_TIMEOUT
Definition: midas.h:680
#define AL_SUCCESS
Definition: midas.h:760
unsigned int DWORD
Definition: mcstd.h:51
#define SUCCESS
Definition: mcstd.h:54
#define TID_KEY
Definition: midas.h:356
#define TID_BOOL
Definition: midas.h:347
#define MERROR
Definition: midas.h:565
#define MTALK
Definition: midas.h:570
#define TID_INT
Definition: midas.h:345
#define TID_DWORD
Definition: midas.h:343
INT ss_semaphore_release(HNDLE semaphore_handle)
Definition: system.cxx:2720
DWORD ss_time()
Definition: system.cxx:3401
INT ss_system(const char *command)
Definition: system.cxx:2087
INT ss_semaphore_wait_for(HNDLE semaphore_handle, INT timeout)
Definition: system.cxx:2600
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition: midas.cxx:917
BOOL equal_ustring(const char *str1, const char *str2)
Definition: odb.cxx:3191
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition: odb.cxx:5405
std::string strcomb1(const char **list)
Definition: odb.cxx:601
INT db_get_record1(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align, const char *rec_str)
Definition: odb.cxx:11809
INT db_check_record(HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct)
Definition: odb.cxx:12975
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition: odb.cxx:6009
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
Definition: odb.cxx:5251
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition: odb.cxx:4069
INT db_set_record(HNDLE hDB, HNDLE hKey, void *data, INT buf_size, INT align)
Definition: odb.cxx:12295
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition: odb.cxx:5576
INT db_create_record(HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str)
Definition: odb.cxx:12803
std::string rpc_get_name()
Definition: midas.cxx:13051
bool rpc_is_remote(void)
Definition: midas.cxx:12728
INT rpc_call(DWORD routine_id,...)
Definition: midas.cxx:13630
#define RPC_AL_CHECK
Definition: mrpc.h:113
HNDLE hDB
main ODB handle
Definition: mana.cxx:207
KEY key
Definition: mdump.cxx:37
INT i
Definition: mdump.cxx:35
#define DWORD
Definition: mhdump.cxx:31
INT HNDLE
Definition: midas.h:132
DWORD BOOL
Definition: midas.h:105
#define AT_PROGRAM
Definition: midas.h:1449
#define ALARM_PERIODIC_STR(_name)
Definition: midas.h:1528
int INT
Definition: midas.h:129
#define AT_PERIODIC
Definition: midas.h:1451
#define PROGRAM_INFO_STR(_name)
Definition: midas.h:1454
#define AT_LAST
Definition: midas.h:1452
#define ALARM_CLASS_STR(_name)
Definition: midas.h:1483
#define ALARM_ODB_STR(_name)
Definition: midas.h:1513
#define TRUE
Definition: midas.h:182
#define AT_EVALUATED
Definition: midas.h:1450
size_t EXPRT strlcpy(char *dst, const char *src, size_t size)
#define name(x)
Definition: midas_macro.h:24
double value[100]
Definition: odbhist.cxx:42
char str[256]
Definition: odbhist.cxx:33
DWORD status
Definition: odbhist.cxx:39
Definition: midas.h:1500
INT type
Definition: midas.h:1503
char alarm_class[32]
Definition: midas.h:1509
INT check_interval
Definition: midas.h:1504
DWORD checked_last
Definition: midas.h:1505
BOOL active
Definition: midas.h:1501
char alarm_message[80]
Definition: midas.h:1510
char condition[256]
Definition: midas.h:1508
Definition: midas.h:1032
DWORD type
Definition: midas.h:1033
char name[NAME_LENGTH]
Definition: midas.h:1035
BOOL auto_restart
Definition: midas.h:1443
DWORD check_interval
Definition: midas.h:1439
char alarm_class[32]
Definition: midas.h:1444
char start_command[256]
Definition: midas.h:1440
DWORD first_failed
Definition: midas.h:1445
Here is the call graph for this function:
Here is the caller graph for this function:

◆ al_define_odb_alarm()

INT EXPRT al_define_odb_alarm ( const char *  name,
const char *  condition,
const char *  aclass,
const char *  message 
)

Create an alarm that will trigger when an ODB condition is met.

Parameters
nameAlarm name, defined in /alarms/alarms
classAlarm class to be triggered
conditionAlarm condition to be evaluated
messageAlarm message
Returns
AL_SUCCESS

Definition at line 835 of file alarm.cxx.

835  {
836  HNDLE hDB, hKey;
837  char str[256];
838  ALARM_ODB_STR(alarm_odb_str);
839 
840  cm_get_experiment_database(&hDB, nullptr);
841 
842  snprintf(str, sizeof(str), "/Alarms/Alarms/%s", name);
843 
844  db_create_record(hDB, 0, str, strcomb1(alarm_odb_str).c_str());
845  db_find_key(hDB, 0, str, &hKey);
846  if (!hKey)
847  return DB_NO_MEMORY;
848 
849  db_set_value(hDB, hKey, "Condition", condition, 256, 1, TID_STRING);
850  db_set_value(hDB, hKey, "Alarm Class", aclass, 32, 1, TID_STRING);
851  db_set_value(hDB, hKey, "Alarm Message", message, 80, 1, TID_STRING);
852 
853  return AL_SUCCESS;
854 }
#define DB_NO_MEMORY
Definition: midas.h:639
#define TID_STRING
Definition: midas.h:353
HNDLE hKey
Definition: lazylogger.cxx:207
#define message(type, str)
Definition: midas_macro.h:262
Here is the call graph for this function:
Here is the caller graph for this function:

◆ al_evaluate_condition()

BOOL al_evaluate_condition ( const char *  condition,
char *  value 
)

dox

Definition at line 42 of file alarm.cxx.

42  {
43  HNDLE hDB, hkey;
44  int i, j, idx1, idx2, idx, size, state;
45  KEY key;
46  double value1, value2;
47  char value1_str[256], value2_str[256], str[256], op[3], function[80];
48  char data[10000];
49  DWORD dtime;
50 
51  strcpy(str, condition);
52  op[1] = op[2] = 0;
53  value1 = value2 = 0;
54  idx1 = idx2 = 0;
55 
56  /* find value and operator */
57  for (i = strlen(str) - 1; i > 0; i--)
58  if (strchr("<>=!&", str[i]) != NULL)
59  break;
60  op[0] = str[i];
61  for (j = 1; str[i + j] == ' '; j++)
62  ;
63  strlcpy(value2_str, str + i + j, sizeof(value2_str));
64  value2 = atof(value2_str);
65  str[i] = 0;
66 
67  if (i > 0 && strchr("<>=!&", str[i - 1])) {
68  op[1] = op[0];
69  op[0] = str[--i];
70  str[i] = 0;
71  }
72 
73  i--;
74  while (i > 0 && str[i] == ' ')
75  i--;
76  str[i + 1] = 0;
77 
78  /* check if function */
79  function[0] = 0;
80  if (str[i] == ')') {
81  str[i--] = 0;
82  if (strchr(str, '(')) {
83  *strchr(str, '(') = 0;
84  strcpy(function, str);
85  for (i = strlen(str) + 1, j = 0; str[i]; i++, j++)
86  str[j] = str[i];
87  str[j] = 0;
88  i = j - 1;
89  }
90  }
91 
92  /* find key */
93  if (str[i] == ']') {
94  str[i--] = 0;
95  if (str[i] == '*') {
96  idx1 = -1;
97  while (i > 0 && str[i] != '[')
98  i--;
99  str[i] = 0;
100  } else if (strchr(str, '[') && strchr(strchr(str, '['), '-')) {
101  while (i > 0 && isdigit(str[i]))
102  i--;
103  idx2 = atoi(str + i + 1);
104  while (i > 0 && str[i] != '[')
105  i--;
106  idx1 = atoi(str + i + 1);
107  str[i] = 0;
108  } else {
109  while (i > 0 && isdigit(str[i]))
110  i--;
111  idx1 = idx2 = atoi(str + i + 1);
112  str[i] = 0;
113  }
114  }
115 
117  db_find_key(hDB, 0, str, &hkey);
118  if (!hkey) {
119  cm_msg(MERROR, "al_evaluate_condition", "Cannot find key %s to evaluate alarm condition", str);
120  if (value)
121  strcpy(value, "unknown");
122  return FALSE;
123  }
124  db_get_key(hDB, hkey, &key);
125 
126  if (idx1 < 0) {
127  idx1 = 0;
128  idx2 = key.num_values - 1;
129  }
130 
131  for (idx = idx1; idx <= idx2; idx++) {
132 
133  if (equal_ustring(function, "access")) {
134  /* check key access time */
135  db_get_key_time(hDB, hkey, &dtime);
136  sprintf(value1_str, "%d", dtime);
137  value1 = atof(value1_str);
138  } else if (equal_ustring(function, "access_running")) {
139  /* check key access time if running */
140  db_get_key_time(hDB, hkey, &dtime);
141  sprintf(value1_str, "%d", dtime);
142  size = sizeof(state);
143  db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, FALSE);
144  if (state != STATE_RUNNING)
145  strcpy(value1_str, "0");
146  value1 = atof(value1_str);
147  } else {
148  /* get key data and convert to double */
149  db_get_key(hDB, hkey, &key);
150  size = sizeof(data);
151  db_get_data_index(hDB, hkey, data, &size, idx, key.type);
152  db_sprintf(value1_str, data, size, 0, key.type);
153  value1 = atof(value1_str);
154  }
155 
156  /* convert boolean values to integers */
157  if (key.type == TID_BOOL) {
158  value1 = (value1_str[0] == 'Y' || value1_str[0] == 'y' || value1_str[0] == '1');
159  value2 = (value2_str[0] == 'Y' || value2_str[0] == 'y' || value2_str[0] == '1');
160  }
161 
162  /* return value */
163  if (value) {
164  if (idx1 != idx2)
165  sprintf(value, "[%d] %s", idx, value1_str);
166  else
167  strcpy(value, value1_str);
168  }
169 
170  /* now do logical operation */
171  if (strcmp(op, "=") == 0)
172  if (value1 == value2)
173  return TRUE;
174  if (strcmp(op, "==") == 0)
175  if (value1 == value2)
176  return TRUE;
177  if (strcmp(op, "!=") == 0)
178  if (value1 != value2)
179  return TRUE;
180  if (strcmp(op, "<") == 0)
181  if (value1 < value2)
182  return TRUE;
183  if (strcmp(op, ">") == 0)
184  if (value1 > value2)
185  return TRUE;
186  if (strcmp(op, "<=") == 0)
187  if (value1 <= value2)
188  return TRUE;
189  if (strcmp(op, ">=") == 0)
190  if (value1 >= value2)
191  return TRUE;
192  if (strcmp(op, "&") == 0)
193  if (((unsigned int) value1 & (unsigned int) value2) > 0)
194  return TRUE;
195  }
196 
197  return FALSE;
198 }
#define STATE_RUNNING
Definition: midas.h:314
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition: odb.cxx:6885
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition: odb.cxx:10847
INT db_get_key_time(HNDLE hDB, HNDLE hKey, DWORD *delta)
Definition: odb.cxx:6122
void * data
Definition: mana.cxx:268
INT j
Definition: odbhist.cxx:40
INT num_values
Definition: midas.h:1034
Definition: tinyexpr.c:70
struct state state
Here is the call graph for this function:
Here is the caller graph for this function:

◆ al_get_alarms()

INT al_get_alarms ( char *  result,
int  result_size 
)

Scan ODB for alarms.

Returns
AL_SUCCESS

Definition at line 768 of file alarm.cxx.

768  {
769  HNDLE hDB, hkey, hsubkey;
770  int i, j, n, flag, size;
771  char alarm_class[32], msg[256], value_str[256], str[256];
772 
774  result[0] = 0;
775  n = 0;
776  db_find_key(hDB, 0, "/Alarms/Alarms", &hkey);
777  if (hkey) {
778  /* check global alarm flag */
779  flag = TRUE;
780  size = sizeof(flag);
781  db_get_value(hDB, 0, "/Alarms/Alarm System active", &flag, &size, TID_BOOL, TRUE);
782  if (flag) {
783  for (i = 0;; i++) {
784  db_enum_link(hDB, hkey, i, &hsubkey);
785 
786  if (!hsubkey)
787  break;
788 
789  size = sizeof(flag);
790  db_get_value(hDB, hsubkey, "Triggered", &flag, &size, TID_INT, TRUE);
791  if (flag) {
792  n++;
793 
794  size = sizeof(alarm_class);
795  db_get_value(hDB, hsubkey, "Alarm Class", alarm_class, &size, TID_STRING, TRUE);
796 
797  size = sizeof(msg);
798  db_get_value(hDB, hsubkey, "Alarm Message", msg, &size, TID_STRING, TRUE);
799 
800  size = sizeof(j);
801  db_get_value(hDB, hsubkey, "Type", &j, &size, TID_INT, TRUE);
802 
803  if (j == AT_EVALUATED) {
804  size = sizeof(str);
805  db_get_value(hDB, hsubkey, "Condition", str, &size, TID_STRING, TRUE);
806 
807  /* retrieve value */
808  al_evaluate_condition(str, value_str);
809  sprintf(str, msg, value_str);
810  } else
811  strlcpy(str, msg, sizeof(str));
812 
813  strlcat(result, alarm_class, result_size);
814  strlcat(result, ": ", result_size);
815  strlcat(result, str, result_size);
816  strlcat(result, "\n", result_size);
817  }
818  }
819  }
820  }
821 
822  return n;
823 }
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition: odb.cxx:5715
DWORD n[4]
Definition: mana.cxx:247
size_t EXPRT strlcat(char *dst, const char *src, size_t size)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ al_reset_alarm()

INT al_reset_alarm ( const char *  alarm_name)

dox Reset (acknoledge) alarm.

Parameters
alarm_nameAlarm name, defined in /alarms/alarms
Returns
AL_SUCCESS, AL_RESETE, AL_INVALID_NAME

Definition at line 472 of file alarm.cxx.

472  {
473  int status, size, i;
474  HNDLE hDB, hkeyalarm, hkeyclass, hsubkey;
475  KEY key;
476  char str[256];
477  ALARM a;
478  ALARM_CLASS ac;
479  ALARM_ODB_STR(alarm_str);
480  ALARM_CLASS_STR(alarm_class_str);
481 
483 
484  if (alarm_name == NULL) {
485  /* reset all alarms */
486  db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyalarm);
487  if (hkeyalarm) {
488  for (i = 0;; i++) {
489  db_enum_link(hDB, hkeyalarm, i, &hsubkey);
490 
491  if (!hsubkey)
492  break;
493 
494  db_get_key(hDB, hsubkey, &key);
496  }
497  }
498  return AL_SUCCESS;
499  }
500 
501  /* find alarm and alarm class */
502  sprintf(str, "/Alarms/Alarms/%s", alarm_name);
503  db_find_key(hDB, 0, str, &hkeyalarm);
504  if (!hkeyalarm) {
505  /*cm_msg(MERROR, "al_reset_alarm", "Alarm %s not found in ODB", alarm_name);*/
506  return AL_INVALID_NAME;
507  }
508 
509  size = sizeof(a);
510  status = db_get_record1(hDB, hkeyalarm, &a, &size, 0, strcomb1(alarm_str).c_str());
511  if (status != DB_SUCCESS) {
512  cm_msg(MERROR, "al_reset_alarm", "Cannot get alarm record");
513  return AL_ERROR_ODB;
514  }
515 
516  sprintf(str, "/Alarms/Classes/%s", a.alarm_class);
517  db_find_key(hDB, 0, str, &hkeyclass);
518  if (!hkeyclass) {
519  cm_msg(MERROR, "al_reset_alarm", "Alarm class %s not found in ODB", a.alarm_class);
520  return AL_INVALID_NAME;
521  }
522 
523  size = sizeof(ac);
524  status = db_get_record1(hDB, hkeyclass, &ac, &size, 0, strcomb1(alarm_class_str).c_str());
525  if (status != DB_SUCCESS) {
526  cm_msg(MERROR, "al_reset_alarm", "Cannot get alarm class record");
527  return AL_ERROR_ODB;
528  }
529 
530  if (a.triggered) {
531  a.triggered = 0;
532  a.time_triggered_first[0] = 0;
533  a.time_triggered_last[0] = 0;
534  a.checked_last = 0;
535 
536  ac.system_message_last = 0;
537  ac.execute_last = 0;
538 
539  status = db_set_record(hDB, hkeyalarm, &a, sizeof(a), 0);
540  if (status != DB_SUCCESS) {
541  cm_msg(MERROR, "al_reset_alarm", "Cannot update alarm record");
542  return AL_ERROR_ODB;
543  }
544  status = db_set_record(hDB, hkeyclass, &ac, sizeof(ac), 0);
545  if (status != DB_SUCCESS) {
546  cm_msg(MERROR, "al_reset_alarm", "Cannot update alarm class record");
547  return AL_ERROR_ODB;
548  }
549  cm_msg(MINFO, "al_reset_alarm", "Alarm \"%s\" reset", alarm_name);
550  return AL_RESET;
551  }
552 
553  return AL_SUCCESS;
554 }
INT al_reset_alarm(const char *alarm_name)
Definition: alarm.cxx:472
#define AL_INVALID_NAME
Definition: midas.h:761
#define AL_RESET
Definition: midas.h:763
#define AL_ERROR_ODB
Definition: midas.h:762
#define MINFO
Definition: midas.h:566
DWORD system_message_last
Definition: midas.h:1474
DWORD execute_last
Definition: midas.h:1477
char time_triggered_first[32]
Definition: midas.h:1506
char time_triggered_last[32]
Definition: midas.h:1507
INT triggered
Definition: midas.h:1502
Here is the call graph for this function:
Here is the caller graph for this function:

◆ al_trigger_alarm()

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

dox 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);
...
LAZY_SETTING lazy
Definition: lazylogger.cxx:180
#define AT_INTERNAL
Definition: midas.h:1448
char alarm[32]
Definition: lazylogger.cxx:164
Parameters
alarm_nameAlarm name, defined in /alarms/alarms
alarm_messageOptional message which goes with alarm
default_classIf alarm is not yet defined under /alarms/alarms/<alarm_name>, a new one is created and this default class is used.
cond_strString displayed in alarm condition
typeAlarm type, one of AT_xxx
Returns
AL_SUCCESS, AL_INVALID_NAME

Definition at line 225 of file alarm.cxx.

226  {
227  if (rpc_is_remote())
228  return rpc_call(RPC_AL_TRIGGER_ALARM, alarm_name, alarm_message, default_class, cond_str, type);
229 
230 #ifdef LOCAL_ROUTINES
231  {
232  int status, size;
233  HNDLE hDB, hkeyalarm, hkey;
234  ALARM a;
235  BOOL flag;
236  ALARM_ODB_STR(alarm_odb_str);
237 
239 
240  /* check online mode */
241  flag = TRUE;
242  size = sizeof(flag);
243  db_get_value(hDB, 0, "/Runinfo/Online Mode", &flag, &size, TID_INT, TRUE);
244  if (!flag)
245  return AL_SUCCESS;
246 
247  /* find alarm */
248  char alarm_path[MAX_ODB_PATH];
249  sprintf(alarm_path, "/Alarms/Alarms/%s", alarm_name);
250  db_find_key(hDB, 0, alarm_path, &hkeyalarm);
251  if (!hkeyalarm) {
252  /* alarm must be an internal analyzer alarm, so create a default alarm */
253  status = db_create_record(hDB, 0, alarm_path, strcomb1(alarm_odb_str).c_str());
254  db_find_key(hDB, 0, alarm_path, &hkeyalarm);
255  if (!hkeyalarm) {
256  cm_msg(MERROR, "al_trigger_alarm",
257  "Cannot create alarm record for alarm \"%s\", db_create_record() status %d", alarm_path, status);
258  return AL_ERROR_ODB;
259  }
260 
261  if (default_class && default_class[0])
262  db_set_value(hDB, hkeyalarm, "Alarm Class", default_class, 32, 1, TID_STRING);
263  status = TRUE;
264  db_set_value(hDB, hkeyalarm, "Active", &status, sizeof(status), 1, TID_BOOL);
265  }
266 
267  /* set parameters for internal alarms */
268  if (type != AT_EVALUATED && type != AT_PERIODIC) {
269  db_set_value(hDB, hkeyalarm, "Type", &type, sizeof(INT), 1, TID_INT);
270  char str[256];
271  strlcpy(str, cond_str, sizeof(str));
272  db_set_value(hDB, hkeyalarm, "Condition", str, 256, 1, TID_STRING);
273  }
274 
275  size = sizeof(a);
276  status = db_get_record1(hDB, hkeyalarm, &a, &size, 0, strcomb1(alarm_odb_str).c_str());
277  if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
278  /* make sure alarm record has right structure */
279  size = sizeof(a);
280  status = db_get_record1(hDB, hkeyalarm, &a, &size, 0, strcomb1(alarm_odb_str).c_str());
281  if (status != DB_SUCCESS) {
282  cm_msg(MERROR, "al_trigger_alarm", "Cannot get alarm record for alarm \"%s\", db_get_record1() status %d",
283  alarm_path, status);
284  return AL_ERROR_ODB;
285  }
286  }
287 
288  /* if internal alarm, check if active and check interval */
289  if (a.type != AT_EVALUATED && a.type != AT_PERIODIC) {
290  /* check global alarm flag */
291  flag = TRUE;
292  size = sizeof(flag);
293  db_get_value(hDB, 0, "/Alarms/Alarm system active", &flag, &size, TID_BOOL, TRUE);
294  if (!flag)
295  return AL_SUCCESS;
296 
297  if (!a.active)
298  return AL_SUCCESS;
299 
300  if ((INT) ss_time() - (INT) a.checked_last < a.check_interval)
301  return AL_SUCCESS;
302 
303  /* now the alarm will be triggered, so save time */
304  a.checked_last = ss_time();
305  }
306 
307  if (a.type == AT_PROGRAM) {
308  /* alarm class of "program not running" alarms is set in two places,
309  * complain if they do not match */
310  if (!equal_ustring(a.alarm_class, default_class)) {
311  cm_msg(MERROR, "al_trigger_alarm",
312  "Program alarm class mismatch: \"%s/Alarm class\" set to \"%s\" does not match \"/Programs/%s/Alarm "
313  "Class\" set to \"%s\"",
314  alarm_path, a.alarm_class, alarm_name, default_class);
315  }
316  }
317 
318  /* write back alarm message for internal alarms */
319  if (a.type != AT_EVALUATED && a.type != AT_PERIODIC) {
320  strncpy(a.alarm_message, alarm_message, 79);
321  a.alarm_message[79] = 0;
322  }
323 
324  /* now trigger alarm class defined in this alarm */
325  if (a.alarm_class[0])
326  al_trigger_class(a.alarm_class, alarm_message, a.triggered > 0);
327 
328  /* check for and trigger "All" class */
329  if (db_find_key(hDB, 0, "/Alarms/Classes/All", &hkey) == DB_SUCCESS)
330  al_trigger_class("All", alarm_message, a.triggered > 0);
331 
332  {
333  char str[256];
334 
335  /* signal alarm being triggered */
336  cm_asctime(str, sizeof(str));
337 
338  if (!a.triggered)
339  strcpy(a.time_triggered_first, str);
340 
341  a.triggered++;
342  strcpy(a.time_triggered_last, str);
343  }
344 
345  a.checked_last = ss_time();
346 
347  status = db_set_record(hDB, hkeyalarm, &a, sizeof(a), 0);
348  if (status != DB_SUCCESS) {
349  cm_msg(MERROR, "al_trigger_alarm", "Cannot update alarm record for alarm \"%s\", db_set_record() status %d",
350  alarm_path, status);
351  return AL_ERROR_ODB;
352  }
353  }
354 #endif /* LOCAL_ROUTINES */
355 
356  return AL_SUCCESS;
357 }
INT al_trigger_class(const char *alarm_class, const char *alarm_message, BOOL first)
Definition: alarm.cxx:363
INT cm_asctime(char *str, INT buf_size)
Definition: midas.cxx:1398
#define RPC_AL_TRIGGER_ALARM
Definition: mrpc.h:114
INT type
Definition: mana.cxx:269
#define MAX_ODB_PATH
Definition: midas.h:284
Here is the call graph for this function:
Here is the caller graph for this function:

◆ al_trigger_class()

INT al_trigger_class ( const char *  alarm_class,
const char *  alarm_message,
BOOL  first 
)

dox

Definition at line 363 of file alarm.cxx.

384 {
385  int status, size, state;
386  HNDLE hDB, hkeyclass;
387  char str[256], command[256], tag[32], url[256];
388  ALARM_CLASS ac;
389  ALARM_CLASS_STR(alarm_class_str);
390  DWORD now = ss_time();
391 
392  tag[0] = 0;
393 
395 
396  /* get alarm class */
397  sprintf(str, "/Alarms/Classes/%s", alarm_class);
398  db_find_key(hDB, 0, str, &hkeyclass);
399  if (!hkeyclass) {
400  cm_msg(MERROR, "al_trigger_class", "Alarm class \"%s\" for alarm \"%s\" not found in ODB", alarm_class,
401  alarm_message);
402  return AL_INVALID_NAME;
403  }
404 
405  size = sizeof(ac);
406  status = db_get_record1(hDB, hkeyclass, &ac, &size, 0, strcomb1(alarm_class_str).c_str());
407  if (status != DB_SUCCESS) {
408  cm_msg(MERROR, "al_trigger_class", "Cannot get alarm class record \"%s\", db_get_record1() status %d", str,
409  status);
410  return AL_ERROR_ODB;
411  }
412 
413  /* write system message */
415  if (equal_ustring(alarm_class, "All"))
416  sprintf(str, "General alarm: %s", alarm_message);
417  else
418  sprintf(str, "%s: %s", alarm_class, alarm_message);
419  cm_msg(MTALK, "al_trigger_class", "%s", str);
420  ac.system_message_last = now;
421  }
422 
423  /* write elog message on first trigger if using internal ELOG */
424  size = sizeof(url);
425  if (ac.write_elog_message && first && db_get_value(hDB, 0, "/Elog/URL", url, &size, TID_STRING, FALSE) != DB_SUCCESS)
426  el_submit(0, "Alarm system", "Alarm", "General", alarm_class, str, "", "plain", "", "", 0, "", "", 0, "", "", 0,
427  tag, sizeof(tag));
428 
429  /* execute command */
430  if (ac.execute_command[0] && ac.execute_interval > 0 && (INT) ss_time() - (INT) ac.execute_last > ac.execute_interval) {
431  if (equal_ustring(alarm_class, "All"))
432  sprintf(str, "General alarm: %s", alarm_message);
433  else
434  sprintf(str, "%s: %s", alarm_class, alarm_message);
435  sprintf(command, ac.execute_command, str);
436  cm_msg(MINFO, "al_trigger_class", "Execute: %s", command);
437  ss_system(command);
438  ac.execute_last = ss_time();
439  }
440 
441  /* stop run */
442  if (ac.stop_run) {
444  size = sizeof(state);
445  db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, TRUE);
446  if (state != STATE_STOPPED) {
447  cm_msg(MINFO, "al_trigger_class", "Stopping the run from alarm class \'%s\', message \'%s\'", alarm_class,
448  alarm_message);
449  cm_transition(TR_STOP, 0, NULL, 0, TR_DETACH, FALSE);
450  }
451  }
452 
453  status = db_set_record(hDB, hkeyclass, &ac, sizeof(ac), 0);
454  if (status != DB_SUCCESS) {
455  cm_msg(MERROR, "al_trigger_class", "Cannot update alarm class record");
456  return AL_ERROR_ODB;
457  }
458 
459  return AL_SUCCESS;
460 }
INT cm_transition(INT transition, INT run_number, char *errstr, INT errstr_size, INT async_flag, INT debug_flag)
Definition: midas.cxx:5282
INT el_submit(int run, const char *author, const char *type, const char *syst, const char *subject, const char *text, const char *reply_to, const char *encoding, const char *afilename1, const char *buffer1, INT buffer_size1, const char *afilename2, const char *buffer2, INT buffer_size2, const char *afilename3, const char *buffer3, INT buffer_size3, char *tag, INT tag_size)
Definition: elog.cxx:126
#define STATE_STOPPED
Definition: midas.h:312
#define TR_DETACH
Definition: midas.h:367
#define TR_STOP
Definition: midas.h:413
BOOL write_system_message
Definition: midas.h:1471
BOOL stop_run
Definition: midas.h:1478
INT execute_interval
Definition: midas.h:1476
char execute_command[256]
Definition: midas.h:1475
INT system_message_interval
Definition: midas.h:1473
BOOL write_elog_message
Definition: midas.h:1472
Here is the call graph for this function:
Here is the caller graph for this function: