//fill mbank from /equip/environ/variables INT read_periodic_event(char *pevent, INT off){ printf("Reading Periodic Event\n"); HNDLE hDB; cm_get_experiment_database(&hDB, NULL); HNDLE hkey; float temp1[3]; INT size; // get key handle for temp db_find_key(hDB, 0, "/Equipment/Temperature/Variables/Input", &hkey); // return temp size = sizeof(temp1); db_get_data(hDB, hkey, &temp1, &size, TID_FLOAT); //char *pevent; bk_init(pevent); float *pdata; // *pdata = temp1[0]; // create SCLR bank bk_create(pevent, "NEW1", TID_FLOAT, &pdata); // *pdata = 29.3; printf("%f\n",temp1[0]); // close SCLR bank bk_close(pevent, pdata); printf("eo fB\n"); return bk_size(pevent); }
int null_init(HNDLE hkey, void **pinfo) { HNDLE hDB, hkeybd; INT size, status; NULL_INFO *info; /* allocate info structure */ info = calloc(1, sizeof(NULL_INFO)); *pinfo = info; cm_get_experiment_database(&hDB, NULL); /* create NULL settings record */ status = db_create_record(hDB, hkey, "BD", NULL_SETTINGS_STR); if (status != DB_SUCCESS) return FE_ERR_ODB; db_find_key(hDB, hkey, "BD", &hkeybd); size = sizeof(info->settings); db_get_record(hDB, hkeybd, &info->settings, &size, 0); /* open port */ info->fd = null_open(info->settings.device); if (info->fd < 0) return FE_ERR_HW; return SUCCESS; }
void multi_read_output(EQUIPMENT * pequipment, int channel) { float value; MULTI_INFO *m_info; HNDLE hDB; m_info = (MULTI_INFO *) pequipment->cd_info; cm_get_experiment_database(&hDB, NULL); device_driver(m_info->driver_output[channel], CMD_GET, channel - m_info->channel_offset_output[channel], &value); value = (value + m_info->offset_output[channel]) / m_info->factor_output[channel]; if (value != m_info->output_mirror[channel]) { m_info->output_mirror[channel] = value; m_info->var_input[channel] = value; db_set_record(hDB, m_info->hKeyOutput, m_info->output_mirror, m_info->num_channels_output * sizeof(float), 0); pequipment->odb_out++; } }
/** Scan ODB for alarms. @return AL_SUCCESS */ INT al_get_alarms(char *result, int result_size) { HNDLE hDB, hkey, hsubkey; int i, j, n, flag, size; char alarm_class[32], msg[256], value_str[256], str[256]; cm_get_experiment_database(&hDB, NULL); result[0] = 0; n = 0; db_find_key(hDB, 0, "/Alarms/Alarms", &hkey); if (hkey) { /* 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) { for (i = 0;; i++) { db_enum_link(hDB, hkey, i, &hsubkey); if (!hsubkey) break; size = sizeof(flag); db_get_value(hDB, hsubkey, "Triggered", &flag, &size, TID_INT, TRUE); if (flag) { n++; size = sizeof(alarm_class); db_get_value(hDB, hsubkey, "Alarm Class", alarm_class, &size, TID_STRING, TRUE); size = sizeof(msg); db_get_value(hDB, hsubkey, "Alarm Message", msg, &size, TID_STRING, TRUE); size = sizeof(j); db_get_value(hDB, hsubkey, "Type", &j, &size, TID_INT, TRUE); if (j == AT_EVALUATED) { size = sizeof(str); db_get_value(hDB, hsubkey, "Condition", str, &size, TID_STRING, TRUE); /* retrieve value */ al_evaluate_condition(str, value_str); sprintf(str, msg, value_str); } else strlcpy(str, msg, sizeof(str)); strlcat(result, alarm_class, result_size); strlcat(result, ": ", result_size); strlcat(result, str, result_size); strlcat(result, "\n", result_size); } } } } return n; }
// Read current INT fgd_read(EQUIPMENT * pequipment, int channel) { static DWORD last_time = 0; int i, status; FGD_INFO *fgd_info; HNDLE hDB; /*---- read measured value ----*/ fgd_info = (FGD_INFO *) pequipment->cd_info; cm_get_experiment_database(&hDB, NULL); //status = device_driver(fgd_info->driver[channel], CMD_GET_CURRENT, // channel - fgd_info->channel_offset[channel], // &fgd_info->measured[channel]); ///* check for update measured */ //for (i = 0; i < fgd_info->num_channels; i++) { // /* update if change is more than update_threshold */ // if (abs(fgd_info->measured[i] - fgd_info->measured_mirror[i]) > // fgd_info->update_threshold[i]) { // for (i = 0; i < fgd_info->num_channels; i++) // fgd_info->measured_mirror[i] = fgd_info->measured[i]; // db_set_data(hDB, fgd_info->hKeyMeasured, fgd_info->measured, // sizeof(float) * fgd_info->num_channels, fgd_info->num_channels, // TID_FLOAT); // pequipment->odb_out++; // break; // } //} // Get the temperatures if ((ss_time() - last_time) > 1) { channel = 0; status = device_driver(fgd_info->driver[channel], CMD_GET_TEMPERATURE1, channel - fgd_info->channel_offset[channel], &fgd_info->temp1[channel]); db_set_data(hDB, fgd_info->hKeyTemp1, fgd_info->temp1, sizeof(float) * fgd_info->num_channels, fgd_info->num_channels, TID_FLOAT); status = device_driver(fgd_info->driver[channel], CMD_GET_TEMPERATURE2, channel - fgd_info->channel_offset[channel], &fgd_info->temp2[channel]); db_set_data(hDB, fgd_info->hKeyTemp2, fgd_info->temp2, sizeof(float) * fgd_info->num_channels, fgd_info->num_channels, TID_FLOAT); status = device_driver(fgd_info->driver[channel], CMD_GET_TEMPERATURE3, channel - fgd_info->channel_offset[channel], &fgd_info->temp3[channel]); db_set_data(hDB, fgd_info->hKeyTemp3, fgd_info->temp3, sizeof(float) * fgd_info->num_channels, fgd_info->num_channels, TID_FLOAT); last_time = ss_time(); } return status; }
INT analyzer_init() { HNDLE hDB, hKey; char str[80]; RUNINFO_STR(runinfo_str); EXP_PARAM_STR(exp_param_str); GLOBAL_PARAM_STR(global_param_str); TRIGGER_SETTINGS_STR(trigger_settings_str); /* open ODB structures */ cm_get_experiment_database(&hDB, NULL); db_create_record(hDB, 0, "/Runinfo", strcomb((const char **)runinfo_str)); db_find_key(hDB, 0, "/Runinfo", &hKey); if (db_open_record(hDB, hKey, &runinfo, sizeof(runinfo), MODE_READ, NULL, NULL) != DB_SUCCESS) { cm_msg(MERROR, "analyzer_init", "Cannot open \"/Runinfo\" tree in ODB"); return 0; } db_create_record(hDB, 0, "/Experiment/Run Parameters", strcomb((const char **)exp_param_str)); db_find_key(hDB, 0, "/Experiment/Run Parameters", &hKey); if (db_open_record(hDB, hKey, &exp_param, sizeof(exp_param), MODE_READ, NULL, NULL) != DB_SUCCESS) { cm_msg(MERROR, "analyzer_init", "Cannot open \"/Experiment/Run Parameters\" tree in ODB"); return 0; } sprintf(str, "/%s/Parameters/Global", analyzer_name); db_create_record(hDB, 0, str, strcomb((const char **)global_param_str)); db_find_key(hDB, 0, str, &hKey); if (db_open_record (hDB, hKey, &global_param, sizeof(global_param), MODE_READ, NULL, NULL) != DB_SUCCESS) { cm_msg(MERROR, "analyzer_init", "Cannot open \"%s\" tree in ODB", str); return 0; } db_create_record(hDB, 0, "/Equipment/Trigger/Settings", strcomb((const char **)trigger_settings_str)); db_find_key(hDB, 0, "/Equipment/Trigger/Settings", &hKey); if (db_open_record (hDB, hKey, &trigger_settings, sizeof(trigger_settings), MODE_READ, NULL, NULL) != DB_SUCCESS) { cm_msg(MERROR, "analyzer_init", "Cannot open \"/Equipment/Trigger/Settings\" tree in ODB"); return 0; } //Initialize gData gData = new TEnvi(); return SUCCESS; }
INT ana_end_of_run(INT run_number, char *error) { FILE *f; time_t now; char str[256]; int size; double n; HNDLE hDB; BOOL flag; cm_get_experiment_database(&hDB, NULL); /* update run log if run was written and running online */ size = sizeof(flag); db_get_value(hDB, 0, "/Logger/Write data", &flag, &size, TID_BOOL, TRUE); if (flag && runinfo.online_mode == 1) { /* update run log */ size = sizeof(str); str[0] = 0; db_get_value(hDB, 0, "/Logger/Data Dir", str, &size, TID_STRING, TRUE); if (str[0] != 0) if (str[strlen(str) - 1] != DIR_SEPARATOR) strcat(str, DIR_SEPARATOR_STR); strcat(str, "runlog.txt"); f = fopen(str, "a"); time(&now); strcpy(str, ctime(&now)); str[10] = 0; fprintf(f, "%s\t%3d\t", str, runinfo.run_number); strcpy(str, runinfo.start_time); str[19] = 0; fprintf(f, "%s\t", str + 11); strcpy(str, ctime(&now)); str[19] = 0; fprintf(f, "%s\t", str + 11); size = sizeof(n); db_get_value(hDB, 0, "/Equipment/Trigger/Statistics/Events sent", &n, &size, TID_DOUBLE, TRUE); fprintf(f, "%5.1lfk\t", n / 1000); fprintf(f, "%s\n", exp_param.comment); fclose(f); } return CM_SUCCESS; }
INT frontend_init() { // get the LabView filename cm_get_experiment_database(&hDB, NULL); if(db_find_key(hDB, 0, Alarm, &hKey) != SUCCESS){ db_create_key(hDB,0,Alarm,TID_INT); } return CM_SUCCESS; }
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 main(int argc, char *argv[]) { char host_name[256], exp_name[32]; cm_get_environment(host_name, sizeof(host_name), exp_name, sizeof(exp_name)); cm_connect_experiment(host_name, exp_name, "Compression", NULL); cm_get_experiment_database(&hDB, NULL); compress_load_all(); if(argc != 2) { printf("Usage: mucap_optimize uncompressed_input.mid\n"); exit(1); } FILE *fp = fopen(argv[1], "r"); if (!fp) { printf("Unable to open %s\n", argv[1]); exit(1); } char *input_event = new char[MAX_EVENT_SIZE]; char *output_event = new char[MAX_EVENT_SIZE]; while (read_midas_event(fp, input_event) == SUCCESS) { EVENT_HEADER header = *((EVENT_HEADER *) input_event); int event_id = header.event_id; if (event_id == EVENTID_BOR || event_id == EVENTID_EOR || event_id == EVENTID_MESSAGE) { continue; } bk_init32(output_event); compress_event(input_event + sizeof(EVENT_HEADER), output_event); } compress_optimize_all(); fclose(fp); cm_disconnect_experiment(); }
int mscbbus_init(HNDLE hkey, void **pinfo) { HNDLE hDB, hkeybd; INT size, status; MSCBBUS_INFO *info; /* allocate info structure */ info = calloc(1, sizeof(MSCBBUS_INFO)); *pinfo = info; cm_get_experiment_database(&hDB, NULL); /* create MSCBBUS settings record */ status = db_create_record(hDB, hkey, "BD", MSCBBUS_SETTINGS_STR); if (status != DB_SUCCESS) return FE_ERR_ODB; db_find_key(hDB, hkey, "BD", &hkeybd); size = sizeof(info->settings); db_get_record(hDB, hkeybd, &info->settings, &size, 0); /* open port */ // check if ethernet submaster info->fd = mscb_init(info->settings.mscb_device, sizeof(info->settings.mscb_device), info->settings.pwd, FALSE); if (info->fd < 0) return FE_ERR_HW; /* check if scs_210 is alive */ status = mscb_addr(info->fd, MCMD_PING16, info->settings.address, 1); if (status != MSCB_SUCCESS) { if (status == MSCB_SEMAPHORE) printf("MSCB used by other process\n"); else if (status == MSCB_SUBM_ERROR) printf("Error: MSCB Submaster not responding\n"); else printf("MSCB Node %d does not respond\n", info->settings.address); return FE_ERR_HW; } return SUCCESS; }
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); }
/*-- Analyzer Init -------------------------------------------------*/ INT analyzer_init() { HNDLE hDB, hKey; char str[80]; RUNINFO_STR(runinfo_str); // RUNINFO_STR in experim.h rn: not true !?!?! EXP_PARAM_STR(exp_param_str); // EXP_PARAM_STR in experim.h rn: not true !!?!?! //GLOBAL_PARAM_STR(global_param_str); // GLOBAL_PARAM_STR in experim.h /* open ODB structures */ cm_get_experiment_database(&hDB, NULL); db_create_record(hDB, 0, "/Runinfo", strcomb(runinfo_str)); db_find_key(hDB, 0, "/Runinfo", &hKey); if (db_open_record(hDB, hKey, &runinfo, sizeof(runinfo), MODE_READ, NULL, NULL) != DB_SUCCESS) { cm_msg(MERROR, "analyzer_init", "Cannot open \"/Runinfo\" tree in ODB"); return 0; } db_create_record(hDB, 0, "/Experiment/Run Parameters", strcomb(exp_param_str)); db_find_key(hDB, 0, "/Experiment/Run Parameters", &hKey); if (db_open_record(hDB, hKey, &exp_param, sizeof(exp_param), MODE_READ, NULL, NULL) != DB_SUCCESS) { cm_msg(MERROR, "analyzer_init", "Cannot open \"/Experiment/Run Parameters\" tree in ODB"); return 0; } //printf("\n---testing testing 123----------------------------------------------- %i \n\n\n\n ",runinfo.run_number); //runnr=runinfo.run_number; ParameterInit(); return SUCCESS; }
/*-- End of Run ----------------------------------------------------*/ INT ana_end_of_run(INT run_number, char *error) { FILE *f; time_t now; char str[256]; int size; double n; HNDLE hDB; BOOL flag; cm_get_experiment_database(&hDB, NULL); /* update run log if run was written and running online */ size = sizeof(flag); db_get_value(hDB, 0, "/Logger/Write data", &flag, &size, TID_BOOL, TRUE); if (flag && runinfo.online_mode == 1) { /* update run log */ size = sizeof(str); str[0] = 0; db_get_value(hDB, 0, "/Logger/Data Dir", str, &size, TID_STRING, TRUE); if (str[0] != 0) if (str[strlen(str) - 1] != DIR_SEPARATOR) strcat(str, DIR_SEPARATOR_STR); strcat(str, "runlog.txt"); f = fopen(str, "a"); time(&now); strcpy(str, ctime(&now)); str[10] = 0; fprintf(f, "%s\t%3d\t", str, runinfo.run_number); strcpy(str, runinfo.start_time); str[19] = 0; fprintf(f, "%s\t", str + 11); strcpy(str, ctime(&now)); str[19] = 0; fprintf(f, "%s\t", str + 11); size = sizeof(n); db_get_value(hDB, 0, "/Equipment/Trigger/Statistics/Events sent", &n, &size, TID_DOUBLE, TRUE); fprintf(f, "%5.1lfk\t", n / 1000); fprintf(f, "%s\n", exp_param.comment); fclose(f); } printf("\n------------------------------------------------------"); printf("\n| |"); printf("\n| TDC Events: %i ",tdc_counter); printf("\n| QDC Events: %i ",qdc_counter1); printf("\n| ADC Events: %i ",adc_counter1); printf("\n| Scaler Events %i ",scaler_counter); // printf("\n| "); // printf("\n| Events with skips %i ",skipcounter); printf("\n| "); printf("\n| Events with no TDC datawords : %i ",empty_tdc_counter); printf("\n| Events with too many TDC datawords : %i ",toolarge_tdc_event_counter); printf("\n| Events with no QDC datawords: %i ",qdc_counter2); printf("\n| Events with no ADC datawords: %i ",adc_counter2); printf("\n| "); printf("\n| TDC chip ERRORS: %i ",trailer_TDCERR_counter); // counter in TDC trailer printf("\n| TDC triggers lost: %i ",trailer_triglost_counter); // counter in TDC trailer printf("\n| TDC buffer overflow: %i ",trailer_bufoverflow_counter); // counter in TDC trailer printf("\n| |"); printf("\n------------------------------------------------------\n"); // close the root file (that containst the trees) created in f-plane.c extern TFile *f1; // declared in main.c extern TTree *t1; // declared in main.c f1->cd(); f1->Write(); f1->Close(); return CM_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 cam_init_rpc(char *host_name, char *exp_name, char *fe_name, char *client_name, char *rpc_server) { INT status, i, size; char str[256]; HNDLE hDB, hKey, hRootKey, hSubkey; if (rpc_server[0]) { /* connect directly to RPC server, not to MIDAS experiment */ midas_connect = FALSE; #ifdef OS_WINNT { WSADATA WSAData; /* Start windows sockets */ if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0) return RPC_NET_ERROR; } #endif rpc_set_name(client_name); rpc_register_functions(rpc_get_internal_list(0), NULL); rpc_register_functions(rpc_get_internal_list(1), NULL); status = rpc_client_connect(rpc_server, 1750, client_name, &hConn); if (status != RPC_SUCCESS) { printf("Cannot connect to RPC server running on %s at port 1750.\n", rpc_server); return status; } } else { /* connect to MIDAS experiment */ midas_connect = TRUE; /* turn off message display, turn on message logging */ cm_set_msg_print(MT_ALL, 0, NULL); /* connect to experiment */ status = cm_connect_experiment(host_name, exp_name, client_name, 0); if (status != CM_SUCCESS) return CM_UNDEF_EXP; /* connect to the database */ cm_get_experiment_database(&hDB, &hKey); /* find CNAF server if not specified */ strcpy(str, fe_name); if (fe_name[0] == '\0') { /* find client which exports CNAF function */ status = db_find_key(hDB, 0, "System/Clients", &hRootKey); if (status == DB_SUCCESS) { for (i = 0, status = 0;; i++) { status = db_enum_key(hDB, hRootKey, i, &hSubkey); if (status == DB_NO_MORE_SUBKEYS) { printf("No client currently exports the CNAF functionality.\n"); cm_disconnect_experiment(); return CM_UNDEF_EXP; } sprintf(str, "RPC/%d", RPC_CNAF16); status = db_find_key(hDB, hSubkey, str, &hKey); if (status == DB_SUCCESS) { size = sizeof(str); db_get_value(hDB, hSubkey, "Name", str, &size, TID_STRING, TRUE); break; } } } } /* register CNAF_RPC call */ if (cm_connect_client(str, &hConn) == CM_SUCCESS) { DWORD data, size, q, x; /* test if CNAF function implemented */ size = sizeof(WORD); status = rpc_client_call(hConn, RPC_CNAF16, CNAF_TEST, 0, 0, 0, 0, 0, &data, &size, &q, &x); if (status != RPC_SUCCESS) { printf("CNAF functionality not implemented by frontend %s\n", fe_name); cm_disconnect_client(hConn, FALSE); return CM_NO_CLIENT; } } else { printf("Cannot connect to frontend %s\n", fe_name); return CM_NO_CLIENT; } } return SUCCESS; }
INT al_trigger_class(const char *alarm_class, const char *alarm_message, BOOL first) /********************************************************************\ Routine: al_trigger_class Purpose: Trigger a certain alarm class Input: char *alarm_class Alarm class, must be defined in /alarms/classes char *alarm_message Optional message which goes with alarm BOOL first TRUE if alarm is triggered first time (used for elog) Output: Function value: AL_INVALID_NAME Alarm class not defined AL_SUCCESS Successful completion \********************************************************************/ { int status, size, state; HNDLE hDB, hkeyclass; char str[256], command[256], tag[32], url[256]; ALARM_CLASS ac; DWORD now = ss_time(); tag[0] = 0; cm_get_experiment_database(&hDB, NULL); /* get alarm class */ sprintf(str, "/Alarms/Classes/%s", alarm_class); db_find_key(hDB, 0, str, &hkeyclass); if (!hkeyclass) { cm_msg(MERROR, "al_trigger_class", "Alarm class %s not found in ODB", alarm_class); return AL_INVALID_NAME; } size = sizeof(ac); status = db_get_record(hDB, hkeyclass, &ac, &size, 0); if (status != DB_SUCCESS) { cm_msg(MERROR, "al_trigger_class", "Cannot get alarm class record"); return AL_ERROR_ODB; } /* write system message */ if (ac.write_system_message && (now - ac.system_message_last >= (DWORD)ac.system_message_interval)) { if (equal_ustring(alarm_class, "All")) sprintf(str, "General alarm: %s", alarm_message); else sprintf(str, "%s: %s", alarm_class, alarm_message); cm_msg(MTALK, "al_trigger_class", "%s", str); ac.system_message_last = now; } /* write elog message on first trigger if using internal ELOG */ size = sizeof(url); if (ac.write_elog_message && first && db_get_value(hDB, 0, "/Elog/URL", url, &size, TID_STRING, FALSE) != DB_SUCCESS) el_submit(0, "Alarm system", "Alarm", "General", alarm_class, str, "", "plain", "", "", 0, "", "", 0, "", "", 0, tag, sizeof(tag)); /* execute command */ if (ac.execute_command[0] && ac.execute_interval > 0 && (INT) ss_time() - (INT) ac.execute_last > ac.execute_interval) { if (equal_ustring(alarm_class, "All")) sprintf(str, "General alarm: %s", alarm_message); else sprintf(str, "%s: %s", alarm_class, alarm_message); sprintf(command, ac.execute_command, str); cm_msg(MINFO, "al_trigger_class", "Execute: %s", command); ss_system(command); ac.execute_last = ss_time(); } /* stop run */ if (ac.stop_run) { state = STATE_STOPPED; size = sizeof(state); db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, TRUE); if (state != STATE_STOPPED) { cm_msg(MINFO, "al_trigger_class", "Stopping the run from alarm class \'%s\', message \'%s\'", alarm_class, alarm_message); cm_transition(TR_STOP, 0, NULL, 0, TR_DETACH, FALSE); } } status = db_set_record(hDB, hkeyclass, &ac, sizeof(ac), 0); if (status != DB_SUCCESS) { cm_msg(MERROR, "al_trigger_class", "Cannot update alarm class record"); return AL_ERROR_ODB; } return AL_SUCCESS; }
INT fgd_init(EQUIPMENT * pequipment) { int status, size, i, j, index, offset; char str[256]; HNDLE hDB, hKey, hNames, hThreshold; FGD_INFO *fgd_info; /* allocate private data */ pequipment->cd_info = calloc(1, sizeof(FGD_INFO)); fgd_info = (FGD_INFO *) pequipment->cd_info; /* get class driver root key */ cm_get_experiment_database(&hDB, NULL); sprintf(str, "/Equipment/%s", pequipment->name); db_create_key(hDB, 0, str, TID_KEY); db_find_key(hDB, 0, str, &fgd_info->hKeyRoot); /* save event format */ size = sizeof(str); db_get_value(hDB, fgd_info->hKeyRoot, "Common/Format", str, &size, TID_STRING, TRUE); if (equal_ustring(str, "Fixed")) fgd_info->format = FORMAT_FIXED; else if (equal_ustring(str, "MIDAS")) fgd_info->format = FORMAT_MIDAS; else if (equal_ustring(str, "YBOS")) fgd_info->format = FORMAT_YBOS; /* count total number of channels */ for (i = 0, fgd_info->num_channels = 0; pequipment->driver[i].name[0]; i++) { if (pequipment->driver[i].channels == 0) { cm_msg(MERROR, "fgd_init", "Driver with zero channels not allowed"); return FE_ERR_ODB; } fgd_info->num_channels += pequipment->driver[i].channels; } if (fgd_info->num_channels == 0) { cm_msg(MERROR, "fgd_init", "No channels found in device driver list"); return FE_ERR_ODB; } /* Allocate memory for buffers */ fgd_info->names = (char *) calloc(fgd_info->num_channels, NAME_LENGTH); fgd_info->demand = (float *) calloc(fgd_info->num_channels, sizeof(float)); fgd_info->measured = (float *) calloc(fgd_info->num_channels, sizeof(float)); fgd_info->temp1 = (float *) calloc(fgd_info->num_channels, sizeof(float)); fgd_info->temp2 = (float *) calloc(fgd_info->num_channels, sizeof(float)); fgd_info->temp3 = (float *) calloc(fgd_info->num_channels, sizeof(float)); fgd_info->update_threshold = (float *) calloc(fgd_info->num_channels, sizeof(float)); fgd_info->demand_mirror = (float *) calloc(fgd_info->num_channels, sizeof(float)); fgd_info->measured_mirror = (float *) calloc(fgd_info->num_channels, sizeof(float)); fgd_info->channel_offset = (INT *) calloc(fgd_info->num_channels, sizeof(INT)); fgd_info->driver = (void *) calloc(fgd_info->num_channels, sizeof(void *)); if (!fgd_info->driver) { cm_msg(MERROR, "hv_init", "Not enough memory"); return FE_ERR_ODB; } /*---- Initialize device drivers ----*/ /* call init method */ for (i = 0; pequipment->driver[i].name[0]; i++) { sprintf(str, "Settings/Devices/%s", pequipment->driver[i].name); status = db_find_key(hDB, fgd_info->hKeyRoot, str, &hKey); if (status != DB_SUCCESS) { db_create_key(hDB, fgd_info->hKeyRoot, str, TID_KEY); status = db_find_key(hDB, fgd_info->hKeyRoot, str, &hKey); if (status != DB_SUCCESS) { cm_msg(MERROR, "hv_init", "Cannot create %s entry in online database", str); free_mem(fgd_info); return FE_ERR_ODB; } } status = device_driver(&pequipment->driver[i], CMD_INIT, hKey); if (status != FE_SUCCESS) { free_mem(fgd_info); return status; } } /* compose device driver channel assignment */ for (i = 0, j = 0, index = 0, offset = 0; i < fgd_info->num_channels; i++, j++) { while (j >= pequipment->driver[index].channels && pequipment->driver[index].name[0]) { offset += j; index++; j = 0; } fgd_info->driver[i] = &pequipment->driver[index]; fgd_info->channel_offset[i] = offset; } /*---- create demand variables ----*/ /* get demand from ODB */ status = db_find_key(hDB, fgd_info->hKeyRoot, "Variables/Demand", &fgd_info->hKeyDemand); if (status == DB_SUCCESS) { size = sizeof(float) * fgd_info->num_channels; db_get_data(hDB, fgd_info->hKeyDemand, fgd_info->demand, &size, TID_FLOAT); } /* let device driver overwrite demand values, if it supports it */ for (i = 0; i < fgd_info->num_channels; i++) { if (fgd_info->driver[i]->flags & DF_PRIO_DEVICE) { device_driver(fgd_info->driver[i], CMD_GET_DEMAND, i - fgd_info->channel_offset[i], &fgd_info->demand[i]); fgd_info->demand_mirror[i] = fgd_info->demand[i]; } else fgd_info->demand_mirror[i] = -12345.f; /* use -12345 as invalid value */ } /* write back demand values */ status = db_find_key(hDB, fgd_info->hKeyRoot, "Variables/Demand", &fgd_info->hKeyDemand); if (status != DB_SUCCESS) { db_create_key(hDB, fgd_info->hKeyRoot, "Variables/Demand", TID_FLOAT); db_find_key(hDB, fgd_info->hKeyRoot, "Variables/Demand", &fgd_info->hKeyDemand); } size = sizeof(float) * fgd_info->num_channels; db_set_data(hDB, fgd_info->hKeyDemand, fgd_info->demand, size, fgd_info->num_channels, TID_FLOAT); db_open_record(hDB, fgd_info->hKeyDemand, fgd_info->demand, fgd_info->num_channels * sizeof(float), MODE_READ, fgd_demand, pequipment); /*---- create measured variables ----*/ db_merge_data(hDB, fgd_info->hKeyRoot, "Variables/Current Measured", fgd_info->measured, sizeof(float) * fgd_info->num_channels, fgd_info->num_channels, TID_FLOAT); db_find_key(hDB, fgd_info->hKeyRoot, "Variables/Current Measured", &fgd_info->hKeyMeasured); memcpy(fgd_info->measured_mirror, fgd_info->measured, fgd_info->num_channels * sizeof(float)); /*---- create Temp1 measured variables ----*/ db_merge_data(hDB, fgd_info->hKeyRoot, "Variables/Temp1", fgd_info->temp1, sizeof(float) * fgd_info->num_channels, fgd_info->num_channels, TID_FLOAT); db_find_key(hDB, fgd_info->hKeyRoot, "Variables/Temp1", &fgd_info->hKeyTemp1); /*---- create Temp2 measured variables ----*/ db_merge_data(hDB, fgd_info->hKeyRoot, "Variables/Temp2", fgd_info->temp2, sizeof(float) * fgd_info->num_channels, fgd_info->num_channels, TID_FLOAT); db_find_key(hDB, fgd_info->hKeyRoot, "Variables/Temp2", &fgd_info->hKeyTemp2); /*---- create Temp3 measured variables ----*/ db_merge_data(hDB, fgd_info->hKeyRoot, "Variables/Temp3", fgd_info->temp3, sizeof(float) * fgd_info->num_channels, fgd_info->num_channels, TID_FLOAT); db_find_key(hDB, fgd_info->hKeyRoot, "Variables/Temp3", &fgd_info->hKeyTemp3); /*---- get default names from device driver ----*/ for (i = 0; i < fgd_info->num_channels; i++) { sprintf(fgd_info->names + NAME_LENGTH * i, "Default%%CH %d", i); device_driver(fgd_info->driver[i], CMD_GET_LABEL, i - fgd_info->channel_offset[i], fgd_info->names + NAME_LENGTH * i); } db_merge_data(hDB, fgd_info->hKeyRoot, "Settings/Names", fgd_info->names, NAME_LENGTH * fgd_info->num_channels, fgd_info->num_channels, TID_STRING); /*---- set labels form midas SC names ----*/ for (i = 0; i < fgd_info->num_channels; i++) { fgd_info = (FGD_INFO *) pequipment->cd_info; device_driver(fgd_info->driver[i], CMD_SET_LABEL, i - fgd_info->channel_offset[i], fgd_info->names + NAME_LENGTH * i); } /* open hotlink on channel names */ if (db_find_key(hDB, fgd_info->hKeyRoot, "Settings/Names", &hNames) == DB_SUCCESS) db_open_record(hDB, hNames, fgd_info->names, NAME_LENGTH*fgd_info->num_channels, MODE_READ, fgd_update_label, pequipment); /*---- get default update threshold from device driver ----*/ for (i = 0; i < fgd_info->num_channels; i++) { fgd_info->update_threshold[i] = 1.f; /* default 1 unit */ device_driver(fgd_info->driver[i], CMD_GET_THRESHOLD, i - fgd_info->channel_offset[i], &fgd_info->update_threshold[i]); } db_merge_data(hDB, fgd_info->hKeyRoot, "Settings/Update Threshold Measured", fgd_info->update_threshold, sizeof(float)*fgd_info->num_channels, fgd_info->num_channels, TID_FLOAT); /* open hotlink on update threshold */ if (db_find_key(hDB, fgd_info->hKeyRoot, "Settings/Update Threshold Measured", &hThreshold) == DB_SUCCESS) db_open_record(hDB, hThreshold, fgd_info->update_threshold, sizeof(float)*fgd_info->num_channels, MODE_READ, NULL, NULL); /*---- set initial demand values ----*/ // fgd_demand(hDB, fgd_info->hKeyDemand, pequipment); /* initially read all channels */ for (i = 0; i < fgd_info->num_channels; i++) fgd_read(pequipment, i); return FE_SUCCESS; }
BOOL al_evaluate_condition(const char *condition, char *value) { HNDLE hDB, hkey; int i, j, idx1, idx2, idx, size, state; KEY key; double value1, value2; char value1_str[256], value2_str[256], str[256], op[3], function[80]; char data[10000]; DWORD dtime; strcpy(str, condition); op[1] = op[2] = 0; value1 = value2 = 0; idx1 = idx2 = 0; /* find value and operator */ for (i = strlen(str) - 1; i > 0; i--) if (strchr("<>=!&", str[i]) != NULL) break; op[0] = str[i]; for (j = 1; str[i + j] == ' '; j++); strlcpy(value2_str, str + i + j, sizeof(value2_str)); value2 = atof(value2_str); str[i] = 0; if (i > 0 && strchr("<>=!&", str[i - 1])) { op[1] = op[0]; op[0] = str[--i]; str[i] = 0; } i--; while (i > 0 && str[i] == ' ') i--; str[i + 1] = 0; /* check if function */ function[0] = 0; if (str[i] == ')') { str[i--] = 0; if (strchr(str, '(')) { *strchr(str, '(') = 0; strcpy(function, str); for (i = strlen(str) + 1, j = 0; str[i]; i++, j++) str[j] = str[i]; str[j] = 0; i = j - 1; } } /* find key */ if (str[i] == ']') { str[i--] = 0; if (str[i] == '*') { idx1 = -1; while (i > 0 && str[i] != '[') i--; str[i] = 0; } else if (strchr(str, '[') && strchr(strchr(str, '['), '-')) { while (i > 0 && isdigit(str[i])) i--; idx2 = atoi(str + i + 1); while (i > 0 && str[i] != '[') i--; idx1 = atoi(str + i + 1); str[i] = 0; } else { while (i > 0 && isdigit(str[i])) i--; idx1 = idx2 = atoi(str + i + 1); str[i] = 0; } } cm_get_experiment_database(&hDB, NULL); db_find_key(hDB, 0, str, &hkey); if (!hkey) { cm_msg(MERROR, "al_evaluate_condition", "Cannot find key %s to evaluate alarm condition", str); if (value) strcpy(value, "unknown"); return FALSE; } db_get_key(hDB, hkey, &key); if (idx1 < 0) { idx1 = 0; idx2 = key.num_values-1; } for (idx=idx1; idx<=idx2 ; idx++) { if (equal_ustring(function, "access")) { /* check key access time */ db_get_key_time(hDB, hkey, &dtime); sprintf(value1_str, "%d", dtime); value1 = atof(value1_str); } else if (equal_ustring(function, "access_running")) { /* check key access time if running */ db_get_key_time(hDB, hkey, &dtime); sprintf(value1_str, "%d", dtime); size = sizeof(state); db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, FALSE); if (state != STATE_RUNNING) strcpy(value1_str, "0"); value1 = atof(value1_str); } else { /* get key data and convert to double */ db_get_key(hDB, hkey, &key); size = sizeof(data); db_get_data_index(hDB, hkey, data, &size, idx, key.type); db_sprintf(value1_str, data, size, 0, key.type); value1 = atof(value1_str); } /* convert boolean values to integers */ if (key.type == TID_BOOL) { value1 = (value1_str[0] == 'Y' || value1_str[0] == 'y' || value1_str[0] == '1'); value2 = (value2_str[0] == 'Y' || value2_str[0] == 'y' || value2_str[0] == '1'); } /* return value */ if (value) strcpy(value, value1_str); /* now do logical operation */ if (strcmp(op, "=") == 0) if (value1 == value2) return TRUE; if (strcmp(op, "==") == 0) if (value1 == value2) return TRUE; if (strcmp(op, "!=") == 0) if (value1 != value2) return TRUE; if (strcmp(op, "<") == 0) if (value1 < value2) return TRUE; if (strcmp(op, ">") == 0) if (value1 > value2) return TRUE; if (strcmp(op, "<=") == 0) if (value1 <= value2) return TRUE; if (strcmp(op, ">=") == 0) if (value1 >= value2) return TRUE; if (strcmp(op, "&") == 0) if (((unsigned int)value1 & (unsigned int)value2) > 0) return TRUE; } return FALSE; }
/** Reset (acknoledge) alarm. @param alarm_name Alarm name, defined in /alarms/alarms @return AL_SUCCESS, AL_RESETE, AL_INVALID_NAME */ INT al_reset_alarm(const char *alarm_name) { int status, size, i; HNDLE hDB, hkeyalarm, hkeyclass, hsubkey; KEY key; char str[256]; ALARM a; ALARM_CLASS ac; cm_get_experiment_database(&hDB, NULL); if (alarm_name == NULL) { /* reset all alarms */ db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyalarm); if (hkeyalarm) { for (i = 0;; i++) { db_enum_link(hDB, hkeyalarm, i, &hsubkey); if (!hsubkey) break; db_get_key(hDB, hsubkey, &key); al_reset_alarm(key.name); } } return AL_SUCCESS; } /* find alarm and alarm class */ sprintf(str, "/Alarms/Alarms/%s", alarm_name); db_find_key(hDB, 0, str, &hkeyalarm); if (!hkeyalarm) { /*cm_msg(MERROR, "al_reset_alarm", "Alarm %s not found in ODB", alarm_name);*/ return AL_INVALID_NAME; } size = sizeof(a); status = db_get_record(hDB, hkeyalarm, &a, &size, 0); if (status != DB_SUCCESS) { cm_msg(MERROR, "al_reset_alarm", "Cannot get alarm record"); return AL_ERROR_ODB; } sprintf(str, "/Alarms/Classes/%s", a.alarm_class); db_find_key(hDB, 0, str, &hkeyclass); if (!hkeyclass) { cm_msg(MERROR, "al_reset_alarm", "Alarm class %s not found in ODB", a.alarm_class); return AL_INVALID_NAME; } size = sizeof(ac); status = db_get_record(hDB, hkeyclass, &ac, &size, 0); if (status != DB_SUCCESS) { cm_msg(MERROR, "al_reset_alarm", "Cannot get alarm class record"); return AL_ERROR_ODB; } if (a.triggered) { a.triggered = 0; a.time_triggered_first[0] = 0; a.time_triggered_last[0] = 0; a.checked_last = 0; ac.system_message_last = 0; ac.execute_last = 0; status = db_set_record(hDB, hkeyalarm, &a, sizeof(a), 0); if (status != DB_SUCCESS) { cm_msg(MERROR, "al_reset_alarm", "Cannot update alarm record"); return AL_ERROR_ODB; } status = db_set_record(hDB, hkeyclass, &ac, sizeof(ac), 0); if (status != DB_SUCCESS) { cm_msg(MERROR, "al_reset_alarm", "Cannot update alarm class record"); return AL_ERROR_ODB; } cm_msg(MINFO, "al_reset_alarm", "Alarm \"%s\" reset", alarm_name); return AL_RESET; } return AL_SUCCESS; }
/** 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; }
INT gen_read(EQUIPMENT * pequipment, int channel) { int i, status; GEN_INFO *gen_info; HNDLE hDB; gen_info = (GEN_INFO *) pequipment->cd_info; cm_get_experiment_database(&hDB, NULL); /* if driver is multi-threaded, read all channels at once */ for (i=0 ; i < gen_info->num_channels ; i++) { if (gen_info->driver[i]->flags & DF_MULTITHREAD) { status = device_driver(gen_info->driver[i], CMD_GET, i - gen_info->channel_offset[i], &gen_info->measured[i]); } } /* else read only single channel */ if (!(gen_info->driver[channel]->flags & DF_MULTITHREAD)) { status = device_driver(gen_info->driver[channel], CMD_GET, channel - gen_info->channel_offset[channel], &gen_info->measured[channel]); } /* check for update measured */ for (i = 0; i < gen_info->num_channels; i++) { /* update if change is more than update_threshold */ if ((ss_isnan(gen_info->measured[i]) && !ss_isnan(gen_info->measured_mirror[i])) || (!ss_isnan(gen_info->measured[i]) && ss_isnan(gen_info->measured_mirror[i])) || (!ss_isnan(gen_info->measured[i]) && !ss_isnan(gen_info->measured_mirror[i]) && abs(gen_info->measured[i] - gen_info->measured_mirror[i]) > gen_info->update_threshold[i])) { for (i = 0; i < gen_info->num_channels; i++) gen_info->measured_mirror[i] = gen_info->measured[i]; db_set_data(hDB, gen_info->hKeyMeasured, gen_info->measured, sizeof(float) * gen_info->num_channels, gen_info->num_channels, TID_FLOAT); pequipment->odb_out++; break; } } /*---- read demand value ----*/ status = device_driver(gen_info->driver[channel], CMD_GET_DEMAND, channel - gen_info->channel_offset[channel], &gen_info->demand[channel]); if ((gen_info->demand[channel] != gen_info->demand_mirror[channel] && !ss_isnan(gen_info->demand[channel])) || (ss_isnan(gen_info->demand[channel]) && !ss_isnan(gen_info->demand_mirror[channel])) || (!ss_isnan(gen_info->demand[channel]) && ss_isnan(gen_info->demand_mirror[channel]))) { gen_info->demand_mirror[channel] = gen_info->demand[channel]; db_set_data(hDB, gen_info->hKeyDemand, gen_info->demand, sizeof(float) * gen_info->num_channels, gen_info->num_channels, TID_FLOAT); } return status; }
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; }
void multi_read(EQUIPMENT * pequipment, int channel) { int i, status; DWORD actual_time; MULTI_INFO *m_info; HNDLE hDB; m_info = (MULTI_INFO *) pequipment->cd_info; cm_get_experiment_database(&hDB, NULL); if (channel == -1 || m_info->driver_input[channel]->flags & DF_MULTITHREAD) for (i = 0; i < m_info->num_channels_input; i++) { status = device_driver(m_info->driver_input[i], CMD_GET, i - m_info->channel_offset_input[i], &m_info->var_input[i]); if (status != FE_SUCCESS) m_info->var_input[i] = (float)ss_nan(); else m_info->var_input[i] = m_info->var_input[i] * m_info->factor_input[i] - m_info->offset_input[i]; } else { status = device_driver(m_info->driver_input[channel], CMD_GET, channel - m_info->channel_offset_input[channel], &m_info->var_input[channel]); if (status != FE_SUCCESS) m_info->var_input[channel] = (float)ss_nan(); else m_info->var_input[channel] = m_info->var_input[channel] * m_info->factor_input[channel] - m_info->offset_input[channel]; } /* check if significant change since last ODB update */ for (i = 0; i < m_info->num_channels_input; i++) if ((!ss_isnan(m_info->var_input[i]) && !ss_isnan(m_info->input_mirror[i]) && abs(m_info->var_input[i] - m_info->input_mirror[i]) > m_info->update_threshold[i]) || (ss_isnan(m_info->var_input[i]) && !ss_isnan(m_info->input_mirror[i])) || (!ss_isnan(m_info->var_input[i]) && ss_isnan(m_info->input_mirror[i]))) break; #ifdef DEBUG_THRESHOLDS if (i < m_info->num_channels_input) { printf("%d: %lf -> %lf, threshold %lf\n", i, m_info->var_input[i], m_info->input_mirror[i], m_info->update_threshold[i]); } #endif /* update if change is more than update_sensitivity or last update more than a minute ago */ actual_time = ss_millitime(); if (i < m_info->num_channels_input || actual_time - m_info->last_update > 60000) { m_info->last_update = actual_time; for (i = 0; i < m_info->num_channels_input; i++) m_info->input_mirror[i] = m_info->var_input[i]; db_set_data(hDB, m_info->hKeyInput, m_info->var_input, m_info->num_channels_input * sizeof(float), m_info->num_channels_input, TID_FLOAT); pequipment->odb_out++; } }
INT multi_init(EQUIPMENT * pequipment) { int status, size, i, j, index, ch_offset; char str[256]; HNDLE hDB, hKey, hNamesIn, hNamesOut; MULTI_INFO *m_info; BOOL partially_disabled; /* allocate private data */ pequipment->cd_info = calloc(1, sizeof(MULTI_INFO)); m_info = (MULTI_INFO *) pequipment->cd_info; /* get class driver root key */ cm_get_experiment_database(&hDB, NULL); sprintf(str, "/Equipment/%s", pequipment->name); db_create_key(hDB, 0, str, TID_KEY); db_find_key(hDB, 0, str, &m_info->hKeyRoot); /* save event format */ size = sizeof(str); db_get_value(hDB, m_info->hKeyRoot, "Common/Format", str, &size, TID_STRING, TRUE); if (equal_ustring(str, "Fixed")) m_info->format = FORMAT_FIXED; else if (equal_ustring(str, "MIDAS")) m_info->format = FORMAT_MIDAS; else if (equal_ustring(str, "YBOS")) m_info->format = FORMAT_YBOS; /* count total number of channels */ for (i = m_info->num_channels_input = m_info->num_channels_output = 0; pequipment->driver[i].name[0]; i++) { if (pequipment->driver[i].flags & DF_INPUT) m_info->num_channels_input += pequipment->driver[i].channels; if (pequipment->driver[i].flags & DF_OUTPUT) m_info->num_channels_output += pequipment->driver[i].channels; } if (m_info->num_channels_input == 0 && m_info->num_channels_output == 0) { cm_msg(MERROR, "multi_init", "No channels found in device driver list"); return FE_ERR_ODB; } /* Allocate memory for buffers */ if (m_info->num_channels_input) { m_info->names_input = (char *) calloc(m_info->num_channels_input, NAME_LENGTH); m_info->var_input = (float *) calloc(m_info->num_channels_input, sizeof(float)); m_info->update_threshold = (float *) calloc(m_info->num_channels_input, sizeof(float)); m_info->offset_input = (float *) calloc(m_info->num_channels_input, sizeof(float)); m_info->factor_input = (float *) calloc(m_info->num_channels_input, sizeof(float)); m_info->input_mirror = (float *) calloc(m_info->num_channels_input, sizeof(float)); m_info->channel_offset_input = (INT *) calloc(m_info->num_channels_input, sizeof(INT)); m_info->driver_input = (void *) calloc(m_info->num_channels_input, sizeof(void *)); } if (m_info->num_channels_output) { m_info->names_output = (char *) calloc(m_info->num_channels_output, NAME_LENGTH); m_info->var_output = (float *) calloc(m_info->num_channels_output, sizeof(float)); m_info->offset_output = (float *) calloc(m_info->num_channels_output, sizeof(float)); m_info->factor_output = (float *) calloc(m_info->num_channels_output, sizeof(float)); m_info->output_mirror = (float *) calloc(m_info->num_channels_output, sizeof(float)); m_info->channel_offset_output = (INT *) calloc(m_info->num_channels_output, sizeof(DWORD)); m_info->driver_output = (void *) calloc(m_info->num_channels_output, sizeof(void *)); } /*---- Create/Read settings ----*/ if (m_info->num_channels_input) { /* Update threshold */ for (i = 0; i < m_info->num_channels_input; i++) m_info->update_threshold[i] = 0.1f; /* default 0.1 */ db_merge_data(hDB, m_info->hKeyRoot, "Settings/Update Threshold", m_info->update_threshold, m_info->num_channels_input * sizeof(float), m_info->num_channels_input, TID_FLOAT); db_find_key(hDB, m_info->hKeyRoot, "Settings/Update Threshold", &hKey); db_open_record(hDB, hKey, m_info->update_threshold, m_info->num_channels_input * sizeof(float), MODE_READ, NULL, NULL); /* Offset */ for (i = 0; i < m_info->num_channels_input; i++) m_info->offset_input[i] = 0.f; /* default 0 */ db_merge_data(hDB, m_info->hKeyRoot, "Settings/Input Offset", m_info->offset_input, m_info->num_channels_input * sizeof(float), m_info->num_channels_input, TID_FLOAT); db_find_key(hDB, m_info->hKeyRoot, "Settings/Input Offset", &hKey); db_open_record(hDB, hKey, m_info->offset_input, m_info->num_channels_input * sizeof(float), MODE_READ, NULL, NULL); } for (i = 0; i < m_info->num_channels_output; i++) m_info->offset_output[i] = 0.f; if (m_info->num_channels_output) { db_merge_data(hDB, m_info->hKeyRoot, "Settings/Output Offset", m_info->offset_output, m_info->num_channels_output * sizeof(float), m_info->num_channels_output, TID_FLOAT); db_find_key(hDB, m_info->hKeyRoot, "Settings/Output Offset", &hKey); db_open_record(hDB, hKey, m_info->offset_output, m_info->num_channels_output * sizeof(float), MODE_READ, NULL, NULL); } /* Factor */ for (i = 0; i < m_info->num_channels_input; i++) m_info->factor_input[i] = 1.f; /* default 1 */ if (m_info->num_channels_input) { db_merge_data(hDB, m_info->hKeyRoot, "Settings/Input Factor", m_info->factor_input, m_info->num_channels_input * sizeof(float), m_info->num_channels_input, TID_FLOAT); db_find_key(hDB, m_info->hKeyRoot, "Settings/Input factor", &hKey); db_open_record(hDB, hKey, m_info->factor_input, m_info->num_channels_input * sizeof(float), MODE_READ, NULL, NULL); } if (m_info->num_channels_output) { for (i = 0; i < m_info->num_channels_output; i++) m_info->factor_output[i] = 1.f; db_merge_data(hDB, m_info->hKeyRoot, "Settings/Output Factor", m_info->factor_output, m_info->num_channels_output * sizeof(float), m_info->num_channels_output, TID_FLOAT); db_find_key(hDB, m_info->hKeyRoot, "Settings/Output factor", &hKey); db_open_record(hDB, hKey, m_info->factor_output, m_info->num_channels_output * sizeof(float), MODE_READ, NULL, NULL); } /*---- Create/Read variables ----*/ /* Input */ if (m_info->num_channels_input) { db_merge_data(hDB, m_info->hKeyRoot, "Variables/Input", m_info->var_input, m_info->num_channels_input * sizeof(float), m_info->num_channels_input, TID_FLOAT); db_find_key(hDB, m_info->hKeyRoot, "Variables/Input", &m_info->hKeyInput); memcpy(m_info->input_mirror, m_info->var_input, m_info->num_channels_input * sizeof(float)); } /* Output */ if (m_info->num_channels_output) { db_merge_data(hDB, m_info->hKeyRoot, "Variables/Output", m_info->var_output, m_info->num_channels_output * sizeof(float), m_info->num_channels_output, TID_FLOAT); db_find_key(hDB, m_info->hKeyRoot, "Variables/Output", &m_info->hKeyOutput); } /*---- Initialize device drivers ----*/ /* call init method */ partially_disabled = FALSE; for (i = 0; pequipment->driver[i].name[0]; i++) { sprintf(str, "Settings/Devices/%s", pequipment->driver[i].name); status = db_find_key(hDB, m_info->hKeyRoot, str, &hKey); if (status != DB_SUCCESS) { db_create_key(hDB, m_info->hKeyRoot, str, TID_KEY); status = db_find_key(hDB, m_info->hKeyRoot, str, &hKey); if (status != DB_SUCCESS) { cm_msg(MERROR, "multi_init", "Cannot create %s entry in online database", str); free_mem(m_info); return FE_ERR_ODB; } } /* check enabled flag */ size = sizeof(pequipment->driver[i].enabled); pequipment->driver[i].enabled = 1; sprintf(str, "Settings/Devices/%s/Enabled", pequipment->driver[i].name); status = db_get_value(hDB, m_info->hKeyRoot, str, &pequipment->driver[i].enabled, &size, TID_BOOL, TRUE); if (status != DB_SUCCESS) return FE_ERR_ODB; if (pequipment->driver[i].enabled) { status = device_driver(&pequipment->driver[i], CMD_INIT, hKey); if (status != FE_SUCCESS) { free_mem(m_info); return status; } } else partially_disabled = TRUE; } /* compose device driver channel assignment */ for (i = 0, j = 0, index = 0, ch_offset = 0; i < m_info->num_channels_input; i++, j++) { while (pequipment->driver[index].name[0] && (j >= pequipment->driver[index].channels || (pequipment->driver[index].flags & DF_INPUT) == 0)) { ch_offset += j; index++; j = 0; } m_info->driver_input[i] = &pequipment->driver[index]; m_info->channel_offset_input[i] = ch_offset; } for (i = 0, j = 0, index = 0, ch_offset = 0; i < m_info->num_channels_output; i++, j++) { while (pequipment->driver[index].name[0] && (j >= pequipment->driver[index].channels || (pequipment->driver[index].flags & DF_OUTPUT) == 0)) { ch_offset += j; index++; j = 0; } m_info->driver_output[i] = &pequipment->driver[index]; m_info->channel_offset_output[i] = ch_offset; } /*---- get default names from device driver ----*/ if (m_info->num_channels_input) { for (i = 0; i < m_info->num_channels_input; i++) { sprintf(m_info->names_input + NAME_LENGTH * i, "Input Channel %d", i); device_driver(m_info->driver_input[i], CMD_GET_LABEL, i - m_info->channel_offset_input[i], m_info->names_input + NAME_LENGTH * i); /* merge existing names with labels from driver */ status = db_find_key(hDB, m_info->hKeyRoot, "Settings/Names Input", &hKey); if (status != DB_SUCCESS) { db_create_key(hDB, m_info->hKeyRoot, "Settings/Names Input", TID_STRING); db_find_key(hDB, m_info->hKeyRoot, "Settings/Names Input", &hKey); db_set_data(hDB, hKey, m_info->names_input, NAME_LENGTH, 1, TID_STRING); } else { size = sizeof(str); db_get_data_index(hDB, hKey, str, &size, i, TID_STRING); if (!str[0]) db_set_data_index(hDB, hKey, m_info->names_input+NAME_LENGTH*i, NAME_LENGTH, i, TID_STRING); } } } if (m_info->num_channels_output) { for (i = 0; i < m_info->num_channels_output; i++) { sprintf(m_info->names_output + NAME_LENGTH * i, "Output Channel %d", i); device_driver(m_info->driver_output[i], CMD_GET_LABEL, i - m_info->channel_offset_output[i], m_info->names_output + NAME_LENGTH * i); /* merge existing names with labels from driver */ status = db_find_key(hDB, m_info->hKeyRoot, "Settings/Names Output", &hKey); if (status != DB_SUCCESS) { db_create_key(hDB, m_info->hKeyRoot, "Settings/Names Output", TID_STRING); db_find_key(hDB, m_info->hKeyRoot, "Settings/Names Output", &hKey); db_set_data(hDB, hKey, m_info->names_input, NAME_LENGTH, 1, TID_STRING); } else { size = sizeof(str); db_get_data_index(hDB, hKey, str, &size, i, TID_STRING); if (!str[0]) db_set_data_index(hDB, hKey, m_info->names_input+NAME_LENGTH*i, NAME_LENGTH, i, TID_STRING); } } } /*---- set labels from midas SC names ----*/ if (m_info->num_channels_input) { for (i = 0; i < m_info->num_channels_input; i++) { device_driver(m_info->driver_input[i], CMD_SET_LABEL, i - m_info->channel_offset_input[i], m_info->names_input + NAME_LENGTH * i); } /* open hotlink on input channel names */ if (db_find_key(hDB, m_info->hKeyRoot, "Settings/Names Input", &hNamesIn) == DB_SUCCESS) db_open_record(hDB, hNamesIn, m_info->names_input, NAME_LENGTH * m_info->num_channels_input, MODE_READ, multi_update_label, pequipment); } for (i = 0; i < m_info->num_channels_output; i++) { device_driver(m_info->driver_output[i], CMD_SET_LABEL, i - m_info->channel_offset_output[i], m_info->names_output + NAME_LENGTH * i); } /* open hotlink on output channel names */ if (m_info->num_channels_output) { if (db_find_key(hDB, m_info->hKeyRoot, "Settings/Names Output", &hNamesOut) == DB_SUCCESS) db_open_record(hDB, hNamesOut, m_info->names_output, NAME_LENGTH * m_info->num_channels_output, MODE_READ, multi_update_label, pequipment); /* open hot link to output record */ db_open_record(hDB, m_info->hKeyOutput, m_info->var_output, m_info->num_channels_output * sizeof(float), MODE_READ, multi_output, pequipment); } /* set initial demand values */ for (i = 0; i < m_info->num_channels_output; i++) { if (pequipment->driver[index].flags & DF_PRIO_DEVICE) { /* read default value directly from device bypassing multi-thread buffer */ device_driver(m_info->driver_output[i], CMD_GET_DEMAND, i - m_info->channel_offset_output[i], &m_info->output_mirror[i]); } else { /* use default value from ODB */ m_info->output_mirror[i] = m_info->var_output[i] * m_info->factor_output[i] - m_info->offset_output[i]; device_driver(m_info->driver_output[i], CMD_SET, i - m_info->channel_offset_output[i], m_info->output_mirror[i]); } } if (m_info->num_channels_output) db_set_record(hDB, m_info->hKeyOutput, m_info->output_mirror, m_info->num_channels_output * sizeof(float), 0); /* initially read all input channels */ if (m_info->num_channels_input) multi_read(pequipment, -1); if (partially_disabled) return FE_PARTIALLY_DISABLED; return FE_SUCCESS; }