void mscb_define(char *submaster, char *equipment, char *devname, DEVICE_DRIVER *driver, int address, unsigned char var_index, char *name, double threshold) { int i, dev_index, chn_index, chn_total; char str[256]; float f_threshold; HNDLE hDB; cm_get_experiment_database(&hDB, NULL); //printf(hDB+"\n"); if (submaster && submaster[0]) { sprintf(str, "/Equipment/%s/Settings/Devices/%s/Device", equipment, devname); db_set_value(hDB, 0, str, submaster, 32, 1, TID_STRING); sprintf(str, "/Equipment/%s/Settings/Devices/%s/Pwd", equipment, devname); db_set_value(hDB, 0, str, "mscb174", 32, 1, TID_STRING); } /* find device in device driver */ for (dev_index=0 ; driver[dev_index].name[0] ; dev_index++) if (equal_ustring(driver[dev_index].name, devname)) break; if (!driver[dev_index].name[0]) { cm_msg(MERROR, "Device \"%s\" not present in device driver list", devname); return; } /* count total number of channels */ for (i=chn_total=0 ; i<=dev_index ; i++) chn_total += driver[i].channels; chn_index = driver[dev_index].channels; sprintf(str, "/Equipment/%s/Settings/Devices/%s/MSCB Address", equipment, devname); db_set_value_index(hDB, 0, str, &address, sizeof(int), chn_index, TID_INT, TRUE); sprintf(str, "/Equipment/%s/Settings/Devices/%s/MSCB Index", equipment, devname); db_set_value_index(hDB, 0, str, &var_index, sizeof(char), chn_index, TID_BYTE, TRUE); if (threshold != -1) { sprintf(str, "/Equipment/%s/Settings/Update Threshold", equipment); f_threshold = (float) threshold; db_set_value_index(hDB, 0, str, &f_threshold, sizeof(float), chn_total, TID_FLOAT, TRUE); } if (name && name[0]) { sprintf(str, "/Equipment/%s/Settings/Names Input", equipment); db_set_value_index(hDB, 0, str, name, 32, chn_total, TID_STRING, TRUE); } /* increment number of channels for this driver */ driver[dev_index].channels++; }
int main() { int status, size; HNDLE hDB, hKey; /* connect to experiment */ status = cm_connect_experiment("", "", "ODBTest", NULL); if (status != CM_SUCCESS) return 1; /* get handle to online database */ cm_get_experiment_database(&hDB, &hKey); /* read key "runinfo/run number" */ size = sizeof(run_number); status = db_get_value(hDB, 0, "/runinfo/run number", &run_number, &size, TID_INT, TRUE); if (status != DB_SUCCESS) { printf("Cannot read run number"); return 0; } printf("Current run number is %d\n", run_number); /* set new run number */ run_number++; db_set_value(hDB, 0, "/runinfo/run number", &run_number, size, 1, TID_INT); /* now open run_number with automatic updates */ db_find_key(hDB, 0, "/runinfo/run number", &hKey); db_open_record(hDB, hKey, &run_number, sizeof(run_number), MODE_READ, run_number_changed, NULL); printf("Waiting for run number to change. Hit RETURN to abort\n"); do { cm_yield(1000); } while (!ss_kbhit()); db_close_record(hDB, hKey); /* disconnect from experiment */ cm_disconnect_experiment(); return 1; }
INT readout(char* pevent, INT off) { DWORD *pdata; bk_init32(pevent); bk_create(pevent,"INPT",TID_DWORD,&pdata); int val = 98; HNDLE hDB; HNDLE hKey; INT size; cm_get_experiment_database(&hDB,NULL); db_find_key(hDB,0,"/Equipment/Environment 2/Variables/Secret",&hKey); size = sizeof(val); db_get_data(hDB,hKey,&val,&size,TID_INT); *pdata++ = val; struct timeval t; int status; status = gettimeofday(&t,NULL); printf(" t_tv.sec: %d",t.tv_sec); printf(" ro: val is %d",val); val++; db_set_value(hDB,0,"/Equipment/Environment 2/Variables/Secret",&val,sizeof(val),1,TID_INT); bk_close(pevent,pdata); return bk_size(pevent); }
/** Scan ODB for alarms. @return AL_SUCCESS */ INT al_check() { if (rpc_is_remote()) return rpc_call(RPC_AL_CHECK); #ifdef LOCAL_ROUTINES { INT i, status, size, semaphore; HNDLE hDB, hkeyroot, hkey; KEY key; ALARM a; char str[256], value[256]; time_t now; PROGRAM_INFO program_info; BOOL flag; ALARM_CLASS_STR(alarm_class_str); ALARM_ODB_STR(alarm_odb_str); ALARM_PERIODIC_STR(alarm_periodic_str); cm_get_experiment_database(&hDB, NULL); if (hDB == 0) return AL_SUCCESS; /* called from server not yet connected */ /* check online mode */ flag = TRUE; size = sizeof(flag); db_get_value(hDB, 0, "/Runinfo/Online Mode", &flag, &size, TID_INT, TRUE); if (!flag) return AL_SUCCESS; /* check global alarm flag */ flag = TRUE; size = sizeof(flag); db_get_value(hDB, 0, "/Alarms/Alarm system active", &flag, &size, TID_BOOL, TRUE); if (!flag) return AL_SUCCESS; /* request semaphore */ cm_get_experiment_semaphore(&semaphore, NULL, NULL, NULL); status = ss_semaphore_wait_for(semaphore, 100); if (status == SS_TIMEOUT) return AL_SUCCESS; /* someone else is doing alarm business */ if (status != SS_SUCCESS) { printf("al_check: Something is wrong with our semaphore, ss_semaphore_wait_for() returned %d, aborting.\n", status); //abort(); // DOES NOT RETURN printf("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"); // NOT REACHED return AL_SUCCESS; } /* check ODB alarms */ db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot); if (!hkeyroot) { /* create default ODB alarm */ status = db_create_record(hDB, 0, "/Alarms/Alarms/Demo ODB", strcomb(alarm_odb_str)); db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot); if (!hkeyroot) { ss_semaphore_release(semaphore); return AL_SUCCESS; } status = db_create_record(hDB, 0, "/Alarms/Alarms/Demo periodic", strcomb(alarm_periodic_str)); db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot); if (!hkeyroot) { ss_semaphore_release(semaphore); return AL_SUCCESS; } /* create default alarm classes */ status = db_create_record(hDB, 0, "/Alarms/Classes/Alarm", strcomb(alarm_class_str)); status = db_create_record(hDB, 0, "/Alarms/Classes/Warning", strcomb(alarm_class_str)); if (status != DB_SUCCESS) { ss_semaphore_release(semaphore); return AL_SUCCESS; } } for (i = 0;; i++) { status = db_enum_key(hDB, hkeyroot, i, &hkey); if (status == DB_NO_MORE_SUBKEYS) break; db_get_key(hDB, hkey, &key); size = sizeof(a); status = db_get_record(hDB, hkey, &a, &size, 0); if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) { /* make sure alarm record has right structure */ db_check_record(hDB, hkey, "", strcomb(alarm_odb_str), TRUE); size = sizeof(a); status = db_get_record(hDB, hkey, &a, &size, 0); if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) { cm_msg(MERROR, "al_check", "Cannot get alarm record"); continue; } } /* check periodic alarm only when active */ if (a.active && a.type == AT_PERIODIC && a.check_interval > 0 && (INT) ss_time() - (INT) a.checked_last > a.check_interval) { /* if checked_last has not been set, set it to current time */ if (a.checked_last == 0) { a.checked_last = ss_time(); db_set_record(hDB, hkey, &a, size, 0); } else al_trigger_alarm(key.name, a.alarm_message, a.alarm_class, "", AT_PERIODIC); } /* check alarm only when active and not internal */ if (a.active && a.type == AT_EVALUATED && a.check_interval > 0 && (INT) ss_time() - (INT) a.checked_last > a.check_interval) { /* if condition is true, trigger alarm */ if (al_evaluate_condition(a.condition, value)) { sprintf(str, a.alarm_message, value); al_trigger_alarm(key.name, str, a.alarm_class, "", AT_EVALUATED); } else { a.checked_last = ss_time(); status = db_set_value(hDB, hkey, "Checked last", &a.checked_last, sizeof(DWORD), 1, TID_DWORD); if (status != DB_SUCCESS) { cm_msg(MERROR, "al_check", "Cannot change alarm record"); continue; } } } } /* check /programs alarms */ db_find_key(hDB, 0, "/Programs", &hkeyroot); if (hkeyroot) { for (i = 0;; i++) { status = db_enum_key(hDB, hkeyroot, i, &hkey); if (status == DB_NO_MORE_SUBKEYS) break; db_get_key(hDB, hkey, &key); /* don't check "execute on xxx" */ if (key.type != TID_KEY) continue; size = sizeof(program_info); status = db_get_record(hDB, hkey, &program_info, &size, 0); if (status != DB_SUCCESS) { cm_msg(MERROR, "al_check", "Cannot get program info record"); continue; } now = ss_time(); rpc_get_name(str); str[strlen(key.name)] = 0; if (!equal_ustring(str, key.name) && cm_exist(key.name, FALSE) == CM_NO_CLIENT) { if (program_info.first_failed == 0) { program_info.first_failed = (DWORD) now; db_set_record(hDB, hkey, &program_info, sizeof(program_info), 0); } /* fire alarm when not running for more than what specified in check interval */ if (now - program_info.first_failed >= program_info.check_interval / 1000) { /* if not running and alarm calss defined, trigger alarm */ if (program_info.alarm_class[0]) { sprintf(str, "Program %s is not running", key.name); al_trigger_alarm(key.name, str, program_info.alarm_class, "Program not running", AT_PROGRAM); } /* auto restart program */ if (program_info.auto_restart && program_info.start_command[0]) { ss_system(program_info.start_command); program_info.first_failed = 0; cm_msg(MTALK, "al_check", "Program %s restarted", key.name); } } } else { if (program_info.first_failed != 0) { program_info.first_failed = 0; db_set_record(hDB, hkey, &program_info, sizeof(program_info), 0); } } } } ss_semaphore_release(semaphore); } #endif /* LOCAL_COUTINES */ return SUCCESS; }
/** Trigger a certain alarm. \code ... 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); ... \endcode @param alarm_name Alarm name, defined in /alarms/alarms @param alarm_message Optional message which goes with alarm @param default_class If alarm is not yet defined under /alarms/alarms/\<alarm_name\>, a new one is created and this default class is used. @param cond_str String displayed in alarm condition @param type Alarm type, one of AT_xxx @return AL_SUCCESS, AL_INVALID_NAME */ INT al_trigger_alarm(const char *alarm_name, const char *alarm_message, const char *default_class, const char *cond_str, INT type) { if (rpc_is_remote()) return rpc_call(RPC_AL_TRIGGER_ALARM, alarm_name, alarm_message, default_class, cond_str, type); #ifdef LOCAL_ROUTINES { int status, size; HNDLE hDB, hkeyalarm, hkey; char str[256]; ALARM a; BOOL flag; ALARM_ODB_STR(alarm_odb_str); cm_get_experiment_database(&hDB, NULL); /* check online mode */ flag = TRUE; size = sizeof(flag); db_get_value(hDB, 0, "/Runinfo/Online Mode", &flag, &size, TID_INT, TRUE); if (!flag) return AL_SUCCESS; /* find alarm */ sprintf(str, "/Alarms/Alarms/%s", alarm_name); db_find_key(hDB, 0, str, &hkeyalarm); if (!hkeyalarm) { /* alarm must be an internal analyzer alarm, so create a default alarm */ status = db_create_record(hDB, 0, str, strcomb(alarm_odb_str)); db_find_key(hDB, 0, str, &hkeyalarm); if (!hkeyalarm) { cm_msg(MERROR, "al_trigger_alarm", "Cannot create alarm record"); return AL_ERROR_ODB; } if (default_class && default_class[0]) db_set_value(hDB, hkeyalarm, "Alarm Class", default_class, 32, 1, TID_STRING); status = TRUE; db_set_value(hDB, hkeyalarm, "Active", &status, sizeof(status), 1, TID_BOOL); } /* set parameters for internal alarms */ if (type != AT_EVALUATED && type != AT_PERIODIC) { db_set_value(hDB, hkeyalarm, "Type", &type, sizeof(INT), 1, TID_INT); strcpy(str, cond_str); db_set_value(hDB, hkeyalarm, "Condition", str, 256, 1, TID_STRING); } size = sizeof(a); status = db_get_record(hDB, hkeyalarm, &a, &size, 0); if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) { /* make sure alarm record has right structure */ db_check_record(hDB, hkeyalarm, "", strcomb(alarm_odb_str), TRUE); size = sizeof(a); status = db_get_record(hDB, hkeyalarm, &a, &size, 0); if (status != DB_SUCCESS) { cm_msg(MERROR, "al_trigger_alarm", "Cannot get alarm record"); return AL_ERROR_ODB; } } /* if internal alarm, check if active and check interval */ if (a.type != AT_EVALUATED && a.type != AT_PERIODIC) { /* check global alarm flag */ flag = TRUE; size = sizeof(flag); db_get_value(hDB, 0, "/Alarms/Alarm system active", &flag, &size, TID_BOOL, TRUE); if (!flag) return AL_SUCCESS; if (!a.active) return AL_SUCCESS; if ((INT) ss_time() - (INT) a.checked_last < a.check_interval) return AL_SUCCESS; /* now the alarm will be triggered, so save time */ a.checked_last = ss_time(); } /* write back alarm message for internal alarms */ if (a.type != AT_EVALUATED && a.type != AT_PERIODIC) { strncpy(a.alarm_message, alarm_message, 79); a.alarm_message[79] = 0; } /* now trigger alarm class defined in this alarm */ if (a.alarm_class[0]) al_trigger_class(a.alarm_class, alarm_message, a.triggered > 0); /* check for and trigger "All" class */ if (db_find_key(hDB, 0, "/Alarms/Classes/All", &hkey) == DB_SUCCESS) al_trigger_class("All", alarm_message, a.triggered > 0); /* signal alarm being triggered */ cm_asctime(str, sizeof(str)); if (!a.triggered) strcpy(a.time_triggered_first, str); a.triggered++; strcpy(a.time_triggered_last, str); a.checked_last = ss_time(); status = db_set_record(hDB, hkeyalarm, &a, sizeof(a), 0); if (status != DB_SUCCESS) { cm_msg(MERROR, "al_trigger_alarm", "Cannot update alarm record"); return AL_ERROR_ODB; } } #endif /* LOCAL_ROUTINES */ return AL_SUCCESS; }
INT ge_ln2_read(char *pevent, INT off) { static INT status, size; static DWORD lastfilled, now, timelimit; static BOOL justfilled; static DWORD *timesincefill; bk_init(pevent); timesincefill = NULL; // Get recent values size = sizeof(lastfilled); status = db_get_value(hDB, 0, sLastFilled, &lastfilled, &size, TID_DWORD, FALSE); if (status != DB_SUCCESS) { cm_msg(MERROR, "ge_ln2_read", "Error getting last filled time"); return 0; } size = sizeof(justfilled); status = db_get_value(hDB, 0, sJustFilled, &justfilled, &size, TID_BOOL, FALSE); if (status != DB_SUCCESS) { cm_msg(MERROR, "ge_ln2_read", "Error getting just filled status"); return 0; } size = sizeof(timelimit); status = db_get_value(hDB, 0, sTimeLimit, &timelimit, &size, TID_DWORD, FALSE); if (status != DB_SUCCESS) { cm_msg(MERROR, "ge_ln2_read", "Error getting time limit between fills"); return 0; } // If just filled, write time to ODB if (justfilled == TRUE) { lastfilled = (DWORD)time(NULL); status = db_set_value(hDB, 0, sLastFilled, &lastfilled, sizeof(lastfilled), 1, TID_DWORD); if (status != DB_SUCCESS) { cm_msg(MERROR, "gn_ln2_read", "Error setting last filled time"); return 0; } justfilled = FALSE; status = db_set_value(hDB, 0, sJustFilled, &justfilled, sizeof(justfilled), 1, TID_BOOL); if (status != DB_SUCCESS) { cm_msg(MERROR, "gn_ln2_read", "Error setting just filled status"); return 0; } al_reset_alarm(sAlarmName); bk_create(pevent, "LN2F", TID_DWORD, ×incefill); *timesincefill = 0; bk_close(pevent, ++timesincefill); return bk_size(pevent); } // Check the status bk_create(pevent, "LN2F", TID_DWORD, ×incefill); now = (DWORD) time(NULL); *timesincefill = now - lastfilled; if (*timesincefill > timelimit) { al_trigger_alarm(sAlarmName, "Germanium must be filled!", "Alarm", "", AT_INTERNAL); printf("Alarm!\n"); } bk_close(pevent, ++timesincefill); return bk_size(pevent); }
INT frontend_init() { INT status; BOOL default_justfilled = FALSE; // Assuming the worst DWORD default_lastfilled = 0; // Assuming the worst DWORD default_timelimit = 28000; // 8 hours between fills // Get handles to database keys if they exist, // and create otherwise with default worst-case-scenario values status = cm_get_experiment_database(&hDB, NULL); if (status != CM_SUCCESS) { printf("Warning: Could not connect to ODB database!\n"); return FE_ERR_HW; } status = db_find_key(hDB, 0, sLastFilled, &kLastFilled); if (status == DB_NO_KEY) { db_create_key(hDB, 0, sLastFilled, TID_DWORD); db_find_key(hDB, 0, sLastFilled, &kLastFilled); status = db_set_value(hDB, 0, sLastFilled, &default_lastfilled, sizeof(default_lastfilled), 1, TID_DWORD); } if (status != DB_SUCCESS) { printf("Warning: Could not access key %s!\n", sLastFilled); return FE_ERR_HW; } status = db_find_key(hDB, 0, sJustFilled, &kJustFilled); if (status == DB_NO_KEY) { db_create_key(hDB, 0, sJustFilled, TID_BOOL); db_find_key(hDB, 0, sJustFilled, &kJustFilled); status = db_set_value(hDB, 0, sJustFilled, &default_justfilled, sizeof(default_justfilled), 1, TID_BOOL); } if (status != DB_SUCCESS) { printf("Warning: Could not access key %s!\n", sJustFilled); return FE_ERR_HW; } status = db_find_key(hDB, 0, sTimeLimit, &kTimeLimit); if (status == DB_NO_KEY) { db_create_key(hDB, 0, sTimeLimit, TID_DWORD); db_find_key(hDB, 0, sTimeLimit, &kTimeLimit); status = db_set_value(hDB, 0, sTimeLimit, &default_timelimit, sizeof(default_timelimit), 1, TID_DWORD); } if (status != DB_SUCCESS) { printf("Warning: Could not access key %s!\n", sTimeLimit); return FE_ERR_HW; } /* // Check if alarm exists and, if not,create it // Copied from midas.c which should take care of this, but doesn't char str[256]; sprintf(str, "/Alarms/Alarms/%s", sAlarmName); db_find_key(hDB, 0, str, &kAlarm); if (!kAlarm) { ALARM_ODB_STR(alarm_odb_str); // The initial "run number too large" settings for a default alarm status = db_create_record(hDB, 0, str, strcomb(alarm_odb_str)); db_find_key(hDB, 0, str, &kAlarm); if (!kAlarm) { cm_msg(MERROR, "ge_ln2_init", "Cannot create alarm record"); return FE_ERR_HW; } BOOL al_active = TRUE; // Alarm should be on INT al_type = AT_EVALUATED; // Alarm type is evaluated; it looks for a certain ODB value to be too large char al_cond[256] = ""; // Not a "conditional" alarm in the MIDAS sense char al_class[32] = "Alarm"; // When triggered, the alarm will have black letters on red background char al_msg[80] = "Germanium must be filled!"; // Message on banner db_set_value(hDB, kAlarm, "Active", &al_active, sizeof(al_active), 1, TID_BOOL); db_set_value(hDB, kAlarm, "Type", &al_type, sizeof(al_type), 1, TID_INT); db_set_value(hDB, kAlarm, "Condition", al_cond, sizeof(al_cond), 1, TID_STRING); db_set_value(hDB, kAlarm, "Alarm Class", al_class, sizeof(al_class), 1, TID_STRING); db_set_value(hDB, kAlarm, "Alarm Message", al_msg, sizeof(al_msg), 1, TID_STRING); } */ return CM_SUCCESS; }