MIDAS
Loading...
Searching...
No Matches
Midas Alarm Functions (al_xxx)

Functions

BOOL al_evaluate_condition (const char *alarm_name, const char *condition, std::string *pvalue)
 
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 (std::string *presult)
 
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 614 of file alarm.cxx.

614 {
615 if (rpc_is_remote())
616 return rpc_call(RPC_AL_CHECK);
617
618#ifdef LOCAL_ROUTINES
619 {
620 INT status, size, semaphore;
622 KEY key;
623 //char str[256];
626 BOOL flag;
627
631
633
634 if (hDB == 0)
635 return AL_SUCCESS; /* called from server not yet connected */
636
637 /* check online mode */
638 flag = TRUE;
639 size = sizeof(flag);
640 db_get_value(hDB, 0, "/Runinfo/Online Mode", &flag, &size, TID_INT, TRUE);
641 if (!flag)
642 return AL_SUCCESS;
643
644 /* check global alarm flag */
645 flag = TRUE;
646 size = sizeof(flag);
647 db_get_value(hDB, 0, "/Alarms/Alarm system active", &flag, &size, TID_BOOL, TRUE);
648 if (!flag)
649 return AL_SUCCESS;
650
651 /* request semaphore */
653 status = ss_semaphore_wait_for(semaphore, 100);
654 if (status == SS_TIMEOUT)
655 return AL_SUCCESS; /* someone else is doing alarm business */
656 if (status != SS_SUCCESS) {
657 printf("al_check: Something is wrong with our semaphore, ss_semaphore_wait_for() returned %d, aborting.\n",
658 status);
659 // abort(); // DOES NOT RETURN
660 printf("al_check: Cannot abort - this will lock you out of odb. From this point, MIDAS will not work "
661 "correctly. Please read the discussion at https://midas.triumf.ca/elog/Midas/945\n");
662 // NOT REACHED
663 return AL_SUCCESS;
664 }
665
666 /* check ODB alarms */
667 db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
668 if (!hkeyroot) {
669 /* create default ODB alarm */
670 status = db_create_record(hDB, 0, "/Alarms/Alarms/Demo ODB", strcomb1(alarm_odb_str).c_str());
671 db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
672 if (!hkeyroot) {
673 ss_semaphore_release(semaphore);
674 return AL_SUCCESS;
675 }
676
677 status = db_create_record(hDB, 0, "/Alarms/Alarms/Demo periodic", strcomb1(alarm_periodic_str).c_str());
678 db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
679 if (!hkeyroot) {
680 ss_semaphore_release(semaphore);
681 return AL_SUCCESS;
682 }
683
684 /* create default alarm classes */
685 status = db_create_record(hDB, 0, "/Alarms/Classes/Alarm", strcomb1(alarm_class_str).c_str());
686 status = db_create_record(hDB, 0, "/Alarms/Classes/Warning", strcomb1(alarm_class_str).c_str());
687 if (status != DB_SUCCESS) {
688 ss_semaphore_release(semaphore);
689 return AL_SUCCESS;
690 }
691 }
692
693 for (int i = 0;; i++) {
694 ALARM a;
695
698 break;
699
701
702 size = sizeof(a);
704 if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
705 /* make sure alarm record has right structure */
707 size = sizeof(a);
709 if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
710 cm_msg(MERROR, "al_check", "Cannot get alarm record");
711 continue;
712 }
713 }
714
715 /* check periodic alarm only when active */
716 if (a.active && a.type == AT_PERIODIC && a.check_interval > 0 && (INT) ss_time() - (INT) a.checked_last > a.check_interval) {
717 /* if checked_last has not been set, set it to current time */
718 if (a.checked_last == 0) {
719 a.checked_last = ss_time();
720 db_set_record(hDB, hkey, &a, size, 0);
721 } else
723 }
724
725 /* check alarm only when active and not internal */
726 if (a.active && a.type == AT_EVALUATED && a.check_interval > 0 && (INT) ss_time() - (INT) a.checked_last > a.check_interval) {
727 /* if condition is true, trigger alarm */
728 std::string value;
730 a.trigger_count++;
731 status = db_set_value(hDB, hkey, "Trigger count", &a.trigger_count, sizeof(DWORD), 1, TID_DWORD);
732 if (status != DB_SUCCESS) {
733 cm_msg(MERROR, "al_check", "Cannot change alarm record");
734 continue;
735 }
737 a.trigger_count = 0;
738 status = db_set_value(hDB, hkey, "Trigger count", &a.trigger_count, sizeof(DWORD), 1, TID_DWORD);
739 if (status != DB_SUCCESS) {
740 cm_msg(MERROR, "al_check", "Cannot change alarm record");
741 continue;
742 }
743
744 std::string str = msprintf(a.alarm_message, value.c_str());
746 }
747 } else {
748 a.checked_last = ss_time();
749 status = db_set_value(hDB, hkey, "Checked last", &a.checked_last, sizeof(DWORD), 1, TID_DWORD);
750 if (status != DB_SUCCESS) {
751 cm_msg(MERROR, "al_check", "Cannot change alarm record");
752 continue;
753 }
754 a.trigger_count = 0;
755 status = db_set_value(hDB, hkey, "Trigger count", &a.trigger_count, sizeof(DWORD), 1, TID_DWORD);
756 if (status != DB_SUCCESS) {
757 cm_msg(MERROR, "al_check", "Cannot change alarm record");
758 continue;
759 }
760 }
761 }
762 }
763
764 /* check /programs alarms */
765 db_find_key(hDB, 0, "/Programs", &hkeyroot);
766 if (hkeyroot) {
767 for (int i = 0;; i++) {
770 break;
771
773
774 /* don't check "execute on xxx" */
775 if (key.type != TID_KEY)
776 continue;
777
778 size = sizeof(program_info);
780 if (status != DB_SUCCESS) {
781 cm_msg(MERROR, "al_check",
782 "Cannot get program info record for program \"%s\", db_get_record1() status %d", key.name,
783 status);
784 continue;
785 }
786
787 time_t now = ss_time();
788
789 // get name of this client
790 std::string name = rpc_get_name();
791 std::string str = name;
792
793 // truncate name of this client to the length of program name in /Programs/xxx
794 // to get rid if "odbedit1", "odbedit2", etc.
795 str.resize(strlen(key.name));
796
797 //printf("str [%s], key.name [%s]\n", str.c_str(), key.name);
798
799 if (!equal_ustring(str.c_str(), key.name) && cm_exist(key.name, FALSE) == CM_NO_CLIENT) {
800 if (program_info.first_failed == 0) {
801 program_info.first_failed = (DWORD) now;
803 }
804
805 // printf("check %d-%d = %d >= %d\n", now, program_info.first_failed, now - program_info.first_failed,
806 // program_info.check_interval / 1000);
807
808 /* fire alarm when not running for more than what specified in check interval */
809 if (now - program_info.first_failed >= program_info.check_interval / 1000) {
810 /* if not running and alarm class defined, trigger alarm */
811 if (program_info.alarm_class[0]) {
812 std::string str = msprintf("Program %s is not running", key.name);
813 al_trigger_alarm(key.name, str.c_str(), program_info.alarm_class, "Program not running", AT_PROGRAM);
814 }
815
816 /* auto restart program */
817 if (program_info.auto_restart && program_info.start_command[0]) {
818 ss_system(program_info.start_command);
819 program_info.first_failed = 0;
820 cm_msg(MTALK, "al_check", "Program %s restarted", key.name);
821 }
822 }
823 } else {
824 if (program_info.first_failed != 0) {
825 program_info.first_failed = 0;
827 }
828 }
829 }
830 }
831
832 ss_semaphore_release(semaphore);
833 }
834#endif /* LOCAL_COUTINES */
835
836 return SUCCESS;
837}
#define FALSE
Definition cfortran.h:309
BOOL al_evaluate_condition(const char *alarm_name, const char *condition, std::string *pvalue)
Definition alarm.cxx:41
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:283
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3011
INT cm_get_experiment_semaphore(INT *semaphore_alarm, INT *semaphore_elog, INT *semaphore_history, INT *semaphore_msg)
Definition midas.cxx:3033
INT cm_exist(const char *name, BOOL bUnique)
Definition midas.cxx:7520
#define CM_NO_CLIENT
Definition midas.h:584
#define DB_SUCCESS
Definition midas.h:631
#define DB_NO_MORE_SUBKEYS
Definition midas.h:646
#define SS_SUCCESS
Definition midas.h:663
#define SS_TIMEOUT
Definition midas.h:674
#define AL_SUCCESS
Definition midas.h:754
unsigned int DWORD
Definition mcstd.h:51
#define SUCCESS
Definition mcstd.h:54
#define TID_KEY
Definition midas.h:349
#define TID_BOOL
Definition midas.h:340
#define MERROR
Definition midas.h:559
#define MTALK
Definition midas.h:564
#define TID_INT
Definition midas.h:338
#define TID_DWORD
Definition midas.h:336
INT ss_semaphore_release(HNDLE semaphore_handle)
Definition system.cxx:2781
DWORD ss_time()
Definition system.cxx:3462
INT ss_semaphore_wait_for(HNDLE semaphore_handle, DWORD timeout_millisec)
Definition system.cxx:2639
INT ss_system(const char *command)
Definition system.cxx:2116
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3201
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5415
std::string strcomb1(const char **list)
Definition odb.cxx:598
INT db_get_record1(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align, const char *rec_str)
Definition odb.cxx:11805
INT db_check_record(HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct)
Definition odb.cxx:12972
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6019
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:5261
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4079
INT db_set_record(HNDLE hDB, HNDLE hKey, void *data, INT buf_size, INT align)
Definition odb.cxx:12291
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5586
INT db_create_record(HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str)
Definition odb.cxx:12800
std::string rpc_get_name()
Definition midas.cxx:13084
bool rpc_is_remote(void)
Definition midas.cxx:12761
INT rpc_call(DWORD routine_id,...)
Definition midas.cxx:13663
#define RPC_AL_CHECK
Definition mrpc.h:113
HNDLE hDB
main ODB handle
Definition mana.cxx:207
KEY key
Definition mdump.cxx:34
INT i
Definition mdump.cxx:32
#define DWORD
Definition mhdump.cxx:31
std::string msprintf(const char *format,...)
Definition midas.cxx:410
INT HNDLE
Definition midas.h:132
DWORD BOOL
Definition midas.h:105
#define AT_PROGRAM
Definition midas.h:1443
#define ALARM_PERIODIC_STR(_name)
Definition midas.h:1528
int INT
Definition midas.h:129
#define AT_PERIODIC
Definition midas.h:1445
#define PROGRAM_INFO_STR(_name)
Definition midas.h:1448
#define AT_LAST
Definition midas.h:1446
#define ALARM_CLASS_STR(_name)
Definition midas.h:1478
#define ALARM_ODB_STR(_name)
Definition midas.h:1511
#define TRUE
Definition midas.h:182
#define AT_EVALUATED
Definition midas.h:1444
#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
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
INT type
Definition midas.h:1499
char alarm_class[32]
Definition midas.h:1507
DWORD trigger_count
Definition midas.h:1502
INT check_interval
Definition midas.h:1500
DWORD trigger_count_required
Definition midas.h:1503
DWORD checked_last
Definition midas.h:1501
BOOL active
Definition midas.h:1497
char alarm_message[80]
Definition midas.h:1508
char condition[256]
Definition midas.h:1506
Definition midas.h:1026
DWORD type
Definition midas.h:1027
char name[NAME_LENGTH]
Definition midas.h:1029
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 921 of file alarm.cxx.

