- extended evcontroller
- remote objects - new ev drivers for oxford IPS,ITC,ILM and LC M.Z.
This commit is contained in:
137
eve.h
Normal file
137
eve.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
eve.h
|
||||||
|
|
||||||
|
extended environment controller utilities
|
||||||
|
|
||||||
|
Markus Zolliker, Sept 2004
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef EVE_H
|
||||||
|
#define EVE_H
|
||||||
|
|
||||||
|
#include "fsm.h"
|
||||||
|
#include "evcontroller.h"
|
||||||
|
#include "rs232controller.h"
|
||||||
|
|
||||||
|
typedef enum { idleState, readState, expectState, lostState } EveState;
|
||||||
|
|
||||||
|
typedef struct EveParArg EveParArg;
|
||||||
|
typedef struct EvePar EvePar;
|
||||||
|
|
||||||
|
/* the parameter definition function may call any parameter function (see below) */
|
||||||
|
typedef void (*EveParDef)(void *private, EveParArg *arg);
|
||||||
|
|
||||||
|
typedef int (*EveSubCmd)(SConnection *pCon, pEVControl evc, int argc, char *argv[]);
|
||||||
|
|
||||||
|
/* Eve must always be the first member of the EVCs private struct */
|
||||||
|
|
||||||
|
typedef struct Eve {
|
||||||
|
EveParDef pardef;
|
||||||
|
rs232 *ser;
|
||||||
|
Fsm *task; /* a pointer to the task */
|
||||||
|
FsmFunc todo;
|
||||||
|
FsmFunc run;
|
||||||
|
FsmFunc read;
|
||||||
|
int hwstate;
|
||||||
|
pEVControl evc;
|
||||||
|
int errCode; /* error code of last operation. not changed on success */
|
||||||
|
int verbose;
|
||||||
|
EveState state;
|
||||||
|
time_t cmdtime;
|
||||||
|
float value;
|
||||||
|
int lost;
|
||||||
|
int syntax; /* not used in Eve, may be used by the driver. used by OiConn */
|
||||||
|
char cmd[32];
|
||||||
|
char ans[64];
|
||||||
|
char version[64];
|
||||||
|
int (*checkStatus)(void *self, SConnection *pCon); /* original CheckStatus function */
|
||||||
|
EvePar *par;
|
||||||
|
int npar;
|
||||||
|
time_t logtime;
|
||||||
|
int period;
|
||||||
|
char errMsg[128];
|
||||||
|
} Eve;
|
||||||
|
|
||||||
|
#define EVE_ACTPAR 1
|
||||||
|
#define EVE_LOGPAR 2
|
||||||
|
#define EVE_SAVEPAR 4
|
||||||
|
|
||||||
|
/* parameter functions (pfs)
|
||||||
|
* -------------------------
|
||||||
|
* there are some restrictions:
|
||||||
|
*
|
||||||
|
* - pfs may only be called from within the pardef function
|
||||||
|
* - the order and number of pfs must not change at runtime
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
*
|
||||||
|
* arg: just the arg Argument in pardef
|
||||||
|
* name: parameter name, must be static and never changed
|
||||||
|
* (usually a string literal)
|
||||||
|
* value: a pointer to the corr. member of the drivers private struct
|
||||||
|
* fmt: a format. if it contains a blank, the content after the blank is
|
||||||
|
* skipped when not listing
|
||||||
|
* access: a SICS access mode (usInternal, usMugger, usUser, usSpy)
|
||||||
|
* flags: the sum of some flags values:
|
||||||
|
* EVE_ACTPAR: parameter is active
|
||||||
|
* EVE_LOGPAR: parameter is logged by default
|
||||||
|
* EVE_SAVEPAR: parameter is saved on sics exit
|
||||||
|
* maxsize: the maximum size of a fixed size string, or 0 for a dynamic string
|
||||||
|
* index: the ObPar index
|
||||||
|
* list: a NULL terminated list of value names
|
||||||
|
* subcmd: a function for handling the subcommand
|
||||||
|
*/
|
||||||
|
void EveFloatPar(EveParArg *arg, char *name, float *value, char *fmt,
|
||||||
|
int access, int flags);
|
||||||
|
void EveIntPar(EveParArg *arg, char *name, int *value,
|
||||||
|
int access, int flags);
|
||||||
|
void EveStrPar(EveParArg *arg, char *name, char **value, int maxsize,
|
||||||
|
int access, int flags);
|
||||||
|
void EveObPar(EveParArg *arg, int index, char *fmt, int flags);
|
||||||
|
void EveObParEnum(EveParArg *arg, int index, char *list[], int flags);
|
||||||
|
void EveEnumPar(EveParArg *arg, char *name, int *value, char *list[],
|
||||||
|
int access, int flags);
|
||||||
|
void EveCmd(EveParArg *arg, char *name, EveSubCmd subcmd, int access);
|
||||||
|
|
||||||
|
/* a collection of parameters from the standard EVController
|
||||||
|
* (limits, tolerance, drive handling, out of tolerance handling)
|
||||||
|
* normally appearing at the top
|
||||||
|
*/
|
||||||
|
void EveStdPar(EveParArg *arg);
|
||||||
|
|
||||||
|
/* some even more standard values (should always be used)
|
||||||
|
* appearing at the end of the list
|
||||||
|
*/
|
||||||
|
void EveStdParEnd(EveParArg *arg, char *fmt, int targetFlag);
|
||||||
|
|
||||||
|
/* return the connection related to the parameter request */
|
||||||
|
SConnection *EveArgConn(EveParArg *arg);
|
||||||
|
|
||||||
|
/* write to the actual (last driving) connection */
|
||||||
|
int EvePrintf(Eve *eve, int iOut, char *fmt, ...);
|
||||||
|
|
||||||
|
void EveWriteError(Eve *eve);
|
||||||
|
void EveWrite(Eve *eve, char *cmd);
|
||||||
|
void EveWaitRead(Eve *eve);
|
||||||
|
int EveHandler(Eve *eve);
|
||||||
|
int EveIdle(long pc, Eve *eve);
|
||||||
|
int EveRun(pEVDriver driver, float fVal);
|
||||||
|
int EveSend(pEVDriver driver, char *pCommand, char *pReply, int iLen);
|
||||||
|
int EveCheckStatus(void *evcVoid, SConnection *pCon);
|
||||||
|
EVMode EveGetMode(void *data);
|
||||||
|
int EveClose(pEVDriver driver);
|
||||||
|
int EveAlwaysOk(void *data);
|
||||||
|
int EveDontFix(pEVDriver driver, int iError);
|
||||||
|
void EveKill(void *pData);
|
||||||
|
int EveGetError(pEVDriver driver, int *iCode, char *error, int iErrLen);
|
||||||
|
int EveInit(pEVDriver driver);
|
||||||
|
pEVDriver MakeEveDriver(int argc, char *argv[], Eve *eve, SConnection *pCon);
|
||||||
|
int EveWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
pEVControl MakeEveEVC(int argc, char *argv[], Eve *eve, SConnection *pCon);
|
||||||
|
|
||||||
|
#define EVE_ILL_ANS -3000
|
||||||
|
#define EVE_FAULT -3001
|
||||||
|
#define EVE_DEV_CHANGED -3002
|
||||||
|
|
||||||
|
#endif
|
117
fsm.c
Normal file
117
fsm.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
fsm.c
|
||||||
|
|
||||||
|
a finite state machine within sics
|
||||||
|
|
||||||
|
M. Zolliker, Aug 2004
|
||||||
|
---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "fsm.h"
|
||||||
|
|
||||||
|
#define MAXSTACK 8
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
long pc;
|
||||||
|
FsmFunc func;
|
||||||
|
} StackItem;
|
||||||
|
|
||||||
|
struct Fsm {
|
||||||
|
void *obj;
|
||||||
|
FsmHandler handler;
|
||||||
|
long pc;
|
||||||
|
FsmFunc func;
|
||||||
|
time_t till;
|
||||||
|
int pause;
|
||||||
|
int sp;
|
||||||
|
StackItem stack[MAXSTACK];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static Fsm *fsm = NULL;
|
||||||
|
|
||||||
|
void FsmWait(long delay) {
|
||||||
|
assert(fsm);
|
||||||
|
fsm->till = time(NULL) + delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FsmTaskHandler(Fsm *this) {
|
||||||
|
long line;
|
||||||
|
|
||||||
|
if (this->pause) {
|
||||||
|
this->handler(this->obj);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (this->pc >= 0) { /* this->pc < 0 means stop current function */
|
||||||
|
if (this->till != 0) {
|
||||||
|
if (time(NULL) < this->till) return 1; /* wait */
|
||||||
|
this->till = 0;
|
||||||
|
}
|
||||||
|
if (this->handler(this->obj) == 0) {
|
||||||
|
return 1; /* wait for answer */
|
||||||
|
}
|
||||||
|
fsm = this;
|
||||||
|
this->pc = this->func(this->pc, this->obj);
|
||||||
|
fsm = NULL;
|
||||||
|
}
|
||||||
|
if (this->pc <= 0) {
|
||||||
|
if (this->sp == 0) return 0;
|
||||||
|
this->sp--;
|
||||||
|
this->pc = this->stack[this->sp].pc;
|
||||||
|
this->func = this->stack[this->sp].func;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FsmKill(void *data) {
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Fsm *FsmStartTask(void *obj, FsmHandler handler, FsmFunc func) {
|
||||||
|
Fsm *new;
|
||||||
|
|
||||||
|
new=malloc(sizeof *new);
|
||||||
|
new->obj = obj;
|
||||||
|
new->pc = 0;
|
||||||
|
new->func = func;
|
||||||
|
new->handler = handler;
|
||||||
|
new->sp = 0;
|
||||||
|
new->till = 0;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FsmStop(Fsm *this, FsmFunc func) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (this == NULL) this = fsm;
|
||||||
|
assert(this);
|
||||||
|
for (i=0; i < this->sp; i++) {
|
||||||
|
if (func == this->stack[i].func) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == this->sp) {
|
||||||
|
if (func != this->func) return 0;
|
||||||
|
} else {
|
||||||
|
this->sp = i;
|
||||||
|
}
|
||||||
|
this->pc = -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FsmPause(Fsm *this, int pause) {
|
||||||
|
this->pause = pause;
|
||||||
|
}
|
||||||
|
|
||||||
|
long FsmCall(long pc, FsmFunc func) {
|
||||||
|
assert(fsm);
|
||||||
|
assert(fsm->sp < MAXSTACK);
|
||||||
|
fsm->stack[fsm->sp].pc = pc;
|
||||||
|
fsm->stack[fsm->sp].func = fsm->func;
|
||||||
|
fsm->sp++;
|
||||||
|
fsm->func = func;
|
||||||
|
fsm->pc = 0;
|
||||||
|
return fsm->func(fsm->pc, fsm->obj);
|
||||||
|
}
|
66
fsm.h
Normal file
66
fsm.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
fsm.h
|
||||||
|
|
||||||
|
a finite state machine
|
||||||
|
|
||||||
|
M. Zolliker, Aug 2004
|
||||||
|
---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifndef FSM_H
|
||||||
|
#define FSM_H
|
||||||
|
|
||||||
|
typedef struct Fsm Fsm;
|
||||||
|
|
||||||
|
typedef long (*FsmFunc)(long pc, void *obj);
|
||||||
|
/* the prototype for a task function
|
||||||
|
a task function body has the following form:
|
||||||
|
|
||||||
|
int Func(long pc, Object *obj) {
|
||||||
|
<declarations>
|
||||||
|
BEGIN
|
||||||
|
...
|
||||||
|
RETURN
|
||||||
|
}
|
||||||
|
|
||||||
|
The ellipsis might be replaced by any code containing fsm macros.
|
||||||
|
Loops and conditional statements containing fsm macros are not
|
||||||
|
allowed, goto statements may be used instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FSM_BEGIN switch (pc) { default:
|
||||||
|
#define FSM_END fsm_quit: return 0; }
|
||||||
|
|
||||||
|
/* fsm macros: */
|
||||||
|
|
||||||
|
#define FSM_NEXT return __LINE__; case __LINE__:
|
||||||
|
/* waiting for response */
|
||||||
|
|
||||||
|
#define FSM_WAIT(DELTA) FsmWait(DELTA); return __LINE__; case __LINE__:
|
||||||
|
/* waiting DELTA seconds */
|
||||||
|
|
||||||
|
#define FSM_CALL(FUNC) return FsmCall(__LINE__, (FsmFunc)FUNC); case __LINE__:
|
||||||
|
/* call a task subfunction */
|
||||||
|
|
||||||
|
typedef int (*FsmHandler)(void *obj);
|
||||||
|
/* the prototype for the handler. Should return 0 when waiting for an answer
|
||||||
|
or 1 when result is o.k. */
|
||||||
|
|
||||||
|
Fsm *FsmStartTask(void *obj, FsmHandler handler, FsmFunc func);
|
||||||
|
/* start a task and return a pointer to it */
|
||||||
|
|
||||||
|
int FsmTaskHandler(Fsm *task);
|
||||||
|
/* this is the task handler.
|
||||||
|
the argument should be the pointer obtained from FsmStartTask
|
||||||
|
returns 0 when finished, 1 when still running */
|
||||||
|
|
||||||
|
int FsmStop(Fsm *task, FsmFunc func);
|
||||||
|
/* stop a function. returns to the caller next time */
|
||||||
|
|
||||||
|
void FsmPause(Fsm *this, int pause);
|
||||||
|
/* pause=1: pause task, pause=0: continue task */
|
||||||
|
|
||||||
|
long FsmCall(long pc, FsmFunc func);
|
||||||
|
void FsmWait(long delay);
|
||||||
|
/* these functions are used in fsm macros and must not be called directly */
|
||||||
|
|
||||||
|
#endif
|
145
ilmdriv.c
Normal file
145
ilmdriv.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
ilmdriv.c
|
||||||
|
|
||||||
|
Driver for the Oxford Instruments ILM503/ILM4 temperature controller
|
||||||
|
and for the Oxford lambda controller
|
||||||
|
|
||||||
|
Markus Zolliker, Sept 2004
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <tcl.h>
|
||||||
|
#include <fortify.h>
|
||||||
|
#include <sics.h>
|
||||||
|
#include <splitter.h>
|
||||||
|
#include <obpar.h>
|
||||||
|
#include <devexec.h>
|
||||||
|
#include <nserver.h>
|
||||||
|
#include <interrupt.h>
|
||||||
|
#include <emon.h>
|
||||||
|
#include <evcontroller.h>
|
||||||
|
#include <evcontroller.i>
|
||||||
|
#include <servlog.h>
|
||||||
|
#include <sicsvar.h>
|
||||||
|
#include <evdriver.i>
|
||||||
|
#include <rs232controller.h>
|
||||||
|
#include "oicom.h"
|
||||||
|
#include "fsm.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Eve eve;
|
||||||
|
float lev2, lev3;
|
||||||
|
int cod1, cod2, cod3;
|
||||||
|
} IlmDriv;
|
||||||
|
|
||||||
|
char *fmts[10]={"unused", "%.1f\t%% N2", "%.1f\t%% He","%.1f\t%% He","",
|
||||||
|
"","","","","error"};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#define A EVE_ACTPAR
|
||||||
|
#define L EVE_LOGPAR
|
||||||
|
#define S EVE_EVE_SAVEPAR
|
||||||
|
|
||||||
|
void IlmPars(IlmDriv *me, EveParArg *arg) {
|
||||||
|
EveFloatPar(arg, "chan2", &me->lev2, fmts[me->cod2],
|
||||||
|
usInternal, (me->cod2 > 0) * A + L);
|
||||||
|
EveFloatPar(arg, "chan3", &me->lev2, fmts[me->cod3],
|
||||||
|
usInternal, (me->cod3 > 0) * A + L);
|
||||||
|
EveStdParEnd(arg, fmts[me->cod1], A+L);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
void IlmStatus(IlmDriv *me) {
|
||||||
|
char *ans;
|
||||||
|
int *code;
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (eve->state != readState) return;
|
||||||
|
ans=eve->ans;
|
||||||
|
code=&eve->errCode;
|
||||||
|
if (ans[0] != 'X' || ans[4] != 'S' || ans[11] != 'R') {
|
||||||
|
EvePrintf(eve, eError, "illegal status response");
|
||||||
|
*code = EVE_FAULT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i=1; i<3; i++) {
|
||||||
|
if (ans[i]<'0' || ans[i] > '9') ans[i]='9';
|
||||||
|
}
|
||||||
|
me->cod1 = ans[1]-'0';
|
||||||
|
me->cod2 = ans[2]-'0';
|
||||||
|
me->cod3 = ans[3]-'0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int IlmRead(long pc, IlmDriv *me) {
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
|
||||||
|
FSM_BEGIN
|
||||||
|
EveWrite(eve, "X");
|
||||||
|
FSM_NEXT
|
||||||
|
IlmStatus(me); /* check for errors */
|
||||||
|
EveWrite(eve, "R1"); /* read sensor 1 */
|
||||||
|
FSM_NEXT
|
||||||
|
me->eve.value = OiGetFlt(eve, 1, NULL);
|
||||||
|
if (me->cod2 == 0) goto skip2;
|
||||||
|
EveWrite(eve, "R2"); /* read sensor 1 */
|
||||||
|
FSM_NEXT
|
||||||
|
me->lev2 = OiGetFlt(eve, 1, NULL);
|
||||||
|
|
||||||
|
skip2:
|
||||||
|
if (me->cod3 == 0) goto skip3;
|
||||||
|
EveWrite(eve, "R3"); /* read sensor 1 */
|
||||||
|
FSM_NEXT
|
||||||
|
me->lev3 = OiGetFlt(eve, 1, NULL);
|
||||||
|
|
||||||
|
skip3:
|
||||||
|
FSM_END
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int IlmStart(long pc, IlmDriv *me) {
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
|
||||||
|
FSM_BEGIN
|
||||||
|
EveWrite(eve, "V");
|
||||||
|
FSM_NEXT
|
||||||
|
if (0 == strncmp(eve->version, "ILM", 3)) {
|
||||||
|
me->eve.syntax = 0;
|
||||||
|
} else {
|
||||||
|
EvePrintf(eve, eError, "unknown level meter version: %s", eve->version);
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
EvePrintf(eve, eStatus, "connected to %s", eve->version);
|
||||||
|
FSM_CALL(IlmRead);
|
||||||
|
|
||||||
|
quit:
|
||||||
|
FSM_END
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
pEVControl IlmMakeEVC(SConnection *pCon, int argc, char *argv[]) {
|
||||||
|
/* args:
|
||||||
|
temperature ilm <rs232>
|
||||||
|
<host> <port>
|
||||||
|
*/
|
||||||
|
Eve *eve;
|
||||||
|
pEVControl evc;
|
||||||
|
IlmDriv *me = NULL;
|
||||||
|
|
||||||
|
evc = MakeEveEVC(argc, argv, calloc(1, sizeof *me), pCon);
|
||||||
|
if (!evc) return NULL;
|
||||||
|
|
||||||
|
me = evc->pDriv->pPrivate;
|
||||||
|
eve=&me->eve;
|
||||||
|
|
||||||
|
eve->run = NULL; /* no run possible */
|
||||||
|
eve->read = (FsmFunc)IlmRead;
|
||||||
|
eve->pardef = (EveParDef)IlmPars;
|
||||||
|
eve->todo = (FsmFunc)IlmStart;
|
||||||
|
eve->task = FsmStartTask(me, (FsmHandler)OiHandler, (FsmFunc)EveIdle);
|
||||||
|
|
||||||
|
evc->pEnvir->IsInTolerance = EveAlwaysOk;
|
||||||
|
|
||||||
|
return evc;
|
||||||
|
}
|
272
itcdriv.c
Normal file
272
itcdriv.c
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
itcdriv.c
|
||||||
|
|
||||||
|
Driver for the Oxford Instruments ITC503/ITC4 temperature controller
|
||||||
|
|
||||||
|
Markus Zolliker, Sept 2004
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <tcl.h>
|
||||||
|
#include <fortify.h>
|
||||||
|
#include <sics.h>
|
||||||
|
#include <splitter.h>
|
||||||
|
#include <obpar.h>
|
||||||
|
#include <devexec.h>
|
||||||
|
#include <nserver.h>
|
||||||
|
#include <interrupt.h>
|
||||||
|
#include <emon.h>
|
||||||
|
#include <evcontroller.h>
|
||||||
|
#include <evcontroller.i>
|
||||||
|
#include <servlog.h>
|
||||||
|
#include <sicsvar.h>
|
||||||
|
#include <evdriver.i>
|
||||||
|
#include <rs232controller.h>
|
||||||
|
#include "oicom.h"
|
||||||
|
#include "fsm.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Eve eve;
|
||||||
|
float t[4]; /* temperatures (0 unused) */
|
||||||
|
int dig[4]; /* format for these */
|
||||||
|
float htr;
|
||||||
|
float coldvalve;
|
||||||
|
int sampleChan;
|
||||||
|
int controlChan;
|
||||||
|
int gas;
|
||||||
|
int remote;
|
||||||
|
int h; /* actual heater channel */
|
||||||
|
int a; /* actual auto mode */
|
||||||
|
} ItcDriv;
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#define A EVE_ACTPAR
|
||||||
|
#define L EVE_LOGPAR
|
||||||
|
#define S EVE_SAVEPAR
|
||||||
|
|
||||||
|
void ItcPars(ItcDriv *me, EveParArg *arg) {
|
||||||
|
char fmt[8]="";
|
||||||
|
int i;
|
||||||
|
int flag;
|
||||||
|
char *ti[4] = {"setp","t1","t2","t3"};
|
||||||
|
|
||||||
|
EveStdPar(arg);
|
||||||
|
|
||||||
|
flag = me->controlChan != 0 && fabsf(me->eve.evc->fTarget - me->t[0]) > 9e-4;
|
||||||
|
sprintf(fmt, "%%.%df\tK", me->dig[me->controlChan]);
|
||||||
|
EveFloatPar(arg, ti[0], &me->t[0], fmt, usInternal, flag*A + L);
|
||||||
|
|
||||||
|
for (i=1; i<=3; i++) {
|
||||||
|
flag = (me->dig[i] >= 0) && (me->sampleChan != i);
|
||||||
|
sprintf(fmt, "%%.%df\tK", me->dig[i]);
|
||||||
|
EveFloatPar(arg, ti[i], &me->t[i], fmt, usInternal, flag*A + L);
|
||||||
|
}
|
||||||
|
|
||||||
|
flag = me->controlChan != 0 || me->htr != 0;
|
||||||
|
EveFloatPar(arg, "htr", &me->htr, "%.1f\t%%", usInternal, flag*A + L);
|
||||||
|
flag = me->gas > 0;
|
||||||
|
EveFloatPar(arg, "coldvalve", &me->coldvalve, "%.1f\t%%", usInternal, flag*A + L);
|
||||||
|
EveIntPar(arg, "dig1", &me->dig[1], usUser, S);
|
||||||
|
EveIntPar(arg, "dig2", &me->dig[2], usUser, S);
|
||||||
|
EveIntPar(arg, "dig3", &me->dig[3], usUser, S);
|
||||||
|
EveIntPar(arg, "gas", &me->gas, usUser, S);
|
||||||
|
EveIntPar(arg, "sampleChan", &me->sampleChan, usUser, A+S);
|
||||||
|
EveIntPar(arg, "controlChan", &me->controlChan, usUser, A+S);
|
||||||
|
sprintf(fmt, "%%.%df\tK", me->dig[me->sampleChan]);
|
||||||
|
EveStdParEnd(arg, fmt, A+L);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
void ItcStatus(ItcDriv *me) {
|
||||||
|
char *ans;
|
||||||
|
int *code;
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
|
||||||
|
if (eve->state != readState) return;
|
||||||
|
ans=eve->ans;
|
||||||
|
code=&eve->errCode;
|
||||||
|
if (ans[0] != 'X' ||
|
||||||
|
ans[2] != 'A' ||
|
||||||
|
ans[4] != 'C' ||
|
||||||
|
ans[6] != 'S') {
|
||||||
|
EvePrintf(eve, eError, "illegal status response");
|
||||||
|
*code = EVE_FAULT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
me->a = ans[3] - '0';
|
||||||
|
if (ans[9] == 'H') {
|
||||||
|
me->h = ans[10] - '0';
|
||||||
|
} else {
|
||||||
|
me->h = me->controlChan;
|
||||||
|
}
|
||||||
|
if (ans[6] != '3' && me->remote == 2) {
|
||||||
|
EvePrintf(eve, eError, "ITC switched to local");
|
||||||
|
*code = EVE_FAULT;
|
||||||
|
me->remote = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int ItcRead(long pc, ItcDriv *me) {
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
char *p;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
FSM_BEGIN
|
||||||
|
EveWrite(eve, "X");
|
||||||
|
FSM_NEXT
|
||||||
|
ItcStatus(me); /* check for errors */
|
||||||
|
if (!me->remote) goto skiprmt;
|
||||||
|
EveWrite(eve, "C0");
|
||||||
|
me->remote = 0;
|
||||||
|
FSM_NEXT
|
||||||
|
|
||||||
|
skiprmt:
|
||||||
|
if (me->dig[1] < 0) goto skip1;
|
||||||
|
EveWrite(eve, "R1"); /* read sensor 1 */
|
||||||
|
FSM_NEXT
|
||||||
|
me->t[1] = OiGetFlt(eve, me->dig[1], &me->dig[1]);
|
||||||
|
|
||||||
|
skip1:
|
||||||
|
if (me->dig[2] < 0) goto skip2;
|
||||||
|
EveWrite(eve, "R2"); /* read sensor 2 */
|
||||||
|
FSM_NEXT
|
||||||
|
me->t[2] = OiGetFlt(eve, me->dig[2], &me->dig[2]);
|
||||||
|
|
||||||
|
skip2:
|
||||||
|
if (me->dig[3] < 0) goto skip3;
|
||||||
|
EveWrite(eve, "R3"); /* read sensor 3 */
|
||||||
|
FSM_NEXT
|
||||||
|
me->t[3] = OiGetFlt(eve, me->dig[3], &me->dig[3]);
|
||||||
|
|
||||||
|
skip3:
|
||||||
|
me->eve.value = me->t[me->sampleChan];
|
||||||
|
if (me->controlChan == 0 || me->a) {
|
||||||
|
me->t[0] = me->eve.evc->fTarget;
|
||||||
|
goto skip0;
|
||||||
|
}
|
||||||
|
EveWrite(eve, "R0"); /* read control T */
|
||||||
|
FSM_NEXT
|
||||||
|
me->t[0] = OiGetFlt(eve, me->dig[me->controlChan], NULL);
|
||||||
|
|
||||||
|
skip0:
|
||||||
|
EveWrite(eve, "R5"); /* read heater */
|
||||||
|
FSM_NEXT
|
||||||
|
me->htr = OiGetFlt(eve, 1, NULL);
|
||||||
|
if (!me->gas < 0) goto skipgas;
|
||||||
|
EveWrite(eve, "R7"); /* read gas flow */
|
||||||
|
FSM_NEXT
|
||||||
|
me->coldvalve = OiGetFlt(eve, 1, NULL);
|
||||||
|
|
||||||
|
skipgas:
|
||||||
|
me->eve.value = me->t[me->sampleChan];
|
||||||
|
FSM_END
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int ItcStart(long pc, ItcDriv *me) {
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
|
||||||
|
FSM_BEGIN
|
||||||
|
EveWrite(eve, "V");
|
||||||
|
FSM_NEXT
|
||||||
|
if (0 == strncmp(eve->version, "ITC503", 6)) {
|
||||||
|
me->eve.syntax = 3;
|
||||||
|
} else if (0 == strncmp(eve->version, "ITC4", 4)) {
|
||||||
|
me->eve.syntax = 0;
|
||||||
|
} else {
|
||||||
|
EvePrintf(eve, eError, "unknown temperature controller version: %s", eve->version);
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
EvePrintf(eve, eStatus, "connected to %s", eve->version);
|
||||||
|
if (me->controlChan == 0 && me->h >= 1 && me->h <= 3) {
|
||||||
|
me->controlChan = me->h;
|
||||||
|
}
|
||||||
|
FSM_CALL(ItcRead);
|
||||||
|
|
||||||
|
quit:
|
||||||
|
FSM_END
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int ItcSetTemp(long pc, ItcDriv *me) {
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
pEVControl evc=eve->evc;
|
||||||
|
float fld;
|
||||||
|
float step;
|
||||||
|
float ramp;
|
||||||
|
char buf[4];
|
||||||
|
SConnection *pCon;
|
||||||
|
int a;
|
||||||
|
|
||||||
|
FSM_BEGIN
|
||||||
|
if (me->controlChan == 0) {
|
||||||
|
EvePrintf(eve, eError, "no control channel selected");
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
EveWrite(eve, "C3");
|
||||||
|
FSM_NEXT
|
||||||
|
if (me->h == me->controlChan) goto skiph;
|
||||||
|
EveWrite(eve, "A0"); /* heater off */
|
||||||
|
FSM_NEXT
|
||||||
|
me->remote = 2;
|
||||||
|
snprintf(buf, sizeof buf, "H%d", me->controlChan);
|
||||||
|
EveWrite(eve, buf); /* set heater to channel */
|
||||||
|
FSM_NEXT
|
||||||
|
|
||||||
|
skiph:
|
||||||
|
OiSet(eve, "T", evc->fTarget, me->dig[me->controlChan]); /* set point */
|
||||||
|
FSM_NEXT
|
||||||
|
a = 1;
|
||||||
|
if (me->gas == 2) a = 3;
|
||||||
|
if (me->h == me->controlChan && me->a == a) goto skipa;
|
||||||
|
if (me->gas == 2) {
|
||||||
|
EveWrite(eve, "A3"); /* auto gas & heater */
|
||||||
|
} else {
|
||||||
|
EveWrite(eve, "A1"); /* auto heater */
|
||||||
|
}
|
||||||
|
FSM_NEXT
|
||||||
|
|
||||||
|
skipa:
|
||||||
|
EveWrite(eve, "C0");
|
||||||
|
FSM_NEXT
|
||||||
|
me->remote = 0;
|
||||||
|
wait:
|
||||||
|
pCon = SCLoad(&evc->conn);
|
||||||
|
eve->hwstate = eve->checkStatus(evc, pCon);
|
||||||
|
if (eve->hwstate != HWBusy) goto quit;
|
||||||
|
FSM_CALL(ItcRead);
|
||||||
|
goto wait;
|
||||||
|
quit:
|
||||||
|
FSM_END
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
pEVControl ItcMakeEVC(SConnection *pCon, int argc, char *argv[]) {
|
||||||
|
/* args:
|
||||||
|
temperature itc <rs232>
|
||||||
|
<host> <port>
|
||||||
|
*/
|
||||||
|
Eve *eve;
|
||||||
|
pEVControl evc;
|
||||||
|
ItcDriv *me = NULL;
|
||||||
|
|
||||||
|
evc = MakeEveEVC(argc, argv, calloc(1, sizeof *me), pCon);
|
||||||
|
if (!evc) return NULL;
|
||||||
|
|
||||||
|
me = evc->pDriv->pPrivate;
|
||||||
|
me->sampleChan = 1;
|
||||||
|
eve=&me->eve;
|
||||||
|
|
||||||
|
eve->run = (FsmFunc)ItcSetTemp;
|
||||||
|
eve->read = (FsmFunc)ItcRead;
|
||||||
|
eve->pardef = (EveParDef)ItcPars;
|
||||||
|
eve->todo = (FsmFunc)ItcStart;
|
||||||
|
eve->task = FsmStartTask(me, (FsmHandler)OiHandler, (FsmFunc)EveIdle);
|
||||||
|
|
||||||
|
/* evc->pEnvir->IsInTolerance not changed */
|
||||||
|
EVCSetPar(evc,"upperlimit",310.0,pCon);
|
||||||
|
EVCSetPar(evc,"lowerlimit",1.0,pCon);
|
||||||
|
|
||||||
|
return evc;
|
||||||
|
}
|
184
lcdriv.c
Normal file
184
lcdriv.c
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
lcdriv.c
|
||||||
|
|
||||||
|
Driver for the Oxford Instruments Teslatron lambda controller
|
||||||
|
|
||||||
|
Markus Zolliker, Sept 2004
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <tcl.h>
|
||||||
|
#include <fortify.h>
|
||||||
|
#include <sics.h>
|
||||||
|
#include <splitter.h>
|
||||||
|
#include <obpar.h>
|
||||||
|
#include <devexec.h>
|
||||||
|
#include <nserver.h>
|
||||||
|
#include <interrupt.h>
|
||||||
|
#include <emon.h>
|
||||||
|
#include <evcontroller.h>
|
||||||
|
#include <evcontroller.i>
|
||||||
|
#include <servlog.h>
|
||||||
|
#include <sicsvar.h>
|
||||||
|
#include <evdriver.i>
|
||||||
|
#include <rs232controller.h>
|
||||||
|
#include "oicom.h"
|
||||||
|
#include "fsm.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Eve eve;
|
||||||
|
float t[4]; /* set t. & 3 temperatures */
|
||||||
|
int dig[4]; /* format for these */
|
||||||
|
float coldvalve;
|
||||||
|
int gas;
|
||||||
|
int remote;
|
||||||
|
int hot;
|
||||||
|
} LcDriv;
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#define A EVE_ACTPAR
|
||||||
|
#define L EVE_LOGPAR
|
||||||
|
#define S EVE_SAVEPAR
|
||||||
|
|
||||||
|
void LcPars(LcDriv *me, EveParArg *arg) {
|
||||||
|
char fmt[80];
|
||||||
|
|
||||||
|
sprintf(fmt, "%%.%df\tK", me->dig[2]);
|
||||||
|
EveFloatPar(arg, "t2", &me->t[2], fmt, usInternal, (me->dig[2] >= 0) * A + L);
|
||||||
|
|
||||||
|
sprintf(fmt, "%%.%df\tK", me->dig[3]);
|
||||||
|
EveFloatPar(arg, "t3", &me->t[3], fmt, usInternal, (me->dig[3] >= 0) * A + L);
|
||||||
|
|
||||||
|
EveFloatPar(arg, "coldvalve", &me->coldvalve, "%.1f\t%%", usInternal, A + L);
|
||||||
|
|
||||||
|
EveIntPar(arg, "dig1", &me->dig[1], usUser, S);
|
||||||
|
EveIntPar(arg, "dig2", &me->dig[2], usUser, S);
|
||||||
|
EveIntPar(arg, "dig3", &me->dig[3], usUser, S);
|
||||||
|
|
||||||
|
sprintf(fmt, "%%.%df\tmbar", me->dig[1]);
|
||||||
|
EveStdParEnd(arg, fmt, 0);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
void LcStatus(LcDriv *me) {
|
||||||
|
char *ans;
|
||||||
|
int *code;
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
|
||||||
|
if (eve->state != readState) return;
|
||||||
|
ans=eve->ans;
|
||||||
|
code=&eve->errCode;
|
||||||
|
if (ans[0] != 'X' ||
|
||||||
|
ans[2] != 'A' ||
|
||||||
|
ans[4] != 'C' ||
|
||||||
|
ans[6] != 'S') {
|
||||||
|
EvePrintf(eve, eError, "illegal status response");
|
||||||
|
*code = EVE_FAULT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ans[6] != '3' && me->remote == 2) {
|
||||||
|
EvePrintf(eve, eError, "LC switched to local");
|
||||||
|
*code = EVE_FAULT;
|
||||||
|
me->remote = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int LcRead(long pc, LcDriv *me) {
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
char *p;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
FSM_BEGIN
|
||||||
|
EveWrite(eve, "X");
|
||||||
|
FSM_NEXT
|
||||||
|
LcStatus(me); /* check for errors */
|
||||||
|
if (!me->remote) goto skiprmt;
|
||||||
|
EveWrite(eve, "C0");
|
||||||
|
me->remote = 0;
|
||||||
|
FSM_NEXT
|
||||||
|
|
||||||
|
skiprmt:
|
||||||
|
if (me->dig[1] < 0) goto skip1;
|
||||||
|
EveWrite(eve, "R1"); /* read sensor 1 */
|
||||||
|
FSM_NEXT
|
||||||
|
me->t[1] = OiGetFlt(eve, me->dig[1], NULL);
|
||||||
|
me->eve.value = me->t[1];
|
||||||
|
skip1:
|
||||||
|
if (me->dig[2] < 0) goto skip2;
|
||||||
|
EveWrite(eve, "R2"); /* read sensor 2 */
|
||||||
|
FSM_NEXT
|
||||||
|
me->t[2] = OiGetFlt(eve, me->dig[2], NULL);
|
||||||
|
skip2:
|
||||||
|
if (me->dig[3] < 0) goto skip3;
|
||||||
|
EveWrite(eve, "R3"); /* read sensor 3 */
|
||||||
|
FSM_NEXT
|
||||||
|
me->t[3] = OiGetFlt(eve, me->dig[3], NULL);
|
||||||
|
skip3:
|
||||||
|
EveWrite(eve, "R7"); /* read gas flow */
|
||||||
|
FSM_NEXT
|
||||||
|
me->coldvalve = OiGetFlt(eve, 1, NULL);
|
||||||
|
quit:
|
||||||
|
FSM_END
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int LcStart(long pc, LcDriv *me) {
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
|
||||||
|
FSM_BEGIN
|
||||||
|
EveWrite(eve, "V");
|
||||||
|
FSM_NEXT
|
||||||
|
if (0 == strncmp(eve->version, "TESLATRON", 9)) {
|
||||||
|
me->eve.syntax = 0;
|
||||||
|
me->dig[1] = 1;
|
||||||
|
me->dig[2] = 2;
|
||||||
|
me->dig[3] = 1;
|
||||||
|
} else {
|
||||||
|
EvePrintf(eve, eError, "unknown lambda controller version: %s", eve->version);
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
EvePrintf(eve, eStatus, "connected to %s", eve->version);
|
||||||
|
FSM_CALL(LcRead);
|
||||||
|
|
||||||
|
quit:
|
||||||
|
FSM_END
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int LcSetTemp(long pc, LcDriv *me) {
|
||||||
|
Eve *eve=&me->eve;
|
||||||
|
pEVControl evc=eve->evc;
|
||||||
|
float fld;
|
||||||
|
float step;
|
||||||
|
float ramp;
|
||||||
|
char buf[4];
|
||||||
|
SConnection *pCon;
|
||||||
|
|
||||||
|
FSM_BEGIN
|
||||||
|
FSM_END
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
pEVControl LcMakeEVC(SConnection *pCon, int argc, char *argv[]) {
|
||||||
|
/* args:
|
||||||
|
<objectname> lc <rs232>
|
||||||
|
<host> <port>
|
||||||
|
*/
|
||||||
|
Eve *eve;
|
||||||
|
pEVControl evc;
|
||||||
|
LcDriv *me = NULL;
|
||||||
|
|
||||||
|
evc = MakeEveEVC(argc, argv, calloc(1, sizeof *me), pCon);
|
||||||
|
if (!evc) return NULL;
|
||||||
|
|
||||||
|
me = evc->pDriv->pPrivate;
|
||||||
|
eve=&me->eve;
|
||||||
|
|
||||||
|
eve->run = (FsmFunc)LcSetTemp;
|
||||||
|
eve->read = (FsmFunc)LcRead;
|
||||||
|
eve->pardef = (EveParDef)LcPars;
|
||||||
|
eve->todo = (FsmFunc)LcStart;
|
||||||
|
eve->task = FsmStartTask(me, (FsmHandler)OiHandler, (FsmFunc)EveIdle);
|
||||||
|
|
||||||
|
return evc;
|
||||||
|
}
|
352
logger.c
Normal file
352
logger.c
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
logger.c
|
||||||
|
|
||||||
|
Markus Zolliker, Sept 2004
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <fortify.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "sics.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
#define LOGGER_NAN -999999.
|
||||||
|
|
||||||
|
struct Logger {
|
||||||
|
char *name;
|
||||||
|
char old[132];
|
||||||
|
int period;
|
||||||
|
time_t last;
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *dir = NULL;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
void LoggerWrite(Logger *log, time_t now, int period, char *value) {
|
||||||
|
char path[256], stim[32], buf[32];
|
||||||
|
struct tm *tm;
|
||||||
|
int yday, isdst;
|
||||||
|
int l;
|
||||||
|
int newday;
|
||||||
|
FILE *fil;
|
||||||
|
|
||||||
|
if (dir == NULL) return;
|
||||||
|
if (now == 0) {
|
||||||
|
printf("now==0\n");
|
||||||
|
}
|
||||||
|
tm = localtime(&log->last);
|
||||||
|
yday = tm->tm_yday;
|
||||||
|
tm = localtime(&now);
|
||||||
|
if (tm->tm_yday != yday) {
|
||||||
|
log->period = 0;
|
||||||
|
} else if (0 == strncmp(value, log->old, sizeof(log->old))) { /* value has not changed */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log->last = now;
|
||||||
|
snprintf(path, sizeof path, "%s/%s/", dir, log->name);
|
||||||
|
l = strlen(path);
|
||||||
|
|
||||||
|
strftime(path + l, sizeof path - l, "%m-%d.log", tm);
|
||||||
|
fil = fopen(path, "a+");
|
||||||
|
if (fil == NULL) return;
|
||||||
|
fseek(fil, 0, SEEK_SET);
|
||||||
|
fgets(buf, sizeof buf, fil);
|
||||||
|
|
||||||
|
strftime(stim, sizeof stim, "#%Y-%m-%d %H:%M:%S\n", tm);
|
||||||
|
if (0 != strncmp(buf, stim, 11)) {
|
||||||
|
fclose(fil);
|
||||||
|
fil=fopen(path, "w+"); /* overwrite old logfile */
|
||||||
|
if (fil == NULL) return;
|
||||||
|
fputs(stim, fil);
|
||||||
|
} else {
|
||||||
|
fseek(fil, 0, SEEK_END); /* set position to end */
|
||||||
|
}
|
||||||
|
if (period != log->period) {
|
||||||
|
log->period = period;
|
||||||
|
snprintf(buf, sizeof buf, "\t%d", period);
|
||||||
|
} else {
|
||||||
|
buf[0]='\0';
|
||||||
|
}
|
||||||
|
strftime(stim, sizeof stim,"%H:%M:%S", tm);
|
||||||
|
fprintf(fil, "%s\t%s%s\n", stim, value, buf);
|
||||||
|
l = strlen(value);
|
||||||
|
if (l >= sizeof(log->old)) {
|
||||||
|
l = sizeof(log->old) - 1;
|
||||||
|
}
|
||||||
|
strncpy(log->old, value, l);
|
||||||
|
log->old[l] = '\0';
|
||||||
|
fclose(fil);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
void LoggerKill(Logger *log) {
|
||||||
|
if (!log) return;
|
||||||
|
LoggerWrite(log, time(NULL), 0, "");
|
||||||
|
free(log->name);
|
||||||
|
free(log);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
char *LoggerGetDir(void) {
|
||||||
|
if (dir == NULL) {
|
||||||
|
dir = IFindOption(pSICSOptions, "LoggerDir");
|
||||||
|
}
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
Logger *LoggerMake(char *name, int period) {
|
||||||
|
Logger *log, *p;
|
||||||
|
char path[256];
|
||||||
|
struct stat st;
|
||||||
|
int i;
|
||||||
|
char *dir;
|
||||||
|
|
||||||
|
dir = LoggerGetDir();
|
||||||
|
if (dir == NULL) return NULL;
|
||||||
|
snprintf(path, sizeof path, "%s/%s", dir, name);
|
||||||
|
i = stat(path, &st);
|
||||||
|
if (i >= 0) {
|
||||||
|
if (((st.st_mode >> 12) & 15) != 4) { /* exists, but is no directory */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i = mkdir(path, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
|
||||||
|
if (i < 0) return NULL; /* mkdir failed */
|
||||||
|
}
|
||||||
|
log = malloc(sizeof *log);
|
||||||
|
if (log == NULL) return NULL;
|
||||||
|
log->name = strdup(name);
|
||||||
|
if (log->name == NULL) {
|
||||||
|
free(log);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
log->period = 0;
|
||||||
|
log->old[0] = '\0';
|
||||||
|
log->last = 0;
|
||||||
|
LoggerWrite(log, time(NULL) - 1, period, "");
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
SConnection *pCon;
|
||||||
|
time_t step;
|
||||||
|
time_t t0, tmin, tmax;
|
||||||
|
time_t tlast;
|
||||||
|
float ymin, ymax;
|
||||||
|
float ylast;
|
||||||
|
long cnt;
|
||||||
|
} Compressor;
|
||||||
|
|
||||||
|
static void LoggerInit(Compressor *c, SConnection *pCon, time_t step) {
|
||||||
|
c->pCon = pCon;
|
||||||
|
c->step = step;
|
||||||
|
c->tmin = -1;
|
||||||
|
c->tmax = 0;
|
||||||
|
c->tlast = 0;
|
||||||
|
c->t0 = 0;
|
||||||
|
c->ylast = LOGGER_NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LoggerOut(Compressor *c, time_t t, float y) {
|
||||||
|
char line[80];
|
||||||
|
|
||||||
|
/* printf("out %ld %g\n", t, y); */
|
||||||
|
if (y != c->ylast) {
|
||||||
|
c->ylast = y;
|
||||||
|
if (y == LOGGER_NAN) {
|
||||||
|
snprintf(line, sizeof line, "%ld\n", t - c->tlast);
|
||||||
|
} else {
|
||||||
|
snprintf(line, sizeof line, "%ld %g\n", t - c->tlast, y);
|
||||||
|
}
|
||||||
|
/* printf("-%s\n", line); */
|
||||||
|
c->cnt--;
|
||||||
|
c->tlast = t;
|
||||||
|
SCWrite(c->pCon, line, eStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LoggerSum(Compressor *c) {
|
||||||
|
if (c->tmin < 0 || c->tmin==0 && c->tmax==0) {
|
||||||
|
/* printf("nos %ld %ld %f %f\n", c->tmin, c->tmax, c->ymin, c->ymax); */
|
||||||
|
LoggerOut(c, c->t0, LOGGER_NAN);
|
||||||
|
c->tmin = -1;
|
||||||
|
} else {
|
||||||
|
/* printf("sum %ld %ld %f %f\n", c->tmin, c->tmax, c->ymin, c->ymax); */
|
||||||
|
if (c->tmin > c->tmax) {
|
||||||
|
if (c->tmax >= c->t0) {
|
||||||
|
LoggerOut(c, c->tmax, c->ymax);
|
||||||
|
}
|
||||||
|
LoggerOut(c, c->tmin, c->ymin);
|
||||||
|
} else if (c->tmin < c->tmax) {
|
||||||
|
if (c->tmin >= c->t0) {
|
||||||
|
LoggerOut(c, c->tmin, c->ymin);
|
||||||
|
}
|
||||||
|
LoggerOut(c, c->tmax, c->ymax);
|
||||||
|
} else {
|
||||||
|
LoggerOut(c, c->tmax, c->ymax);
|
||||||
|
}
|
||||||
|
if (c->ylast != LOGGER_NAN) {
|
||||||
|
c->ymin = c->ylast;
|
||||||
|
c->ymax = c->ylast;
|
||||||
|
c->tmin = 0;
|
||||||
|
c->tmax = 0;
|
||||||
|
} else {
|
||||||
|
c->tmin = -1;
|
||||||
|
}
|
||||||
|
/* printf("end %ld %ld %f %f\n", c->tmin, c->tmax, c->ymin, c->ymax); */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LoggerPut(Compressor *c, time_t t, float y) {
|
||||||
|
/* printf("put %ld %g\n", t, y); */
|
||||||
|
if (t >= c->t0 + c->step) {
|
||||||
|
LoggerSum(c);
|
||||||
|
c->t0 = t;
|
||||||
|
}
|
||||||
|
if (y == LOGGER_NAN) return;
|
||||||
|
if (c->tmin < 0) {
|
||||||
|
c->tmin = t;
|
||||||
|
c->tmax = t;
|
||||||
|
c->ymin = y;
|
||||||
|
c->ymax = y;
|
||||||
|
} else if (y <= c->ymin) {
|
||||||
|
c->ymin = y;
|
||||||
|
c->tmin = t;
|
||||||
|
} else if (y >= c->ymax) {
|
||||||
|
c->ymax = y;
|
||||||
|
c->tmax = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]) {
|
||||||
|
time_t from, to, step, xs, lastx, now;
|
||||||
|
char *p;
|
||||||
|
int i, l, yday, iret, loss;
|
||||||
|
time_t tim, tr;
|
||||||
|
struct tm tm;
|
||||||
|
char path[256], line[80];
|
||||||
|
char *lin, *val, *stp;
|
||||||
|
FILE *fil;
|
||||||
|
Compressor c;
|
||||||
|
float yy, lasty;
|
||||||
|
|
||||||
|
if (argc < 4) {
|
||||||
|
SCWrite(pCon, "illegal number of arguments", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
now = time(NULL);
|
||||||
|
from = strtol(argv[1], &p, 0); /* unix time, not year 2038 safe */
|
||||||
|
if (p == argv[1]) goto illarg;
|
||||||
|
to = strtol(argv[2], NULL, 0);
|
||||||
|
if (p == argv[2]) goto illarg;
|
||||||
|
step = strtol(argv[3], NULL, 0);
|
||||||
|
if (p == argv[3]) goto illarg;
|
||||||
|
if (from <= 0) from += now;
|
||||||
|
if (to <= 0) to += now;
|
||||||
|
if (step <= 0) step = 1;
|
||||||
|
|
||||||
|
dir = LoggerGetDir();
|
||||||
|
if (dir == NULL) {
|
||||||
|
SCWrite(pCon, "LoggerDir not found", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
loss = 0;
|
||||||
|
for (i=4; i<argc; i++) {
|
||||||
|
tim = from;
|
||||||
|
xs = step;
|
||||||
|
LoggerInit(&c, pCon, step);
|
||||||
|
c.cnt = (to - from) / step + 1;
|
||||||
|
lastx = 0;
|
||||||
|
lasty = LOGGER_NAN;
|
||||||
|
snprintf(path, sizeof path, "%s/%s/", dir, argv[i]);
|
||||||
|
l = strlen(path);
|
||||||
|
fil = NULL;
|
||||||
|
snprintf(line, sizeof line, "*%s\n", argv[i]);
|
||||||
|
SCWrite(pCon, line, eStatus);
|
||||||
|
while (tim <= to) {
|
||||||
|
tm = *localtime(&tim);
|
||||||
|
if (fil == NULL || tm.tm_yday != yday) {
|
||||||
|
yday = tm.tm_yday;
|
||||||
|
strftime(path + l, sizeof path - l, "%m-%d.log", &tm);
|
||||||
|
fil = fopen(path, "r");
|
||||||
|
}
|
||||||
|
if (fil == NULL) {
|
||||||
|
lin == NULL;
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
lin = fgets(line, sizeof line, fil);
|
||||||
|
/* printf("%s\n", line); */
|
||||||
|
if (lin == NULL) break;
|
||||||
|
p = strchr(line, '\n'); if (p) *p='\0';
|
||||||
|
p = strchr(line, '#'); if (p) *p='\0';
|
||||||
|
} while (lin[0] == '\0');
|
||||||
|
}
|
||||||
|
if (lin != NULL) {
|
||||||
|
/* printf(" %s\n", line); */
|
||||||
|
p = strchr(line, '\t');
|
||||||
|
if (p) {
|
||||||
|
*p='\0';
|
||||||
|
val = p+1;
|
||||||
|
} else {
|
||||||
|
val = "";
|
||||||
|
}
|
||||||
|
p = strchr(val, '\t');
|
||||||
|
if (p) {
|
||||||
|
*p='\0';
|
||||||
|
stp = val+1;
|
||||||
|
iret = sscanf(stp, "%ld", &xs);
|
||||||
|
if (xs < step) {
|
||||||
|
loss = 1;
|
||||||
|
xs = step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iret = sscanf(line, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
|
||||||
|
if (iret != 3) {
|
||||||
|
lin = NULL;
|
||||||
|
} else {
|
||||||
|
tm.tm_isdst = -1;
|
||||||
|
tr=mktime(&tm);
|
||||||
|
iret = sscanf(val, "%f", &yy);
|
||||||
|
if (iret <= 0) {
|
||||||
|
yy = LOGGER_NAN;
|
||||||
|
} else {
|
||||||
|
if (yy == LOGGER_NAN) yy *= 1.0000002;
|
||||||
|
}
|
||||||
|
if (tr >= tim) {
|
||||||
|
if (lastx != 0) {
|
||||||
|
lastx += xs;
|
||||||
|
while (lastx < tr) {
|
||||||
|
LoggerPut(&c, lastx, lasty);
|
||||||
|
lastx += xs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LoggerPut(&c, tr, yy);
|
||||||
|
}
|
||||||
|
lastx = tr;
|
||||||
|
lasty = yy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lin == NULL) {
|
||||||
|
tm.tm_hour = 24; /* try next day */
|
||||||
|
tm.tm_min = 0;
|
||||||
|
tm.tm_sec = 0;
|
||||||
|
tm.tm_isdst = -1;
|
||||||
|
tim=mktime(&tm);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.ylast = LOGGER_NAN;
|
||||||
|
LoggerSum(&c);
|
||||||
|
}
|
||||||
|
snprintf(line, sizeof line, "*%d\n", loss);
|
||||||
|
SCWrite(pCon, line, eStatus);
|
||||||
|
return 1;
|
||||||
|
illarg:
|
||||||
|
SCWrite(pCon, "illegal argument", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
19
logger.h
Normal file
19
logger.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
logger.c
|
||||||
|
|
||||||
|
Markus Zolliker, Sept 2004
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOGGER_H
|
||||||
|
#define LOGGER_H
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
typedef struct Logger Logger;
|
||||||
|
|
||||||
|
Logger *LoggerMake(char *name, int period);
|
||||||
|
void LoggerKill(Logger *log);
|
||||||
|
void LoggerWrite(Logger *log, time_t now, int period, char *value);
|
||||||
|
|
||||||
|
#endif
|
4
make_gen
4
make_gen
@ -18,7 +18,9 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \
|
|||||||
bruker.o ltc11.o A1931.o dilludriv.o eurodriv.o slsmagnet.o \
|
bruker.o ltc11.o A1931.o dilludriv.o eurodriv.o slsmagnet.o \
|
||||||
el755driv.o amorscan.o serial.o scontroller.o t_update.o \
|
el755driv.o amorscan.o serial.o scontroller.o t_update.o \
|
||||||
t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o \
|
t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o \
|
||||||
el737hpv2driv.o swmotor2.o ipsdriv.o tricssupport.o
|
el737hpv2driv.o swmotor2.o tricssupport.o \
|
||||||
|
oicom.o fsm.o remob.o eve.o logger.o \
|
||||||
|
ipsdriv.o itcdriv.o ilmdriv.o lcdriv.o
|
||||||
|
|
||||||
libpsi.a: $(OBJ)
|
libpsi.a: $(OBJ)
|
||||||
rm -f libpsi.a
|
rm -f libpsi.a
|
||||||
|
128
oicom.c
Normal file
128
oicom.c
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
oicom.c
|
||||||
|
|
||||||
|
Communication routines for Oxford Instruments equipment
|
||||||
|
|
||||||
|
Markus Zolliker, Aug 2004
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
there is no error return value, eve->errCode is used. On success, eve->errCode
|
||||||
|
is not changed, i.e. an existing errCode is not overwritten.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <fortify.h>
|
||||||
|
#include "sics.h"
|
||||||
|
#include "rs232controller.h"
|
||||||
|
#include "oicom.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
int OiHandler(Eve *eve) {
|
||||||
|
int iret, l;
|
||||||
|
|
||||||
|
if (availableNetRS232(eve->ser)) {
|
||||||
|
l = sizeof(eve->ans);
|
||||||
|
iret = readRS232TillTerm(eve->ser, eve->ans, &l);
|
||||||
|
if (eve->state < expectState) {
|
||||||
|
if (iret == 1) {
|
||||||
|
EvePrintf(eve, eError, "unexpected answer: %s", eve->ans);
|
||||||
|
}
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
if (iret == 1) {
|
||||||
|
EvePrintf(eve, -2, "ans: %s", eve->ans);
|
||||||
|
if (strcmp(eve->ans, "?ck") == 0) {
|
||||||
|
if (eve->state == lostState) {
|
||||||
|
EveWrite(eve, "V");
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
} else if (eve->state == lostState) {
|
||||||
|
goto quit;
|
||||||
|
} else if (eve->cmd[0] == 'V') {
|
||||||
|
if (strcmp(eve->ans, eve->version) == 0) {
|
||||||
|
/* we are still connected with the same device */
|
||||||
|
} else if (*eve->version == '\0') {
|
||||||
|
strncat(eve->version, eve->ans, sizeof(eve->version)-1);
|
||||||
|
} else { /* version (and therefore device) changed */
|
||||||
|
eve->errCode = EVE_DEV_CHANGED;
|
||||||
|
eve->state = idleState;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
eve->state = idleState;
|
||||||
|
goto quit;
|
||||||
|
} else if (eve->cmd[1] == 'k') { /* ck */
|
||||||
|
} else if (eve->cmd[0] != eve->ans[0]) {
|
||||||
|
iret = EVE_ILL_ANS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (iret != 1) {
|
||||||
|
eve->errCode = iret;
|
||||||
|
eve->state = idleState;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
eve->state = readState;
|
||||||
|
} else if (eve->state == expectState) {
|
||||||
|
if (time(NULL) > eve->cmdtime+60) {
|
||||||
|
eve->errCode = TIMEOUT;
|
||||||
|
eve->state = lostState;
|
||||||
|
}
|
||||||
|
} else if (eve->state == lostState) {
|
||||||
|
if (time(NULL) > eve->cmdtime) {
|
||||||
|
EveWrite(eve, "ck");
|
||||||
|
eve->state = lostState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto quit;
|
||||||
|
error:
|
||||||
|
EveWriteError(eve);
|
||||||
|
quit:
|
||||||
|
return EveHandler(eve);
|
||||||
|
}
|
||||||
|
|
||||||
|
double OiGetFlt(Eve *eve, int dig, int *pdig) {
|
||||||
|
char *endp, *p;
|
||||||
|
double val;
|
||||||
|
|
||||||
|
if (eve->state != readState) {
|
||||||
|
/* eve->errCode = EVE_ILL_ANS; */
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
p = strchr(eve->ans, '.');
|
||||||
|
if (p) {
|
||||||
|
if (pdig != NULL) {
|
||||||
|
*pdig = strlen(eve->ans) - (p - eve->ans) - 1;
|
||||||
|
}
|
||||||
|
val=strtod(eve->ans+1, &endp);
|
||||||
|
if (*endp != '\0') {
|
||||||
|
eve->errCode = EVE_ILL_ANS;
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val=strtol(eve->ans+1, &endp, 10);
|
||||||
|
if (*endp != '\0') {
|
||||||
|
eve->errCode = EVE_ILL_ANS;
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (eve->syntax == 0) { /* old style format */
|
||||||
|
for (; dig > 0; dig--) val=val*0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OiSet(Eve *eve, char *cmd, double val, int dig) {
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
if (eve->syntax == 0) {
|
||||||
|
for (;dig>0;dig--) val=val*10;
|
||||||
|
snprintf(buf, sizeof(buf), "%s%05d", cmd, val);
|
||||||
|
} else {
|
||||||
|
snprintf(buf, sizeof(buf), "%s%f", cmd, val);
|
||||||
|
}
|
||||||
|
EveWrite(eve, buf);
|
||||||
|
}
|
||||||
|
|
16
oicom.h
Normal file
16
oicom.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
oicom.h
|
||||||
|
|
||||||
|
Communication routines for Oxford Instruments equipment
|
||||||
|
|
||||||
|
Markus Zolliker, Aug 2004
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#include "rs232controller.h"
|
||||||
|
#include "eve.h"
|
||||||
|
|
||||||
|
int OiHandler(Eve *eve);
|
||||||
|
double OiGetFlt(Eve *eve, int dig, int *pdig);
|
||||||
|
void OiSet(Eve *eve, char *cmd, double val, int dig);
|
||||||
|
|
||||||
|
|
||||||
|
|
35
psi.c
35
psi.c
@ -39,7 +39,6 @@
|
|||||||
#include "tdchm.h"
|
#include "tdchm.h"
|
||||||
#include "tecsdriv.h"
|
#include "tecsdriv.h"
|
||||||
#include "itc4.h"
|
#include "itc4.h"
|
||||||
#include "ipsdriv.h"
|
|
||||||
#include "bruker.h"
|
#include "bruker.h"
|
||||||
#include "ltc11.h"
|
#include "ltc11.h"
|
||||||
#include "A1931.h"
|
#include "A1931.h"
|
||||||
@ -50,10 +49,13 @@
|
|||||||
#include "amorscan.h"
|
#include "amorscan.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "fomerge.h"
|
#include "fomerge.h"
|
||||||
|
#include "remob.h"
|
||||||
#include "tricssupport.h"
|
#include "tricssupport.h"
|
||||||
|
|
||||||
static pSite sitePSI = NULL;
|
static pSite sitePSI = NULL;
|
||||||
|
|
||||||
|
int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
static void AddPsiCommands(SicsInterp *pInter){
|
static void AddPsiCommands(SicsInterp *pInter){
|
||||||
AddCommand(pInter,"MakeRuenBuffer",InitBufferSys,NULL,NULL);
|
AddCommand(pInter,"MakeRuenBuffer",InitBufferSys,NULL,NULL);
|
||||||
@ -77,6 +79,8 @@ static void AddPsiCommands(SicsInterp *pInter){
|
|||||||
AddCommand(pInter,"MakePSDFrame",MakeFrameFunc,NULL,NULL);
|
AddCommand(pInter,"MakePSDFrame",MakeFrameFunc,NULL,NULL);
|
||||||
AddCommand(pInter,"SerialInit",SerialInit,NULL,NULL);
|
AddCommand(pInter,"SerialInit",SerialInit,NULL,NULL);
|
||||||
AddCommand(pInter,"InstallFocusMerge",InstallFocusMerge,NULL,NULL);
|
AddCommand(pInter,"InstallFocusMerge",InstallFocusMerge,NULL,NULL);
|
||||||
|
AddCommand(pInter,"Remob",RemobCreate,NULL,NULL);
|
||||||
|
AddCommand(pInter,"Graph",LoggerGraph,NULL,NULL);
|
||||||
/*
|
/*
|
||||||
AddCommand(pInter,"MakeDifrac",MakeDifrac,NULL,NULL);
|
AddCommand(pInter,"MakeDifrac",MakeDifrac,NULL,NULL);
|
||||||
*/
|
*/
|
||||||
@ -317,8 +321,6 @@ static void ConfigureController(char *name, pEVControl pNew,
|
|||||||
EVCSetPar(pNew,"lowerlimit",1.0,pCon);
|
EVCSetPar(pNew,"lowerlimit",1.0,pCon);
|
||||||
if(strcmp(name,"tecs") == 0){
|
if(strcmp(name,"tecs") == 0){
|
||||||
TecsCustomize(pCon, pNew);
|
TecsCustomize(pCon, pNew);
|
||||||
} else if(strcmp(name,"ips") == 0){
|
|
||||||
IpsCustomize(pCon, pNew);
|
|
||||||
} else if(strcmp(name,"euro") == 0){
|
} else if(strcmp(name,"euro") == 0){
|
||||||
EVCSetPar(pNew,"upperlimit",750.0,pCon);
|
EVCSetPar(pNew,"upperlimit",750.0,pCon);
|
||||||
EVCSetPar(pNew,"lowerlimit",15.0,pCon);
|
EVCSetPar(pNew,"lowerlimit",15.0,pCon);
|
||||||
@ -335,7 +337,13 @@ static void ConfigureController(char *name, pEVControl pNew,
|
|||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
extern pEVDriver CreateSLSDriv(int argc, char *argv[]);
|
extern pEVDriver CreateSLSDriv(int argc, char *argv[]);
|
||||||
|
|
||||||
|
pEVControl IpsMakeEVC(SConnection *pCon, int argc, char *argv[]);
|
||||||
|
pEVControl ItcMakeEVC(SConnection *pCon, int argc, char *argv[]);
|
||||||
|
pEVControl IlmMakeEVC(SConnection *pCon, int argc, char *argv[]);
|
||||||
|
pEVControl LcMakeEVC(SConnection *pCon, int argc, char *argv[]);
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
|
|
||||||
static pEVControl InstallPsiEnvironmentController(SicsInterp *pSics,
|
static pEVControl InstallPsiEnvironmentController(SicsInterp *pSics,
|
||||||
SConnection *pCon,
|
SConnection *pCon,
|
||||||
int argc, char *argv[]){
|
int argc, char *argv[]){
|
||||||
@ -374,16 +382,13 @@ static pEVControl InstallPsiEnvironmentController(SicsInterp *pSics,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(strcmp(argv[3],"ips") == 0) {
|
} else if(strcmp(argv[3],"ips") == 0) {
|
||||||
checkError = 1;
|
return IpsMakeEVC(pCon, argc-2, argv+2); /* we should organize all devices like this M.Z. */
|
||||||
pDriv = CreateIpsDriver(argc-4,&argv[4]);
|
} else if(strcmp(argv[3],"itc") == 0) {
|
||||||
if(pDriv){
|
return ItcMakeEVC(pCon, argc-2, argv+2);
|
||||||
pNew = CreateEVController(pDriv,argv[2],&status);
|
} else if(strcmp(argv[3],"ilm") == 0) {
|
||||||
if(pNew != NULL){
|
return IlmMakeEVC(pCon, argc-2, argv+2);
|
||||||
AddCommand(pSics,argv[2],IpsWrapper,DeleteEVController,
|
} else if(strcmp(argv[3],"lc") == 0) {
|
||||||
pNew);
|
return LcMakeEVC(pCon, argc-2, argv+2);
|
||||||
commandInstalled = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if(strcmp(argv[3],"bruker") == 0){
|
} else if(strcmp(argv[3],"bruker") == 0){
|
||||||
checkError = 1;
|
checkError = 1;
|
||||||
pDriv = CreateBrukerDriver(argc-4,&argv[4]);
|
pDriv = CreateBrukerDriver(argc-4,&argv[4]);
|
||||||
@ -439,6 +444,10 @@ static pEVControl InstallPsiEnvironmentController(SicsInterp *pSics,
|
|||||||
if(pDriv != NULL){
|
if(pDriv != NULL){
|
||||||
pNew = CreateEVController(pDriv,argv[2],&status);
|
pNew = CreateEVController(pDriv,argv[2],&status);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(pBueffel,"ERROR: %s not recognized as a valid driver type", argv[3]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we recognized the driver, check for installation errors */
|
/* if we recognized the driver, check for installation errors */
|
||||||
|
785
remob.c
Normal file
785
remob.c
Normal file
@ -0,0 +1,785 @@
|
|||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
remob.c
|
||||||
|
|
||||||
|
implements remote driveable objects living on an other sics server
|
||||||
|
|
||||||
|
M. Zolliker July 04
|
||||||
|
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <tcl.h>
|
||||||
|
#include "fortify.h"
|
||||||
|
#include "sics.h"
|
||||||
|
#include "devexec.h"
|
||||||
|
#include "remob.h"
|
||||||
|
#include "splitter.h"
|
||||||
|
#include "status.h"
|
||||||
|
#include "servlog.h"
|
||||||
|
#include "site.h"
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
#define INTERRUPTMODE 0
|
||||||
|
#define ACCESSCODE 1
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------ */
|
||||||
|
typedef struct Remob Remob;
|
||||||
|
|
||||||
|
typedef struct RemServer {
|
||||||
|
pObjectDescriptor desc;
|
||||||
|
char *name;
|
||||||
|
char *host;
|
||||||
|
int port;
|
||||||
|
char *user;
|
||||||
|
char *pass;
|
||||||
|
mkChannel *chan;
|
||||||
|
int incomplete;
|
||||||
|
char line[256];
|
||||||
|
Remob *objList;
|
||||||
|
int matchMap;
|
||||||
|
int timeout;
|
||||||
|
int taskActive;
|
||||||
|
SCStore conn;
|
||||||
|
} RemServer;
|
||||||
|
|
||||||
|
struct Remob {
|
||||||
|
pObjectDescriptor desc;
|
||||||
|
char *name;
|
||||||
|
ObPar *ParArray;
|
||||||
|
pIDrivable pDrivInt;
|
||||||
|
pICallBack pCall;
|
||||||
|
RemServer *server;
|
||||||
|
int status;
|
||||||
|
Remob *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float fVal;
|
||||||
|
char *pName;
|
||||||
|
} RemobCallback;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *pName;
|
||||||
|
SConnection *pCon;
|
||||||
|
} RemobInfo;
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static char *StartsWith(char *line, char *name) {
|
||||||
|
/* if line does not start with name, return NULL
|
||||||
|
else return a pointer to the next non-white space character
|
||||||
|
*/
|
||||||
|
char *str;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
l = strlen(name);
|
||||||
|
if (0 != strncmp(line, name, l)) return NULL;
|
||||||
|
str = line + l;
|
||||||
|
while (*str == ' ') {
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int RemWrite(RemServer *remserver, char *line) {
|
||||||
|
if (remserver->chan) {
|
||||||
|
/* printf("> %s\n", line); */
|
||||||
|
return NETWrite(remserver->chan, line, strlen(line));
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int RemRead(RemServer *remserver, long tmo) {
|
||||||
|
int iRet;
|
||||||
|
|
||||||
|
if (remserver->chan == NULL) return 0; /* no data */
|
||||||
|
iRet = NETReadTillTermNew(remserver->chan, tmo, "\n",
|
||||||
|
remserver->line+remserver->incomplete, sizeof(remserver->line)-remserver->incomplete);
|
||||||
|
if (iRet == 0) {
|
||||||
|
remserver->incomplete = strlen(remserver->line); /* number of chars already received */
|
||||||
|
return 0; /* timeout */
|
||||||
|
} else {
|
||||||
|
remserver->incomplete=0;
|
||||||
|
}
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int RemHandle(RemServer *remserver) {
|
||||||
|
char *line, *par, *str;
|
||||||
|
Remob *remob;
|
||||||
|
|
||||||
|
/* skip whitespace at the beginning */
|
||||||
|
line=remserver->line;
|
||||||
|
while (*line < ' ' && *line != '\0') {
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
memmove(remserver->line, line, strlen(line));
|
||||||
|
|
||||||
|
/* handle drivstat messages */
|
||||||
|
line = remserver->line;
|
||||||
|
for (remob = remserver->objList; remob != NULL; remob = remob->next) {
|
||||||
|
par=StartsWith(line, remob->name);
|
||||||
|
if (par != NULL) {
|
||||||
|
if (str = StartsWith(par, "finished")) {
|
||||||
|
if (*str == '\0') {
|
||||||
|
remob->status = HWIdle;
|
||||||
|
} else {
|
||||||
|
remob->status = HWFault;
|
||||||
|
}
|
||||||
|
line[0]='\0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (str = StartsWith(par, "started")) {
|
||||||
|
remob->status = HWBusy;
|
||||||
|
line[0]='\0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int RemCopy(RemServer *remserver, SConnection *pCon) {
|
||||||
|
char buf[256];
|
||||||
|
if (pCon != NULL && remserver->line[0] != '\0') {
|
||||||
|
snprintf(buf, sizeof(buf), " %s", remserver->line);
|
||||||
|
/* snprintf(buf, sizeof(buf), "%s (%s)", remserver->line, remserver->name); */
|
||||||
|
SCWrite(pCon, buf, eStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int RemServerTask(void *data) {
|
||||||
|
RemServer *remserver=data;
|
||||||
|
int iRet;
|
||||||
|
SConnection *pCon;
|
||||||
|
|
||||||
|
if (!remserver->taskActive) return 0; /* remove task */
|
||||||
|
if (RemRead(remserver, 0) <= 0) return 1; /* continue */
|
||||||
|
|
||||||
|
/* printf("< %s\n", buf); */
|
||||||
|
|
||||||
|
if (RemHandle(remserver)) { /* handle drivstat messages */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* forward oll other messages */
|
||||||
|
pCon = SCLoad(&remserver->conn);
|
||||||
|
if (pCon) {
|
||||||
|
RemCopy(remserver, pCon);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static void RemDisconnect(RemServer *remserver) {
|
||||||
|
if (remserver->chan != NULL) {
|
||||||
|
NETClosePort(remserver->chan);
|
||||||
|
free(remserver->chan);
|
||||||
|
remserver->chan=NULL;
|
||||||
|
/* printf("disconnected\n"); */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static void RemConnect(RemServer *remserver) {
|
||||||
|
int iRet;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
if (!remserver->chan) {
|
||||||
|
remserver->timeout = 0;
|
||||||
|
remserver->chan = NETConnect(remserver->host, remserver->port);
|
||||||
|
if (!remserver->chan) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf), "%s %s\ntransact listexe interest\n"
|
||||||
|
, remserver->user, remserver->pass);
|
||||||
|
iRet = RemWrite(remserver, buf);
|
||||||
|
if (iRet < 0) goto close;
|
||||||
|
iRet = RemRead(remserver, 1000);
|
||||||
|
while (iRet > 0) { /* eat login response */
|
||||||
|
if (StartsWith(remserver->line, "TRANSACTIONFINISHED")) {
|
||||||
|
/* printf("connected\n"); */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
iRet = RemRead(remserver, 1000);
|
||||||
|
}
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
close:
|
||||||
|
RemDisconnect(remserver);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int RemTransact(RemServer *remserver, SConnection *pCon, char *cmd, ...) {
|
||||||
|
/* the variable arguments are for filtering:
|
||||||
|
|
||||||
|
"<name", &val get float value named m
|
||||||
|
"!blabla" skip lines starting with blabla
|
||||||
|
">" write untreated lines to pCon
|
||||||
|
*/
|
||||||
|
char buf[256];
|
||||||
|
int iRet;
|
||||||
|
int i, typ;
|
||||||
|
char *arg, *val, *endp;
|
||||||
|
float *f;
|
||||||
|
va_list ap;
|
||||||
|
int try;
|
||||||
|
int argMask;
|
||||||
|
|
||||||
|
try=2;
|
||||||
|
if (remserver->timeout) { /* eat old responses */
|
||||||
|
while (RemRead(remserver, 0) > 0) {
|
||||||
|
RemHandle(remserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tryagain:
|
||||||
|
strcpy(buf, "transact ");
|
||||||
|
strcat(buf, cmd);
|
||||||
|
strcat(buf,"\n");
|
||||||
|
RemConnect(remserver);
|
||||||
|
iRet = RemWrite(remserver, buf);
|
||||||
|
if (iRet < 0) goto close;
|
||||||
|
|
||||||
|
iRet = RemRead(remserver, 2000);
|
||||||
|
if (iRet <= 0) goto close;
|
||||||
|
while (!StartsWith(remserver->line, "TRANSACTIONFINISHED")) {
|
||||||
|
RemHandle(remserver);
|
||||||
|
va_start(ap, cmd);
|
||||||
|
arg = va_arg(ap, char *);
|
||||||
|
argMask=1;
|
||||||
|
remserver->matchMap = 0;
|
||||||
|
while (arg != NULL) {
|
||||||
|
if (*arg == '>') {
|
||||||
|
RemCopy(remserver, pCon);
|
||||||
|
} else if (*arg == '<') {
|
||||||
|
f = va_arg(ap, float *);
|
||||||
|
val = StartsWith(remserver->line, arg+1);
|
||||||
|
if (val != NULL) {
|
||||||
|
val = StartsWith(val, "=");
|
||||||
|
if (val != NULL) {
|
||||||
|
*f = strtod(val, &endp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (*arg == '!') {
|
||||||
|
if (StartsWith(remserver->line, arg+1)) {
|
||||||
|
remserver->matchMap |= argMask;
|
||||||
|
argMask = argMask*2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("unknown argument in RemTransact: %s\n", arg);
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
arg = va_arg(ap, char *);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
iRet = RemRead(remserver, 2000);
|
||||||
|
if (iRet <= 0) goto close;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
close:
|
||||||
|
if (iRet == 0) {
|
||||||
|
snprintf(buf, sizeof(buf), "ERROR: timeout on %s", remserver->name);
|
||||||
|
SCWrite(pCon,buf,eError);
|
||||||
|
remserver->timeout = 1;
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf), "ERROR: no connection to %s", remserver->name);
|
||||||
|
SCWrite(pCon,buf,eError);
|
||||||
|
RemDisconnect(remserver);
|
||||||
|
try--;
|
||||||
|
if (try>0) goto tryagain;
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static void *RemobGetInterface(void *pData, int iID) {
|
||||||
|
Remob *self = pData;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
if(iID == DRIVEID) {
|
||||||
|
return self->pDrivInt;
|
||||||
|
} else if(iID == CALLBACKINTERFACE) {
|
||||||
|
return self->pCall;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int RemobHalt(void *self) {
|
||||||
|
Remob *remob=self;
|
||||||
|
RemServer *remserver;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
assert(remob);
|
||||||
|
remserver = remob->server;
|
||||||
|
RemConnect(remserver);
|
||||||
|
snprintf(buf, sizeof(buf), "stopexe %s\n", remob->name);
|
||||||
|
return RemWrite(remserver, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static int RemobLimits(void *self, float fVal, char *error, int iErrLen) {
|
||||||
|
float fHard;
|
||||||
|
Remob *remob=self;
|
||||||
|
|
||||||
|
assert(remob);
|
||||||
|
/* check is done one remote server */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static float RemobGetValue(void *pData, SConnection *pCon) {
|
||||||
|
Remob *remob=pData;
|
||||||
|
char buf[80];
|
||||||
|
float none, value;
|
||||||
|
int iRet;
|
||||||
|
|
||||||
|
assert(remob);
|
||||||
|
|
||||||
|
SCSave(&remob->server->conn, pCon);
|
||||||
|
none = -1.25e6;
|
||||||
|
value= none;
|
||||||
|
snprintf(buf, sizeof(buf), "<%s", remob->name);
|
||||||
|
iRet = RemTransact(remob->server, pCon, remob->name, buf, &value, ">", NULL);
|
||||||
|
if (iRet <= 0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (value != none) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf), "can not get %s", remob->name);
|
||||||
|
SCWrite(pCon, buf, eWarning);
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int RemobSaveStatus(void *pData, char *name, FILE *fd) {
|
||||||
|
Remob *self = pData;
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
assert(fd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
data is stored on remote server
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int RemobStatus(void *pData, SConnection *pCon) {
|
||||||
|
Remob *remob=pData;
|
||||||
|
|
||||||
|
assert(remob);
|
||||||
|
|
||||||
|
SCSave(&remob->server->conn, pCon);
|
||||||
|
return remob->status;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static long RemobRun(void *self, SConnection *pCon, float fNew) {
|
||||||
|
Remob *remob=self;
|
||||||
|
float fHard;
|
||||||
|
int i, iRet, iCode;
|
||||||
|
char buf[512], sBuf[64];
|
||||||
|
char pError[132];
|
||||||
|
Remob *p;
|
||||||
|
RemServer *remserver;
|
||||||
|
long lTime;
|
||||||
|
float fDelta;
|
||||||
|
|
||||||
|
remserver = remob->server;
|
||||||
|
SCSave(&remserver->conn, pCon);
|
||||||
|
assert(remob);
|
||||||
|
assert(pCon);
|
||||||
|
|
||||||
|
/* check if I'am allowed to move this motor */
|
||||||
|
if (!SCMatchRights(pCon,(int)ObVal(remob->ParArray,ACCESSCODE))) {
|
||||||
|
snprintf(buf,sizeof(buf), "ERROR: You are not authorised to run %s",
|
||||||
|
remob->name);
|
||||||
|
SCWrite(pCon,buf,eError);
|
||||||
|
SCSetInterrupt(pCon,eAbortBatch);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
remob->status = HWIdle;
|
||||||
|
snprintf(buf, sizeof(buf), "run %s %f", remob->name, fNew);
|
||||||
|
iRet = RemTransact(remserver, pCon, buf, "!ERROR: somebody else", "!ERROR: cannot", ">", NULL);
|
||||||
|
if (iRet <= 0) return 0;
|
||||||
|
|
||||||
|
if (remserver->matchMap & 1) { /* already running, stop first */
|
||||||
|
remob->status = HWBusy;
|
||||||
|
snprintf(sBuf, sizeof(sBuf), "stopexe %s", remob->name, fNew);
|
||||||
|
iRet = RemTransact(remserver, pCon, sBuf, ">", NULL);
|
||||||
|
if (iRet <= 0) return 0;
|
||||||
|
while (remob->status == HWBusy) {
|
||||||
|
iRet = RemRead(remserver, 1000);
|
||||||
|
if (iRet <= 0) break;
|
||||||
|
RemCopy(remserver, pCon);
|
||||||
|
}
|
||||||
|
iRet = RemTransact(remserver, pCon, buf, ">", NULL);
|
||||||
|
if (iRet <= 0) return 0;
|
||||||
|
}
|
||||||
|
if (remob->status != HWBusy) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return OKOK;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
static void KillInfo(void *pData) {
|
||||||
|
RemobInfo *self = pData;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
if (self->pName) {
|
||||||
|
free(self->pName);
|
||||||
|
}
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
/*------------------- The CallBack function for interest ------------------*/
|
||||||
|
static int InterestCallback(int iEvent, void *pEvent, void *pUser) {
|
||||||
|
RemobCallback *psCall = pEvent;
|
||||||
|
RemobInfo *pInfo = pUser;
|
||||||
|
char buf[80];
|
||||||
|
|
||||||
|
assert(psCall);
|
||||||
|
assert(pInfo);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf),"%s.position = %f ", pInfo->pName, psCall->fVal);
|
||||||
|
SCWrite(pInfo->pCon,buf,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]) {
|
||||||
|
Remob *remob = pData;
|
||||||
|
char buf[512];
|
||||||
|
TokenList *pList = NULL;
|
||||||
|
TokenList *pCurrent;
|
||||||
|
TokenList *pName;
|
||||||
|
int iRet;
|
||||||
|
int i;
|
||||||
|
int pos;
|
||||||
|
float fValue;
|
||||||
|
long lID;
|
||||||
|
char *endp;
|
||||||
|
ObPar *par;
|
||||||
|
char acce[128], inte[128];
|
||||||
|
|
||||||
|
assert(pCon);
|
||||||
|
assert(pSics);
|
||||||
|
assert(remob);
|
||||||
|
|
||||||
|
argtolower(argc,argv);
|
||||||
|
|
||||||
|
SCSave(&remob->server->conn, pCon);
|
||||||
|
if (argc == 1) {
|
||||||
|
iRet = RemTransact(remob->server, pCon, argv[0], ">", NULL);
|
||||||
|
} else if (strcmp(argv[1],"list") == 0) {
|
||||||
|
snprintf(buf, sizeof(buf), "%s list", remob->name);
|
||||||
|
snprintf(acce, sizeof(acce), "!%s.accesscode", remob->name);
|
||||||
|
snprintf(inte, sizeof(inte), "!%s.interruptmode", remob->name);
|
||||||
|
|
||||||
|
RemTransact(remob->server, pCon, buf, acce, inte, ">", NULL);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%s = %.0f", acce+1, ObVal(remob->ParArray,ACCESSCODE));
|
||||||
|
SCWrite(pCon, buf, eStatus);
|
||||||
|
snprintf(buf, sizeof(buf), "%s = %.0f", inte+1, ObVal(remob->ParArray,INTERRUPTMODE));
|
||||||
|
SCWrite(pCon, buf, eStatus);
|
||||||
|
iRet=1;
|
||||||
|
} else {
|
||||||
|
par=ObParFind(remob->ParArray, argv[1]);
|
||||||
|
if (par != NULL) {
|
||||||
|
if (argc == 3) {
|
||||||
|
fValue = strtod(argv[2], &endp);
|
||||||
|
if (endp == argv[2]) {
|
||||||
|
snprintf(buf, sizeof(buf), "number expected instead of %s", argv[2]);
|
||||||
|
SCWrite(pCon, buf, eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
iRet = ObParSet(remob->ParArray,argv[0],argv[1],fValue,pCon);
|
||||||
|
}
|
||||||
|
if (iRet) {
|
||||||
|
snprintf(buf, sizeof(buf), "%s.%s = %.0f", argv[0], argv[1], par->fVal);
|
||||||
|
SCWrite(pCon, buf, eStatus);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pos=snprintf(buf, sizeof(buf), "%s ", remob->name);
|
||||||
|
for (i=1; i<argc; i++) {
|
||||||
|
pos+=snprintf(buf+pos, sizeof(buf)-pos, "%s ", argv[i]);
|
||||||
|
}
|
||||||
|
iRet = RemTransact(remob->server, pCon, buf, ">", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]) {
|
||||||
|
RemServer *remserver = pData;
|
||||||
|
char buf[512];
|
||||||
|
TokenList *pList = NULL;
|
||||||
|
TokenList *pCurrent;
|
||||||
|
TokenList *pName;
|
||||||
|
int iRet;
|
||||||
|
int i;
|
||||||
|
int pos;
|
||||||
|
float fValue;
|
||||||
|
long lID;
|
||||||
|
char *endp;
|
||||||
|
ObPar *par;
|
||||||
|
char acce[128], inte[128];
|
||||||
|
|
||||||
|
assert(pCon);
|
||||||
|
assert(pSics);
|
||||||
|
assert(remserver);
|
||||||
|
|
||||||
|
argtolower(argc,argv);
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
snprintf(buf, sizeof(buf), "%s = %s:%d", argv[0], remserver->host, remserver->port);
|
||||||
|
SCWrite(pCon, buf, eStatus);
|
||||||
|
} else {
|
||||||
|
pos=0;
|
||||||
|
for (i=1; i<argc; i++) {
|
||||||
|
pos+=snprintf(buf+pos, sizeof(buf)-pos, "%s ", argv[i]);
|
||||||
|
}
|
||||||
|
iRet = RemTransact(remserver, pCon, buf, ">", NULL);
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static void RemobKill(void *self) {
|
||||||
|
Remob *remob = self;
|
||||||
|
Remob *p, **last;
|
||||||
|
|
||||||
|
assert(remob);
|
||||||
|
|
||||||
|
/* remove from object list */
|
||||||
|
if (remob->server) {
|
||||||
|
last = &remob->server->objList;
|
||||||
|
p = *last;
|
||||||
|
while (p != remob && p !=NULL) {
|
||||||
|
last = &p->next;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
if (p != NULL) {
|
||||||
|
*last = p->next;
|
||||||
|
}
|
||||||
|
remob->next = NULL;
|
||||||
|
}
|
||||||
|
if (remob->name) {
|
||||||
|
free(remob->name);
|
||||||
|
}
|
||||||
|
if (remob->pDrivInt) {
|
||||||
|
free(remob->pDrivInt);
|
||||||
|
}
|
||||||
|
if (remob->pCall) {
|
||||||
|
DeleteCallBackInterface(remob->pCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get rid of parameter space */
|
||||||
|
if (remob->ParArray) {
|
||||||
|
ObParDelete(remob->ParArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* kill Descriptor */
|
||||||
|
DeleteDescriptor(remob->desc);
|
||||||
|
|
||||||
|
free(remob);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static void RemServerKill(void *self) {
|
||||||
|
RemServer *remserver = self;
|
||||||
|
|
||||||
|
assert(remserver);
|
||||||
|
|
||||||
|
if (remserver->taskActive) {
|
||||||
|
remserver->taskActive=0;
|
||||||
|
/* let the tasker kill me */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
remserver = (RemServer *)self;
|
||||||
|
if (remserver->chan) {
|
||||||
|
RemDisconnect(remserver);
|
||||||
|
}
|
||||||
|
DeleteDescriptor(remserver->desc);
|
||||||
|
if (remserver->name) free(remserver->name);
|
||||||
|
if (remserver->host) free(remserver->host);
|
||||||
|
if (remserver->user) free(remserver->user);
|
||||||
|
if (remserver->pass) free(remserver->pass);
|
||||||
|
free(remserver);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
static Remob *RemobInit(char *name, RemServer *remserver) {
|
||||||
|
Remob *remob, *p;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
/* get memory */
|
||||||
|
remob = (Remob *)malloc(sizeof(Remob));
|
||||||
|
if(!remob) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create and initialize parameters */
|
||||||
|
remob->ParArray = ObParCreate(2);
|
||||||
|
if (!remob->ParArray) {
|
||||||
|
free(remob);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ObParInit(remob->ParArray,INTERRUPTMODE,"interruptmode",0.0,usUser);
|
||||||
|
ObParInit(remob->ParArray,ACCESSCODE,"accesscode",(float)usUser,usMugger);
|
||||||
|
|
||||||
|
/* copy arguments */
|
||||||
|
remob->server = remserver;
|
||||||
|
remob->name = strdup(name);
|
||||||
|
|
||||||
|
/* initialise object descriptor */
|
||||||
|
remob->desc = CreateDescriptor("Remob");
|
||||||
|
if (!remob->desc) {
|
||||||
|
ObParDelete(remob->ParArray);
|
||||||
|
free(remob);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
remob->desc->GetInterface = RemobGetInterface;
|
||||||
|
remob->desc->SaveStatus = RemobSaveStatus;
|
||||||
|
|
||||||
|
/* initialise Drivable interface */
|
||||||
|
remob->pDrivInt = CreateDrivableInterface();
|
||||||
|
if (!remob->pDrivInt) {
|
||||||
|
DeleteDescriptor(remob->desc);
|
||||||
|
ObParDelete(remob->ParArray);
|
||||||
|
free(remob);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
remob->pDrivInt->SetValue = RemobRun;
|
||||||
|
remob->pDrivInt->CheckLimits = RemobLimits;
|
||||||
|
remob->pDrivInt->CheckStatus = RemobStatus;
|
||||||
|
remob->pDrivInt->GetValue = RemobGetValue;
|
||||||
|
remob->pDrivInt->Halt = RemobHalt;
|
||||||
|
|
||||||
|
/* initialise callback interface */
|
||||||
|
remob->pCall = CreateCallBackInterface();
|
||||||
|
if(!remob->pCall) {
|
||||||
|
RemobKill(remob);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if not yet in object list */
|
||||||
|
for (p = remserver->objList; p != NULL; p=p->next) {
|
||||||
|
if (p == remob) break;
|
||||||
|
}
|
||||||
|
if (p == NULL) {
|
||||||
|
remob->next = remserver->objList;
|
||||||
|
remserver->objList = remob;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!remserver->taskActive) {
|
||||||
|
remserver->taskActive = 1;
|
||||||
|
TaskRegister(pServ->pTasker, RemServerTask, NULL, RemServerKill, remserver, 1);
|
||||||
|
}
|
||||||
|
/* done */
|
||||||
|
return remob;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
static RemServer *RemServerInit(char *name, char *host, int port, char *user, char *pass) {
|
||||||
|
RemServer *remserver = NULL;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
remserver = malloc(sizeof(RemServer));
|
||||||
|
if (!remserver) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialise object descriptor */
|
||||||
|
remserver->desc = CreateDescriptor("RemServer");
|
||||||
|
if (!remserver->desc) {
|
||||||
|
free(remserver);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
remserver->taskActive = 0;
|
||||||
|
remserver->name = strdup(name);
|
||||||
|
remserver->host = strdup(host);
|
||||||
|
remserver->port = port;
|
||||||
|
remserver->user = strdup(user);
|
||||||
|
remserver->pass = strdup(pass);
|
||||||
|
remserver->incomplete = 0;
|
||||||
|
|
||||||
|
if (!remserver->name ||
|
||||||
|
!remserver->host ||
|
||||||
|
!remserver->port ||
|
||||||
|
!remserver->pass) {
|
||||||
|
/* no success, clean up */
|
||||||
|
RemServerKill(remserver);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return remserver;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
The Factory function for creating a remote driveable object.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
Remob server serverName host port user pass
|
||||||
|
Remob new remobName serverName
|
||||||
|
Remob del remobName (not yet implemented)
|
||||||
|
Remob del serverName (not yet implemented)
|
||||||
|
*/
|
||||||
|
|
||||||
|
int RemobCreate(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]) {
|
||||||
|
RemServer *remserver = NULL;
|
||||||
|
Remob *remob = NULL;
|
||||||
|
char buf[512];
|
||||||
|
int iD, iRet;
|
||||||
|
Tcl_Interp *pTcl = (Tcl_Interp *)pSics->pTcl;
|
||||||
|
|
||||||
|
assert(pCon);
|
||||||
|
assert(pSics);
|
||||||
|
|
||||||
|
if (argc <= 5) {
|
||||||
|
argtolower(argc,argv);
|
||||||
|
} else {
|
||||||
|
argtolower(5,argv);
|
||||||
|
}
|
||||||
|
if (argc == 7 && strcmp(argv[1], "server") == 0) {
|
||||||
|
remserver = RemServerInit(argv[2], argv[3], atoi(argv[4]), argv[5], argv[6]);
|
||||||
|
if (!remserver) {
|
||||||
|
snprintf(buf, sizeof(buf), "Failure to create remote server connection %s", argv[2]);
|
||||||
|
SCWrite(pCon, buf, eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* create the interpreter command */
|
||||||
|
iRet = AddCommand(pSics,argv[2],RemServerAction,RemServerKill,remserver);
|
||||||
|
if (!iRet) {
|
||||||
|
snprintf(buf, sizeof(buf),"ERROR: duplicate command %s not created",argv[1]);
|
||||||
|
SCWrite(pCon,buf,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
} else if (argc == 4 && strcmp(argv[1], "new") == 0) {
|
||||||
|
remserver = FindCommandData(pServ->pSics, argv[3], "RemServer");
|
||||||
|
if (!remserver) {
|
||||||
|
snprintf(buf, sizeof(buf), "remote server %s not found", argv[3]);
|
||||||
|
SCWrite(pCon, buf, eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
remob = RemobInit(argv[2], remserver);
|
||||||
|
if (!remob) {
|
||||||
|
snprintf(buf, sizeof(buf), "Failure to create remote driveable object %s", argv[1]);
|
||||||
|
SCWrite(pCon, buf, eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* create the interpreter command */
|
||||||
|
iRet = AddCommand(pSics,argv[2],RemobAction,RemobKill,remob);
|
||||||
|
if (!iRet) {
|
||||||
|
snprintf(buf, sizeof(buf),"ERROR: duplicate command %s not created",argv[1]);
|
||||||
|
SCWrite(pCon,buf,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf),"ERROR: illegal arguments for command remob",argv[1]);
|
||||||
|
SCWrite(pCon,buf,eError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
19
remob.h
Normal file
19
remob.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
remote driveable objects
|
||||||
|
|
||||||
|
Markus Zolliker July 04
|
||||||
|
|
||||||
|
copyright: see implementation file
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#ifndef SICSREM
|
||||||
|
#define SICSREM
|
||||||
|
#include "Scommon.h"
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int RemobCreate(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
13
tecs/didi
13
tecs/didi
@ -42,7 +42,7 @@ foreach dest ($destlist)
|
|||||||
endif
|
endif
|
||||||
end
|
end
|
||||||
|
|
||||||
set items=(TecsServer TecsClient six keep_running cfg)
|
set items=(TecsServer TecsClient six keep_running)
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo " all $items"
|
echo " all $items"
|
||||||
@ -70,21 +70,12 @@ if ($this == $0) then
|
|||||||
endif
|
endif
|
||||||
cd $this
|
cd $this
|
||||||
|
|
||||||
set makeit=1
|
|
||||||
set obj=../../obj/$SICS_VERSION/psi/tecs
|
set obj=../../obj/$SICS_VERSION/psi/tecs
|
||||||
foreach dest ($where)
|
foreach dest ($where)
|
||||||
alias get 'set d=$'"d_$dest;"'set t=$'"t_$dest"
|
alias get 'set d=$'"d_$dest;"'set t=$'"t_$dest"
|
||||||
get
|
get
|
||||||
foreach item ($what)
|
foreach item ($what)
|
||||||
echo $item D $d T $t
|
if ("$t" == "$OSTYPE") then
|
||||||
if ($item == cfg) then
|
|
||||||
if ($makeit) then
|
|
||||||
make config
|
|
||||||
set makeit=0
|
|
||||||
endif
|
|
||||||
echo tecs $d
|
|
||||||
rsync -e ssh -rCtv --delete-excluded $obj/cfg $d
|
|
||||||
else if ("$t" == "$OSTYPE") then
|
|
||||||
echo $item to $d
|
echo $item to $d
|
||||||
rsync -e ssh -vt $obj/$item $d
|
rsync -e ssh -vt $obj/$item $d
|
||||||
endif
|
endif
|
||||||
|
@ -9,7 +9,7 @@ foreach file ($files)
|
|||||||
echo ' $Q -p$(CFGDIR)' >> src/make_crv
|
echo ' $Q -p$(CFGDIR)' >> src/make_crv
|
||||||
echo '' >> src/make_crv
|
echo '' >> src/make_crv
|
||||||
end
|
end
|
||||||
echo "all_crv: \" >> src/make_crv
|
echo "all_crv: dev.list \" >> src/make_crv
|
||||||
foreach file ($files)
|
foreach file ($files)
|
||||||
set sens=${file:t:s/.inp//}
|
set sens=${file:t:s/.inp//}
|
||||||
echo ' $(CFGDIR)'"$sens.crv \" >> src/make_crv
|
echo ' $(CFGDIR)'"$sens.crv \" >> src/make_crv
|
||||||
|
@ -39,6 +39,10 @@ CFGDIR=/afs/psi.ch/project/sinq/common/lib/tecs/cfg/
|
|||||||
$(SRC)make_crv: make_crv.tcsh inp/lsc.codes $(ALLINP)
|
$(SRC)make_crv: make_crv.tcsh inp/lsc.codes $(ALLINP)
|
||||||
$(SRC)make_crv.tcsh $(SRC)inp/lsc.codes
|
$(SRC)make_crv.tcsh $(SRC)inp/lsc.codes
|
||||||
|
|
||||||
|
dev.list:
|
||||||
|
$(SRC)make_list.tcsh $(CFGDIR)*.cfg > $@
|
||||||
|
cp $@ $(CFGDIR)
|
||||||
|
|
||||||
# use target all_crv to make all curves in inp directory
|
# use target all_crv to make all curves in inp directory
|
||||||
|
|
||||||
TecsServer: $(SERV_OBJ) $(HARDSUPLIB) $(FORTIFYOBJ)
|
TecsServer: $(SERV_OBJ) $(HARDSUPLIB) $(FORTIFYOBJ)
|
||||||
|
@ -227,31 +227,38 @@ void StrNLink(StrBuf *buf, char *str, int length) {
|
|||||||
|
|
||||||
void flt_to_char4(double f, char buf[4]) {
|
void flt_to_char4(double f, char buf[4]) {
|
||||||
double m;
|
double m;
|
||||||
int e, res, ir;
|
int e;
|
||||||
|
long res;
|
||||||
|
|
||||||
m=frexp(f, &e);
|
m = frexp(f, &e);
|
||||||
e=e+EXP_OFFS;
|
e += EXP_OFFS;
|
||||||
if (e<0 || m==0) {
|
if (e < 0 || m == 0) {
|
||||||
res=0; m=0;
|
res = 0; m = 0;
|
||||||
} else {
|
} else {
|
||||||
if (e>255) {
|
if (e > 255) {
|
||||||
res=255*TWO_23+(TWO_23-1); /* max. representable number */
|
res = 255 * TWO_23 + (TWO_23 - 1); /* max. representable number */
|
||||||
} else {
|
} else {
|
||||||
res=e*TWO_23+(int)(0.5+(fabs(m*2)-1.0)*TWO_23);
|
res = (long)(0.5 + (fabs(m * 2) - 1.0) * TWO_23);
|
||||||
|
/* here we may think about the case, where m is just a little less than 1.0:
|
||||||
|
the mantissa part overflows to bit23, but, the result would be o.k., since this
|
||||||
|
just increases the exponent by one, and the mantissa bits get all zero.
|
||||||
|
but what happens when e is already 255 ? the next line handles this */
|
||||||
|
if (res == TWO_23 && e == 255) res--;
|
||||||
|
res += e * TWO_23;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf[0]=res % 256; res=res/256;
|
buf[0] = res % 256; res = res / 256;
|
||||||
buf[1]=res % 256; res=res/256;
|
buf[1] = res % 256; res = res / 256;
|
||||||
buf[2]=res % 256; res=res/256;
|
buf[2] = res % 256; res = res / 256;
|
||||||
if (m<0) {
|
if (m < 0) {
|
||||||
buf[3]=res-128;
|
buf[3] = res - 128;
|
||||||
} else {
|
} else {
|
||||||
buf[3]=res;
|
buf[3] = res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double flt_from_char4(char buf[4]) {
|
double flt_from_char4(char buf[4]) {
|
||||||
int s, i, b0, b1, b2, b3;
|
long i, b0, b1, b2, b3;
|
||||||
|
|
||||||
b0=buf[0]; if (b0<0) b0+=256;
|
b0=buf[0]; if (b0<0) b0+=256;
|
||||||
b1=buf[1]; if (b1<0) b1+=256;
|
b1=buf[1]; if (b1<0) b1+=256;
|
||||||
|
@ -2195,13 +2195,15 @@ static int xw_read_cursor(xw, mode, posn, ref, pos, key)
|
|||||||
/*
|
/*
|
||||||
* Discard un-handled ButtonPress, KeyPress and MotionNotify events.
|
* Discard un-handled ButtonPress, KeyPress and MotionNotify events.
|
||||||
*/
|
*/
|
||||||
if (xw->nofocus) { /* M.Z. */
|
/* removed M.Z.
|
||||||
|
if (xw->nofocus) {
|
||||||
while(xw_check_window_event(xw, xw->window, (long)
|
while(xw_check_window_event(xw, xw->window, (long)
|
||||||
(ButtonPressMask | PointerMotionMask), &event));
|
(ButtonPressMask | PointerMotionMask), &event));
|
||||||
} else {
|
} else {
|
||||||
while(xw_check_window_event(xw, xw->window, (long)
|
while(xw_check_window_event(xw, xw->window, (long)
|
||||||
(ButtonPressMask | KeyPressMask | PointerMotionMask), &event));
|
(ButtonPressMask | KeyPressMask | PointerMotionMask), &event));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if(xw->bad_device)
|
if(xw->bad_device)
|
||||||
return xw_end_cursor(xw, bc, 1);
|
return xw_end_cursor(xw, bc, 1);
|
||||||
xw->nofocus=0; /* M.Z. */
|
xw->nofocus=0; /* M.Z. */
|
||||||
@ -2329,6 +2331,7 @@ static int xw_read_cursor(xw, mode, posn, ref, pos, key)
|
|||||||
*/
|
*/
|
||||||
while(xw_check_window_event(xw, xw->window, (long)(PointerMotionMask),
|
while(xw_check_window_event(xw, xw->window, (long)(PointerMotionMask),
|
||||||
&event));
|
&event));
|
||||||
|
|
||||||
if(xw->bad_device || xw_erase_cursor(xw, bc))
|
if(xw->bad_device || xw_erase_cursor(xw, bc))
|
||||||
return xw_end_cursor(xw, bc, 1);
|
return xw_end_cursor(xw, bc, 1);
|
||||||
last.x = event.xmotion.x;
|
last.x = event.xmotion.x;
|
||||||
@ -3548,7 +3551,7 @@ static int xw_next_event(xw, event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*.......................................................................
|
/*.......................................................................
|
||||||
* like xw_next_event (see above), but with timeout in decisSecs (M.Z.)
|
* like xw_next_event (see above), but with timeout in deciSecs (M.Z.)
|
||||||
*/
|
*/
|
||||||
#ifdef __STDC__
|
#ifdef __STDC__
|
||||||
static int xw_next_event_tmo(XWdev *xw, XEvent *event, int tmo_10)
|
static int xw_next_event_tmo(XWdev *xw, XEvent *event, int tmo_10)
|
||||||
|
20
tecs/six.c
20
tecs/six.c
@ -259,18 +259,6 @@ int setrights(int gotolevel) {
|
|||||||
} else {
|
} else {
|
||||||
deflevel=2;
|
deflevel=2;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (NULL != strstr(instr, "TASP")) {
|
|
||||||
if (user1[0]=='\0') {
|
|
||||||
str_copy(user1,"Spy");
|
|
||||||
str_copy(pswd1,"007");
|
|
||||||
}
|
|
||||||
if (user2[0]=='\0') {
|
|
||||||
str_copy(user2,"Spy");
|
|
||||||
str_copy(pswd2,"007");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (gotolevel==0) gotolevel=deflevel;
|
if (gotolevel==0) gotolevel=deflevel;
|
||||||
if (gotolevel==1) {
|
if (gotolevel==1) {
|
||||||
if (user1[0]=='\0') {
|
if (user1[0]=='\0') {
|
||||||
@ -401,6 +389,7 @@ int main (int argc, char *argv[]) {
|
|||||||
int iret, pos;
|
int iret, pos;
|
||||||
fd_set mask;
|
fd_set mask;
|
||||||
int l, i, j, port, skip, gotolevel, sicslogin;
|
int l, i, j, port, skip, gotolevel, sicslogin;
|
||||||
|
int savehist = 0;
|
||||||
char buf[128], lbuf[16], ilow[64];
|
char buf[128], lbuf[16], ilow[64];
|
||||||
char stdPrompt[128], prompt[256];
|
char stdPrompt[128], prompt[256];
|
||||||
char *sim="";
|
char *sim="";
|
||||||
@ -527,6 +516,7 @@ int main (int argc, char *argv[]) {
|
|||||||
pos=0;
|
pos=0;
|
||||||
|
|
||||||
term_read_hist("six");
|
term_read_hist("six");
|
||||||
|
savehist = 1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (*p=='E') { /* Eager to ... */
|
if (*p=='E') { /* Eager to ... */
|
||||||
@ -589,15 +579,17 @@ int main (int argc, char *argv[]) {
|
|||||||
assert(fd==iret);
|
assert(fd==iret);
|
||||||
ERR_P(p=readWrite(fd,1000,0,"status = "));
|
ERR_P(p=readWrite(fd,1000,0,"status = "));
|
||||||
if (strcmp(p, "0") == 0) {
|
if (strcmp(p, "0") == 0) {
|
||||||
printf("\nconnection lost\n");
|
term_clear();
|
||||||
|
printf("\nconnection lost");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fputs("\n", stdout);
|
printf("\nexit %s\n", prompt);
|
||||||
term_save_hist(1); /* save history without last line */
|
term_save_hist(1); /* save history without last line */
|
||||||
return 0;
|
return 0;
|
||||||
OnError:
|
OnError:
|
||||||
|
if (savehist) term_save_hist(0); /* save history with last line */
|
||||||
ErrShow("end");
|
ErrShow("end");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
85
tecs/tecs.c
85
tecs/tecs.c
@ -21,6 +21,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TABLE_FILE "tecs.cfg"
|
#define TABLE_FILE "tecs.cfg"
|
||||||
|
#define DEV_LIST "dev.list"
|
||||||
#define LSC_CODES "lsc.codes"
|
#define LSC_CODES "lsc.codes"
|
||||||
#define LOGLIFETIME 24*3600
|
#define LOGLIFETIME 24*3600
|
||||||
|
|
||||||
@ -168,8 +169,7 @@ static int
|
|||||||
swRangeOn=0, /* switch heater range on when controller switched it off */
|
swRangeOn=0, /* switch heater range on when controller switched it off */
|
||||||
initMaxPower=0, /* set MaxPower for the first time */
|
initMaxPower=0, /* set MaxPower for the first time */
|
||||||
lockAlarm,
|
lockAlarm,
|
||||||
cntError,
|
cntError;
|
||||||
tableTime; /* last time when table was read */
|
|
||||||
|
|
||||||
int tim, rdTim; /* actual time, read Time */
|
int tim, rdTim; /* actual time, read Time */
|
||||||
|
|
||||||
@ -536,14 +536,12 @@ int InstalCurve(SensorT *sensor, char *devArg) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReadTable(void) {
|
int ReadTable(void) { /* obsolete */
|
||||||
char nbuf[256];
|
char nbuf[256];
|
||||||
if (table!=NULL && tim>tableTime+60) { FREE(table); table=NULL; }; /* clear old table */
|
if (table!=NULL) { FREE(table); table=NULL; };
|
||||||
if (table!=NULL) return 0;
|
|
||||||
str_copy(nbuf, binDir);
|
str_copy(nbuf, binDir);
|
||||||
str_append(nbuf, TABLE_FILE);
|
str_append(nbuf, TABLE_FILE);
|
||||||
ERR_P(table=str_read_file(nbuf));
|
ERR_P(table=str_read_file(nbuf));
|
||||||
tableTime=tim;
|
|
||||||
return 1;
|
return 1;
|
||||||
OnError: return -1;
|
OnError: return -1;
|
||||||
}
|
}
|
||||||
@ -574,11 +572,13 @@ int PrepInput(char *label) {
|
|||||||
} else {
|
} else {
|
||||||
str_copy(nam, label);
|
str_copy(nam, label);
|
||||||
}
|
}
|
||||||
|
again:
|
||||||
str_copy(buf, binDir);
|
str_copy(buf, binDir);
|
||||||
str_append(buf, nam);
|
str_append(buf, nam);
|
||||||
str_append(buf, ".cfg");
|
str_append(buf, ".cfg");
|
||||||
cfg=str_read_file(buf);
|
cfg=str_read_file(buf);
|
||||||
if (cfg==NULL) { /* will be obsolete */
|
if (cfg==NULL) { /* will be obsolete */
|
||||||
|
logfileOut(LOG_MAIN, "%s not found, try tecs.cfg\n", buf);
|
||||||
ERR_I(ReadTable());
|
ERR_I(ReadTable());
|
||||||
t=strstr(table, label);
|
t=strstr(table, label);
|
||||||
if (t==NULL) ERR_MSG("device not found");
|
if (t==NULL) ERR_MSG("device not found");
|
||||||
@ -586,6 +586,14 @@ int PrepInput(char *label) {
|
|||||||
if (e==NULL || e>strchr(t,'\n')) ERR_MSG("missing ' or device name in table file");
|
if (e==NULL || e>strchr(t,'\n')) ERR_MSG("missing ' or device name in table file");
|
||||||
t=e+1;
|
t=e+1;
|
||||||
}
|
}
|
||||||
|
if (cfg && *cfg=='@') { /* alias */
|
||||||
|
t=strchr(cfg,'\n');
|
||||||
|
if (t) *t='\0';
|
||||||
|
str_copy(nam, cfg+1);
|
||||||
|
str_copy(plug->device, nam);
|
||||||
|
FREE(cfg);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
if (plug==&plug0) {
|
if (plug==&plug0) {
|
||||||
InitSensor(&sensA);
|
InitSensor(&sensA);
|
||||||
InitSensor(&sensB);
|
InitSensor(&sensB);
|
||||||
@ -694,8 +702,15 @@ int PrepInput(char *label) {
|
|||||||
str_copy(plug->device, nam);
|
str_copy(plug->device, nam);
|
||||||
ConcatDevice();
|
ConcatDevice();
|
||||||
}
|
}
|
||||||
|
if (cfg) {
|
||||||
|
FREE(cfg);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
OnError: return -1;
|
OnError:
|
||||||
|
if (cfg) {
|
||||||
|
FREE(cfg);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LoadCache(void) {
|
int LoadCache(void) {
|
||||||
@ -1709,11 +1724,16 @@ int ConfigByCode(int plugNr) {
|
|||||||
p=fgets(buf, sizeof(buf), fil);
|
p=fgets(buf, sizeof(buf), fil);
|
||||||
}
|
}
|
||||||
fclose(fil);
|
fclose(fil);
|
||||||
logfileOut(LOG_MAIN+LOG_STAT ,"configure plug%d for %s (code %d)\n", plugNr, nam, plug->code);
|
if (plug->code != c1 && plug->code != c2) {
|
||||||
str_copy(buf, "'");
|
logfileOut(LOG_MAIN+LOG_STAT ,"unknown code %d on plug%d\n", plug->code, plugNr);
|
||||||
str_append(buf, nam);
|
return 0;
|
||||||
str_append(buf, "'");
|
} else {
|
||||||
ERR_I(PrepInput(buf));
|
logfileOut(LOG_MAIN+LOG_STAT ,"configure plug%d for %s (code %d)\n", plugNr, nam, plug->code);
|
||||||
|
str_copy(buf, "'");
|
||||||
|
str_append(buf, nam);
|
||||||
|
str_append(buf, "'");
|
||||||
|
ERR_I(PrepInput(buf));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
settingsFlag=1;
|
settingsFlag=1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -2606,39 +2626,14 @@ EndStatus:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int DevHelpHdl(int mode, void *base, int fd) {
|
int DevHelpHdl(int mode, void *base, int fd) {
|
||||||
char *t, *n, *d, *en, *ed;
|
char nbuf[256];
|
||||||
char line[80], nbuf[256];
|
char *list;
|
||||||
int l, iret;
|
|
||||||
static int doit=1;
|
|
||||||
|
|
||||||
ERR_I(iret=ReadTable());
|
str_copy(nbuf, binDir);
|
||||||
if (iret) doit=1;
|
str_append(nbuf, DEV_LIST);
|
||||||
if (doit) {
|
ERR_P(list=str_read_file(nbuf));
|
||||||
doit=0;
|
str_copy(devHelp, list);
|
||||||
t=table;
|
FREE(list);
|
||||||
str_copy(devHelp,"\n");
|
|
||||||
while (t!=NULL) {
|
|
||||||
t++;
|
|
||||||
n=strchr(t, '\'');
|
|
||||||
d=strstr(t, "dev=\"");
|
|
||||||
t=strchr(t, '\n');
|
|
||||||
if (n!=NULL && d!=NULL && n < d && d < t) {
|
|
||||||
en=strchr(n+1, '\'');
|
|
||||||
ed=strchr(d+5, '"');
|
|
||||||
if (en != NULL && en<d && ed != NULL && ed<t) {
|
|
||||||
l=en-n;
|
|
||||||
if (l>12) l=12;
|
|
||||||
str_ncpy(line, n+1, l);
|
|
||||||
str_npad(line, line, 12);
|
|
||||||
l=ed-d;
|
|
||||||
if (l>77) l=77;
|
|
||||||
str_ncpy(line+12, d+5, l);
|
|
||||||
str_append(line, "\n");
|
|
||||||
str_append(devHelp, line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
OnError: return -1;
|
OnError: return -1;
|
||||||
}
|
}
|
||||||
@ -2901,7 +2896,7 @@ int main(int argc, char *argv[]) {
|
|||||||
CocDefInt(relay, RW); CocHdl(RelayHdl);
|
CocDefInt(relay, RW); CocHdl(RelayHdl);
|
||||||
CocDefInt(manual, RW); CocHdl(ManualHdl);
|
CocDefInt(manual, RW); CocHdl(ManualHdl);
|
||||||
CocDefInt(htrst, RD);
|
CocDefInt(htrst, RD);
|
||||||
CocDefInt(loop, RD);
|
CocDefInt(loop, RW);
|
||||||
CocDefInt(rdTim, RD);
|
CocDefInt(rdTim, RD);
|
||||||
CocDefInt(tim0, RD);
|
CocDefInt(tim0, RD);
|
||||||
CocDefInt(ibuf, RD);
|
CocDefInt(ibuf, RD);
|
||||||
|
@ -73,7 +73,8 @@
|
|||||||
l=0
|
l=0
|
||||||
1 if (oneCommand) goto 99
|
1 if (oneCommand) goto 99
|
||||||
if (nfiles .gt. 0) then
|
if (nfiles .gt. 0) then
|
||||||
read(luns(idx), '(q,a)', err=22,end=22) l, line
|
read(luns(idx), '(a)', err=22,end=22) line
|
||||||
|
call str_trim(line, line, l)
|
||||||
print '(x,2a)', prompt(1:promptlen),line(1:max(1,l))
|
print '(x,2a)', prompt(1:promptlen),line(1:max(1,l))
|
||||||
else
|
else
|
||||||
call sys_rd_line(line, l, prompt(1:promptlen))
|
call sys_rd_line(line, l, prompt(1:promptlen))
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
logical yzoom
|
logical yzoom
|
||||||
integer winconf(nwin) ! number of windows below actual
|
integer winconf(nwin) ! number of windows below actual
|
||||||
integer showsets
|
integer showsets
|
||||||
|
integer nextfocus
|
||||||
real winh
|
real winh
|
||||||
integer nticks
|
integer nticks
|
||||||
character key*1
|
character key*1
|
||||||
@ -128,6 +129,7 @@
|
|||||||
allpars=allpars(1:l)//' '//parnam(im)
|
allpars=allpars(1:l)//' '//parnam(im)
|
||||||
enddo
|
enddo
|
||||||
showsets=1
|
showsets=1
|
||||||
|
nextfocus=0
|
||||||
|
|
||||||
1 continue
|
1 continue
|
||||||
|
|
||||||
@ -135,6 +137,10 @@
|
|||||||
if (iret .lt. 0) goto 99
|
if (iret .lt. 0) goto 99
|
||||||
tdif=myc_now()-t
|
tdif=myc_now()-t
|
||||||
tdif=tdif-mod(tdif+1800*25, 3600)+1800 ! round to next full hour
|
tdif=tdif-mod(tdif+1800*25, 3600)+1800 ! round to next full hour
|
||||||
|
if (tdif .gt. 7200 .or. tdif .lt. -7200) then ! a hack
|
||||||
|
t=myc_now()
|
||||||
|
tdif=0
|
||||||
|
endif
|
||||||
if (tdif .ne. 0) then
|
if (tdif .ne. 0) then
|
||||||
print *,'time difference ',tdif/3600,' h'
|
print *,'time difference ',tdif/3600,' h'
|
||||||
endif
|
endif
|
||||||
@ -258,16 +264,18 @@
|
|||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
if (j .eq. 0) then
|
if (j .eq. 0) then
|
||||||
if (.not. yzoom) then
|
if (nextfocus .ne. 0) then
|
||||||
|
do is=1,nset
|
||||||
|
im=imx(is)
|
||||||
|
if (retLen(is) .gt. 0 .and. unit(im) .eq. 1) focus(im)=.true.
|
||||||
|
enddo
|
||||||
|
else if (.not. yzoom) then
|
||||||
y1=ymin(1)
|
y1=ymin(1)
|
||||||
y2=ymax(1)
|
y2=ymax(1)
|
||||||
yzoom=.true.
|
yzoom=.true.
|
||||||
endif
|
endif
|
||||||
! do is=1,nset
|
|
||||||
! im=imx(is)
|
|
||||||
! if (retLen(is) .gt. 0 .and. unit(im) .eq. 1) focus(im)=.true.
|
|
||||||
! enddo
|
|
||||||
endif
|
endif
|
||||||
|
nextfocus=0
|
||||||
if (saveit) goto 9
|
if (saveit) goto 9
|
||||||
if (mode .eq. live) then
|
if (mode .eq. live) then
|
||||||
x2=max(tim0,x2)+min(1800., window*0.5)
|
x2=max(tim0,x2)+min(1800., window*0.5)
|
||||||
@ -360,8 +368,8 @@
|
|||||||
|
|
||||||
ey=(ymax(rl)-ymin(rl))
|
ey=(ymax(rl)-ymin(rl))
|
||||||
fy=abs(ymax(rl))
|
fy=abs(ymax(rl))
|
||||||
ymax(rl)=ymax(rl)+max(fy*0.0075,ey*0.01)
|
ymax(rl)=ymax(rl)+max(fy*0.02,ey*0.01)
|
||||||
ymin(rl)=ymin(rl)-max(fy*0.005,ey*0.01)
|
ymin(rl)=ymin(rl)-max(fy*0.02,ey*0.01)
|
||||||
if (mode .eq. live) then
|
if (mode .eq. live) then
|
||||||
ymin(rl)=min(ymin(rl),max(0.0,ylast1-ey*0.4))
|
ymin(rl)=min(ymin(rl),max(0.0,ylast1-ey*0.4))
|
||||||
ymax(rl)=max(ymax(rl),ylast2+ey*0.4)
|
ymax(rl)=max(ymax(rl),ylast2+ey*0.4)
|
||||||
@ -628,7 +636,7 @@
|
|||||||
elseif (key .eq. 'X') then
|
elseif (key .eq. 'X') then
|
||||||
window=0
|
window=0
|
||||||
mode=0
|
mode=0
|
||||||
yzoom=.true.
|
yzoom=.false.
|
||||||
elseif (key .eq. '+' .or. key .eq. ',') then
|
elseif (key .eq. '+' .or. key .eq. ',') then
|
||||||
window=max(winmin,window/2)
|
window=max(winmin,window/2)
|
||||||
if (ex .eq. undef) then
|
if (ex .eq. undef) then
|
||||||
@ -759,6 +767,7 @@
|
|||||||
goto 9
|
goto 9
|
||||||
elseif (key .eq. 'A') then
|
elseif (key .eq. 'A') then
|
||||||
showsets=2
|
showsets=2
|
||||||
|
yzoom=.false.
|
||||||
elseif (key .eq. 'C') then ! clear set
|
elseif (key .eq. 'C') then ! clear set
|
||||||
if (ex .lt. x1) then
|
if (ex .lt. x1) then
|
||||||
if (ey .ge. ymin(1) .and.
|
if (ey .ge. ymin(1) .and.
|
||||||
@ -806,17 +815,28 @@
|
|||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
if (n .gt. 1) then
|
if (n .gt. 1) then
|
||||||
if (j .gt. 4) then ! was "all", set to "default"
|
if (j .gt. 3) then ! was "all", set to "default"
|
||||||
focus(1)=.true.
|
focus(1)=.true.
|
||||||
focus(2)=.true.
|
focus(2)=.true.
|
||||||
focus(3)=.true.
|
focus(3)=.true.
|
||||||
else ! was "default" select 1
|
else ! was "default" select 1
|
||||||
focus(1)=.true.
|
focus(1)=.true.
|
||||||
endif
|
endif
|
||||||
else if (j .lt. nset) then ! select next
|
goto 89
|
||||||
im=imx(j)
|
endif
|
||||||
|
nextfocus=1
|
||||||
|
do is=1,nset
|
||||||
|
im=imx(is)
|
||||||
|
if (im .gt. j) then ! select next
|
||||||
|
focus(im)=.true.
|
||||||
|
goto 89
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
! select all
|
||||||
|
do is=1,nset
|
||||||
|
im=imx(is)
|
||||||
focus(im)=.true.
|
focus(im)=.true.
|
||||||
endif ! else select none -> will be all
|
enddo
|
||||||
89 yzoom=.false.
|
89 yzoom=.false.
|
||||||
elseif (mode .eq. live) then
|
elseif (mode .eq. live) then
|
||||||
goto 7
|
goto 7
|
||||||
|
@ -201,8 +201,7 @@ char *term_fgets(char *buf, int size, FILE *fil) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void term_save_hist(int
|
void term_save_hist(int trimlast) {
|
||||||
trimlast) {
|
|
||||||
FILE *fil;
|
FILE *fil;
|
||||||
int i,n;
|
int i,n;
|
||||||
if (filehead[0]=='\0') return;
|
if (filehead[0]=='\0') return;
|
||||||
@ -319,6 +318,11 @@ int term_get_line(char *buf, int size, int *pos, char *prompt, fd_set *mask) {
|
|||||||
}
|
}
|
||||||
hist_pos=hist_end;
|
hist_pos=hist_end;
|
||||||
term_save_hist(0);
|
term_save_hist(0);
|
||||||
|
printf("\r\033[K\n");
|
||||||
|
for (i = strlen(prompt) - 1; i > 0; i--) {
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf(" %s", buf);
|
||||||
return(STDIN_FILENO);
|
return(STDIN_FILENO);
|
||||||
|
|
||||||
/* normal EXIT */
|
/* normal EXIT */
|
||||||
|
Reference in New Issue
Block a user