32#ifndef DOXYGEN_SHOULD_SKIP_THIS
48 std::vector<char> buf;
49 buf.insert(buf.end(), condition, condition+strlen(condition)+1);
50 char*
str = buf.data();
54 op[0] = op[1] = op[2] = 0;
55 for (
i = strlen(
str) - 1;
i > 0;
i--)
56 if (strchr(
"<>=!&",
str[
i]) != NULL)
59 for (
j = 1;
str[
i +
j] ==
' ';
j++)
62 std::string value2_str =
str +
i +
j;
63 double value2 = atof(value2_str.c_str());
67 if (
i > 0 && strchr(
"<>=!&",
str[
i - 1])) {
74 while (
i > 0 &&
str[
i] ==
' ')
82 if (strchr(
str,
'(')) {
83 *strchr(
str,
'(') = 0;
92 std::vector<int> indices;
93 bool index_present =
false;
96 if (strchr(
str,
'[') &&
str[strlen(
str)-1] ==
']') {
100 std::string cleanInput = strchr(
str,
'[') + 1;
101 cleanInput.pop_back();
104 *strchr(
str,
'[') = 0;
108 cm_msg(
MERROR,
"al_evaluate_condition",
"Alarm \"%s\": Cannot find ODB key \"%s\" to evaluate alarm condition", alarm_name,
str);
110 *pvalue =
"(cannot find in odb)";
116 std::stringstream ss(cleanInput);
118 while (std::getline(ss, token,
',')) {
120 token.erase(std::remove_if(token.begin(), token.end(), ::isspace), token.end());
124 for (
int i = 0;
i <
k.get_num_values(); ++
i)
125 indices.push_back(
i);
128 auto dashPos = token.find(
'-');
129 if (dashPos != std::string::npos) {
131 int start = std::stoi(token.substr(0, dashPos));
132 int end = std::stoi(token.substr(dashPos + 1));
135 for (
int i = start;
i <=
end; ++
i) {
136 indices.push_back(
i);
140 indices.push_back(std::stoi(token));
150 cm_msg(
MERROR,
"al_evaluate_condition",
"Alarm \"%s\": Cannot find ODB key \"%s\" to evaluate alarm condition", alarm_name,
str);
152 *pvalue =
"(cannot find in odb)";
163 indices.push_back(0);
166 for (
int idx : indices) {
167 std::string value1_str;
175 value1 = atof(value1_str.c_str());
176 }
else if (
equal_ustring(function.c_str(),
"access_running")) {
181 size =
sizeof(
state);
184 value1_str =
msprintf(
"%d", dtime).c_str();
185 value1 = atof(value1_str.c_str());
194 cm_msg(
MERROR,
"al_evaluate_condition",
"Alarm \"%s\": Cannot get ODB key \"%s\" to evaluate alarm condition", alarm_name,
str);
196 *pvalue =
"(odb error)";
203 cm_msg(
MERROR,
"al_evaluate_condition",
"Alarm \"%s\": Cannot get ODB value \"%s\" index %d to evaluate alarm condition", alarm_name,
str, idx);
205 *pvalue =
"(odb error)";
210 value1 = atof(value1_str.c_str());
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');
223 *pvalue =
msprintf(
"[%d] %s", idx, value1_str.c_str());
225 *pvalue = value1_str;
229 if (strcmp(op,
"=") == 0)
230 if (value1 == value2)
232 if (strcmp(op,
"==") == 0)
233 if (value1 == value2)
235 if (strcmp(op,
"!=") == 0)
236 if (value1 != value2)
238 if (strcmp(op,
"<") == 0)
241 if (strcmp(op,
">") == 0)
244 if (strcmp(op,
"<=") == 0)
245 if (value1 <= value2)
247 if (strcmp(op,
">=") == 0)
248 if (value1 >= value2)
250 if (strcmp(op,
"&") == 0)
251 if (((
unsigned int) value1 & (
unsigned int) value2) > 0)
283INT al_trigger_alarm(
const char *alarm_name,
const char *alarm_message,
const char *default_class,
const char *cond_str,
306 std::string alarm_path =
msprintf(
"/Alarms/Alarms/%s", alarm_name);
314 cm_msg(
MERROR,
"al_trigger_alarm",
"Cannot create alarm record for alarm \"%s\", db_create_record() status %d", alarm_path.c_str(),
status);
318 if (default_class && default_class[0])
328 mstrlcpy(
str, cond_str,
sizeof(
str));
339 cm_msg(
MERROR,
"al_trigger_alarm",
"Cannot get alarm record for alarm \"%s\", db_get_record1() status %d", alarm_path.c_str(),
status);
368 "Program alarm class mismatch: \"%s/Alarm class\" set to \"%s\" does not match \"/Programs/%s/Alarm "
369 "Class\" set to \"%s\"",
370 alarm_path.c_str(), a.
alarm_class, alarm_name, default_class);
400 cm_msg(
MERROR,
"al_trigger_alarm",
"Cannot update alarm record for alarm \"%s\", db_set_record() status %d", alarm_path.c_str(),
status);
410#ifndef DOXYGEN_SHOULD_SKIP_THIS
444 std::string alarm_path =
msprintf(
"/Alarms/Classes/%s", alarm_class);
447 cm_msg(
MERROR,
"al_trigger_class",
"Alarm class \"%s\" for alarm \"%s\" not found in ODB", alarm_class, alarm_message);
454 cm_msg(
MERROR,
"al_trigger_class",
"Cannot get alarm class record \"%s\", db_get_record1() status %d", alarm_path.c_str(),
status);
463 msg =
msprintf(
"General alarm: %s", alarm_message);
465 msg =
msprintf(
"%s: %s", alarm_class, alarm_message);
466 cm_msg(
MTALK,
"al_trigger_class",
"%s", msg.c_str());
473 size =
sizeof(external_elog);
475 if (!external_elog) {
478 el_submit(0,
"Alarm system",
"Alarm",
"General", alarm_class, msg.c_str(),
"",
"plain",
"",
"", 0,
"",
"", 0,
"",
"", 0, tag,
sizeof(tag));
485 msg =
msprintf(
"General alarm: %s", alarm_message);
487 msg =
msprintf(
"%s: %s", alarm_class, alarm_message);
489 cm_msg(
MINFO,
"al_trigger_class",
"Execute: %s", command.c_str());
497 size =
sizeof(
state);
500 cm_msg(
MINFO,
"al_trigger_class",
"Stopping the run from alarm class \'%s\', message \'%s\'", alarm_class,
508 cm_msg(
MERROR,
"al_trigger_class",
"Cannot update alarm class record");
527 HNDLE hDB, hkeyalarm, hkeyclass, hsubkey;
536 if (alarm_name == NULL) {
554 std::string
str =
msprintf(
"/Alarms/Alarms/%s", alarm_name);
564 cm_msg(
MERROR,
"al_reset_alarm",
"Cannot get alarm record");
578 cm_msg(
MERROR,
"al_reset_alarm",
"Cannot get alarm class record");
588 memset(&tm_time, 0,
sizeof(tm_time));
591 time_t t = mktime(&tm_time);
611 cm_msg(
MERROR,
"al_reset_alarm",
"Cannot update alarm record");
616 cm_msg(
MERROR,
"al_reset_alarm",
"Cannot update alarm class record");
619 cm_msg(
MINFO,
"al_reset_alarm",
"Alarm \"%s\" reset", alarm_name);
675 fprintf(stderr,
"al_check: Something is wrong with our semaphore, ss_semaphore_wait_for() returned %d, aborting.\n",
status);
678 fprintf(stderr,
"al_check: Cannot abort - this will lock you out of odb. From this point, MIDAS will not work correctly. Please read the discussion at https://midas.triumf.ca/elog/Midas/945\n");
717 for (
int i = 0;;
i++) {
757 cm_msg(
MERROR,
"al_check",
"Cannot change alarm record");
763 cm_msg(
MERROR,
"al_check",
"Cannot change alarm record");
770 cm_msg(
MERROR,
"al_check",
"Cannot change alarm record");
784 cm_msg(
MERROR,
"al_check",
"Cannot change alarm record");
790 cm_msg(
MERROR,
"al_check",
"Cannot change alarm record");
800 for (
int i = 0;;
i++) {
811 size =
sizeof(program_info);
815 "Cannot get program info record for program \"%s\", db_get_record1() status %d",
key.
name,
891 int size =
sizeof(flag);
894 for (
int i = 0;;
i++) {
911 std::string alarm_class, msg;
917 size =
sizeof(alarm_type);
932 *presult += alarm_class;
static bool exists(const std::string &name)
INT al_trigger_class(const char *alarm_class, const char *alarm_message, BOOL first)
BOOL al_evaluate_condition(const char *alarm_name, const char *condition, std::string *pvalue)
INT EXPRT al_define_odb_alarm(const char *name, const char *condition, const char *aclass, const char *message)
INT al_get_alarms(std::string *presult)
INT al_reset_alarm(const char *alarm_name)
INT al_trigger_alarm(const char *alarm_name, const char *alarm_message, const char *default_class, const char *cond_str, INT type)
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
INT cm_get_experiment_semaphore(INT *semaphore_alarm, INT *semaphore_elog, INT *semaphore_history, INT *semaphore_msg)
INT cm_transition(INT transition, INT run_number, char *errstr, INT errstr_size, INT async_flag, INT debug_flag)
INT cm_exist(const char *name, BOOL bUnique)
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)
#define DB_NO_MORE_SUBKEYS
INT ss_semaphore_release(HNDLE semaphore_handle)
INT ss_semaphore_wait_for(HNDLE semaphore_handle, DWORD timeout_millisec)
INT ss_system(const char *command)
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
BOOL equal_ustring(const char *str1, const char *str2)
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
std::string strcomb1(const char **list)
INT db_get_record1(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align, const char *rec_str)
INT db_check_record(HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct)
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
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)
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
INT db_get_key_time(HNDLE hDB, HNDLE hKey, DWORD *delta)
INT db_set_record(HNDLE hDB, HNDLE hKey, void *data, INT buf_size, INT align)
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
INT db_create_record(HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str)
std::string rpc_get_name()
#define RPC_AL_TRIGGER_ALARM
INT rpc_call(DWORD routine_id,...)
std::string msprintf(const char *format,...)
#define ALARM_PERIODIC_STR(_name)
#define PROGRAM_INFO_STR(_name)
#define ALARM_CLASS_STR(_name)
#define ALARM_ODB_STR(_name)
#define message(type, str)
BOOL write_system_message
DWORD system_message_last
char execute_command[256]
INT system_message_interval
char time_triggered_first[32]
char time_triggered_last[32]
DWORD trigger_count_required