921 {
922 HNDLE hDB, hKey;
924
926
927 std::string str = msprintf("/Alarms/Alarms/%s", name);
928
930 db_find_key(hDB, 0, str.c_str(), &hKey);
931 if (!hKey)
932 return DB_NO_MEMORY;
933
934 db_set_value(hDB, hKey, "Condition", condition, 256, 1, TID_STRING);
935 db_set_value(hDB, hKey, "Alarm Class", aclass, 32, 1, TID_STRING);
936 db_set_value(hDB, hKey, "Alarm Message", message, 80, 1, TID_STRING);
937
938 return AL_SUCCESS;
939}
#define DB_NO_MEMORY
Definition midas.h:633
#define TID_STRING
Definition midas.h:346
HNDLE hKey
#define message(type, str)
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 alarm_name,
const char condition,
std::string *  pvalue 
)

dox

Definition at line 41 of file alarm.cxx.

42{
43 int i, j, size, status;
44
45 //char str[256];
46 //strcpy(str, condition);
47
48 std::vector<char> buf;
49 buf.insert(buf.end(), condition, condition+strlen(condition)+1);
50 char* str = buf.data();
51
52 /* find value and operator */
53 char op[3];
54 op[0] = op[1] = op[2] = 0;
55 for (i = strlen(str) - 1; i > 0; i--)
56 if (strchr("<>=!&", str[i]) != NULL)
57 break;
58 op[0] = str[i];
59 for (j = 1; str[i + j] == ' '; j++)
60 ;
61
62 std::string value2_str = str + i + j;
63 double value2 = atof(value2_str.c_str());
64
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 std::string function;
80 if (str[i] == ')') {
81 str[i--] = 0;
82 if (strchr(str, '(')) {
83 *strchr(str, '(') = 0;
84 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 std::vector<int> indices;
93 bool index_present = false;
94
95 // process indices
96 if (strchr(str, '[') && str[strlen(str)-1] == ']') {
97 index_present = true;
98
99 // Remove the square brackets from the string
100 std::string cleanInput = strchr(str, '[') + 1;
101 cleanInput.pop_back();
102
103 // Remove index from str
104 *strchr(str, '[') = 0;
105
106 // retrieve key
107 if (!midas::odb::exists(str)) {
108 cm_msg(MERROR, "al_evaluate_condition", "Alarm \"%s\": Cannot find ODB key \"%s\" to evaluate alarm condition", alarm_name, str);
109 if (pvalue)
110 *pvalue = "(cannot find in odb)";
111 return FALSE;
112 }
113 midas::odb k((const char *)str);
114
115 // Split the string by commas
116 std::stringstream ss(cleanInput);
117 std::string token;
118 while (std::getline(ss, token, ',')) {
119 // Remove whitespace
120 token.erase(std::remove_if(token.begin(), token.end(), ::isspace), token.end());
121
122 // Check if token is "*", if so set all indices
123 if (token == "*") {
124 for (int i = 0; i < k.get_num_values(); ++i)
125 indices.push_back(i);
126 } else {
127 // Check if the token represents a range (e.g., "4-7")
128 auto dashPos = token.find('-');
129 if (dashPos != std::string::npos) {
130 // Extract the start and end of the range
131 int start = std::stoi(token.substr(0, dashPos));
132 int end = std::stoi(token.substr(dashPos + 1));
133
134 // Add all numbers in the range [start, end]
135 for (int i = start; i <= end; ++i) {
136 indices.push_back(i);
137 }
138 } else {
139 // It's a single number, add it to the list
140 indices.push_back(std::stoi(token));
141 }
142 }
143 }
144 }
145
146 HNDLE hDB, hkey;
148 db_find_key(hDB, 0, str, &hkey);
149 if (!hkey) {
150 cm_msg(MERROR, "al_evaluate_condition", "Alarm \"%s\": Cannot find ODB key \"%s\" to evaluate alarm condition", alarm_name, str);
151 if (pvalue)
152 *pvalue = "(cannot find in odb)";
153 return FALSE;
154 }
155
156 KEY key;
158
159 //printf("Alarm \"%s\": [%s], idx1 %d, idx2 %d, op [%s], value2 [%s] %g, function [%s]\n", alarm_name, condition, idx1, idx2, op, value2_str.c_str(), value2, function.c_str());
160
161 // put at least one value into the indices
162 if (indices.empty())
163 indices.push_back(0);
164
165 // go through all indices
166 for (int idx : indices) {
167 std::string value1_str;
168 double value1 = 0;
169
170 if (equal_ustring(function.c_str(), "access")) {
171 /* check key access time */
172 DWORD dtime;
174 value1_str = msprintf("%d", dtime);
175 value1 = atof(value1_str.c_str());
176 } else if (equal_ustring(function.c_str(), "access_running")) {
177 /* check key access time if running */
178 DWORD dtime;
180 int state = 0;
181 size = sizeof(state);
182 db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, FALSE);
183 if (state == STATE_RUNNING) {
184 value1_str = msprintf("%d", dtime).c_str();
185 value1 = atof(value1_str.c_str());
186 } else {
187 value1_str = "0";
188 value1 = 0;
189 }
190 } else {
191 /* get key data and convert to double */
193 if (status != DB_SUCCESS) {
194 cm_msg(MERROR, "al_evaluate_condition", "Alarm \"%s\": Cannot get ODB key \"%s\" to evaluate alarm condition", alarm_name, str);
195 if (pvalue)
196 *pvalue = "(odb error)";
197 return FALSE;
198 } else {
199 char data[256];
200 size = sizeof(data);
202 if (status != DB_SUCCESS) {
203 cm_msg(MERROR, "al_evaluate_condition", "Alarm \"%s\": Cannot get ODB value \"%s\" index %d to evaluate alarm condition", alarm_name, str, idx);
204 if (pvalue)
205 *pvalue = "(odb error)";
206 return FALSE;
207 }
208
209 value1_str = db_sprintf(data, size, 0, key.type);
210 value1 = atof(value1_str.c_str());
211 }
212 }
213
214 /* convert boolean values to integers */
215 if (key.type == TID_BOOL) {
216 value1 = (value1_str[0] == 'Y' || value1_str[0] == 'y' || value1_str[0] == '1');
217 value2 = (value2_str[0] == 'Y' || value2_str[0] == 'y' || value2_str[0] == '1');
218 }
219
220 /* return value */
221 if (pvalue) {
222 if (index_present)
223 *pvalue = msprintf("[%d] %s", idx, value1_str.c_str());
224 else
226 }
227
228 /* now do logical operation */
229 if (strcmp(op, "=") == 0)
230 if (value1 == value2)
231 return TRUE;
232 if (strcmp(op, "==") == 0)
233 if (value1 == value2)
234 return TRUE;
235 if (strcmp(op, "!=") == 0)
236 if (value1 != value2)
237 return TRUE;
238 if (strcmp(op, "<") == 0)
239 if (value1 < value2)
240 return TRUE;
241 if (strcmp(op, ">") == 0)
242 if (value1 > value2)
243 return TRUE;
244 if (strcmp(op, "<=") == 0)
245 if (value1 <= value2)
246 return TRUE;
247 if (strcmp(op, ">=") == 0)
248 if (value1 >= value2)
249 return TRUE;
250 if (strcmp(op, "&") == 0)
251 if (((unsigned int) value1 & (unsigned int) value2) > 0)
252 return TRUE;
253 }
254
255 return FALSE;
256}
static bool exists(const std::string &name)
Definition odbxx.cxx:66
#define STATE_RUNNING
Definition midas.h:307
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition odb.cxx:6893
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10843
INT db_get_key_time(HNDLE hDB, HNDLE hKey, DWORD *delta)
Definition odb.cxx:6132
void * data
Definition mana.cxx:268
#define end
INT j
Definition odbhist.cxx:40
INT k
Definition odbhist.cxx:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ al_get_alarms()

INT al_get_alarms ( std::string *  presult)

Scan ODB for alarms.

Returns
AL_SUCCESS

Definition at line 844 of file alarm.cxx.

845{
846 if (!presult)
847 return 0;
848
849 HNDLE hDB, hkey;
850
852 presult->clear();
853 int n = 0;
854 db_find_key(hDB, 0, "/Alarms/Alarms", &hkey);
855 if (hkey) {
856 /* check global alarm flag */
857 int flag = TRUE;
858 int size = sizeof(flag);
859 db_get_value(hDB, 0, "/Alarms/Alarm System active", &flag, &size, TID_BOOL, FALSE);
860 if (flag) {
861 for (int i = 0;; i++) {
863
865
866 if (!hsubkey)
867 break;
868
869 KEY key;
871
872 flag = 0;
873 size = sizeof(flag);
874 db_get_value(hDB, hsubkey, "Triggered", &flag, &size, TID_INT, FALSE);
875 if (flag) {
876 n++;
877
878 std::string alarm_class, msg;
879 int alarm_type;
880
881 db_get_value_string(hDB, hsubkey, "Alarm Class", 0, &alarm_class);
882 db_get_value_string(hDB, hsubkey, "Alarm Message", 0, &msg);
883
884 size = sizeof(alarm_type);
885 db_get_value(hDB, hsubkey, "Type", &alarm_type, &size, TID_INT, FALSE);
886
887 std::string str;
888
889 if (alarm_type == AT_EVALUATED) {
890 db_get_value_string(hDB, hsubkey, "Condition", 0, &str);
891
892 /* retrieve value */
893 std::string value;
895 str = msprintf(msg.c_str(), value.c_str());
896 } else
897 str = msg;
898
899 *presult += alarm_class;
900 *presult += ": ";
901 *presult += str;
902 *presult += "\n";
903 }
904 }
905 }
906 }
907
908 return n;
909}
INT EXPRT db_get_value_string(HNDLE hdb, HNDLE hKeyRoot, const char *key_name, int index, std::string *s, BOOL create, int create_string_length)
Definition odb.cxx:13934
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5725
DWORD n[4]
Definition mana.cxx:247
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 525 of file alarm.cxx.

525 {
526 int status, size, i;
528 KEY key;
529 ALARM a;
533
535
536 if (alarm_name == NULL) {
537 /* reset all alarms */
538 db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyalarm);
539 if (hkeyalarm) {
540 for (i = 0;; i++) {
542
543 if (!hsubkey)
544 break;
545
548 }
549 }
550 return AL_SUCCESS;
551 }
552
553 /* find alarm and alarm class */
554 std::string str = msprintf("/Alarms/Alarms/%s", alarm_name);
555 db_find_key(hDB, 0, str.c_str(), &hkeyalarm);
556 if (!hkeyalarm) {
557 /*cm_msg(MERROR, "al_reset_alarm", "Alarm %s not found in ODB", alarm_name);*/
558 return AL_INVALID_NAME;
559 }
560
561 size = sizeof(a);
563 if (status != DB_SUCCESS) {
564 cm_msg(MERROR, "al_reset_alarm", "Cannot get alarm record");
565 return AL_ERROR_ODB;
566 }
567
568 str = msprintf("/Alarms/Classes/%s", a.alarm_class);
569 db_find_key(hDB, 0, str.c_str(), &hkeyclass);
570 if (!hkeyclass) {
571 cm_msg(MERROR, "al_reset_alarm", "Alarm class %s not found in ODB", a.alarm_class);
572 return AL_INVALID_NAME;
573 }
574
575 size = sizeof(ac);
577 if (status != DB_SUCCESS) {
578 cm_msg(MERROR, "al_reset_alarm", "Cannot get alarm class record");
579 return AL_ERROR_ODB;
580 }
581
582 if (a.triggered) {
583 a.triggered = 0;
584 a.time_triggered_first[0] = 0;
585 a.time_triggered_last[0] = 0;
586 a.checked_last = 0;
587 a.trigger_count = 0;
588
589 ac.system_message_last = 0;
590 ac.execute_last = 0;
591
592 status = db_set_record(hDB, hkeyalarm, &a, sizeof(a), 0);
593 if (status != DB_SUCCESS) {
594 cm_msg(MERROR, "al_reset_alarm", "Cannot update alarm record");
595 return AL_ERROR_ODB;
596 }
597 status = db_set_record(hDB, hkeyclass, &ac, sizeof(ac), 0);
598 if (status != DB_SUCCESS) {
599 cm_msg(MERROR, "al_reset_alarm", "Cannot update alarm class record");
600 return AL_ERROR_ODB;
601 }
602 cm_msg(MINFO, "al_reset_alarm", "Alarm \"%s\" reset", alarm_name);
603 return AL_RESET;
604 }
605
606 return AL_SUCCESS;
607}
INT al_reset_alarm(const char *alarm_name)
Definition alarm.cxx:525
#define AL_INVALID_NAME
Definition midas.h:755
#define AL_RESET
Definition midas.h:757
#define AL_ERROR_ODB
Definition midas.h:756
#define MINFO
Definition midas.h:560
char time_triggered_first[32]
Definition midas.h:1504
char time_triggered_last[32]
Definition midas.h:1505
INT triggered
Definition midas.h:1498
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
#define AT_INTERNAL
Definition midas.h:1442
char alarm[32]
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 283 of file alarm.cxx.

