bug fixes and enhancements related to evcontroller

This commit is contained in:
zolliker
2005-03-03 14:13:45 +00:00
parent 48da61421c
commit 0677ecfbe7
13 changed files with 474 additions and 204 deletions

View File

@ -20,9 +20,7 @@
#include <servlog.h> #include <servlog.h>
#include <fortify.h> #include <fortify.h>
typedef struct __EVDriver *pEVDriver; #include "evdriver.h"
#include <evdriver.i>
#include "hardsup/dillutil.h" #include "hardsup/dillutil.h"
#include "hardsup/el734_def.h" #include "hardsup/el734_def.h"
#include "hardsup/el734fix.h" #include "hardsup/el734fix.h"

View File

@ -18,9 +18,7 @@
#include <servlog.h> #include <servlog.h>
#include <fortify.h> #include <fortify.h>
typedef struct __EVDriver *pEVDriver; #include "evdriver.h"
#include <evdriver.i>
#include "hardsup/el755_def.h" #include "hardsup/el755_def.h"
#include "hardsup/el755_errcodes.h" #include "hardsup/el755_errcodes.h"
#include "hardsup/sinq_prototypes.h" #include "hardsup/sinq_prototypes.h"

View File

@ -22,9 +22,7 @@
#include <servlog.h> #include <servlog.h>
#include <fortify.h> #include <fortify.h>
typedef struct __EVDriver *pEVDriver; #include "evdriver.h"
#include <evdriver.i>
#include "hardsup/el734_def.h" #include "hardsup/el734_def.h"
#include "hardsup/el734fix.h" #include "hardsup/el734fix.h"
#include "hardsup/serialsinq.h" #include "hardsup/serialsinq.h"

77
eve.c
View File

