a connection during an active run. - Added an additional output mode for the connection in order to support the batch run editor. - Made clientput send everything with eWarning mode in order to support the batch run editor. - Added a better NetReadTillTerm - Fixed a problem in synchronize.c - Fixed an issue with reading empty line on normal connection sockets. - Added a psi scan mode to mesure.c for TRICS - Made motor print warnings when trying to reposition. - Fixed abug in hkl.c which cause wrong signs. SKIPPED: psi/el734driv.c psi/el734hp.c psi/el737driv.c psi/el737hpdriv.c psi/nextrics.c psi/nxamor.c psi/psi.c psi/slsmagnet.c psi/swmotor2.c psi/tasscan.c psi/tasutil.c
290 lines
7.8 KiB
C
290 lines
7.8 KiB
C
/*-----------------------------------------------------------------------
|
|
Automatic update of NeXus files a scheduled time intervalls.
|
|
For more information see nxudpate.tex.
|
|
|
|
copyright: see file COPYRIGHT
|
|
|
|
Mark Koennecke, December 2003
|
|
----------------------------------------------------------------------*/
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "splitter.h"
|
|
#include "nxupdate.h"
|
|
#include "nxupdate.i"
|
|
/*-------------------------------------------------------------------*/
|
|
static int UpdateTask(void *pData){
|
|
pNXupdate self = NULL;
|
|
|
|
self = (pNXupdate)pData;
|
|
if(self == NULL){
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
update when intervall reached or when end
|
|
*/
|
|
if(time(NULL) >= self->nextUpdate || self->iEnd == 1){
|
|
if(self->updateScript != NULL && self->pCon != NULL){
|
|
InterpExecute(pServ->pSics,self->pCon,self->updateScript);
|
|
}
|
|
self->nextUpdate = time(NULL) + self->updateIntervall;
|
|
}
|
|
|
|
if(self->iEnd == 1){
|
|
self->pCon = NULL;
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static int CountCallback(int iEvent, void *pEventData, void *pUser){
|
|
pNXupdate self = NULL;
|
|
SConnection *pCon = NULL;
|
|
|
|
self = (pNXupdate)pUser;
|
|
pCon = (SConnection *)pEventData;
|
|
if(iEvent == COUNTSTART){
|
|
assert(pCon);
|
|
assert(self);
|
|
/*
|
|
start file
|
|
*/
|
|
if(self->startScript != NULL){
|
|
InterpExecute(pServ->pSics,pCon,self->startScript);
|
|
}
|
|
if(self->updateScript != NULL){
|
|
InterpExecute(pServ->pSics,pCon,self->updateScript);
|
|
}
|
|
if(self->linkScript != NULL){
|
|
InterpExecute(pServ->pSics,pCon,self->linkScript);
|
|
}
|
|
/*
|
|
register update function
|
|
*/
|
|
self->nextUpdate = time(NULL) + self->updateIntervall;
|
|
self->iEnd = 0;
|
|
self->pCon = pCon;
|
|
TaskRegister(pServ->pTasker,UpdateTask,NULL,NULL,self,1);
|
|
return 1;
|
|
} else if(iEvent == COUNTEND){
|
|
self->iEnd = 1;
|
|
assert(self);
|
|
return 1;
|
|
}
|
|
return 1;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
void KillUpdate(void *pData){
|
|
pNXupdate self = NULL;
|
|
|
|
self = (pNXupdate)pData;
|
|
if(self == NULL){
|
|
return;
|
|
}
|
|
|
|
if(self->startScript != NULL){
|
|
free(self->startScript);
|
|
self->startScript = NULL;
|
|
}
|
|
if(self->updateScript != NULL){
|
|
free(self->updateScript);
|
|
self->updateScript = NULL;
|
|
}
|
|
if(self->linkScript != NULL){
|
|
free(self->linkScript);
|
|
self->linkScript = NULL;
|
|
}
|
|
free(self);
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
static void printUpdateList(SConnection *pCon, pNXupdate self, char *name){
|
|
char pBueffel[256];
|
|
|
|
snprintf(pBueffel,255,"%s.startScript = %s",name, self->startScript);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
snprintf(pBueffel,255,"%s.updateScript = %s",name, self->updateScript);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
snprintf(pBueffel,255,"%s.linkScript = %s",name, self->linkScript);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
snprintf(pBueffel,255,"%s.updateIntervall = %d",name,
|
|
self->updateIntervall);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static int printUpdateParameters(SConnection *pCon, pNXupdate self,
|
|
char *name, char *param){
|
|
char pBueffel[256];
|
|
if(strcmp(param,"list") == 0){
|
|
printUpdateList(pCon,self, name);
|
|
return 1;
|
|
} else if(strcmp(param,"startscript") == 0){
|
|
snprintf(pBueffel,255,"%s.startScript = %s",name, self->startScript);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
} else if(strcmp(param,"updatescript")== 0){
|
|
snprintf(pBueffel,255,"%s.updateScript = %s",name, self->updateScript);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
} else if(strcmp(param,"linkscript") == 0){
|
|
snprintf(pBueffel,255,"%s.linkScript = %s",name, self->linkScript);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
} else if(strcmp(param,"updateintervall") == 0){
|
|
snprintf(pBueffel,255,"%s.updateIntervall = %d",name,
|
|
self->updateIntervall);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
} else {
|
|
snprintf(pBueffel,255,"ERROR: parameter %s not known", param);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 0;
|
|
}
|
|
}
|
|
/*---------------------------------------------------------------------*/
|
|
static int configureUpdate(SConnection *pCon, pNXupdate self,
|
|
char *param, char *value){
|
|
char pBueffel[256];
|
|
int newUpdate;
|
|
|
|
if(strcmp(param,"startscript") == 0){
|
|
if(self->startScript != NULL){
|
|
free(self->startScript);
|
|
}
|
|
self->startScript = strdup(value);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if(strcmp(param,"updatescript")== 0){
|
|
if(self->updateScript != NULL){
|
|
free(self->updateScript);
|
|
}
|
|
self->updateScript = strdup(value);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if(strcmp(param,"linkscript") == 0){
|
|
if(self->linkScript != NULL){
|
|
free(self->linkScript);
|
|
}
|
|
self->linkScript = strdup(value);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if(strcmp(param,"updateintervall") == 0){
|
|
if(Tcl_GetInt(InterpGetTcl(pServ->pSics),value,&newUpdate) != TCL_OK){
|
|
snprintf(pBueffel,255,
|
|
"ERROR: %s not an int, cannot set updateIntervall", value);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
self->updateIntervall = newUpdate;
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else {
|
|
snprintf(pBueffel,255,"ERROR: parameter %s not known", param);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 0;
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
int UpdateAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]){
|
|
pNXupdate self = NULL;
|
|
char pBueffel[132];
|
|
|
|
self = (pNXupdate)pData;
|
|
assert(self);
|
|
|
|
if(argc < 2){
|
|
snprintf(pBueffel,131,"ERROR: need argument to %s", argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
|
|
if(argc < 3){
|
|
strtolower(argv[1]);
|
|
return printUpdateParameters(pCon,self,argv[0], argv[1]);
|
|
} else {
|
|
Arg2Text(argc-2,&argv[2],pBueffel,131);
|
|
return configureUpdate(pCon,self,argv[1],pBueffel);
|
|
}
|
|
|
|
/*
|
|
not reached
|
|
*/
|
|
assert(0);
|
|
return 0;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
int UpdateFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]){
|
|
pICountable pCount = NULL;
|
|
pICallBack pCall = NULL;
|
|
void *pPtr = NULL;
|
|
char pBueffel[256];
|
|
pNXupdate self = NULL;
|
|
CommandList *pCom = NULL;
|
|
|
|
if(argc < 3){
|
|
SCWrite(pCon,"ERROR: insuffcient number of argument to UpdateFactory",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
argv[1] = name
|
|
argv[2] = counter with which to register for automatic notifications
|
|
*/
|
|
pCom = FindCommand(pSics,argv[2]);
|
|
if(pCom){
|
|
pPtr = pCom->pData;
|
|
}
|
|
if(!pPtr){
|
|
snprintf(pBueffel,255,"ERROR: cannot find %s to register to", argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
pCount = GetCountableInterface(pPtr);
|
|
pCall = GetCallbackInterface(pPtr);
|
|
if(!pCount || !pCall){
|
|
snprintf(pBueffel,255,"ERROR: %s is not a usable counter",argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
allocate memory and initialize
|
|
*/
|
|
self = (pNXupdate)malloc(sizeof(NXupdate));
|
|
if(self == NULL){
|
|
SCWrite(pCon,"ERROR: out of memory in UpdateFactory",eError);
|
|
return 0;
|
|
}
|
|
memset(self,0,sizeof(NXupdate));
|
|
self->pDes = CreateDescriptor("AutoUpdate");
|
|
if(self->pDes == NULL){
|
|
SCWrite(pCon,"ERROR: out of memory in UpdateFactory",eError);
|
|
return 0;
|
|
}
|
|
self->startScript = strdup("UNDEFINED");
|
|
self->updateScript = strdup("UNDEFINED");
|
|
self->linkScript = strdup("UNDEFINED");
|
|
self->updateIntervall = 1200; /* 20 min */
|
|
|
|
|
|
/*
|
|
register callbacks
|
|
*/
|
|
RegisterCallback(pCall,COUNTSTART,CountCallback,
|
|
self,NULL);
|
|
RegisterCallback(pCall,COUNTEND,CountCallback,
|
|
self,NULL);
|
|
|
|
AddCommand(pSics,argv[1],UpdateAction,KillUpdate,self);
|
|
return 1;
|
|
}
|
|
|
|
|
|
|