284 {
285 if (rpc_is_remote())
287
288#ifdef LOCAL_ROUTINES
289 {
290 int status, size;
292 ALARM a;
293 BOOL flag;
295
297
298 /* check online mode */
299 flag = TRUE;
300 size = sizeof(flag);
301 db_get_value(hDB, 0, "/Runinfo/Online Mode", &flag, &size, TID_INT, TRUE);
302 if (!flag)
303 return AL_SUCCESS;
304
305 /* find alarm */
306 std::string alarm_path = msprintf("/Alarms/Alarms/%s", alarm_name);
307
308 db_find_key(hDB, 0, alarm_path.c_str(), &hkeyalarm);
309 if (!hkeyalarm) {
310 /* alarm must be an internal analyzer alarm, so create a default alarm */
312 db_find_key(hDB, 0, alarm_path.c_str(), &hkeyalarm);
313 if (!hkeyalarm) {
314 cm_msg(MERROR, "al_trigger_alarm", "Cannot create alarm record for alarm \"%s\", db_create_record() status %d", alarm_path.c_str(), status);
315 return AL_ERROR_ODB;
316 }
317
319 db_set_value(hDB, hkeyalarm, "Alarm Class", default_class, 32, 1, TID_STRING);
320 status = TRUE;
321 db_set_value(hDB, hkeyalarm, "Active", &status, sizeof(status), 1, TID_BOOL);
322 }
323
324 /* set parameters for internal alarms */
325 if (type != AT_EVALUATED && type != AT_PERIODIC) {
326 db_set_value(hDB, hkeyalarm, "Type", &type, sizeof(INT), 1, TID_INT);
327 char str[256];
328 mstrlcpy(str, cond_str, sizeof(str));
329 db_set_value(hDB, hkeyalarm, "Condition", str, 256, 1, TID_STRING);
330 }
331
332 size = sizeof(a);
334 if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
335 /* make sure alarm record has right structure */
336 size = sizeof(a);
338 if (status != DB_SUCCESS) {
339 cm_msg(MERROR, "al_trigger_alarm", "Cannot get alarm record for alarm \"%s\", db_get_record1() status %d", alarm_path.c_str(), status);
340 return AL_ERROR_ODB;
341 }
342 }
343
344 /* if internal alarm, check if active and check interval */
345 if (a.type != AT_EVALUATED && a.type != AT_PERIODIC) {
346 /* check global alarm flag */
347 flag = TRUE;
348 size = sizeof(flag);
349 db_get_value(hDB, 0, "/Alarms/Alarm system active", &flag, &size, TID_BOOL, TRUE);
350 if (!flag)
351 return AL_SUCCESS;
352
353 if (!a.active)
354 return AL_SUCCESS;
355
356 if ((INT) ss_time() - (INT) a.checked_last < a.check_interval)
357 return AL_SUCCESS;
358
359 /* now the alarm will be triggered, so save time */
360 a.checked_last = ss_time();
361 }
362
363 if (a.type == AT_PROGRAM) {
364 /* alarm class of "program not running" alarms is set in two places,
365 * complain if they do not match */
367 cm_msg(MERROR, "al_trigger_alarm",
368 "Program alarm class mismatch: \"%s/Alarm class\" set to \"%s\" does not match \"/Programs/%s/Alarm "
369 "Class\" set to \"%s\"",
371 }
372 }
373
374 /* write back alarm message for internal alarms */
375 if (a.type != AT_EVALUATED && a.type != AT_PERIODIC) {
376 mstrlcpy(a.alarm_message, alarm_message, sizeof(a.alarm_message));
377 }
378
379 /* now trigger alarm class defined in this alarm */
380 if (a.alarm_class[0])
381 al_trigger_class(a.alarm_class, alarm_message, a.triggered > 0);
382
383 /* check for and trigger "All" class */
384 if (db_find_key(hDB, 0, "/Alarms/Classes/All", &hkey) == DB_SUCCESS)
385 al_trigger_class("All", alarm_message, a.triggered > 0);
386
387 /* signal alarm being triggered */
388 std::string now = cm_asctime();
389
390 if (!a.triggered)
392
393 a.triggered++;
395
396 a.checked_last = ss_time();
397
398 status = db_set_record(hDB, hkeyalarm, &a, sizeof(a), 0);
399 if (status != DB_SUCCESS) {
400 cm_msg(MERROR, "al_trigger_alarm", "Cannot update alarm record for alarm \"%s\", db_set_record() status %d", alarm_path.c_str(), status);
401 return AL_ERROR_ODB;
402 }
403 }
404#endif /* LOCAL_ROUTINES */
405
406 return AL_SUCCESS;
407}
INT al_trigger_class(const char *alarm_class, const char *alarm_message, BOOL first)
Definition alarm.cxx:413
std::string cm_asctime()
Definition midas.cxx:1412
#define RPC_AL_TRIGGER_ALARM
Definition mrpc.h:114
INT type
Definition mana.cxx:269
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 413 of file alarm.cxx.

