bug fixes and enhancements related to evcontroller
This commit is contained in:
@ -20,9 +20,7 @@
|
||||
#include <servlog.h>
|
||||
#include <fortify.h>
|
||||
|
||||
typedef struct __EVDriver *pEVDriver;
|
||||
|
||||
#include <evdriver.i>
|
||||
#include "evdriver.h"
|
||||
#include "hardsup/dillutil.h"
|
||||
#include "hardsup/el734_def.h"
|
||||
#include "hardsup/el734fix.h"
|
||||
|
@ -18,9 +18,7 @@
|
||||
#include <servlog.h>
|
||||
#include <fortify.h>
|
||||
|
||||
typedef struct __EVDriver *pEVDriver;
|
||||
|
||||
#include <evdriver.i>
|
||||
#include "evdriver.h"
|
||||
#include "hardsup/el755_def.h"
|
||||
#include "hardsup/el755_errcodes.h"
|
||||
#include "hardsup/sinq_prototypes.h"
|
||||
|
@ -22,9 +22,7 @@
|
||||
#include <servlog.h>
|
||||
#include <fortify.h>
|
||||
|
||||
typedef struct __EVDriver *pEVDriver;
|
||||
|
||||
#include <evdriver.i>
|
||||
#include "evdriver.h"
|
||||
#include "hardsup/el734_def.h"
|
||||
#include "hardsup/el734fix.h"
|
||||
#include "hardsup/serialsinq.h"
|
||||
|
75
eve.c
75
eve.c
@ -26,9 +26,9 @@ Markus Zolliker, Sept 2004
|
||||
#define ILLNUM -1456
|
||||
#define ILLARGC -1457
|
||||
#define AMBIGUOS -1458
|
||||
#define UNCHANGEABLE -1459
|
||||
#define ILLPRIV -1460
|
||||
#define BADLOG -1461
|
||||
#define BUSY -1462
|
||||
|
||||
typedef enum {
|
||||
cntAction, iniAction, parAction, listAction,
|
||||
@ -140,9 +140,7 @@ char *EveInt2Text(char *list[], int num) {
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int EveCheckRights(EveParArg *arg, int access) {
|
||||
|
||||
if (access == usInternal) {
|
||||
arg->ret = UNCHANGEABLE;
|
||||
} else if (SCMatchRights(arg->pCon,access)) {
|
||||
if (SCMatchRights(arg->pCon,access)) {
|
||||
return 1;
|
||||
} else {
|
||||
arg->ret = ILLPRIV;
|
||||
@ -181,10 +179,9 @@ EvePar *EveThisPar(EveParArg *arg, char *name, int flags) {
|
||||
if (!eve->par) return NULL;
|
||||
assert(arg->idx < eve->npar);
|
||||
par = eve->par + arg->idx;
|
||||
/* arg->idx ++ */
|
||||
if (par->name == NULL) {
|
||||
par->name = name;
|
||||
if (flags & 2) { /* first time: default logger */
|
||||
if (flags & EVE_LOGPAR) { /* first time: default logger */
|
||||
EveSwitchLog(eve, par, 1);
|
||||
}
|
||||
} else {
|
||||
@ -252,12 +249,12 @@ ArgOp EveOp(EveParArg *arg, char *name, char **fmt, int access, int flags) {
|
||||
arg->idx ++;
|
||||
return noOp;
|
||||
case listAction:
|
||||
if (flags & 1) {
|
||||
if (flags & EVE_ACTPAR) {
|
||||
return fmtOp;
|
||||
}
|
||||
return noOp;
|
||||
case logAction:
|
||||
if (flags & 1) {
|
||||
if (flags & EVE_ACTPAR) {
|
||||
op = fmtOp;
|
||||
break; /* reduce fmt */
|
||||
}
|
||||
@ -295,7 +292,7 @@ ArgOp EveOp(EveParArg *arg, char *name, char **fmt, int access, int flags) {
|
||||
}
|
||||
return noOp;
|
||||
case saveAction:
|
||||
if (flags & 4) {
|
||||
if (flags & EVE_SAVEPAR) {
|
||||
op = fmtOp;
|
||||
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) {
|
||||
EvePar *par;
|
||||
int l, i, j, m, ln, lp;
|
||||
int l, i, j, m, ln, lp, iret;
|
||||
char *p, *q, *tab;
|
||||
char buffer[256];
|
||||
char *dot;
|
||||
|
||||
switch (arg->action) {
|
||||
case listAction:
|
||||
@ -367,7 +366,16 @@ void EveOut(EveParArg *arg, char *name, char *buf) {
|
||||
par = EveThisPar(arg, name, 0);
|
||||
arg->idx ++;
|
||||
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;
|
||||
case saveAction:
|
||||
@ -394,6 +402,7 @@ void EveFloatPar(EveParArg *arg, char *name, float *value, char *fmt,
|
||||
break;
|
||||
}
|
||||
*value = f;
|
||||
SCparChange(arg->pCon);
|
||||
/* fall through */
|
||||
case fmtOp:
|
||||
snprintf(buf, sizeof buf, fmt, *value);
|
||||
@ -419,6 +428,7 @@ void EveIntPar(EveParArg *arg, char *name, int *value, int access, int flags) {
|
||||
break;
|
||||
}
|
||||
*value = i;
|
||||
SCparChange(arg->pCon);
|
||||
/* fall through */
|
||||
case fmtOp:
|
||||
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 */
|
||||
EveArg2Text(arg->argc, arg->argv, *value, maxsize);
|
||||
}
|
||||
SCparChange(arg->pCon);
|
||||
/* fall through */
|
||||
case fmtOp:
|
||||
if (*value == NULL) value = ∅
|
||||
@ -465,6 +476,7 @@ void EveObPar(EveParArg *arg, int index, char *fmt, int flags) {
|
||||
} else {
|
||||
arg->evc->pParam[index].fVal = f;
|
||||
}
|
||||
SCparChange(arg->pCon);
|
||||
/* fall through */
|
||||
case fmtOp:
|
||||
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 {
|
||||
arg->evc->pParam[index].fVal = i;
|
||||
}
|
||||
SCparChange(arg->pCon);
|
||||
/* fall through */
|
||||
case fmtOp:
|
||||
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;
|
||||
} else {
|
||||
*value = i;
|
||||
SCparChange(arg->pCon);
|
||||
}
|
||||
/* fall through */
|
||||
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 L EVE_LOGPAR
|
||||
#define S EVE_SAVEPAR
|
||||
@ -580,6 +608,10 @@ SConnection *EveArgConn(EveParArg *arg) {
|
||||
return arg->pCon;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int EveUserAction(EveParArg *arg) {
|
||||
return (arg->action == parAction || arg->action == listAction);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int EveWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]) {
|
||||
pEVControl evc = pData;
|
||||
@ -620,9 +652,6 @@ error:
|
||||
case AMBIGUOS:
|
||||
SCPrintf(pCon, eError, "ERROR: doubly defined parameter %s.%s", evc->pName, argv[1]);
|
||||
break;
|
||||
case UNCHANGEABLE:
|
||||
SCPrintf(pCon, eError, "ERROR: %s.%s is not changeable", evc->pName, argv[1]);
|
||||
break;
|
||||
case ILLPRIV:
|
||||
SCPrintf(pCon, eError, "ERROR: Insufficient privilege to change %s.%s", evc->pName, argv[1]);
|
||||
break;
|
||||
@ -635,6 +664,9 @@ error:
|
||||
case BADLOG:
|
||||
SCPrintf(pCon, eError, "ERROR: can not create log directory for %s %s", evc->pName, argv[1]);
|
||||
break;
|
||||
case BUSY:
|
||||
SCPrintf(pCon, eError, "ERROR: %s busy", evc->pName);
|
||||
break;
|
||||
default:
|
||||
return arg.ret;
|
||||
}
|
||||
@ -740,7 +772,7 @@ int EveIdle(long pc, Eve *eve) {
|
||||
rd:
|
||||
if (eve->hwstate == HWBusy) eve->hwstate = HWIdle;
|
||||
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->todo) goto doit;
|
||||
/*
|
||||
@ -856,19 +888,17 @@ int EveDontFix(pEVDriver driver, int iError) {
|
||||
return(DEVFAULT); /* severe */
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int EveSaveStatus(void *data, char *name, FILE *fil)
|
||||
int EveSavePars(pEVDriver driver, FILE *fil)
|
||||
{
|
||||
pEVControl evc = data;
|
||||
Eve *eve = evc->pDriv->pPrivate;
|
||||
Eve *eve = driver->pPrivate;
|
||||
EveParArg arg;
|
||||
|
||||
EVSaveStatus(data, name, fil);
|
||||
arg.action = saveAction;
|
||||
arg.pCon = NULL;
|
||||
arg.evc = evc;
|
||||
arg.evc = eve->evc;
|
||||
arg.fil = fil;
|
||||
eve->pardef(eve, &arg);
|
||||
return 1;
|
||||
return 2; /* no (duplicate) save of standard parameters ! */
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void EveKill(void *pData) {
|
||||
@ -880,7 +910,9 @@ void EveKill(void *pData) {
|
||||
assert(eve);
|
||||
KillRS232(eve->ser);
|
||||
for (i=0; i<eve->npar; i++) {
|
||||
if (eve->par[i].log) {
|
||||
LoggerKill(eve->par[i].log);
|
||||
}
|
||||
eve->par[i].log = NULL;
|
||||
}
|
||||
free(eve);
|
||||
@ -982,6 +1014,7 @@ pEVControl MakeEveEVC(int argc, char *argv[], Eve *eve, SConnection *pCon) {
|
||||
driver->Send = EveSend;
|
||||
driver->GetError = EveGetError;
|
||||
driver->TryFixIt = EveDontFix;
|
||||
driver->SavePars = EveSavePars;
|
||||
driver->Init = EveInit;
|
||||
driver->Close = EveClose;
|
||||
|
||||
|
9
eve.h
9
eve.h
@ -80,6 +80,7 @@ typedef struct Eve {
|
||||
* index: the ObPar index
|
||||
* list: a NULL terminated list of value names
|
||||
* 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,
|
||||
int access, int flags);
|
||||
@ -92,6 +93,8 @@ 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);
|
||||
void EveFloatCmd(EveParArg *arg, char *name, float *value, char *fmt,
|
||||
FsmFunc fsmFunc, int access, int flags);
|
||||
|
||||
/* a collection of parameters from the standard EVController
|
||||
* (limits, tolerance, drive handling, out of tolerance handling)
|
||||
@ -107,9 +110,15 @@ void EveStdParEnd(EveParArg *arg, char *fmt, int targetFlag);
|
||||
/* return the connection related to the parameter request */
|
||||
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 */
|
||||
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 EveWrite(Eve *eve, char *cmd);
|
||||
void EveWaitRead(Eve *eve);
|
||||
|
1
fsm.c
1
fsm.c
@ -78,6 +78,7 @@ Fsm *FsmStartTask(void *obj, FsmHandler handler, FsmFunc func) {
|
||||
new->func = func;
|
||||
new->handler = handler;
|
||||
new->sp = 0;
|
||||
new->pause = 0;
|
||||
new->till = 0;
|
||||
return new;
|
||||
}
|
||||
|
40
ipsdriv.c
40
ipsdriv.c
@ -33,6 +33,7 @@ typedef struct {
|
||||
float current; /* current (in Tesla) */
|
||||
float persfield; /* persistent field from IPS (in Tesla) */
|
||||
float lastfield; /* persistent field from last drive */
|
||||
float confirmfield; /* field confirmed in 1st step */
|
||||
float ramp; /* actual ramp rate (Telsa/min) */
|
||||
int persmode; /* 0: leave switch on, 1: go to persistant mode */
|
||||
int perswitch; /* state of switch */
|
||||
@ -43,22 +44,18 @@ typedef struct {
|
||||
time_t tim;
|
||||
} IpsDriv;
|
||||
|
||||
int IpsConfirm(SConnection *pCon, pEVControl evc, int argc, char *argv[]);
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int IpsOk(IpsDriv *me, SConnection *pCon) {
|
||||
float dif;
|
||||
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 (fabs(me->persfield - me->lastfield) < 1e-5) {
|
||||
return 1;
|
||||
}
|
||||
if (me->force == 2) {
|
||||
return 1;
|
||||
}
|
||||
if (fabs(me->persfield - me->lastfield) < 1e-5
|
||||
|| me->force == 2) return 1;
|
||||
if (fabs(me->persfield - me->lastfield) < 1e-5) return 1;
|
||||
if (me->force != 0) return 1;
|
||||
eve->errCode = EVE_FAULT;
|
||||
if (!pCon) pCon = SCLoad(&eve->evc->conn);
|
||||
SCPrintf(pCon, eWarning,
|
||||
"\nit is not sure which field is in the magnet\n"
|
||||
"value stored in power supply: %f\n"
|
||||
@ -75,12 +72,17 @@ static int IpsOk(IpsDriv *me, SConnection *pCon) {
|
||||
#define S EVE_SAVEPAR
|
||||
|
||||
void IpsPars(IpsDriv *me, EveParArg *arg) {
|
||||
IpsOk(me, EveArgConn(arg));
|
||||
EveIntPar(arg, "persmode", &me->persmode, usUser, A+S);
|
||||
EveIntPar(arg, "perswitch", &me->perswitch, usInternal, A);
|
||||
EveObPar(arg, UPLIMIT, "%.5g\tT", A+S);
|
||||
EveFloatPar(arg, "ramp", &me->ramp, "%.5g\tT/min", usUser, A+S);
|
||||
EveStdParEnd(arg, "%.5g\tT", A+L+S);
|
||||
EveObPar(arg, UPLIMIT, "%.5g\tTesla", A+S);
|
||||
EveFloatPar(arg, "ramp", &me->ramp, "%.5g\tTesla/min", usUser, A+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) {
|
||||
@ -158,11 +160,12 @@ static int IpsRead(long pc, IpsDriv *me) {
|
||||
EveWrite(eve, "X");
|
||||
FSM_NEXT
|
||||
IpsStatus(me); /* check for errors and get perswitch */
|
||||
/*
|
||||
if (!me->remote) goto rd;
|
||||
EveWrite(eve, "C0");
|
||||
me->remote = 0;
|
||||
FSM_NEXT
|
||||
|
||||
*/
|
||||
rd:
|
||||
EveWrite(eve, "R7"); /* read current (in Tesla) */
|
||||
FSM_NEXT
|
||||
@ -176,6 +179,7 @@ static int IpsRead(long pc, IpsDriv *me) {
|
||||
IpsSetField(me, OiGetFlt(eve, 3, NULL));
|
||||
|
||||
quit:
|
||||
EveLog(eve);
|
||||
FSM_END
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -245,6 +249,7 @@ static int IpsChangeField(long pc, IpsDriv *me) {
|
||||
EveWrite(eve, "R7"); /* read current (in Tesla) */
|
||||
FSM_NEXT
|
||||
me->current = OiGetFlt(eve, 3, NULL);
|
||||
EveLog(eve);
|
||||
if (fabs(me->current - me->lastfield) > 1e-5) goto stab1;
|
||||
|
||||
stab2:
|
||||
@ -316,6 +321,7 @@ static int IpsChangeField(long pc, IpsDriv *me) {
|
||||
}
|
||||
OiSet(eve, "J", fld, 3);
|
||||
FSM_NEXT
|
||||
EveLog(eve);
|
||||
goto ramping;
|
||||
|
||||
target_reached:
|
||||
@ -388,7 +394,7 @@ int IpsConfirm(SConnection *pCon, pEVControl evc, int argc, char *argv[]) {
|
||||
return -1;
|
||||
}
|
||||
fld=atof(argv[1]);
|
||||
if (fld < ObVal(evc->pParam, UPLIMIT)) {
|
||||
if (fld > ObVal(evc->pParam, UPLIMIT)) {
|
||||
SCPrintf(pCon, eError, "Field outside limit");
|
||||
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) {
|
||||
SCPrintf(pCon, eWarning, "Be aware that this does neither match the field"
|
||||
" 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) {
|
||||
SCPrintf(pCon, eWarning, "Please repeat this command, to confirm again"
|
||||
" the persistent field of\n %f Tesla.", fld);
|
||||
IpsSetField(me, fld);
|
||||
me->confirmfield = fld;
|
||||
me->force=1;
|
||||
} else {
|
||||
me->force=2;
|
||||
|
@ -47,9 +47,7 @@
|
||||
#include <servlog.h>
|
||||
#include <fortify.h>
|
||||
|
||||
typedef struct __EVDriver *pEVDriver;
|
||||
|
||||
#include <evdriver.i>
|
||||
#include "evdriver.h"
|
||||
#include "hardsup/itc4util.h"
|
||||
#include "hardsup/el734_def.h"
|
||||
#include "hardsup/el734fix.h"
|
||||
|
105
itcdriv.c
105
itcdriv.c
@ -34,15 +34,18 @@ typedef struct {
|
||||
float t[4]; /* temperatures (0 unused) */
|
||||
int dig[4]; /* format for these */
|
||||
float htr;
|
||||
float coldvalve;
|
||||
float gas;
|
||||
int sampleChan;
|
||||
int controlChan;
|
||||
int gas;
|
||||
int gasMode;
|
||||
int htrMode;
|
||||
int remote;
|
||||
int h; /* actual heater channel */
|
||||
int a; /* actual auto mode */
|
||||
} ItcDriv;
|
||||
|
||||
static long ItcSetGas(long pc, void *obj);
|
||||
static long ItcSetHtr(long pc, void *obj);
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define A EVE_ACTPAR
|
||||
#define L EVE_LOGPAR
|
||||
@ -53,6 +56,7 @@ void ItcPars(ItcDriv *me, EveParArg *arg) {
|
||||
int i;
|
||||
int flag;
|
||||
char *ti[4] = {"setp","t1","t2","t3"};
|
||||
static char *modeList[]={"off", "manual", "auto", NULL };
|
||||
|
||||
EveStdPar(arg);
|
||||
|
||||
@ -67,13 +71,14 @@ void ItcPars(ItcDriv *me, EveParArg *arg) {
|
||||
}
|
||||
|
||||
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);
|
||||
EveEnumPar(arg, "htrMode", &me->htrMode, modeList, usUser, A+S);
|
||||
EveFloatCmd(arg, "htr", &me->htr, "%.1f\t%%", ItcSetHtr, usUser, 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, "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]);
|
||||
@ -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;
|
||||
char *p;
|
||||
int l;
|
||||
@ -152,21 +157,24 @@ static int ItcRead(long pc, ItcDriv *me) {
|
||||
FSM_NEXT
|
||||
me->t[0] = OiGetFlt(eve, me->dig[me->controlChan], NULL);
|
||||
|
||||
if (me->htrMode != 2 && me->a % 2 == 0) goto skiphtr;
|
||||
skip0:
|
||||
EveWrite(eve, "R5"); /* read heater */
|
||||
FSM_NEXT
|
||||
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 */
|
||||
FSM_NEXT
|
||||
me->coldvalve = OiGetFlt(eve, 1, NULL);
|
||||
me->gas = OiGetFlt(eve, 1, NULL);
|
||||
|
||||
skipgas:
|
||||
me->eve.value = me->t[me->sampleChan];
|
||||
EveLog(eve);
|
||||
FSM_END
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int ItcStart(long pc, ItcDriv *me) {
|
||||
static long ItcStart(long pc, ItcDriv *me) {
|
||||
Eve *eve=&me->eve;
|
||||
|
||||
FSM_BEGIN
|
||||
@ -190,7 +198,7 @@ static int ItcStart(long pc, ItcDriv *me) {
|
||||
FSM_END
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int ItcSetTemp(long pc, ItcDriv *me) {
|
||||
static long ItcSetTemp(long pc, ItcDriv *me) {
|
||||
Eve *eve=&me->eve;
|
||||
pEVControl evc=eve->evc;
|
||||
float fld;
|
||||
@ -219,9 +227,10 @@ static int ItcSetTemp(long pc, ItcDriv *me) {
|
||||
OiSet(eve, "T", evc->fTarget, me->dig[me->controlChan]); /* set point */
|
||||
FSM_NEXT
|
||||
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->gas == 2) {
|
||||
me->htrMode = 2; /* heater auto */
|
||||
if (me->gasMode == 2) {
|
||||
EveWrite(eve, "A3"); /* auto gas & heater */
|
||||
} else {
|
||||
EveWrite(eve, "A1"); /* auto heater */
|
||||
@ -241,6 +250,74 @@ static int ItcSetTemp(long pc, ItcDriv *me) {
|
||||
quit:
|
||||
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[]) {
|
||||
/* args:
|
||||
@ -256,6 +333,8 @@ pEVControl ItcMakeEVC(SConnection *pCon, int argc, char *argv[]) {
|
||||
|
||||
me = evc->pDriv->pPrivate;
|
||||
me->sampleChan = 1;
|
||||
me->gasMode = 1;
|
||||
me->htrMode = 1;
|
||||
eve=&me->eve;
|
||||
|
||||
eve->run = (FsmFunc)ItcSetTemp;
|
||||
|
37
lcdriv.c
37
lcdriv.c
@ -32,12 +32,13 @@ typedef struct {
|
||||
Eve eve;
|
||||
float t[4]; /* set t. & 3 temperatures */
|
||||
int dig[4]; /* format for these */
|
||||
float coldvalve;
|
||||
int gas;
|
||||
float gas;
|
||||
int remote;
|
||||
int hot;
|
||||
} LcDriv;
|
||||
|
||||
static long LcSetGas(long pc, void *obj);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define A EVE_ACTPAR
|
||||
#define L EVE_LOGPAR
|
||||
@ -52,7 +53,7 @@ void LcPars(LcDriv *me, EveParArg *arg) {
|
||||
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);
|
||||
EveFloatCmd(arg, "gas", &me->gas, "%.1f\t%%", LcSetGas, usUser, A + L);
|
||||
|
||||
EveIntPar(arg, "dig1", &me->dig[1], usUser, S);
|
||||
EveIntPar(arg, "dig2", &me->dig[2], usUser, S);
|
||||
@ -95,10 +96,10 @@ static int LcRead(long pc, LcDriv *me) {
|
||||
EveWrite(eve, "X");
|
||||
FSM_NEXT
|
||||
LcStatus(me); /* check for errors */
|
||||
if (!me->remote) goto skiprmt;
|
||||
EveWrite(eve, "C0");
|
||||
me->remote = 0;
|
||||
FSM_NEXT
|
||||
// if (!me->remote) goto skiprmt;
|
||||
// EveWrite(eve, "C0");
|
||||
// me->remote = 0;
|
||||
// FSM_NEXT
|
||||
|
||||
skiprmt:
|
||||
if (me->dig[1] < 0) goto skip1;
|
||||
@ -117,9 +118,27 @@ static int LcRead(long pc, LcDriv *me) {
|
||||
FSM_NEXT
|
||||
me->t[3] = OiGetFlt(eve, me->dig[3], NULL);
|
||||
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
|
||||
me->coldvalve = OiGetFlt(eve, 1, NULL);
|
||||
quit:
|
||||
FSM_END
|
||||
}
|
||||
|
351
logger.c
351
logger.c
@ -19,16 +19,74 @@ Markus Zolliker, Sept 2004
|
||||
|
||||
struct Logger {
|
||||
char *name;
|
||||
char old[132];
|
||||
char old[256];
|
||||
int period;
|
||||
time_t last;
|
||||
long pos;
|
||||
Logger *next;
|
||||
};
|
||||
|
||||
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];
|
||||
struct tm *tm;
|
||||
int yday, isdst;
|
||||
@ -37,7 +95,8 @@ void LoggerWrite(Logger *log, time_t now, int period, char *value) {
|
||||
FILE *fil;
|
||||
long pos;
|
||||
|
||||
if (dir == NULL) return;
|
||||
LoggerGetDir();
|
||||
if (dir == NULL) return 0;
|
||||
if (now == 0) {
|
||||
printf("now==0\n");
|
||||
}
|
||||
@ -46,6 +105,8 @@ void LoggerWrite(Logger *log, time_t now, int period, char *value) {
|
||||
tm = localtime(&now);
|
||||
if (tm->tm_yday != yday) {
|
||||
log->period = 0;
|
||||
} else if (0 == strncmp(value, log->old, sizeof(log->old))) {
|
||||
return 0;
|
||||
}
|
||||
log->last = now;
|
||||
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+");
|
||||
if (fil == NULL) { /* create new file */
|
||||
fil = fopen(path, "w+");
|
||||
if (fil == NULL) return;
|
||||
if (fil == NULL) return 0;
|
||||
fputs(stim, fil);
|
||||
} else { /* check if file is actual */
|
||||
fgets(buf, sizeof buf, fil);
|
||||
if (0 != strncmp(buf, stim, 11)) {
|
||||
fclose(fil);
|
||||
fil=fopen(path, "w+"); /* overwrite old logfile */
|
||||
if (fil == NULL) return;
|
||||
if (fil == NULL) return 0;
|
||||
fputs(stim, fil);
|
||||
} else {
|
||||
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 {
|
||||
buf[0]='\0';
|
||||
}
|
||||
/*
|
||||
if (log->pos > 0) {
|
||||
fseek(fil, log->pos, SEEK_SET);
|
||||
}
|
||||
log->pos = ftell(fil);
|
||||
*/
|
||||
strftime(stim, sizeof stim,"%H:%M:%S", tm);
|
||||
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 */
|
||||
log->pos = ftell(fil); /* next time append to the end */
|
||||
}
|
||||
|
||||
// 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 */
|
||||
// }
|
||||
l = strlen(value);
|
||||
if (l >= sizeof(log->old)) {
|
||||
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);
|
||||
log->old[l] = '\0';
|
||||
fclose(fil);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
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, "");
|
||||
free(log->name);
|
||||
free(log);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char *LoggerGetDir(void) {
|
||||
if (dir == NULL) {
|
||||
dir = IFindOption(pSICSOptions, "LoggerDir");
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
Logger *LoggerMake(char *name, int period) {
|
||||
@ -114,9 +169,9 @@ Logger *LoggerMake(char *name, int period) {
|
||||
char path[256];
|
||||
struct stat st;
|
||||
int i;
|
||||
char *dir;
|
||||
time_t t;
|
||||
|
||||
dir = LoggerGetDir();
|
||||
LoggerGetDir();
|
||||
if (dir == NULL) return NULL;
|
||||
snprintf(path, sizeof path, "%s/%s", dir, name);
|
||||
i = stat(path, &st);
|
||||
@ -128,6 +183,8 @@ Logger *LoggerMake(char *name, int period) {
|
||||
i = mkdir(path, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
|
||||
if (i < 0) return NULL; /* mkdir failed */
|
||||
}
|
||||
log = LoggerFind(name); /* look if logger already exists */
|
||||
if (log == NULL) {
|
||||
log = malloc(sizeof *log);
|
||||
if (log == NULL) return NULL;
|
||||
log->name = strdup(name);
|
||||
@ -139,30 +196,54 @@ Logger *LoggerMake(char *name, int period) {
|
||||
log->old[0] = '\0';
|
||||
log->last = 0;
|
||||
log->pos = 0;
|
||||
LoggerWrite(log, time(NULL) - 1, period, "");
|
||||
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 */
|
||||
}
|
||||
return log;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
typedef enum { numeric, text } CompType;
|
||||
|
||||
typedef struct {
|
||||
SConnection *pCon;
|
||||
CompType type;
|
||||
time_t step;
|
||||
time_t t0, tmin, tmax;
|
||||
time_t tlast;
|
||||
float ymin, ymax;
|
||||
float ylast;
|
||||
long cnt;
|
||||
time_t tlim;
|
||||
time_t tmin, tmax, tlast, told;
|
||||
float ymin, ymax, ylast, yold;
|
||||
char slast[256];
|
||||
char set[256];
|
||||
} Compressor;
|
||||
|
||||
static void LoggerInit(Compressor *c, SConnection *pCon, time_t step) {
|
||||
c->pCon = pCon;
|
||||
c->step = step;
|
||||
c->tmin = -1;
|
||||
c->tmin = -2;
|
||||
c->tmax = 0;
|
||||
c->tlast = 0;
|
||||
c->t0 = 0;
|
||||
c->tlim = 0;
|
||||
c->told = 0;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
/* 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, char *value) {
|
||||
char *p;
|
||||
double y;
|
||||
|
||||
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 (c->type == numeric) {
|
||||
if (t == 0) { /* finish */
|
||||
t = c->tlim + 3 * c->step;
|
||||
y = 0;
|
||||
} else {
|
||||
y = strtod(value, &p);
|
||||
if (p == value) {
|
||||
y = LOGGER_NAN;
|
||||
} else {
|
||||
if (y == LOGGER_NAN) y *= 1.0000002;
|
||||
}
|
||||
if (y == LOGGER_NAN) return;
|
||||
if (c->tmin < 0) {
|
||||
}
|
||||
/* 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);
|
||||
c->ymax = c->ymin;
|
||||
c->tmax = c->tmin;
|
||||
} else {
|
||||
LoggerOut(c, c->tmin, c->ymin);
|
||||
if (c->tmin == c->tmax) goto first;
|
||||
c->ymin = c->ymax;
|
||||
c->tmin = c->tmax;
|
||||
}
|
||||
if (t >= c->tlim) {
|
||||
LoggerOut(c, c->tmin, c->ymin);
|
||||
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;
|
||||
}
|
||||
c->yold = y;
|
||||
c->told = t;
|
||||
return;
|
||||
first:
|
||||
c->tlim = t + 2 * c->step;
|
||||
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;
|
||||
return;
|
||||
} else if (c->type == text) {
|
||||
if (t != 0) LoggerOutStr(c, t, value);
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]) {
|
||||
time_t from, to, step, xs, lastx, now;
|
||||
time_t from, to, step, xs, lastt, now;
|
||||
char *p;
|
||||
int i, l, yday, iret, loss;
|
||||
time_t tim, tr;
|
||||
int inRange;
|
||||
time_t t, startim;
|
||||
struct tm tm;
|
||||
char path[256], line[80];
|
||||
char stim[32], path[256], line[256], lastval[256];
|
||||
char *lin, *val, *stp;
|
||||
FILE *fil;
|
||||
Compressor c;
|
||||
float yy, lasty;
|
||||
Logger *log;
|
||||
|
||||
if (argc < 4) {
|
||||
SCWrite(pCon, "illegal number of arguments", eError);
|
||||
return 0;
|
||||
if (argc < 2) goto illarg;
|
||||
strtolower(argv[1]);
|
||||
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);
|
||||
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;
|
||||
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 (from <= 0) from += now;
|
||||
if (to <= 0) to += now;
|
||||
if (step <= 0) step = 1;
|
||||
|
||||
dir = LoggerGetDir();
|
||||
LoggerGetDir();
|
||||
if (dir == NULL) {
|
||||
SCWrite(pCon, "LoggerDir not found", eError);
|
||||
return 0;
|
||||
@ -270,23 +375,37 @@ int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
|
||||
loss = 0;
|
||||
for (i=4; i<argc; i++) {
|
||||
tim = from;
|
||||
startim = from;
|
||||
t = 0;
|
||||
lastt = 0;
|
||||
inRange = 0;
|
||||
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) {
|
||||
while (startim <= to) {
|
||||
tm = *localtime(&startim);
|
||||
if (tm.tm_yday != yday) {
|
||||
if (fil != NULL) { /* close file if day changed */
|
||||
fclose(fil);
|
||||
fil=NULL;
|
||||
}
|
||||
}
|
||||
if (fil == NULL) {
|
||||
yday = tm.tm_yday;
|
||||
strftime(path + l, sizeof path - l, "%m-%d.log", &tm);
|
||||
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) {
|
||||
lin == NULL;
|
||||
@ -310,38 +429,37 @@ int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
}
|
||||
p = strchr(val, '\t');
|
||||
if (p) {
|
||||
stp = p+1;
|
||||
*p='\0';
|
||||
stp = val+1;
|
||||
iret = sscanf(stp, "%ld", &xs);
|
||||
if (iret == 1) {
|
||||
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;
|
||||
t=mktime(&tm);
|
||||
if (!inRange) {
|
||||
if (t < startim) {
|
||||
lastval[0]='\0';
|
||||
strncat(lastval, val, sizeof lastval - 1);
|
||||
lastt = t;
|
||||
} else {
|
||||
if (yy == LOGGER_NAN) yy *= 1.0000002;
|
||||
inRange=1;
|
||||
if (lastt != 0) {
|
||||
LoggerPut(&c, lastt, lastval);
|
||||
}
|
||||
if (tr >= tim) {
|
||||
if (lastx != 0) {
|
||||
lastx += xs;
|
||||
while (lastx < tr) {
|
||||
LoggerPut(&c, lastx, lasty);
|
||||
lastx += xs;
|
||||
LoggerPut(&c, t, val);
|
||||
}
|
||||
} else {
|
||||
LoggerPut(&c, t, val);
|
||||
}
|
||||
LoggerPut(&c, tr, yy);
|
||||
}
|
||||
lastx = tr;
|
||||
lasty = yy;
|
||||
}
|
||||
}
|
||||
if (lin == NULL) {
|
||||
@ -349,17 +467,32 @@ int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
tm.tm_isdst = -1;
|
||||
tim=mktime(&tm);
|
||||
startim=mktime(&tm);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
c.ylast = LOGGER_NAN;
|
||||
LoggerSum(&c);
|
||||
if (!inRange) {
|
||||
if (lastt != 0) {
|
||||
LoggerPut(&c, lastt, lastval);
|
||||
}
|
||||
snprintf(line, sizeof line, "*%d\n", loss);
|
||||
}
|
||||
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 %ld %ld\n", loss, from, to);
|
||||
SCWrite(pCon, line, eStatus);
|
||||
return 1;
|
||||
illarg:
|
||||
SCWrite(pCon, "illegal argument", eError);
|
||||
SCWrite(pCon, "illegal argument(s)", eError);
|
||||
return 0;
|
||||
}
|
||||
|
2
logger.h
2
logger.h
@ -14,6 +14,6 @@ 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);
|
||||
int LoggerWrite(Logger *log, time_t now, int period, char *value);
|
||||
|
||||
#endif
|
||||
|
@ -25,9 +25,7 @@
|
||||
#include <servlog.h>
|
||||
#include <fortify.h>
|
||||
|
||||
typedef struct __EVDriver *pEVDriver;
|
||||
|
||||
#include <evdriver.i>
|
||||
#include "evdriver.h"
|
||||
#include <network.h>
|
||||
#include <rs232controller.h>
|
||||
|
||||
|
Reference in New Issue
Block a user