/*-------------------------------------------------------------------------- P O L T E R W R I T E Polterwrite is an object for writing POLTI data files. copyright: see copyright.h Uwe Filges, November 2001 Various edits, added rotation_speed_targets, Mark Koennecke, 2011 ----------------------------------------------------------------------------*/ #include #include #include #include #include #undef VOID #include "sics.h" #include "event.h" #include "counter.h" #include "HistMem.h" #include "nxdict.h" #include "nxutil.h" #include "motor.h" #include "sicsvar.h" #include "polterwrite.h" #include "sicsvar.h" #include "nxscript.h" #include "sicshipadaba.h" /* diaphragm1 - chopper */ #define DIA1DIST 8000 /* histogram memory name */ #define HM "hm" #define DETRADIUS 3000 typedef struct { pObjectDescriptor pDes; pHistMem pHist; int iNew; time_t tUpdate; int iInterval; int iEnd; SConnection *pCon; char *dictfile; char *pFile; } Polterdi, *pPolterdi; /* ------------------- forward declaration of task function --------------*/ static int PoldiTask(void *pData); static void PoldiUpdate(pPolterdi self, SConnection * pCon); static void PoldiStart(pPolterdi s, SConnection * pCon); static void PoldiLink(pPolterdi s, SConnection * pCon); /*------------------ The Countstart Callback Function ----------------------*/ static int Countstartcallback(int iEvent, void *pEventData, void *pUser) { pPolterdi self = NULL; if (iEvent == COUNTSTART) { self = (pPolterdi) pUser; assert(self); self->iNew = 1; self->iEnd = 0; self->tUpdate = time(NULL); self->pCon = (SConnection *) pEventData; TaskRegisterN(pServ->pTasker,"POLDIUpdater", PoldiTask, NULL, NULL, self, TASK_PRIO_LOW); return 1; } return 1; } /*------------------ The Countend Callback Function ----------------------*/ static int Countendcallback(int iEvent, void *pEventData, void *pUser) { pPolterdi self = NULL; if (iEvent == COUNTEND) { self = (pPolterdi) pUser; assert(self); self->tUpdate = time(NULL); self->iEnd = 1; if (self->iNew == 1) { PoldiStart(self, self->pCon); PoldiLink(self, self->pCon); } else { PoldiUpdate(self, self->pCon); } return 1; } return 1; } /*-----------------------------------------------------------------------*/ static void SNError(void *pData, char *text) { SConnection *pCon; assert(pData); pCon = (SConnection *) pData; SCWrite(pCon, text, eError); } /*-------------------------------------------------------------------*/ static void writePolterdiGlobal(NXhandle hfil, NXdict hdict, SConnection * pCon) { char pBueffel[512]; SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "etitle", "title"); SNXFormatTime(pBueffel, 511); NXDputalias(hfil, hdict, "estart", pBueffel); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "iname", "instrument"); sprintf(pBueffel, "%d", (int) strlen("SINQ, PSI, Switzerland")); NXDupdate(hdict, "strdim", pBueffel); NXDputalias(hfil, hdict, "sname", "SINQ, PSI, Switzerland"); sprintf(pBueffel, "%d", (int) strlen("continous spallation source")); NXDupdate(hdict, "strdim", pBueffel); NXDputalias(hfil, hdict, "stype", "continous spallation source"); NXDupdate(hdict, "strdim", "132"); } /*-------------------------------------------------------------------*/ static void writeChopper(NXhandle hfil, NXdict hdict, SConnection * pCon) { pHdb node = NULL; float fVal; SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "cname", "choppername"); SNXSPutDrivable(pServ->pSics, pCon, hfil, hdict, "chopperspeed", "crot"); SNXSPutDrivable(pServ->pSics, pCon, hfil, hdict, "chopperphase", "cphase"); node = FindHdbNode(NULL,"/sics/choco/chopper/nspee", NULL); if(node != NULL){ fVal = atof(node->value.v.text); NXDputalias(hfil,hdict,"crottarget",&fVal); } } /*-------------------------------------------------------------------*/ static void writeDiaphragm1(NXhandle hfil, NXdict hdict, SConnection * pCon) { float dist; SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia1x", "d1hl"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia1x0", "d1hl"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia1y", "d1hr"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia1y0", "d1hr"); dist = (float) DIA1DIST; NXDputalias(hfil, hdict, "dia1dist", &dist); } /*------------------------------------------------------------------*/ static void writeDiaphragm2(NXhandle hfil, NXdict hdict, SConnection * pCon) { SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia2x_plus", "d2hl"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia2xplus0", "d2hl"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia2x_minus", "d2hr"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia2xminus0", "d2hr"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia2z_plus", "d2vu"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia2zplus0", "d2vu"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia2z_minus", "d2vl"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia2zminus0", "d2vl"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia2z_x", "d2x"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia2z_x0", "d2x"); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "dia2dist", "dia1_dia2"); } /*---------------------------------------------------------------------*/ static void writeCollimator(NXhandle hfil, NXdict hdict, SConnection * pCon) { char pBueffel[50]; SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "cov", "cov"); memset(pBueffel,0,sizeof(pBueffel)); Tcl_Eval(InterpGetTcl(pServ->pSics),"coll"); strncpy(pBueffel,Tcl_GetStringResult(InterpGetTcl(pServ->pSics)), 49); NXDputalias(hfil, hdict, "collpos", pBueffel); } /*--------------------------------------------------------------------*/ static void writeSample(NXhandle hfil, NXdict hdict, SConnection * pCon) { 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 ((pCom = FindCommand(pServ->pSics, "temperature")) != NULL) { SNXSPutDrivable(pServ->pSics, pCon, hfil, hdict, "temperature", "stemp"); } active = FindCommandData(pServ->pSics, "activetable", "SicsVariable"); if (active != NULL) { VarGetInt(active, &iActive); if (iActive == 1) { SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "srsu", "rsu"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "srsu0", "rsu"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "srsl", "rsl"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "srsl0", "rsl"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "srsa", "rsa"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "srsa0", "rsa"); } } SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "sshu", "shu"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "sshu0", "shu"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "sshl", "shl"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "sshl0", "shl"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "ssgu", "sgu"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "ssgu0", "sgu"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "ssgl", "sgl"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "ssgl0", "sgl"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "ssv", "sv"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "ssv0", "sv"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "ssa", "sa"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "ssa0", "sa"); pCom = FindCommand(pServ->pSics,"chi"); if(pCom != NULL){ SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "schi", "chi"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "schi0", "chi"); SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "sphi", "phi"); SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "sphi0", "phi"); } } /*--------------------------------------------------------------------*/ static void PoldiStart(pPolterdi self, SConnection * pCon) { char pBueffel[256]; NXhandle hfil = NULL; NXdict hdict = NULL; int status; const float *fTime = NULL; CounterMode eMode; float *fTime2 = NULL, fTheta0[801], fTheta[801], fVal; pSicsVariable pVar = NULL; float det_radius, det_size, x0det, y0det, twothet; float pi, alpha1, alphasamp, sms, phidetav, phim; float phi2det, val1, val2, nodet, scancheck; int iLength, i, nzell; pMotor sa; HistInt *lData = NULL; long lVal; pCounter pCount; /* create filename */ self->pFile = makeFilename(pServ->pSics, pCon); if (!self->pFile) { SCWrite(pCon, "ERROR: Extra severe: failed to create data file name", eError); return; } /* create a Nexus file */ NXopen(self->pFile, NXACC_CREATE5, &hfil); if (!hfil) { SCWrite(pCon, "ERROR: cannot create data file ", eError); return; } /* tell Uwe User what we are doing */ pVar = NULL; pVar = FindVariable(pServ->pSics, "scancheck"); if (pVar) { VarGetFloat(pVar, &scancheck); } else { SCWrite(pCon, "ERROR: Command not found!", eError); return; } if (scancheck == 0) { snprintf(pBueffel,255, "Writing %s ......", self->pFile); SCWrite(pCon, pBueffel, eLog); } /* write globals */ SNXSPutGlobals(hfil, self->pFile, "POLDI", pCon); /* open nxdict */ status = NXDinitfromfile(self->dictfile, &hdict); if (status != NX_OK) { sprintf(pBueffel, "ERROR: failed to open dictionary file %s", self->dictfile); SCWrite(pCon, pBueffel, eError); SCWrite(pCon, "ERROR: Aborting data file writing", eError); SCWrite(pCon, "ERROR: This is a SERIOUS problem!", eError); SCWrite(pCon, "ERROR: DATA NOT WRITTEN", eError); NXclose(&hfil); return; } writePolterdiGlobal(hfil, hdict, pCon); writeChopper(hfil, hdict, pCon); writeDiaphragm1(hfil, hdict, pCon); writeDiaphragm2(hfil, hdict, pCon); writeCollimator(hfil, hdict, pCon); writeSample(hfil, hdict, pCon); /* write time binning */ fTime = GetHistTimeBin(self->pHist, &iLength); fTime2 = (float *) malloc(iLength * sizeof(float)); if (fTime2) { for (i = 0; i < iLength; i++) { fTime2[i] = fTime[i] / 2.; } if(iLength > 2){ sprintf(pBueffel, "%d", iLength); } else { sprintf(pBueffel, "%d", 1); } NXDupdate(hdict, "timebin", pBueffel); NXDputalias(hfil, hdict, "dtime", fTime2); free(fTime2); } else { SCWrite(pCon, "ERROR: out of memory while writing time binning", eError); } /* theta calculation */ det_radius = (float) DETRADIUS; pVar = FindVariable(pServ->pSics, "det_size"); if (pVar) { VarGetFloat(pVar, &det_size); } else { SCWrite(pCon, "ERROR: Command not found!", eError); return; } pVar = NULL; pVar = FindVariable(pServ->pSics, "nodet"); if (pVar) { VarGetFloat(pVar, &nodet); } else { SCWrite(pCon, "ERROR: Command not found!", eError); return; } pVar = NULL; nzell = (int) nodet; pVar = FindVariable(pServ->pSics, "x0_det"); if (pVar) { VarGetFloat(pVar, &x0det); } else { SCWrite(pCon, "ERROR: Command not found!", eError); return; } pVar = NULL; pVar = FindVariable(pServ->pSics, "y0_det"); if (pVar) { VarGetFloat(pVar, &y0det); } else { SCWrite(pCon, "ERROR: Command not found!", eError); return; } pVar = NULL; pVar = FindVariable(pServ->pSics, "twotheta"); if (pVar) { VarGetFloat(pVar, &twothet); } else { SCWrite(pCon, "ERROR: Command not found!", eError); return; } pi = 3.1415926536; /* transformation to radient */ twothet = twothet * pi / 180; if (x0det < 0) { alpha1 = atan(y0det / x0det); } if (x0det > 0) { alpha1 = pi + atan(y0det / x0det); } alphasamp = pi + alpha1 - twothet; sms = sqrt(x0det * x0det + y0det * y0det); phidetav = pi - alphasamp - asin(sms / det_radius * sin(alphasamp)) + alpha1; phim = atan(y0det / x0det); if (phim < 0) { phim = pi + phim; } for (i = 0; i <= nzell; i++) { phi2det = phidetav + (i - 0.5 * (nzell - 1.0)) * det_size / (det_radius); val1 = det_radius * sin(phi2det) - sms * sin(phim); val2 = det_radius * cos(phi2det) - sms * cos(phim); fTheta0[i] = atan(val1 / val2); if (fTheta0[i] < 0) { fTheta0[i] = pi + fTheta0[i]; } /* transformation to degree */ fTheta0[i] = fTheta0[i] * 180 / pi; } for (i = 0; i <= nzell; i++) { fTheta[i] = fTheta0[nzell - i]; } NXDputalias(hfil, hdict, "dtheta", fTheta); NXDputalias(hfil, hdict, "detector_radius", &det_radius); NXDputalias(hfil, hdict, "cell_size", &det_size); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "ddist", "detectordist"); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "sangle", "scatt_angle"); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "detx0", "x0_det"); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "dety0", "y0_det"); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "theta", "twotheta"); SNXSPutDrivable(pServ->pSics, pCon, hfil, hdict, "cnhepress","he_pressure"); /* write Histogram */ lData = GetHistogramPointer(self->pHist, pCon); if (lData) { NXDputalias(hfil, hdict, "dcounts", lData); } else { SCWrite(pCon, "ERROR: failed to get histogram data", eError); } /* write counting data */ pCount = (pCounter)FindCommandData(pServ->pSics,"counter","SingleCounter"); if(pCount){ fVal = GetCountTime(pCount, pCon); NXDputalias(hfil, hdict, "cntime", &fVal); lVal = GetMonitor(pCount, 1, pCon); NXDputalias(hfil, hdict, "cnmon1", &lVal); lVal = GetMonitor(pCount, 2, pCon); NXDputalias(hfil, hdict, "cnmon3", &lVal); lVal = GetMonitor(pCount, 3, pCon); NXDputalias(hfil, hdict, "cnmon4", &lVal); eMode = GetCounterMode(pCount); if (eMode == eTimer) { strcpy(pBueffel, "timer"); } else { strcpy(pBueffel, "monitor"); } NXDputalias(hfil, hdict, "cnmode", pBueffel); fVal = GetCounterPreset(pCount); NXDputalias(hfil, hdict, "cnpreset", &fVal); } else { SCWrite(pCon,"ERROR: counter not found writing data file", eLogError); } /* close everything */ NXclose(&hfil); NXDclose(hdict, NULL); self->iNew = 0; } /*---------------------------------------------------------------------------*/ static void PoldiUpdate(pPolterdi self, SConnection * pCon) { char pBueffel[256]; NXhandle hfil = NULL; NXdict hdict = NULL; int status; const float *fTime = NULL; CounterMode eMode; float *fTime2 = NULL, fTheta[801], fVal; pSicsVariable pVar = NULL; float det_radius, det_size, x0det, y0det, twothet; float pi, alpha1, alphasamp, sms, phidetav, phim; float phi2det, val1, val2, nodet, scancheck; int iLength, i, nzell; pMotor sa; HistInt *lData = NULL; long lVal; time_t zeit; pCounter pCount = NULL; /* open everything again */ status = NXopen(self->pFile, NXACC_RDWR, &hfil); if (status != NX_OK) { SCWrite(pCon, "ERROR: cannot reopen data file ", eError); return; } status = NXDinitfromfile(self->dictfile, &hdict); if (status != NX_OK) { sprintf(pBueffel, "ERROR: failed to open dictionary file %s", self->dictfile); SCWrite(pCon, pBueffel, eError); SCWrite(pCon, "ERROR: Aborting data file writing", eError); SCWrite(pCon, "ERROR: This is a SERIOUS problem!", eError); SCWrite(pCon, "ERROR: DATA NOT WRITTEN", eError); NXclose(&hfil); return; } /* tell the user that something is happening */ pVar = NULL; pVar = FindVariable(pServ->pSics, "scancheck"); if (pVar) { VarGetFloat(pVar, &scancheck); } else { SCWrite(pCon, "ERROR: Command not found!", eError); return; } if (scancheck == 0) { time(&zeit); snprintf(pBueffel,255, "Updating %s on %s ", self->pFile, asctime(localtime(&zeit))); SCWrite(pCon, pBueffel, eWarning); } SNXFormatTime(pBueffel, sizeof(pBueffel)); NXDputalias(hfil, hdict, "eend", pBueffel); /* write time binning */ /* fTime = GetHistTimeBin(self->pHist, &iLength); fTime2 = (float *) malloc(iLength * sizeof(float)); if (fTime2) { for (i = 0; i < iLength; i++) { fTime2[i] = fTime[i] / 2.; } sprintf(pBueffel, "%d", iLength); NXDupdate(hdict, "timebin", pBueffel); NXDputalias(hfil, hdict, "dtime", fTime2); free(fTime2); } else { SCWrite(pCon, "ERROR: out of memory while writing time binning", eError); } */ /* write Histogram */ lData = GetHistogramPointer(self->pHist, pCon); if (lData) { NXDputalias(hfil, hdict, "dcounts", lData); } else { SCWrite(pCon, "ERROR: failed to get histogram data", eError); } /* write counting data */ pCount = (pCounter)FindCommandData(pServ->pSics,"counter","SingleCounter"); if(pCount){ fVal = GetCountTime(pCount, pCon); NXDputalias(hfil, hdict, "cntime", &fVal); lVal = GetMonitor(pCount, 1, pCon); NXDputalias(hfil, hdict, "cnmon1", &lVal); lVal = GetMonitor(pCount, 4, pCon); NXDputalias(hfil, hdict, "cnprot", &lVal); lVal = GetMonitor(pCount, 2, pCon); NXDputalias(hfil, hdict, "cnmon3", &lVal); lVal = GetMonitor(pCount, 3, pCon); NXDputalias(hfil, hdict, "cnmon4", &lVal); eMode = GetCounterMode(pCount); if (eMode == eTimer) { strcpy(pBueffel, "timer"); } else { strcpy(pBueffel, "monitor"); } NXDputalias(hfil, hdict, "cnmode", pBueffel); fVal = GetCounterPreset(pCount); NXDputalias(hfil, hdict, "cnpreset", &fVal); } else { SCWrite(pCon,"ERROR: counter not found writing data file", eLogError); } /* close everything */ NXclose(&hfil); NXDclose(hdict, NULL); } /*------------------------------------------------------------------------- FoLink sets all the links for the NXdata vGroup. Had to be separate because at least one update is necessary before this can be done. -------------------------------------------------------------------------*/ static void PoldiLink(pPolterdi self, SConnection * pCon) { NXhandle hfil = NULL; NXdict hdict = NULL; int status; char pBueffel[512]; /* open everything again */ NXopen(self->pFile, NXACC_RDWR, &hfil); if (!self->pFile) { SCWrite(pCon, "ERROR: cannot reopen data file ", eError); return; } status = NXDinitfromfile(self->dictfile, &hdict); if (status != NX_OK) { sprintf(pBueffel, "ERROR: failed to open dictionary file %s", self->dictfile); SCWrite(pCon, pBueffel, eError); SCWrite(pCon, "ERROR: Aborting data file writing", eError); SCWrite(pCon, "ERROR: This is a SERIOUS problem!", eError); SCWrite(pCon, "ERROR: DATA NOT WRITTEN", eError); NXclose(&hfil); return; } NXDaliaslink(hfil, hdict, "dana", "dcounts"); NXDaliaslink(hfil, hdict, "dana", "dtheta"); NXDaliaslink(hfil, hdict, "dana", "dtime"); /* close everything */ NXclose(&hfil); NXDclose(hdict, NULL); } /*--------------------------------------------------------------------------- This is the task function for updating the data file any now and then automatically --------------------------------------------------------------------------*/ static int PoldiTask(void *pData) { pPolterdi self = NULL; int iWrite, iRet, ltask; self = (pPolterdi) pData; if (!self) return 0; /* figure out if we need to write */ iWrite = 0; iRet = 1; /* first case: update intervall */ if (time(NULL) >= self->tUpdate) { ltask = GetDevexecID(pServ->pExecutor); if (ltask > 0) { self->tUpdate = time(NULL) + self->iInterval; iWrite = 1; iRet = 1; } else { self->iEnd = 1; } } if (self->iEnd == 1) { self->tUpdate = 0; iWrite = 0; iRet = 0; } if (iWrite) { if (self->iNew) { PoldiStart(self, self->pCon); PoldiUpdate(self, self->pCon); PoldiLink(self, self->pCon); } else { PoldiUpdate(self, self->pCon); } } return iRet; } /*----------------------------------------------------------------------*/ static void KillPolterdi(void *pData) { pPolterdi self = (pPolterdi) pData; if (!self) return; if (self->pDes) { DeleteDescriptor(self->pDes); } if (self->pFile) { free(self->pFile); } if (self->dictfile) { free(self->dictfile); } free(self); } /*-----------------------------------------------------------------------*/ int PolterInstall(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) { pPolterdi pNew = NULL; pICallBack pCall = NULL; pDummy pDum; pHistMem pHist = NULL; commandContext comCon; /* configure fortify */ /* iFortifyScope = Fortify_EnterScope(); Fortify_CheckAllMemory(); */ if (argc < 2) { SCWrite(pCon, "ERROR: insufficient number of arguments to PolterInstall", eError); return 0; } pHist = (pHistMem) FindCommandData(pSics, HM, "HistMem"); if (!pHist) { SCWrite(pCon, "ERROR: Histogram memory NOT found", eError); return 0; } pNew = (pPolterdi) malloc(sizeof(Polterdi)); if (!pNew) { SCWrite(pCon, "ERROR: out of memory in PolterInstall", eError); return 0; } memset(pNew, 0, sizeof(Polterdi)); pNew->pDes = CreateDescriptor("PoldiWrite"); pNew->pHist = pHist; pNew->dictfile = strdup(argv[1]); pNew->iInterval = 20 * 60; if (!pNew->pDes || !pNew->dictfile) { SCWrite(pCon, "ERROR: out of memory in PolterInstall", eError); return 0; } /* install callbacks */ pDum = (pDummy) pHist; pCall = (pICallBack) pDum->pDescriptor->GetInterface(pHist, CALLBACKINTERFACE); if (!pCall) { SCWrite(pCon, "ERROR: no callback interface found at your histogram memory", eError); KillPolterdi(pNew); return 0; } strlcpy(comCon.deviceID, "internal", SCDEVIDLEN); RegisterCallback(pCall, COUNTSTART, Countstartcallback, pNew, NULL); RegisterCallback(pCall, COUNTEND, Countendcallback, pNew, NULL); AddCommand(pSics, "storedata", PolterAction, KillPolterdi, pNew); return 1; } /*----------------------------------------------------------------------*/ int PolterAction(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) { int iRet, iVal; pPolterdi self = NULL; char pBueffel[512]; if (argc < 2) { SCWrite(pCon, "ERROR: Insufficient number of arguments to StoreData", eError); return 0; } self = (pPolterdi) pData; assert(self); strtolower(argv[1]); if (strcmp(argv[1], "start") == 0) { PoldiStart(self, pCon); PoldiUpdate(self, pCon); PoldiLink(self, pCon); return 1; } else if (strcmp(argv[1], "update") == 0) { if ((self->iNew) || (!self->pFile)) { PoldiStart(self, pCon); PoldiUpdate(self, pCon); PoldiLink(self, pCon); } else { PoldiUpdate(self, pCon); } return 1; } else if (strcmp(argv[1], "getfile") == 0) { snprintf(pBueffel,511, "StoreData.file = %s", self->pFile); SCWrite(pCon, pBueffel, eValue); return 1; } else if (strcmp(argv[1], "interval") == 0) { if (argc > 2) { /* set value */ if (!SCMatchRights(pCon, usUser)) { return 0; } iRet = Tcl_GetInt(pSics->pTcl, argv[2], &iVal); if (iRet != TCL_OK) { snprintf(pBueffel,511, "ERROR: cannot convert --> %s <-- to number ", argv[2]); SCWrite(pCon, pBueffel, eError); return 0; } self->iInterval = iVal * 60; /* go to seconds from minutes */ SCSendOK(pCon); return 1; } else { /* read the value */ sprintf(pBueffel, "storedata.interval = %d", self->iInterval / 60); SCWrite(pCon, pBueffel, eValue); return 1; } } SCWrite(pCon, "ERROR: subcommand to StoreData not recognized", eError); return 0; }