Пример #1
0
//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);


}
Пример #2
0
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;
}
Пример #3
0
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++;
   }

}
Пример #4
0
/**
 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;
}
Пример #5
0
// 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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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++;
}
Пример #10
0
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;
}
Пример #11
0
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();
}
Пример #12
0
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;
}
Пример #13
0
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);

}
Пример #14
0
/*-- 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;
}
Пример #15
0
/*-- 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;
}
Пример #16
0
/**
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;
}
Пример #17
0
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;
}
Пример #18
0
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;
}
Пример #19
0
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;
}
Пример #20
0
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;
}
Пример #21
0
/**
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;
}
Пример #22
0
/**
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;
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
0
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++;
   }
}
Пример #26
0
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;
}