@ -26,9 +26,9 @@ Markus Zolliker, Sept 2004
#define ILLNUM -1456 #define ILLNUM -1456
#define ILLARGC -1457 #define ILLARGC -1457
#define AMBIGUOS -1458 #define AMBIGUOS -1458
#define UNCHANGEABLE -1459
#define ILLPRIV -1460 #define ILLPRIV -1460
#define BADLOG -1461 #define BADLOG -1461
#define BUSY -1462
typedef enum { typedef enum {
cntAction, iniAction, parAction, listAction, cntAction, iniAction, parAction, listAction,
@ -140,9 +140,7 @@ char *EveInt2Text(char *list[], int num) {
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
int EveCheckRights(EveParArg *arg, int access) { int EveCheckRights(EveParArg *arg, int access) {
if (access == usInternal) { if (SCMatchRights(arg->pCon,access)) {
arg->ret = UNCHANGEABLE;
} else if (SCMatchRights(arg->pCon,access)) {
return 1; return 1;
} else { } else {
arg->ret = ILLPRIV; arg->ret = ILLPRIV;
@ -181,10 +179,9 @@ EvePar *EveThisPar(EveParArg *arg, char *name, int flags) {
if (!eve->par) return NULL; if (!eve->par) return NULL;
assert(arg->idx < eve->npar); assert(arg->idx < eve->npar);
par = eve->par + arg->idx; par = eve->par + arg->idx;
/* arg->idx ++ */
if (par->name == NULL) { if (par->name == NULL) {
par->name = name; par->name = name;
if (flags & 2) { /* first time: default logger */ if (flags & EVE_LOGPAR) { /* first time: default logger */
EveSwitchLog(eve, par, 1); EveSwitchLog(eve, par, 1);
} }
} else { } else {
@ -252,12 +249,12 @@ ArgOp EveOp(EveParArg *arg, char *name, char **fmt, int access, int flags) {
arg->idx ++; arg->idx ++;
return noOp; return noOp;
case listAction: case listAction:
if (flags & 1) { if (flags & EVE_ACTPAR) {
return fmtOp; return fmtOp;
} }
return noOp; return noOp;
case logAction: case logAction:
if (flags & 1) { if (flags & EVE_ACTPAR) {
op = fmtOp; op = fmtOp;
break; /* reduce fmt */ break; /* reduce fmt */
} }
@ -295,7 +292,7 @@ ArgOp EveOp(EveParArg *arg, char *name, char **fmt, int access, int flags) {
} }
return noOp; return noOp;
case saveAction: case saveAction:
if (flags & 4) { if (flags & EVE_SAVEPAR) {
op = fmtOp; op = fmtOp;
break; /* reduce fmt */ break; /* reduce fmt */
} }
@ -320,8 +317,10 @@ ArgOp EveOp(EveParArg *arg, char *name, char **fmt, int access, int flags) {
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void EveOut(EveParArg *arg, char *name, char *buf) { void EveOut(EveParArg *arg, char *name, char *buf) {
EvePar *par; EvePar *par;
int l, i, j, m, ln, lp; int l, i, j, m, ln, lp, iret;
char *p, *q, *tab; char *p, *q, *tab;
char buffer[256];
char *dot;
switch (arg->action) { switch (arg->action) {
case listAction: case listAction:
@ -367,7 +366,16 @@ void EveOut(EveParArg *arg, char *name, char *buf) {
par = EveThisPar(arg, name, 0); par = EveThisPar(arg, name, 0);
arg->idx ++; arg->idx ++;
if (par->log) { if (par->log) {
LoggerWrite(par->log, arg->now, arg->period, buf); iret = LoggerWrite(par->log, arg->now, arg->period, buf);
if (iret) {
if (*name) {
dot = ".";
} else {
dot = "";
}
snprintf(buffer, sizeof buffer, "%s%s%s = %s", arg->evc->pName, dot, name, buf);
InvokeCallBack(arg->evc->pCall, VALUECHANGE, buffer);
}
} }
break; break;
case saveAction: case saveAction:
@ -394,6 +402,7 @@ void EveFloatPar(EveParArg *arg, char *name, float *value, char *fmt,
break; break;
} }
*value = f; *value = f;
SCparChange(arg->pCon);
/* fall through */ /* fall through */
case fmtOp: case fmtOp:
snprintf(buf, sizeof buf, fmt, *value); snprintf(buf, sizeof buf, fmt, *value);
@ -419,6 +428,7 @@ void EveIntPar(EveParArg *arg, char *name, int *value, int access, int flags) {
break; break;
} }
*value = i; *value = i;
SCparChange(arg->pCon);
/* fall through */ /* fall through */
case fmtOp: case fmtOp:
snprintf(buf, sizeof buf, "%d", *value); snprintf(buf, sizeof buf, "%d", *value);
@ -438,6 +448,7 @@ void EveStrPar(EveParArg *arg, char *name, char **value, int maxsize, int access
} else { /* fixed string */ } else { /* fixed string */
EveArg2Text(arg->argc, arg->argv, *value, maxsize); EveArg2Text(arg->argc, arg->argv, *value, maxsize);
} }
SCparChange(arg->pCon);
/* fall through */ /* fall through */
case fmtOp: case fmtOp:
if (*value == NULL) value = &empty; if (*value == NULL) value = &empty;
@ -465,6 +476,7 @@ void EveObPar(EveParArg *arg, int index, char *fmt, int flags) {
} else { } else {
arg->evc->pParam[index].fVal = f; arg->evc->pParam[index].fVal = f;
} }
SCparChange(arg->pCon);
/* fall through */ /* fall through */
case fmtOp: case fmtOp:
snprintf(buf, sizeof buf, fmt, arg->evc->pParam[index].fVal); snprintf(buf, sizeof buf, fmt, arg->evc->pParam[index].fVal);
@ -492,6 +504,7 @@ void EveObParEnum(EveParArg *arg, int index, char *list[], int flags) {
} else { } else {
arg->evc->pParam[index].fVal = i; arg->evc->pParam[index].fVal = i;
} }
SCparChange(arg->pCon);
/* fall through */ /* fall through */
case fmtOp: case fmtOp:
i = (int)ObVal(arg->evc->pParam, index); i = (int)ObVal(arg->evc->pParam, index);
@ -517,6 +530,7 @@ void EveEnumPar(EveParArg *arg, char *name, int *value, char *list[], int access
arg->ret = ILLNUM; arg->ret = ILLNUM;
} else { } else {
*value = i; *value = i;
SCparChange(arg->pCon);
} }
/* fall through */ /* fall through */
case fmtOp: case fmtOp:
@ -540,6 +554,20 @@ void EveCmd(EveParArg *arg, char *name, EveSubCmd subcmd, int access) {
} }
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void EveFloatCmd(EveParArg *arg, char *name, float *value, char *fmt,
FsmFunc fsmFunc, int access, int flags) {
Eve *eve;
EveFloatPar(arg, name, value, fmt, access, flags);
if (arg->action == parAction && arg->argc == 2 && 0==strcasecmp(name, arg->argv[0])) {
eve = (Eve *)arg->evc->pDriv->pPrivate;
if (eve->todo) {
arg->ret = BUSY;
} else {
eve->todo = fsmFunc;
}
}
}
/*----------------------------------------------------------------------------*/
#define A EVE_ACTPAR #define A EVE_ACTPAR
#define L EVE_LOGPAR #define L EVE_LOGPAR
#define S EVE_SAVEPAR #define S EVE_SAVEPAR
@ -580,6 +608,10 @@ SConnection *EveArgConn(EveParArg *arg) {
return arg->pCon; return arg->pCon;
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
int EveUserAction(EveParArg *arg) {
return (arg->action == parAction || arg->action == listAction);
}
/*----------------------------------------------------------------------------*/
int EveWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, int EveWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) { int argc, char *argv[]) {
pEVControl evc = pData; pEVControl evc = pData;
@ -620,9 +652,6 @@ error:
case AMBIGUOS: case AMBIGUOS:
SCPrintf(pCon, eError, "ERROR: doubly defined parameter %s.%s", evc->pName, argv[1]); SCPrintf(pCon, eError, "ERROR: doubly defined parameter %s.%s", evc->pName, argv[1]);
break; break;
case UNCHANGEABLE:
SCPrintf(pCon, eError, "ERROR: %s.%s is not changeable", evc->pName, argv[1]);
break;
case ILLPRIV: case ILLPRIV:
SCPrintf(pCon, eError, "ERROR: Insufficient privilege to change %s.%s", evc->pName, argv[1]); SCPrintf(pCon, eError, "ERROR: Insufficient privilege to change %s.%s", evc->pName, argv[1]);
break; break;
@ -635,6 +664,9 @@ error:
case BADLOG: case BADLOG:
SCPrintf(pCon, eError, "ERROR: can not create log directory for %s %s", evc->pName, argv[1]); SCPrintf(pCon, eError, "ERROR: can not create log directory for %s %s", evc->pName, argv[1]);
break; break;
case BUSY:
SCPrintf(pCon, eError, "ERROR: %s busy", evc->pName);
break;
default: default:
return arg.ret; return arg.ret;
} }
@ -740,7 +772,7 @@ int EveIdle(long pc, Eve *eve) {
rd: rd:
if (eve->hwstate == HWBusy) eve->hwstate = HWIdle; if (eve->hwstate == HWBusy) eve->hwstate = HWIdle;
FSM_CALL(eve->read); FSM_CALL(eve->read);
EveLog(eve); EveLog(eve); /* just for the case EveLog was not included in the read function */
if (eve->logtime == 0) eve->logtime = 1; if (eve->logtime == 0) eve->logtime = 1;
if (eve->todo) goto doit; if (eve->todo) goto doit;
/* /*
@ -856,19 +888,17 @@ int EveDontFix(pEVDriver driver, int iError) {
return(DEVFAULT); /* severe */ return(DEVFAULT); /* severe */
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
int EveSaveStatus(void *data, char *name, FILE *fil) int EveSavePars(pEVDriver driver, FILE *fil)
{ {
pEVControl evc = data; Eve *eve = driver->pPrivate;
Eve *eve = evc->pDriv->pPrivate;
EveParArg arg; EveParArg arg;
EVSaveStatus(data, name, fil);
arg.action = saveAction; arg.action = saveAction;
arg.pCon = NULL; arg.pCon = NULL;
arg.evc = evc; arg.evc = eve->evc;
arg.fil = fil; arg.fil = fil;
eve->pardef(eve, &arg); eve->pardef(eve, &arg);
return 1; return 2; /* no (duplicate) save of standard parameters ! */
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
void EveKill(void *pData) { void EveKill(void *pData) {
@ -880,7 +910,9 @@ void EveKill(void *pData) {
assert(eve); assert(eve);
KillRS232(eve->ser); KillRS232(eve->ser);
for (i=0; i<eve->npar; i++) { for (i=0; i<eve->npar; i++) {
LoggerKill(eve->par[i].log); if (eve->par[i].log) {
LoggerKill(eve->par[i].log);
}
eve->par[i].log = NULL; eve->par[i].log = NULL;
} }
free(eve); free(eve);
@ -982,6 +1014,7 @@ pEVControl MakeEveEVC(int argc, char *argv[], Eve *eve, SConnection *pCon) {
driver->Send = EveSend; driver->Send = EveSend;
driver->GetError = EveGetError; driver->GetError = EveGetError;
driver->TryFixIt = EveDontFix; driver->TryFixIt = EveDontFix;
driver->SavePars = EveSavePars;
driver->Init = EveInit; driver->Init = EveInit;
driver->Close = EveClose; driver->Close = EveClose;

11
eve.h
View File

@ -80,6 +80,7 @@ typedef struct Eve {
* index: the ObPar index * index: the ObPar index
* list: a NULL terminated list of value names * list: a NULL terminated list of value names
* subcmd: a function for handling the subcommand * subcmd: a function for handling the subcommand
* fsmFunc: a fsm function to handle a subcommand
*/ */
void EveFloatPar(EveParArg *arg, char *name, float *value, char *fmt, void EveFloatPar(EveParArg *arg, char *name, float *value, char *fmt,
int access, int flags); int access, int flags);
@ -92,7 +93,9 @@ void EveObParEnum(EveParArg *arg, int index, char *list[], int flags);
void EveEnumPar(EveParArg *arg, char *name, int *value, char *list[], void EveEnumPar(EveParArg *arg, char *name, int *value, char *list[],
int access, int flags); int access, int flags);
void EveCmd(EveParArg *arg, char *name, EveSubCmd subcmd, int access); void EveCmd(EveParArg *arg, char *name, EveSubCmd subcmd, int access);
void EveFloatCmd(EveParArg *arg, char *name, float *value, char *fmt,
FsmFunc fsmFunc, int access, int flags);
/* a collection of parameters from the standard EVController /* a collection of parameters from the standard EVController
* (limits, tolerance, drive handling, out of tolerance handling) * (limits, tolerance, drive handling, out of tolerance handling)
* normally appearing at the top * normally appearing at the top
@ -107,9 +110,15 @@ void EveStdParEnd(EveParArg *arg, char *fmt, int targetFlag);
/* return the connection related to the parameter request */ /* return the connection related to the parameter request */
SConnection *EveArgConn(EveParArg *arg); SConnection *EveArgConn(EveParArg *arg);
/* check if it is a user action (parameter list, set or read) */
int EveUserAction(EveParArg *arg);
/* write to the actual (last driving) connection */ /* write to the actual (last driving) connection */
int EvePrintf(Eve *eve, int iOut, char *fmt, ...); int EvePrintf(Eve *eve, int iOut, char *fmt, ...);
/* evelog has to be called after all read operations */
void EveLog(Eve *eve);
void EveWriteError(Eve *eve); void EveWriteError(Eve *eve);
void EveWrite(Eve *eve, char *cmd); void EveWrite(Eve *eve, char *cmd);
void EveWaitRead(Eve *eve); void EveWaitRead(Eve *eve);

1
fsm.c
View File

@ -78,6 +78,7 @@ Fsm *FsmStartTask(void *obj, FsmHandler handler, FsmFunc func) {
new->func = func; new->func = func;
new->handler = handler; new->handler = handler;
new->sp = 0; new->sp = 0;
new->pause = 0;
new->till = 0; new->till = 0;
return new; return new;
} }

View File

@ -33,6 +33,7 @@ typedef struct {
float current; /* current (in Tesla) */ float current; /* current (in Tesla) */
float persfield; /* persistent field from IPS (in Tesla) */ float persfield; /* persistent field from IPS (in Tesla) */
float lastfield; /* persistent field from last drive */ float lastfield; /* persistent field from last drive */
float confirmfield; /* field confirmed in 1st step */
float ramp; /* actual ramp rate (Telsa/min) */ float ramp; /* actual ramp rate (Telsa/min) */
int persmode; /* 0: leave switch on, 1: go to persistant mode */ int persmode; /* 0: leave switch on, 1: go to persistant mode */
int perswitch; /* state of switch */ int perswitch; /* state of switch */
@ -43,22 +44,18 @@ typedef struct {
time_t tim; time_t tim;
} IpsDriv; } IpsDriv;
int IpsConfirm(SConnection *pCon, pEVControl evc, int argc, char *argv[]);
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
static int IpsOk(IpsDriv *me, SConnection *pCon) { static int IpsOk(IpsDriv *me, SConnection *pCon) {
float dif; float dif;
Eve *eve=&me->eve; Eve *eve=&me->eve;
if (!pCon) pCon = SCLoad(&eve->evc->conn); if (me->eve.version[0]=='\0') return 1; /* connection not yet confirmed */
if (me->perswitch) return 1; if (me->perswitch) return 1;
if (fabs(me->persfield - me->lastfield) < 1e-5) { if (fabs(me->persfield - me->lastfield) < 1e-5) return 1;
return 1; if (me->force != 0) return 1;
}
if (me->force == 2) {
return 1;
}
if (fabs(me->persfield - me->lastfield) < 1e-5
|| me->force == 2) return 1;
eve->errCode = EVE_FAULT; eve->errCode = EVE_FAULT;
if (!pCon) pCon = SCLoad(&eve->evc->conn);
SCPrintf(pCon, eWarning, SCPrintf(pCon, eWarning,
"\nit is not sure which field is in the magnet\n" "\nit is not sure which field is in the magnet\n"
"value stored in power supply: %f\n" "value stored in power supply: %f\n"
@ -75,12 +72,17 @@ static int IpsOk(IpsDriv *me, SConnection *pCon) {
#define S EVE_SAVEPAR #define S EVE_SAVEPAR
void IpsPars(IpsDriv *me, EveParArg *arg) { void IpsPars(IpsDriv *me, EveParArg *arg) {
IpsOk(me, EveArgConn(arg));
EveIntPar(arg, "persmode", &me->persmode, usUser, A+S); EveIntPar(arg, "persmode", &me->persmode, usUser, A+S);
EveIntPar(arg, "perswitch", &me->perswitch, usInternal, A); EveIntPar(arg, "perswitch", &me->perswitch, usInternal, A);
EveObPar(arg, UPLIMIT, "%.5g\tT", A+S); EveObPar(arg, UPLIMIT, "%.5g\tTesla", A+S);
EveFloatPar(arg, "ramp", &me->ramp, "%.5g\tT/min", usUser, A+S); EveFloatPar(arg, "ramp", &me->ramp, "%.5g\tTesla/min", usUser, A+S);
EveStdParEnd(arg, "%.5g\tT", A+L+S); EveFloatPar(arg, "current", &me->current, "%.5g\tTesla", usInternal, A+L);
EveFloatPar(arg, "lastfield", &me->lastfield, "%.5g\tTesla", usInternal, S);
EveCmd(arg, "confirm", IpsConfirm, usUser);
EveStdParEnd(arg, "%.5g\tTesla", A+L+S);
if (EveUserAction(arg)) {
IpsOk(me, EveArgConn(arg));
}
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void IpsStatus(IpsDriv *me) { void IpsStatus(IpsDriv *me) {
@ -158,11 +160,12 @@ static int IpsRead(long pc, IpsDriv *me) {
EveWrite(eve, "X"); EveWrite(eve, "X");
FSM_NEXT FSM_NEXT
IpsStatus(me); /* check for errors and get perswitch */ IpsStatus(me); /* check for errors and get perswitch */
/*
if (!me->remote) goto rd; if (!me->remote) goto rd;
EveWrite(eve, "C0"); EveWrite(eve, "C0");
me->remote = 0; me->remote = 0;
FSM_NEXT FSM_NEXT
*/
rd: rd:
EveWrite(eve, "R7"); /* read current (in Tesla) */ EveWrite(eve, "R7"); /* read current (in Tesla) */
FSM_NEXT FSM_NEXT
@ -176,6 +179,7 @@ static int IpsRead(long pc, IpsDriv *me) {
IpsSetField(me, OiGetFlt(eve, 3, NULL)); IpsSetField(me, OiGetFlt(eve, 3, NULL));
quit: quit:
EveLog(eve);
FSM_END FSM_END
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -245,6 +249,7 @@ static int IpsChangeField(long pc, IpsDriv *me) {
EveWrite(eve, "R7"); /* read current (in Tesla) */ EveWrite(eve, "R7"); /* read current (in Tesla) */
FSM_NEXT FSM_NEXT
me->current = OiGetFlt(eve, 3, NULL); me->current = OiGetFlt(eve, 3, NULL);
EveLog(eve);
if (fabs(me->current - me->lastfield) > 1e-5) goto stab1; if (fabs(me->current - me->lastfield) > 1e-5) goto stab1;
stab2: stab2:
@ -316,6 +321,7 @@ static int IpsChangeField(long pc, IpsDriv *me) {
} }
OiSet(eve, "J", fld, 3); OiSet(eve, "J", fld, 3);
FSM_NEXT FSM_NEXT
EveLog(eve);
goto ramping; goto ramping;
target_reached: target_reached:
@ -388,7 +394,7 @@ int IpsConfirm(SConnection *pCon, pEVControl evc, int argc, char *argv[]) {
return -1; return -1;
} }
fld=atof(argv[1]); fld=atof(argv[1]);
if (fld < ObVal(evc->pParam, UPLIMIT)) { if (fld > ObVal(evc->pParam, UPLIMIT)) {
SCPrintf(pCon, eError, "Field outside limit"); SCPrintf(pCon, eError, "Field outside limit");
return -1; return -1;
} }
@ -399,12 +405,12 @@ int IpsConfirm(SConnection *pCon, pEVControl evc, int argc, char *argv[]) {
if (fabs(fld - me->persfield) > 1e-5 && fabs(fld - me->lastfield) > 1e-5) { if (fabs(fld - me->persfield) > 1e-5 && fabs(fld - me->lastfield) > 1e-5) {
SCPrintf(pCon, eWarning, "Be aware that this does neither match the field" SCPrintf(pCon, eWarning, "Be aware that this does neither match the field"
" stored in software\nnor the field stored in power supply."); " stored in software\nnor the field stored in power supply.");
me->force = 0;
} }
if (me->force && fld != me->confirmfield) me->force = 0;
if (me->force == 0) { if (me->force == 0) {
SCPrintf(pCon, eWarning, "Please repeat this command, to confirm again" SCPrintf(pCon, eWarning, "Please repeat this command, to confirm again"
" the persistent field of\n %f Tesla.", fld); " the persistent field of\n %f Tesla.", fld);
IpsSetField(me, fld); me->confirmfield = fld;
me->force=1; me->force=1;
} else { } else {
me->force=2; me->force=2;

View File

@ -47,9 +47,7 @@
#include <servlog.h> #include <servlog.h>
#include <fortify.h> #include <fortify.h>
typedef struct __EVDriver *pEVDriver; #include "evdriver.h"
#include <evdriver.i>
#include "hardsup/itc4util.h" #include "hardsup/itc4util.h"
#include "hardsup/el734_def.h" #include "hardsup/el734_def.h"
#include "hardsup/el734fix.h" #include "hardsup/el734fix.h"

105
itcdriv.c
View File

@ -34,15 +34,18 @@ typedef struct {
float t[4]; /* temperatures (0 unused) */ float t[4]; /* temperatures (0 unused) */
int dig[4]; /* format for these */ int dig[4]; /* format for these */
float htr; float htr;
float coldvalve; float gas;
int sampleChan; int sampleChan;
int controlChan; int controlChan;
int gas; int gasMode;
int htrMode;
int remote; int remote;
int h; /* actual heater channel */ int h; /* actual heater channel */
int a; /* actual auto mode */ int a; /* actual auto mode */
} ItcDriv; } ItcDriv;
static long ItcSetGas(long pc, void *obj);
static long ItcSetHtr(long pc, void *obj);
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
#define A EVE_ACTPAR #define A EVE_ACTPAR
#define L EVE_LOGPAR #define L EVE_LOGPAR
@ -53,6 +56,7 @@ void ItcPars(ItcDriv *me, EveParArg *arg) {
int i; int i;
int flag; int flag;
char *ti[4] = {"setp","t1","t2","t3"}; char *ti[4] = {"setp","t1","t2","t3"};
static char *modeList[]={"off", "manual", "auto", NULL };
EveStdPar(arg); EveStdPar(arg);
@ -67,13 +71,14 @@ void ItcPars(ItcDriv *me, EveParArg *arg) {
} }
flag = me->controlChan != 0 || me->htr != 0; flag = me->controlChan != 0 || me->htr != 0;
EveFloatPar(arg, "htr", &me->htr, "%.1f\t%%", usInternal, flag*A + L); EveEnumPar(arg, "htrMode", &me->htrMode, modeList, usUser, A+S);
flag = me->gas > 0; EveFloatCmd(arg, "htr", &me->htr, "%.1f\t%%", ItcSetHtr, usUser, flag*A + L);
EveFloatPar(arg, "coldvalve", &me->coldvalve, "%.1f\t%%", usInternal, flag*A + L); EveEnumPar(arg, "gasMode", &me->gasMode, modeList, usUser, A+S);
flag = me->gasMode > 0;
EveFloatCmd(arg, "gas", &me->gas, "%.1f\t%%", ItcSetGas, usUser, flag*A + L);
EveIntPar(arg, "dig1", &me->dig[1], usUser, S); EveIntPar(arg, "dig1", &me->dig[1], usUser, S);
EveIntPar(arg, "dig2", &me->dig[2], usUser, S); EveIntPar(arg, "dig2", &me->dig[2], usUser, S);
EveIntPar(arg, "dig3", &me->dig[3], 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, "sampleChan", &me->sampleChan, usUser, A+S);
EveIntPar(arg, "controlChan", &me->controlChan, usUser, A+S); EveIntPar(arg, "controlChan", &me->controlChan, usUser, A+S);
sprintf(fmt, "%%.%df\tK", me->dig[me->sampleChan]); sprintf(fmt, "%%.%df\tK", me->dig[me->sampleChan]);
@ -110,7 +115,7 @@ void ItcStatus(ItcDriv *me) {
} }
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
static int ItcRead(long pc, ItcDriv *me) { static long ItcRead(long pc, ItcDriv *me) {
Eve *eve=&me->eve; Eve *eve=&me->eve;
char *p; char *p;
int l; int l;
@ -152,21 +157,24 @@ static int ItcRead(long pc, ItcDriv *me) {
FSM_NEXT FSM_NEXT
me->t[0] = OiGetFlt(eve, me->dig[me->controlChan], NULL); me->t[0] = OiGetFlt(eve, me->dig[me->controlChan], NULL);
if (me->htrMode != 2 && me->a % 2 == 0) goto skiphtr;
skip0: skip0:
EveWrite(eve, "R5"); /* read heater */ EveWrite(eve, "R5"); /* read heater */
FSM_NEXT FSM_NEXT
me->htr = OiGetFlt(eve, 1, NULL); me->htr = OiGetFlt(eve, 1, NULL);
if (!me->gas < 0) goto skipgas; skiphtr:
if (me->gasMode != 2 && me->a < 2) goto skipgas;
EveWrite(eve, "R7"); /* read gas flow */ EveWrite(eve, "R7"); /* read gas flow */
FSM_NEXT FSM_NEXT
me->coldvalve = OiGetFlt(eve, 1, NULL); me->gas = OiGetFlt(eve, 1, NULL);
skipgas: skipgas:
me->eve.value = me->t[me->sampleChan]; me->eve.value = me->t[me->sampleChan];
EveLog(eve);
FSM_END FSM_END
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
static int ItcStart(long pc, ItcDriv *me) { static long ItcStart(long pc, ItcDriv *me) {
Eve *eve=&me->eve; Eve *eve=&me->eve;
FSM_BEGIN FSM_BEGIN
@ -190,7 +198,7 @@ static int ItcStart(long pc, ItcDriv *me) {
FSM_END FSM_END
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
static int ItcSetTemp(long pc, ItcDriv *me) { static long ItcSetTemp(long pc, ItcDriv *me) {
Eve *eve=&me->eve; Eve *eve=&me->eve;
pEVControl evc=eve->evc; pEVControl evc=eve->evc;
float fld; float fld;
@ -219,9 +227,10 @@ static int ItcSetTemp(long pc, ItcDriv *me) {
OiSet(eve, "T", evc->fTarget, me->dig[me->controlChan]); /* set point */ OiSet(eve, "T", evc->fTarget, me->dig[me->controlChan]); /* set point */
FSM_NEXT FSM_NEXT
a = 1; a = 1;
if (me->gas == 2) a = 3; if (me->gasMode == 2) a = 3;
if (me->h == me->controlChan && me->a == a) goto skipa; if (me->h == me->controlChan && me->a == a) goto skipa;
if (me->gas == 2) { me->htrMode = 2; /* heater auto */
if (me->gasMode == 2) {
EveWrite(eve, "A3"); /* auto gas & heater */ EveWrite(eve, "A3"); /* auto gas & heater */
} else { } else {
EveWrite(eve, "A1"); /* auto heater */ EveWrite(eve, "A1"); /* auto heater */
@ -241,6 +250,74 @@ static int ItcSetTemp(long pc, ItcDriv *me) {
quit: quit:
FSM_END FSM_END
} }
/*----------------------------------------------------------------------------*/
static long ItcSetGas(long pc, void *obj) {
ItcDriv *me = obj;
Eve *eve=&me->eve;
pEVControl evc=eve->evc;
float fld;
float step;
float ramp;
char buf[4];
SConnection *pCon;
int a;
FSM_BEGIN
EveWrite(eve, "C3");
FSM_NEXT
if (me->gasMode != 1) {
EvePrintf(eve, eError, "gasMode must be set to manual");
goto quit;
}
FSM_NEXT
if (me->a == 2) {
EveWrite(eve, "A0");
} else if (me->a == 3) {
EveWrite(eve, "A1");
} else {
goto skipmode;
}
FSM_NEXT
skipmode:
OiSet(eve, "G", me->gas, 1); /* cold valve setting */
FSM_NEXT
EveWrite(eve, "C0");
FSM_NEXT
me->remote = 0;
quit:
FSM_END
}
/*----------------------------------------------------------------------------*/
static long ItcSetHtr(long pc, void *obj) {
ItcDriv *me = obj;
Eve *eve=&me->eve;
pEVControl evc=eve->evc;
float fld;
float step;
float ramp;
char buf[4];
SConnection *pCon;
int a;
FSM_BEGIN
EveWrite(eve, "C3");
FSM_NEXT
if (me->htrMode != 1) {
EvePrintf(eve, eError, "htrMode must be set to manual");
goto quit;
}
if (me->a == 0) goto skipmode;
EveWrite(eve, "A0");
FSM_NEXT
skipmode:
OiSet(eve, "O", me->htr, 1); /* manual heater setting */
FSM_NEXT
EveWrite(eve, "C0");
FSM_NEXT
me->remote = 0;
quit:
FSM_END
}
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
pEVControl ItcMakeEVC(SConnection *pCon, int argc, char *argv[]) { pEVControl ItcMakeEVC(SConnection *pCon, int argc, char *argv[]) {
/* args: /* args:
@ -256,6 +333,8 @@ pEVControl ItcMakeEVC(SConnection *pCon, int argc, char *argv[]) {
me = evc->pDriv->pPrivate; me = evc->pDriv->pPrivate;
me->sampleChan = 1; me->sampleChan = 1;
me->gasMode = 1;
me->htrMode = 1;
eve=&me->eve; eve=&me->eve;
eve->run = (FsmFunc)ItcSetTemp; eve->run = (FsmFunc)ItcSetTemp;

View File

@ -32,12 +32,13 @@ typedef struct {
Eve eve; Eve eve;
float t[4]; /* set t. & 3 temperatures */ float t[4]; /* set t. & 3 temperatures */
int dig[4]; /* format for these */ int dig[4]; /* format for these */
float coldvalve; float gas;
int gas;
int remote; int remote;
int hot; int hot;
} LcDriv; } LcDriv;
static long LcSetGas(long pc, void *obj);
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
#define A EVE_ACTPAR #define A EVE_ACTPAR
#define L EVE_LOGPAR #define L EVE_LOGPAR
@ -52,7 +53,7 @@ void LcPars(LcDriv *me, EveParArg *arg) {
sprintf(fmt, "%%.%df\tK", me->dig[3]); sprintf(fmt, "%%.%df\tK", me->dig[3]);
EveFloatPar(arg, "t3", &me->t[3], fmt, usInternal, (me->dig[3] >= 0) * A + L); EveFloatPar(arg, "t3", &me->t[3], fmt, usInternal, (me->dig[3] >= 0) * A + L);
EveFloatPar(arg, "coldvalve", &me->coldvalve, "%.1f\t%%", usInternal, A + L); EveFloatCmd(arg, "gas", &me->gas, "%.1f\t%%", LcSetGas, usUser, A + L);
EveIntPar(arg, "dig1", &me->dig[1], usUser, S); EveIntPar(arg, "dig1", &me->dig[1], usUser, S);
EveIntPar(arg, "dig2", &me->dig[2], usUser, S); EveIntPar(arg, "dig2", &me->dig[2], usUser, S);
@ -95,10 +96,10 @@ static int LcRead(long pc, LcDriv *me) {
EveWrite(eve, "X"); EveWrite(eve, "X");
FSM_NEXT FSM_NEXT
LcStatus(me); /* check for errors */ LcStatus(me); /* check for errors */
if (!me->remote) goto skiprmt; // if (!me->remote) goto skiprmt;
EveWrite(eve, "C0"); // EveWrite(eve, "C0");
me->remote = 0; // me->remote = 0;
FSM_NEXT // FSM_NEXT
skiprmt: skiprmt:
if (me->dig[1] < 0) goto skip1; if (me->dig[1] < 0) goto skip1;
@ -117,9 +118,27 @@ static int LcRead(long pc, LcDriv *me) {
FSM_NEXT FSM_NEXT
me->t[3] = OiGetFlt(eve, me->dig[3], NULL); me->t[3] = OiGetFlt(eve, me->dig[3], NULL);
skip3: skip3:
EveWrite(eve, "R7"); /* read gas flow */ FSM_END
}
/*----------------------------------------------------------------------------*/
static long LcSetGas(long pc, void *obj) {
LcDriv *me = obj;
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->remote) goto skipremote;
EveWrite(eve, "C1");
FSM_NEXT
skipremote:
OiSet(eve, "G", me->gas, 1); /* cold valve setting */
FSM_NEXT FSM_NEXT
me->coldvalve = OiGetFlt(eve, 1, NULL);
quit: quit:
FSM_END FSM_END
} }

385
logger.c
View File

@ -19,16 +19,74 @@ Markus Zolliker, Sept 2004
struct Logger { struct Logger {
char *name; char *name;
char old[132]; char old[256];
int period; int period;
time_t last; time_t last;
long pos; long pos;
Logger *next;
}; };
static char *dir = NULL; static char *dir = NULL;
static Logger *vars = NULL;
static Logger *list;
static time_t lastLife = 0;
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void LoggerWrite(Logger *log, time_t now, int period, char *value) { Logger *LoggerFind(char *name) {
Logger *p;
p = list;
while (p != NULL) {
if (0==strcasecmp(name, p->name)) {
return p;
}
p = p->next;
}
return NULL;
}
/*--------------------------------------------------------------------------*/
char *LoggerGetDir(void) {
char path[256], line[32];
FILE *fil;
time_t now;
static time_t last;
#define LASTLOGTXT "#last logging entry at:\n"
if (dir == NULL) {
dir = IFindOption(pSICSOptions, "LoggerDir");
snprintf(path, sizeof path, "%s/lastlife.dat", dir);
fil = fopen(path, "r");
if (fil) {
fgets(line, sizeof line, fil);
if (strcmp(line, LASTLOGTXT) == 0) {
fgets(line, sizeof line, fil);
lastLife = atol(line);
if (lastLife < 1000000000) {
printf("bad lastLife %ld\n", lastLife);
}
}
fclose(fil);
} else {
perror("open read error \n");
}
}
now = time(NULL);
if (now != last) {
snprintf(path, sizeof path, "%s/lastlife.dat", dir);
fil = fopen(path, "w");
if (fil) {
fprintf(fil, "%s%ld\n", LASTLOGTXT, now);
fclose(fil);
} else {
printf("can not open %s\n", path);
perror("open write error \n");
}
last = now;
}
return dir;
}
/*--------------------------------------------------------------------------*/
int LoggerWrite(Logger *log, time_t now, int period, char *value) {
char path[256], stim[32], buf[32]; char path[256], stim[32], buf[32];
struct tm *tm; struct tm *tm;
int yday, isdst; int yday, isdst;
@ -37,7 +95,8 @@ void LoggerWrite(Logger *log, time_t now, int period, char *value) {
FILE *fil; FILE *fil;
long pos; long pos;
if (dir == NULL) return; LoggerGetDir();
if (dir == NULL) return 0;
if (now == 0) { if (now == 0) {
printf("now==0\n"); printf("now==0\n");
} }
@ -46,6 +105,8 @@ void LoggerWrite(Logger *log, time_t now, int period, char *value) {
tm = localtime(&now); tm = localtime(&now);
if (tm->tm_yday != yday) { if (tm->tm_yday != yday) {
log->period = 0; log->period = 0;
} else if (0 == strncmp(value, log->old, sizeof(log->old))) {
return 0;
} }
log->last = now; log->last = now;
snprintf(path, sizeof path, "%s/%s/", dir, log->name); snprintf(path, sizeof path, "%s/%s/", dir, log->name);
@ -56,14 +117,14 @@ void LoggerWrite(Logger *log, time_t now, int period, char *value) {
fil = fopen(path, "r+"); fil = fopen(path, "r+");
if (fil == NULL) { /* create new file */ if (fil == NULL) { /* create new file */
fil = fopen(path, "w+"); fil = fopen(path, "w+");
if (fil == NULL) return; if (fil == NULL) return 0;
fputs(stim, fil); fputs(stim, fil);
} else { /* check if file is actual */ } else { /* check if file is actual */
fgets(buf, sizeof buf, fil); fgets(buf, sizeof buf, fil);
if (0 != strncmp(buf, stim, 11)) { if (0 != strncmp(buf, stim, 11)) {
fclose(fil); fclose(fil);
fil=fopen(path, "w+"); /* overwrite old logfile */ fil=fopen(path, "w+"); /* overwrite old logfile */
if (fil == NULL) return; if (fil == NULL) return 0;
fputs(stim, fil); fputs(stim, fil);
} else { } else {
fseek(fil, 0, SEEK_END); /* set position to end */ fseek(fil, 0, SEEK_END); /* set position to end */
@ -76,16 +137,17 @@ void LoggerWrite(Logger *log, time_t now, int period, char *value) {
} else { } else {
buf[0]='\0'; buf[0]='\0';
} }
/*
if (log->pos > 0) { if (log->pos > 0) {
fseek(fil, log->pos, SEEK_SET); fseek(fil, log->pos, SEEK_SET);
} }
log->pos = ftell(fil); log->pos = ftell(fil);
*/
strftime(stim, sizeof stim,"%H:%M:%S", tm); strftime(stim, sizeof stim,"%H:%M:%S", tm);
fprintf(fil, "%s\t%s%s\n", stim, value, buf); fprintf(fil, "%s\t%s%s\n", stim, value, buf);
if (0 != strncmp(value, log->old, sizeof(log->old)) || buf[0]!='\0') { /* value has changed */ // if (0 != strncmp(value, log->old, sizeof(log->old)) || buf[0]!='\0') { /* value has changed */
log->pos = ftell(fil); /* next time append to the end */ // log->pos = ftell(fil); /* next time append to the end */
} // }
l = strlen(value); l = strlen(value);
if (l >= sizeof(log->old)) { if (l >= sizeof(log->old)) {
l = sizeof(log->old) - 1; l = sizeof(log->old) - 1;
@ -93,20 +155,13 @@ void LoggerWrite(Logger *log, time_t now, int period, char *value) {
strncpy(log->old, value, l); strncpy(log->old, value, l);
log->old[l] = '\0'; log->old[l] = '\0';
fclose(fil); fclose(fil);
return 1;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void LoggerKill(Logger *log) { void LoggerKill(Logger *log) {
if (!log) return; /* we do not really free the logger, it might be reused
for the same variable later. We set the value to undefined */
LoggerWrite(log, time(NULL), 0, ""); 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 *LoggerMake(char *name, int period) {
@ -114,9 +169,9 @@ Logger *LoggerMake(char *name, int period) {
char path[256]; char path[256];
struct stat st; struct stat st;
int i; int i;
char *dir; time_t t;
dir = LoggerGetDir(); LoggerGetDir();
if (dir == NULL) return NULL; if (dir == NULL) return NULL;
snprintf(path, sizeof path, "%s/%s", dir, name); snprintf(path, sizeof path, "%s/%s", dir, name);
i = stat(path, &st); i = stat(path, &st);
@ -128,41 +183,67 @@ Logger *LoggerMake(char *name, int period) {
i = mkdir(path, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH); i = mkdir(path, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
if (i < 0) return NULL; /* mkdir failed */ if (i < 0) return NULL; /* mkdir failed */
} }
log = malloc(sizeof *log); log = LoggerFind(name); /* look if logger already exists */
if (log == NULL) return NULL; if (log == NULL) {
log->name = strdup(name); log = malloc(sizeof *log);
if (log->name == NULL) { if (log == NULL) return NULL;
free(log); log->name = strdup(name);
return NULL; if (log->name == NULL) {
free(log);
return NULL;
}
log->period = 0;
log->old[0] = '\0';
log->last = 0;
log->pos = 0;
log->next = list;
list = log;
t = time(NULL) -1;
if (lastLife != 0 && lastLife + period < t) {
t = lastLife + period;
}
LoggerWrite(log, t, period, ""); /* value was undefined since last life of server */
} }
log->period = 0;
log->old[0] = '\0';
log->last = 0;
log->pos = 0;
LoggerWrite(log, time(NULL) - 1, period, "");
return log; return log;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
typedef enum { numeric, text } CompType;
typedef struct { typedef struct {
SConnection *pCon; SConnection *pCon;
CompType type;
time_t step; time_t step;
time_t t0, tmin, tmax; time_t tlim;
time_t tlast; time_t tmin, tmax, tlast, told;
float ymin, ymax; float ymin, ymax, ylast, yold;
float ylast; char slast[256];
long cnt; char set[256];
} Compressor; } Compressor;
static void LoggerInit(Compressor *c, SConnection *pCon, time_t step) { static void LoggerInit(Compressor *c, SConnection *pCon, time_t step) {
c->pCon = pCon; c->pCon = pCon;
c->step = step; c->step = step;
c->tmin = -1; c->tmin = -2;
c->tmax = 0; c->tmax = 0;
c->tlast = 0; c->tlast = 0;
c->t0 = 0; c->tlim = 0;
c->told = 0;
c->ylast = LOGGER_NAN; c->ylast = LOGGER_NAN;
} }
static void LoggerOutStr(Compressor *c, time_t t, char *str) {
char line[256];
/* printf("out %ld %g\n", t, y); */
if (0 != strcmp(str, c->slast)) {
snprintf(line, sizeof line, "%ld %s\n", t - c->tlast, str);
c->tlast = t;
c->slast[0]='\0';
strncat(c->slast, str, sizeof c->slast - 1);
SCWrite(c->pCon, line, eStatus);
}
}
static void LoggerOut(Compressor *c, time_t t, float y) { static void LoggerOut(Compressor *c, time_t t, float y) {
char line[80]; char line[80];
@ -175,94 +256,118 @@ static void LoggerOut(Compressor *c, time_t t, float y) {
snprintf(line, sizeof line, "%ld %g\n", t - c->tlast, y); snprintf(line, sizeof line, "%ld %g\n", t - c->tlast, y);
} }
/* printf("-%s\n", line); */ /* printf("-%s\n", line); */
c->cnt--;
c->tlast = t; c->tlast = t;
SCWrite(c->pCon, line, eStatus); SCWrite(c->pCon, line, eStatus);
} }
} }
static void LoggerSum(Compressor *c) { static void LoggerPut(Compressor *c, time_t t, char *value) {
if (c->tmin < 0 || c->tmin==0 && c->tmax==0) { char *p;
/* printf("nos %ld %ld %f %f\n", c->tmin, c->tmax, c->ymin, c->ymax); */ double y;
LoggerOut(c, c->t0, LOGGER_NAN);
c->tmin = -1; if (c->type == numeric) {
} else { if (t == 0) { /* finish */
/* printf("sum %ld %ld %f %f\n", c->tmin, c->tmax, c->ymin, c->ymax); */ t = c->tlim + 3 * c->step;
if (c->tmin > c->tmax) { y = 0;
if (c->tmax >= c->t0) { } else {
y = strtod(value, &p);
if (p == value) {
y = LOGGER_NAN;
} else {
if (y == LOGGER_NAN) y *= 1.0000002;
}
}
/* printf("put %ld %g\n", t, y); */
if (c->tlim == 0) goto first;
if (t >= c->tlim) {
c->tlim += c->step;
if (c->tmin > c->tmax) {
LoggerOut(c, c->tmax, c->ymax); LoggerOut(c, c->tmax, c->ymax);
} c->ymax = c->ymin;
LoggerOut(c, c->tmin, c->ymin); c->tmax = c->tmin;
} else if (c->tmin < c->tmax) { } else {
if (c->tmin >= c->t0) {
LoggerOut(c, c->tmin, c->ymin); LoggerOut(c, c->tmin, c->ymin);
if (c->tmin == c->tmax) goto first;
c->ymin = c->ymax;
c->tmin = c->tmax;
} }
LoggerOut(c, c->tmax, c->ymax); if (t >= c->tlim) {
} else { LoggerOut(c, c->tmin, c->ymin);
LoggerOut(c, c->tmax, c->ymax); if (t >= c->tlim + c->step) {
LoggerOut(c, c->told, c->yold);
}
goto first;
}
}
if (y <= c->ymin) {
c->ymin = y;
c->tmin = t;
} else if (y > c->ymax) {
c->ymax = y;
c->tmax = t;
} }
if (c->ylast != LOGGER_NAN) { c->yold = y;
c->ymin = c->ylast; c->told = t;
c->ymax = c->ylast; return;
c->tmin = 0; first:
c->tmax = 0; c->tlim = t + 2 * c->step;
} else { c->tmin = t;
c->tmin = -1; c->tmax = t;
} c->ymin = y;
/* printf("end %ld %ld %f %f\n", c->tmin, c->tmax, c->ymin, c->ymax); */ c->ymax = y;
return;
} else if (c->type == text) {
if (t != 0) LoggerOutStr(c, t, value);
} }
} }
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 LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) { int argc, char *argv[]) {
time_t from, to, step, xs, lastx, now; time_t from, to, step, xs, lastt, now;
char *p; char *p;
int i, l, yday, iret, loss; int i, l, yday, iret, loss;
time_t tim, tr; int inRange;
time_t t, startim;
struct tm tm; struct tm tm;
char path[256], line[80]; char stim[32], path[256], line[256], lastval[256];
char *lin, *val, *stp; char *lin, *val, *stp;
FILE *fil; FILE *fil;
Compressor c; Compressor c;
float yy, lasty; float yy, lasty;
Logger *log;
if (argc < 4) { if (argc < 2) goto illarg;
SCWrite(pCon, "illegal number of arguments", eError); strtolower(argv[1]);
return 0; if (strcmp(argv[1], "vars") == 0) { /* default variables on a graph */
if (vars == NULL) {
vars = LoggerMake("vars", 1);
if (vars == NULL) return 0;
}
Arg2Text(argc-2, argv+2, line, sizeof line);
LoggerWrite(vars, time(NULL), 1, line);
SCSendOK(pCon);
return 1;
} }
argtolower(argc, argv);
if (argc < 4) goto illarg;
now = time(NULL); now = time(NULL);
from = strtol(argv[1], &p, 0); /* unix time, not year 2038 safe */ from = strtol(argv[1], &p, 0); /* unix time, not year 2038 safe */
if (p == argv[1]) goto illarg; if (p == argv[1]) goto illarg;
to = strtol(argv[2], NULL, 0); to = strtol(argv[2], NULL, 0);
if (p == argv[2]) goto illarg; if (p == argv[2]) goto illarg;
step = strtol(argv[3], NULL, 0); if (strcmp(argv[3],"text") == 0) { /* non-numeric values */
step = 1;
c.type = text;
} else {
step = strtol(argv[3], NULL, 0);
c.type = numeric;
}
if (p == argv[3]) goto illarg; if (p == argv[3]) goto illarg;
if (from <= 0) from += now; if (from <= 0) from += now;
if (to <= 0) to += now; if (to <= 0) to += now;
if (step <= 0) step = 1; if (step <= 0) step = 1;
dir = LoggerGetDir(); LoggerGetDir();
if (dir == NULL) { if (dir == NULL) {
SCWrite(pCon, "LoggerDir not found", eError); SCWrite(pCon, "LoggerDir not found", eError);
return 0; return 0;
@ -270,23 +375,37 @@ int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData,
loss = 0; loss = 0;
for (i=4; i<argc; i++) { for (i=4; i<argc; i++) {
tim = from; startim = from;
t = 0;
lastt = 0;
inRange = 0;
xs = step; xs = step;
LoggerInit(&c, pCon, 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]); snprintf(path, sizeof path, "%s/%s/", dir, argv[i]);
l = strlen(path); l = strlen(path);
fil = NULL; fil = NULL;
snprintf(line, sizeof line, "*%s\n", argv[i]); snprintf(line, sizeof line, "*%s\n", argv[i]);
SCWrite(pCon, line, eStatus); SCWrite(pCon, line, eStatus);
while (tim <= to) { while (startim <= to) {
tm = *localtime(&tim); tm = *localtime(&startim);
if (fil == NULL || tm.tm_yday != yday) { if (tm.tm_yday != yday) {
if (fil != NULL) { /* close file if day changed */
fclose(fil);
fil=NULL;
}
}
if (fil == NULL) {
yday = tm.tm_yday; yday = tm.tm_yday;
strftime(path + l, sizeof path - l, "%m-%d.log", &tm); strftime(path + l, sizeof path - l, "%m-%d.log", &tm);
fil = fopen(path, "r"); fil = fopen(path, "r");
if (fil != NULL) { /* check if file is from this year */
strftime(stim, sizeof stim, "#%Y-%m-%d", &tm);
fgets(line, sizeof line, fil);
if (0 != strncmp(line, stim, 11)) {
fclose(fil);
fil = NULL;
}
}
} }
if (fil == NULL) { if (fil == NULL) {
lin == NULL; lin == NULL;
@ -310,12 +429,14 @@ int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData,
} }
p = strchr(val, '\t'); p = strchr(val, '\t');
if (p) { if (p) {
stp = p+1;
*p='\0'; *p='\0';
stp = val+1;
iret = sscanf(stp, "%ld", &xs); iret = sscanf(stp, "%ld", &xs);
if (xs < step) { if (iret == 1) {
loss = 1; if (xs < step) {
xs = step; loss = 1;
xs = step;
}
} }
} }
iret = sscanf(line, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); iret = sscanf(line, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
@ -323,25 +444,22 @@ int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData,
lin = NULL; lin = NULL;
} else { } else {
tm.tm_isdst = -1; tm.tm_isdst = -1;
tr=mktime(&tm); t=mktime(&tm);
iret = sscanf(val, "%f", &yy); if (!inRange) {
if (iret <= 0) { if (t < startim) {
yy = LOGGER_NAN; lastval[0]='\0';
} else { strncat(lastval, val, sizeof lastval - 1);
if (yy == LOGGER_NAN) yy *= 1.0000002; lastt = t;
} } else {
if (tr >= tim) { inRange=1;
if (lastx != 0) { if (lastt != 0) {
lastx += xs; LoggerPut(&c, lastt, lastval);
while (lastx < tr) {
LoggerPut(&c, lastx, lasty);
lastx += xs;
} }
LoggerPut(&c, t, val);
} }
LoggerPut(&c, tr, yy); } else {
LoggerPut(&c, t, val);
} }
lastx = tr;
lasty = yy;
} }
} }
if (lin == NULL) { if (lin == NULL) {
@ -349,17 +467,32 @@ int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData,
tm.tm_min = 0; tm.tm_min = 0;
tm.tm_sec = 0; tm.tm_sec = 0;
tm.tm_isdst = -1; tm.tm_isdst = -1;
tim=mktime(&tm); startim=mktime(&tm);
continue; continue;
} }
} }
c.ylast = LOGGER_NAN; if (!inRange) {
LoggerSum(&c); if (lastt != 0) {
LoggerPut(&c, lastt, lastval);
}
}
LoggerPut(&c, 0, ""); /* finish */
log = LoggerFind(argv[i]);
if (log) { /* add actual value if it is within range */
if (to >= log->last) {
c.slast[0]='\0';
LoggerOutStr(&c, now, log->old);
}
}
if (fil) {
fclose(fil);
fil = NULL;
}
} }
snprintf(line, sizeof line, "*%d\n", loss); snprintf(line, sizeof line, "*%d %ld %ld\n", loss, from, to);
SCWrite(pCon, line, eStatus); SCWrite(pCon, line, eStatus);
return 1; return 1;
illarg: illarg:
SCWrite(pCon, "illegal argument", eError); SCWrite(pCon, "illegal argument(s)", eError);
return 0; return 0;
} }

View File

@ -14,6 +14,6 @@ typedef struct Logger Logger;
Logger *LoggerMake(char *name, int period); Logger *LoggerMake(char *name, int period);
void LoggerKill(Logger *log); void LoggerKill(Logger *log);
void LoggerWrite(Logger *log, time_t now, int period, char *value); int LoggerWrite(Logger *log, time_t now, int period, char *value);
#endif #endif

View File

@ -25,9 +25,7 @@
#include <servlog.h> #include <servlog.h>
#include <fortify.h> #include <fortify.h>
typedef struct __EVDriver *pEVDriver; #include "evdriver.h"
#include <evdriver.i>
#include <network.h> #include <network.h>
#include <rs232controller.h> #include <rs232controller.h>