Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018 
<== Date ==> <== Thread ==>

Subject: RE: how to put value to other record in subroutine record
From: Emmanuel Mayssat <emayssat@outlook.com>
To: marco_hair <marco_hair@163.com>, tech-talk <tech-talk@aps.anl.gov>
Date: Mon, 21 Oct 2013 14:41:30 -0700
This is the code for a gensub record (asub record are said to be 100% compatible with gensub)
Here is the code for a simple status code translation
Note that the asub and gensub have input and output records
In the example below:
1/ read the input (status code)
2/ write output (status string)


record(genSub,      "$(deviceName)$(_)StsGS") {
    field(DESC, "Status Translator")
    field(SCAN, "Passive")
    field(SCAN, "1 second")
    field(INAM, "")
    field(SNAM, "SNOVA_funcTranslateStatusCodes")
    #field(SNAM, "SNOVA_funcIdle")
    field(EFLG, "ON CHANGE")
    #--- input
    field(INPA, "$(deviceName)$(_)Main$(_)StsLI")
    field(FTA,  "LONG")
    field(UFA,  "")
    field(NOA,  "1")
    field(INPB, "$(deviceName)$(_)HighVltg$(_)StsLI")
    field(FTB,  "LONG")
    field(UFB,  "")
    field(NOB,  "1")
    field(INPC, "$(deviceName)$(_)Flmnt$(_)StsLI")
    field(FTC,  "LONG")
    field(UFC,  "")
    field(NOC,  "1")
    field(INPD, "$(deviceName)$(_)Cmnctn$(_)StsLI")
    field(FTD,  "LONG")
    field(UFD,  "")
    field(NOD,  "1")
    field(INPE, "$(deviceName)$(_)Reset$(_)StsLI")
    field(FTE,  "LONG")
    field(UFE,  "")
    field(NOE,  "1")
    field(INPF, "$(deviceName)$(_)Mode$(_)StsLI")
    field(FTF,  "LONG")
    field(UFF,  "")
    field(NOF,  "1")
    #gensub counter
    field(INPU, "$(deviceName)$(_)StsGS NPP NMS")
    field(FTU,  "LONG")
    field(NOU,  "1")
    field(UFU,  "")
    #--- ouput
    field(OUTA, "$(deviceName)$(_)Main$(_)StsSI PP")
    field(FTVA, "STRING")
    field(NOVA, "40")
    field(OUTB, "$(deviceName)$(_)HighVltg$(_)StsSI PP")
    field(FTVB, "STRING")
    field(NOVB, "40")
    field(OUTC, "$(deviceName)$(_)Flmnt$(_)StsSI PP")
    field(FTVC, "STRING")
    field(NOVC, "40")
    field(OUTD, "$(deviceName)$(_)Cmnctn$(_)StsSI PP")
    field(FTVD, "STRING")
    field(NOVD, "40")
    field(OUTE, "$(deviceName)$(_)Reset$(_)StsSI PP")
    field(FTVE, "STRING")
    field(NOVE, "40")
    field(OUTF, "$(deviceName)$(_)Mode$(_)StsSI PP")
    field(FTVF, "STRING")
    field(NOVF, "40")
    field(OUTG, "$(deviceName)$(_)WrnngBI PP")
    field(FTVG, "SHORT")
    field(NOVG, "1")
    field(OUTH, "$(deviceName)$(_)AlarmBI PP")
    field(FTVH, "SHORT")
    field(NOVH, "1")
}


#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "dbCommon.h"
#include "dbDefs.h"
#include "dbEvent.h"
#include "epicsExport.h"
#include "genSubRecord.h"
#include "recSup.h"
#include "registryFunction.h"

#define SUCCESS 0
#define ERROR -1
#define BUFLEN 40

int SNOVA_funcTranslateStatusCodes_LOG=1;
epicsExportAddress(int, SNOVA_funcTranslateStatusCodes_LOG);