434{
435 int status, size, state;
439 DWORD now = ss_time();
440
442
443 /* get alarm class */
444 std::string alarm_path = msprintf("/Alarms/Classes/%s", alarm_class);
445 db_find_key(hDB, 0, alarm_path.c_str(), &hkeyclass);
446 if (!hkeyclass) {
447 cm_msg(MERROR, "al_trigger_class", "Alarm class \"%s\" for alarm \"%s\" not found in ODB", alarm_class, alarm_message);
448 return AL_INVALID_NAME;
449 }
450
451 size = sizeof(ac);
453 if (status != DB_SUCCESS) {
454 cm_msg(MERROR, "al_trigger_class", "Cannot get alarm class record \"%s\", db_get_record1() status %d", alarm_path.c_str(), status);
455 return AL_ERROR_ODB;
456 }
457
458 std::string msg;
459
460 /* write system message */
461 if (ac.write_system_message && (now - ac.system_message_last >= (DWORD) ac.system_message_interval)) {
462 if (equal_ustring(alarm_class, "All"))
463 msg = msprintf("General alarm: %s", alarm_message);
464 else
465 msg = msprintf("%s: %s", alarm_class, alarm_message);
466 cm_msg(MTALK, "al_trigger_class", "%s", msg.c_str());
467 ac.system_message_last = now;
468 }
469
470 /* write elog message on first trigger if using internal ELOG */
471 if (ac.write_elog_message && first) {
473 size = sizeof(external_elog);
474 db_get_value(hDB, 0, "/Elog/External Elog", &external_elog, &size, TID_BOOL, FALSE);
475 if (!external_elog) {
476 char tag[32];
477 tag[0] = 0;
478 el_submit(0, "Alarm system", "Alarm", "General", alarm_class, msg.c_str(), "", "plain", "", "", 0, "", "", 0, "", "", 0, tag, sizeof(tag));
479 }
480 }
481
482 /* execute command */
483 if (ac.execute_command[0] && ac.execute_interval > 0 && (INT) ss_time() - (INT) ac.execute_last > ac.execute_interval) {
484 if (equal_ustring(alarm_class, "All"))
485 msg = msprintf("General alarm: %s", alarm_message);
486 else
487 msg = msprintf("%s: %s", alarm_class, alarm_message);
488 std::string command = msprintf(ac.execute_command, msg.c_str());
489 cm_msg(MINFO, "al_trigger_class", "Execute: %s", command.c_str());
490 ss_system(command.c_str());
491 ac.execute_last = ss_time();
492 }
493
494 /* stop run */
495 if (ac.stop_run) {
497 size = sizeof(state);
498 db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, TRUE);
499 if (state != STATE_STOPPED) {
500 cm_msg(MINFO, "al_trigger_class", "Stopping the run from alarm class \'%s\', message \'%s\'", alarm_class,
501 alarm_message);
503 }
504 }
505
506 status = db_set_record(hDB, hkeyclass, &ac, sizeof(ac), 0);
507 if (status != DB_SUCCESS) {
508 cm_msg(MERROR, "al_trigger_class", "Cannot update alarm class record");
509 return AL_ERROR_ODB;
510 }
511
512 return AL_SUCCESS;
513}
INT cm_transition(INT transition, INT run_number, char *errstr, INT errstr_size, INT async_flag, INT debug_flag)
Definition midas.cxx:5286
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:124
#define STATE_STOPPED
Definition midas.h:305
#define TR_DETACH
Definition midas.h:360
#define TR_STOP
Definition midas.h:406
Here is the call graph for this function:
Here is the caller graph for this function: