Files
sicspsi/polterwrite.c

841 lines
24 KiB
C

/*--------------------------------------------------------------------------
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 <stdlib.h>
#include <assert.h>
#include <math.h>
#include <time.h>
#include <tcl.h>
#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;
}