/*----------------------------------------------------------------------*/
static int funcLog(int logLevel, const char *format, ...) {
  va_list args;
  if (    (SNOVA_funcTranslateStatusCodes_LOG % logLevel ) == 0  ) {
     va_start(args, format);
     vfprintf(stderr, format, args);
     va_end(args);
  }
  return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateMainStatus(long mainStatusLI, char *p_mainStatusSI) {
  switch(mainStatusLI) {
    case 1: strncpy(p_mainStatusSI,"HV-TankOpen interlock",40); break;
    case 2: strncpy(p_mainStatusSI,"HV-Temp interlock",40); break;
    case 3: strncpy(p_mainStatusSI,"HV-Oil level interlock",40); break;
    case 4: strncpy(p_mainStatusSI,"HV-Pressure interlock",40); break;
    case 5: strncpy(p_mainStatusSI,"HV-DCPS interlock",40); break;
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17: strncpy(p_mainStatusSI,"HV-IGBT interlock",40); break;
    case 18: strncpy(p_mainStatusSI,"HV-Voltage interlock",40); break;
    case 19: strncpy(p_mainStatusSI,"HV-Spark interlock",40); break;
    case 20: strncpy(p_mainStatusSI,"HV-Power exceeded interlock",40); break;
    case 21: strncpy(p_mainStatusSI,"HV-DcReset interlock",40); break;
    case 22: strncpy(p_mainStatusSI,"Communication interlock",40); break;
    case 23: strncpy(p_mainStatusSI,"Spark interlock",40); break;
    case 24: strncpy(p_mainStatusSI,"Power exceeded interlock",40); break;
    case 25: strncpy(p_mainStatusSI,"SafetyBus interlock",40); break;
    case 26: strncpy(p_mainStatusSI,"Waterflow interlock",40); break;
    case 27:
    case 99: strncpy(p_mainStatusSI,"HV-Spare",40); break;
    case 100: strncpy(p_mainStatusSI,"Temp interlock",40); break;
    case 101: strncpy(p_mainStatusSI,"LoOil interlock",40); break;
    case 102: strncpy(p_mainStatusSI,"HiOil interlock",40); break;
    case 103: strncpy(p_mainStatusSI,"FilVolt interlock",40); break;
    case 104: strncpy(p_mainStatusSI,"FilCurr interlock",40); break;
    case 105: strncpy(p_mainStatusSI,"Waterflow interlock",40); break;
    case 106:
    case 199: strncpy(p_mainStatusSI,"Spare",40); break;
    case 1000: strncpy(p_mainStatusSI,"Off",40); break;
    case 2000: strncpy(p_mainStatusSI,"Cooling down...",40); break;
    case 7000: strncpy(p_mainStatusSI,"Warming up...",40); break;
    case 7001: strncpy(p_mainStatusSI,"Warm",40); break;
    case 8000: strncpy(p_mainStatusSI,"HV On",40); break;
    case 8001: strncpy(p_mainStatusSI,"HV Trig",40); break;
    default: strncpy(p_mainStatusSI,"Unknown status",40); break;
  }
  return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateHighVoltageStatus(
                long highVoltageStatusLI, char *p_highVoltageStatusSI) {
  switch(highVoltageStatusLI) {
    case 1: strncpy(p_highVoltageStatusSI,"OilTemp interlock",40); break;
    case 2: strncpy(p_highVoltageStatusSI,"LoOilLevel interlock",40); break;
    case 3: strncpy(p_highVoltageStatusSI,"HiOilLevel interlock",40); break;
    case 4: strncpy(p_highVoltageStatusSI,"Dcps interlock",40); break;
    case 5: strncpy(p_highVoltageStatusSI,"DcpsVoltage interlock",40); break;
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17: strncpy(p_highVoltageStatusSI,"Lgbt interlock",40); break;
    case 18: strncpy(p_highVoltageStatusSI,"Load Current interlock",40); break;
    case 19: strncpy(p_highVoltageStatusSI,"Load Voltage interlock",40); break;
    case 20: strncpy(p_highVoltageStatusSI,"DcResetCurr interlock",40); break;
    case 21: strncpy(p_highVoltageStatusSI,"DcResetVltg interlock",40); break;
    case 22: strncpy(p_highVoltageStatusSI,"Communication interlock",40); break;
    case 23: strncpy(p_highVoltageStatusSI,"Spark interlock",40); break;
    case 24: strncpy(p_highVoltageStatusSI,"Power exceed interlock",40); break;
    case 25: strncpy(p_highVoltageStatusSI,"SafetyBus interlock",40); break;
    case 26: strncpy(p_highVoltageStatusSI,"Waterflow interlock",40); break;
    case 27:
    case 98: strncpy(p_highVoltageStatusSI,"Spare",40); break;
    case 1000: strncpy(p_highVoltageStatusSI,"Off",40); break;
    case 1001: strncpy(p_highVoltageStatusSI,"HV-Cnd",40); break;
    case 2000: strncpy(p_highVoltageStatusSI,"Off requested",40); break;
    case 7000: strncpy(p_highVoltageStatusSI,"On requested",40); break;
    case 7001: strncpy(p_highVoltageStatusSI,"Ramp up HV",40); break;
    case 8000: strncpy(p_highVoltageStatusSI,"HV on",40); break;
    case 8001: strncpy(p_highVoltageStatusSI,"HV trig",40); break;
    default: strncpy(p_highVoltageStatusSI,"Unknown",40);
  }
  return(SUCCESS);
}
   
/*----------------------------------------------------------------------*/
static int translateFilamentStatus(long filamentStatusLI, char *p_filamentStatusSI) {
  switch(filamentStatusLI) {
    case 100: strncpy(p_filamentStatusSI,"Temp interlock",40); break;
    case 101: strncpy(p_filamentStatusSI,"LoOil interlock",40); break;
    case 102: strncpy(p_filamentStatusSI,"HiOil interlock",40); break;
    case 103: strncpy(p_filamentStatusSI,"FilVolt interlock",40); break;
    case 104: strncpy(p_filamentStatusSI,"FilCurr interlock",40); break;
    case 105: strncpy(p_filamentStatusSI,"Waterflow interlock",40); break;
    case 106:
    case 198: strncpy(p_filamentStatusSI,"Spare",40); break;
    case 199: strncpy(p_filamentStatusSI,"Fault",40); break;
    case 1000: strncpy(p_filamentStatusSI,"Off",40); break;
    case 1001: strncpy(p_filamentStatusSI,"FilPs-Cnd",40); break;
    case 2000: strncpy(p_filamentStatusSI,"Off requested",40); break;
    case 7000: strncpy(p_filamentStatusSI,"On requested",40); break;
    case 7001: strncpy(p_filamentStatusSI,"Preheating (0min)",40); break;
    case 7002: strncpy(p_filamentStatusSI,"Preheating (1min)",40); break;
    case 7003: strncpy(p_filamentStatusSI,"Preheating (2min)",40); break;
    case 7004: strncpy(p_filamentStatusSI,"Preheating (3min)",40); break;
    case 7005: strncpy(p_filamentStatusSI,"Preheating (4min)",40); break;
    case 7006: strncpy(p_filamentStatusSI,"Preheating (5min)",40); break;
    case 7007: strncpy(p_filamentStatusSI,"Preheating (6min)",40); break;
    case 7008: strncpy(p_filamentStatusSI,"Preheating (7min)",40); break;
    case 7009: strncpy(p_filamentStatusSI,"Preheating (8min)",40); break;
    case 7010: strncpy(p_filamentStatusSI,"Preheating (9min)",40); break;
    case 7011: strncpy(p_filamentStatusSI,"Preheating (10min)",40); break;
    case 7012: strncpy(p_filamentStatusSI,"Preheating (11min)",40); break;
    case 7013: strncpy(p_filamentStatusSI,"Preheating (12min)",40); break;
    case 7014: strncpy(p_filamentStatusSI,"Preheating (13min)",40); break;
    case 7015: strncpy(p_filamentStatusSI,"Preheating (14min)",40); break;
    case 7016: strncpy(p_filamentStatusSI,"Preheating (15min)",40); break;
    case 8000: strncpy(p_filamentStatusSI,"On",40); break;
    default: strncpy(p_filamentStatusSI,"Unknown Filament",40);
  }
  return(SUCCESS);
}

/*----------------------------------------------------------------------*/
static int translateCommunicationStatus(long communicationStatusLI, char *p_communicationStatusSI) {
  switch(communicationStatusLI) {
    case 1: strncpy(p_communicationStatusSI,"Communication interlock",40); break;
    case 1000: strncpy(p_communicationStatusSI,"Off",40); break;
    case 8000: strncpy(p_communicationStatusSI,"Ok",40); break;
    case 8001: strncpy(p_communicationStatusSI,"One missed reply",40); break;
    case 8002: strncpy(p_communicationStatusSI,"Two missed reply",40); break;
    case 8003: strncpy(p_communicationStatusSI,"Three missed reply",40); break;
    case 8004: strncpy(p_communicationStatusSI,"Four missed reply",40); break;
    default: strncpy(p_communicationStatusSI,"Unknown Com",40);
  }
  return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateResetStatus(long resetStatusLI, char *p_resetStatusSI) {
  switch(resetStatusLI) {
    case 1000: strncpy(p_resetStatusSI,"Off",40); break;
    case 7000: strncpy(p_resetStatusSI,"Reset requested",40); break;
    case 8000: strncpy(p_resetStatusSI,"Resetting",40); break;
    default: strncpy(p_resetStatusSI,"Unknown Reset",40);
  }
  return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateModeStatus(long modeStatusLI, char *p_modeStatusSI) {
  switch(modeStatusLI) {
    case 0: strncpy(p_modeStatusSI,"Off",40); break;
    case 1: strncpy(p_modeStatusSI,"Status 1",40); break;
    case 2: strncpy(p_modeStatusSI,"Status 2",40); break;
    case 3: strncpy(p_modeStatusSI,"Status 3",40); break;
    case 4: strncpy(p_modeStatusSI,"Ready",40); break;
    default: strncpy(p_modeStatusSI,"Unknown Mode",40);
  }
  return(SUCCESS);
}

/*----------------------------------------------------------------------*/
static long SNOVA_funcTranslateStatusCodes( struct genSubRecord *p_gensub ) {
  long mainStatusLI;
  long highVoltageStatusLI;
  long filamentStatusLI;
  long communicationStatusLI;
  long resetStatusLI;
  long modeStatusLI;
  char p_mainStatusSI[BUFLEN];
  char p_highVoltageStatusSI[BUFLEN];
  char p_filamentStatusSI[BUFLEN];
  char p_communicationStatusSI[BUFLEN];
  char p_resetStatusSI[BUFLEN];
  char p_modeStatusSI[BUFLEN];
  long *p_counter;
  short alarmBI;
  short warningBI;

  funcLog( 3, __FILE__ "[%d] --> %s (%s)\n",
                  __LINE__, __func__, p_gensub->name);

  mainStatusLI=*(long *)p_gensub->a;
  translateMainStatus(mainStatusLI,p_mainStatusSI);
  memcpy(p_gensub->vala, p_mainStatusSI, BUFLEN*sizeof(char));

  highVoltageStatusLI=*(long *)p_gensub->b;
  translateHighVoltageStatus(highVoltageStatusLI,p_highVoltageStatusSI);
  memcpy(p_gensub->valb, p_highVoltageStatusSI, BUFLEN*sizeof(char));

  filamentStatusLI=*(long *)p_gensub->c;
  translateFilamentStatus(filamentStatusLI,p_filamentStatusSI);
  memcpy(p_gensub->valc, p_filamentStatusSI, BUFLEN*sizeof(char));

  communicationStatusLI=*(long *)p_gensub->d;
  translateCommunicationStatus(communicationStatusLI,p_communicationStatusSI);
  memcpy(p_gensub->vald, p_communicationStatusSI, BUFLEN*sizeof(char));

  resetStatusLI=*(long *)p_gensub->e;
  translateResetStatus(resetStatusLI,p_resetStatusSI);
  memcpy(p_gensub->vale, p_resetStatusSI, BUFLEN*sizeof(char));

  modeStatusLI=*(long *)p_gensub->f;
  translateModeStatus(modeStatusLI,p_modeStatusSI);
  memcpy(p_gensub->valf, p_modeStatusSI, BUFLEN*sizeof(char));

  alarmBI=0;
  warningBI=0;
  if (mainStatusLI<200) {
   alarmBI=0;
   warningBI=1;
  }
  memcpy(p_gensub->valg, &warningBI, sizeof(short));
  memcpy(p_gensub->valh, &alarmBI, sizeof(short));

  funcLog( 5, __FILE__ "[%d] %s\n", __LINE__, p_gensub->name);
  funcLog( 5, __FILE__ "[%d] mainStatusSI         = >%s< (%d)\n",
                                __LINE__, p_gensub->vala, mainStatusLI);
  funcLog( 5, __FILE__ "[%d] highVoltageStatusSI  = >%s< (%d)\n",
                                __LINE__, p_gensub->valb, highVoltageStatusLI);
  funcLog( 5, __FILE__ "[%d] filamentStatusSI     = >%s< (%d)\n",
                                __LINE__, p_gensub->valc, filamentStatusLI);
  funcLog( 5, __FILE__ "[%d] communicationStatusSI= >%s< (%d)\n",
                                __LINE__, p_gensub->vald, communicationStatusLI);
  funcLog( 5, __FILE__ "[%d] resetStatusSI        = >%s< (%d)\n",
                                __LINE__, p_gensub->vale, resetStatusLI);
  funcLog( 5, __FILE__ "[%d] modeStatusSI         = >%s< (%d)\n",
                                __LINE__, p_gensub->valf, modeStatusLI);
  funcLog( 5, __FILE__ "[%d] warningBI            = %d (%d,%d)\n",
                                __LINE__, *(short *)p_gensub->valg, warningBI, mainStatusLI);
  funcLog( 5, __FILE__ "[%d] alarmBI              = %d (%d,%d)\n",
                                __LINE__, *(short *)p_gensub->valh, alarmBI, mainStatusLI);

  p_counter=(long *)p_gensub->u;
  *p_counter=*p_counter+1;

  funcLog( 3, __FILE__ "[%d] <-- %s (%ld)\n",
                  __LINE__, __func__, *p_counter);

  return(*p_counter);
}

epicsRegisterFunction(SNOVA_funcTranslateStatusCodes);


> Date: Wed, 16 Oct 2013 18:16:44 +0800
> From: marco_hair@163.com
> To: tech-talk@aps.anl.gov
> Subject: how to put value to other record in subroutine record
>
> hi, all:
>
> if I want to change another record's value in a subroutine record's process function, can I call dbPutField() or other functions? can anyone show me some examples?
> thanks a lot in advance.
>
>
> --------------
> Best wishes
> Geyang 2013-10-16
>

Replies:
Re: how to put value to other record in subroutine record Martin L. Smith
References:
how to put value to other record in subroutine record Silver

Navigate by Date:
Prev: Re: How to Read Multiple Values using StreamDevice with array_in Dirk Zimoch
Next: Proper initialisation of Motor Record .RMP value Peter Linardakis
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018 
Navigate by Thread:
Prev: how to put value to other record in subroutine record Silver
Next: Re: how to put value to other record in subroutine record Martin L. Smith
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018 
ANJ, 20 Apr 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·