From 99f545e67fc1c6b5e98e8dcb6b2d34950031d69d Mon Sep 17 00:00:00 2001 From: koennecke Date: Wed, 19 Dec 2007 09:55:13 +0000 Subject: [PATCH] - Added delcam driver - Fixed temperature writing at POLDI - Added support for the HRPT tempoerature surveillance device --- delcam.c | 7 +- lmd200.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++ polterwrite.c | 5 +- 3 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 lmd200.c diff --git a/delcam.c b/delcam.c index e07a03d..fae3550 100644 --- a/delcam.c +++ b/delcam.c @@ -235,10 +235,13 @@ static int DelcamCountStatus(pHistDriver self,SConnection *pCon){ status = pPriv->count->pDriv->GetStatus(pPriv->count->pDriv,&val); if(status == HWNoBeam) { - SCWrite(pCon,"ERROR: NO BEAM, aborting CCD measurement",eError); + /* + SCWrite(pCon,"WARNING: NO BEAM, during CCD measurement",eWarning); DelcamHalt(self); pPriv->error = NOBEAM; - status = HWFault; + status = HWFault; + */ + return HWBusy; } if(status != HWBusy && pPriv->running == 1) { pPriv->running = 0; diff --git a/lmd200.c b/lmd200.c new file mode 100644 index 0000000..1b86ffd --- /dev/null +++ b/lmd200.c @@ -0,0 +1,202 @@ +/** + * This is a module to manage the LMD-400 device used to monitor HRPT detector + * electronics temperatures and pressures. It is read only. The device sends + * alarm messages or temperature readings any now and then asynchronously. The + * format of the messages is: + * - Alarm message: date time device type of alarm + * - Data message: 3 lines + * --- date time + * --- 001..008 val val val .... + * --- 009..016 val val .... + * Please note that the values use a komma as the decimal separator and not a . + * + * copyright: see file COPYRIGHT + * + * Mark Koennecke, October 2007 + */ + #include + #include + #include + #include + #include + #include + #include +/* + * possible states + */ +#define IDLE 0 +#define WAITDATA1 1 +#define WAITDATA2 2 + /* + * private data structure + */ +#define BUFLEN 1024 + typedef struct { + int state; + char host[256]; + int port; + mkChannel *pSock; + pNWContext watchContext; + char lineBuffer[BUFLEN]; + } LMD200, *pLMD200; + /*----------------------------------------------------------------------------*/ + static void killLMD200(void *data){ + pLMD200 priv = (pLMD200)data; + if(priv == NULL){ + return; + } + if(priv->watchContext != NULL){ + NetWatchRemoveCallback(priv->watchContext); + } + if(priv->pSock != NULL){ + NETClosePort(priv->pSock); + free(priv->pSock); + } + free(priv); + } +/*--------------------------------------------------------------------------*/ +static void doAlarm(pSICSOBJ self, char *lineBuffer){ + hdbValue alarmVal; + pHdb node = NULL; + + alarmVal = MakeHdbText(lineBuffer); + node = GetHipadabaNode(self->objectNode,"alarm"); + assert(node != NULL); + UpdateHipadabaPar(node,alarmVal, NULL); + WriteToCommandLog("CERCA>> ", lineBuffer); + ServerWriteGlobal(lineBuffer,eError); +} +/*--------------------------------------------------------------------------*/ +extern char *trim(char *); + +static void storeData(pSICSOBJ self, int start, char *lineBuffer){ + pHdb node = NULL; + char number[80], *pPtr = NULL, *pKomma; + + node = GetHipadabaNode(self->objectNode,"data"); + assert(node != NULL); + /* + * throw first away + */ + pPtr = stptok(lineBuffer,number,80," "); + pPtr = stptok(pPtr,number,80," "); + while(pPtr != NULL){ + if(strstr(number,"noinp") != NULL){ + node->value.v.floatArray[start] = -9999.99; + start++; + } else { + pKomma = strchr(number,','); + if(pKomma != NULL){ + *pKomma = '.'; + } + node->value.v.floatArray[start] = atof(trim(number)); + start++; + } + pPtr = stptok(pPtr,number,80," "); + } + } +/*--------------------------------------------------------------------------*/ +static int countTokens(char *lineBuffer){ + int count = 0; + char myBuffer[BUFLEN]; + char *pPtr = NULL; + + memset(myBuffer,0,BUFLEN); + strcpy(myBuffer, lineBuffer); + pPtr = myBuffer; + while(pPtr != NULL){ + count++; + pPtr = strtok(pPtr," "); + } + return count; +} +/*--------------------------------------------------------------------------*/ +static void interpretLine(pSICSOBJ self, pLMD200 priv){ + switch(priv->state){ + case IDLE: + if(countTokens(priv->lineBuffer) == 2){ + priv->state = WAITDATA1; + return; + } else { + doAlarm(self, priv->lineBuffer); + return; + } + break; + case WAITDATA1: + storeData(self, 0, priv->lineBuffer); + priv->state = WAITDATA2; + break; + case WAITDATA2: + storeData(self, 8, priv->lineBuffer); + priv->state = IDLE; + break; + } +} +/*--------------------------------------------------------------------------- + * This handles the terminator discovery and causes the evaluation of complete + * lines. + * --------------------------------------------------------------------------*/ +static int LMD200Callback(void *context, int mode){ + pSICSOBJ self = (pSICSOBJ)context; + pLMD200 priv = NULL; + char buffer[512], *pPtr = NULL; + + assert(self != NULL); + priv = (pLMD200)self->pPrivate; + if(mode == nwatch_read){ + memset(buffer,0,512); + NETRead(priv->pSock, buffer, 512, 0); + pPtr = strchr(buffer,'\n'); + if(pPtr != NULL){ + *pPtr = '\0'; + strncat(priv->lineBuffer,buffer,BUFLEN); + interpretLine(self, priv); + priv->lineBuffer[0] = '\0'; + pPtr++; + strncpy(priv->lineBuffer,pPtr,BUFLEN); + } else { + strncat(priv->lineBuffer,buffer,BUFLEN); + } + } + return 1; +} + /*---------------------------------------------------------------------------*/ +int MakeLMD200(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]){ + pSICSOBJ self = NULL; + pLMD200 priv = NULL; + hdbValue dataValue, textValue; + + if(argc < 5){ + SCWrite(pCon, + "ERROR: require name class host and port parameter for initialization", + eError); + return 0; + } + priv = (pLMD200)malloc(sizeof(LMD200)); + memset(priv,0,sizeof(LMD200)); + strncpy(priv->host,argv[3], 256); + priv->port = atoi(argv[4]); + priv->pSock = NETConnect(priv->host,priv->port); + if(priv->pSock == NULL){ + SCWrite(pCon,"ERROR: failed to connect to LMD200",eError); + killLMD200(priv); + return 0; + } + + self = SetupSICSOBJ(pCon,pSics, pData,argc, argv); + if(self == NULL || priv == NULL){ + return 0; + } + textValue = MakeHdbText("I do not feel very alarmed"); + dataValue = makeHdbValue(HIPFLOATAR,16); + AddSICSHdbPar(self->objectNode,"alarm", usInternal,textValue); + AddSICSHdbPar(self->objectNode,"data", usInternal,dataValue); + self->pPrivate = priv; + self->KillPrivate = killLMD200; + ReleaseHdbValue(&dataValue); + ReleaseHdbValue(&textValue); + NetWatchRegisterCallback(&priv->watchContext, priv->pSock->sockid, + LMD200Callback, self); + return 1; +} diff --git a/polterwrite.c b/polterwrite.c index 9df533c..b052498 100644 --- a/polterwrite.c +++ b/polterwrite.c @@ -157,15 +157,16 @@ static void writeSample(NXhandle hfil, NXdict hdict, { pSicsVariable active = NULL; int iActive; + CommandList *pCom = NULL; SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"sdist","dia2_sample"); SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"chopperdist","chopper_sample"); SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"saname","sample"); SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"senvir","environment"); - if(FindCommandData(pServ->pSics,"temperature","Environment Controller") + if((pCom = FindCommand(pServ->pSics,"temperature")) != NULL){ - SNXSPutEVVar(hfil,hdict,"temperature",pCon,"stemp","stddev"); + SNXSPutDrivable(pServ->pSics,pCon, hfil, hdict, "temperature","stemp"); } active = FindCommandData(pServ->pSics,"activetable","SicsVariable"); if(active != NULL){