diff --git a/arrobj.c b/arrobj.c index 5e1eb39..a566b53 100644 --- a/arrobj.c +++ b/arrobj.c @@ -31,6 +31,7 @@ static ParClass arrayObjClass = { "array", sizeof(ArrayObj) }; typedef struct WrtObjContext { FILE *file; + int pos; char filename[PATH_MAX]; } WrtObjContext; @@ -38,9 +39,17 @@ typedef struct WrtObjContext { int WrtObjOpen(WrtObjContext *ctx, char *fileName) { int iret; - + char *slashpos; + /* create a temporary file first */ - iret = snprintf(ctx->filename, sizeof(ctx->filename), ".%s", fileName); + slashpos = strrchr(fileName, '/'); + if (slashpos == NULL) { + ctx->pos = 0; + } else { + ctx->pos = slashpos - fileName + 1; + } + iret = snprintf(ctx->filename, sizeof(ctx->filename), "%.*s.%s" + , ctx->pos, fileName, fileName + ctx->pos); if (iret < 0 || iret >= sizeof(ctx->filename)) { return 0; } @@ -66,9 +75,13 @@ void WrtObj(WrtObjContext *ctx, char *objectName) { } /*-----------------------------------------------------------------------*/ void WrtObjClose(WrtObjContext *ctx) { + char finalName[PATH_MAX]; + if (ctx) { fclose(ctx->file); - rename(ctx->filename, ctx->filename+1); + snprintf(finalName, sizeof finalName, "%.*s%s" + , ctx->pos, ctx->filename, ctx->filename + ctx->pos + 1); + rename(ctx->filename, finalName); } } /*----------------------------------------------------------------------------*/ @@ -277,5 +290,5 @@ static int ArrayObjInit(SConnection *con, int argc, char *argv[], int dynamic) { /*----------------------------------------------------------------------------*/ void ArrayObjStartup(void) { ParMakeClass(&arrayObjClass, NULL); - MakeDriver("array", ArrayObjInit, 0); + MakeDriver("array", ArrayObjInit, 0, "String Array Object"); } diff --git a/ease.c b/ease.c index e516fbb..0edd82f 100644 --- a/ease.c +++ b/ease.c @@ -44,6 +44,7 @@ EaseDriv *EaseDrivCast(void *object) { /*----------------------------------------------------------------------------*/ void EaseStop(EaseBase *eab) { FsmStop(eab->task, eab->idle); + closeRS232(eab->ser); eab->state = EASE_notconnected; } /*----------------------------------------------------------------------------*/ @@ -105,6 +106,7 @@ void EaseWrite(EaseBase *eab, char *cmd) { snprintf(eab->msg, sizeof eab->msg, "connection to %s:%d lost", eab->ser->pHost, eab->ser->iPort); ParPrintf(eab, eError, "ERROR: %s", eab->msg); + closeRS232(eab->ser); eab->state = EASE_notconnected; eab->errCode = iRet; return; @@ -205,9 +207,11 @@ int EaseHandler(EaseBase *eab) { snprintf(eab->msg, sizeof eab->msg, "connection for %s failed", eab->p.name); ParPrintf(eab, eError, "%s", eab->msg); + closeRS232(eab->ser); eab->state = EASE_notconnected; return 0; } else { + eab->tmo = 20; snprintf(eab->msg, sizeof eab->msg, "get a first answer from %s", eab->p.name); eab->state = EASE_idle; @@ -345,7 +349,7 @@ int EaseUpdate(int flag) { assert(flag >= 0); assert(flag <= eab->maxflag); eab->updateFlags[flag / EASE_FLAGBITS] |= 1 << (flag % EASE_FLAGBITS); - FsmSpeed(eab->task); + if (eab->task) FsmSpeed(eab->task); return 1; } return 0; @@ -614,6 +618,7 @@ static int EaseInit(SConnection *pCon, EaseBase *eab, int argc, char *argv[], eab->version[0] = '\0'; eab->maxflag = maxflag; eab->sendCmd = NULL; + eab->tmo = 20; eab->updateFlags = calloc(maxflag / EASE_FLAGBITS + 1, sizeof (*eab->updateFlags)); if (eab->updateFlags == NULL) { SCWrite(pCon, "out of memory", eError); @@ -723,7 +728,14 @@ void *EaseMakeDriv(SConnection *con, void *class, int argc, char *argv[], ead->drivInt->SetValue = EaseRun; ead->drivInt->CheckStatus = EaseCheckStatus; ead->drivInt->GetValue = EaseGetValue; - + + ead->maxwait = -1; + ead->lowerLimit = 0; + ead->upperLimit = 1000; + ead->settle = 0; + ead->tolerance = 1; + ead->targetValue = 0; + /* EMon interface to be implemented */ return ead; } diff --git a/ease.h b/ease.h index 3798713..184bb4f 100644 --- a/ease.h +++ b/ease.h @@ -49,6 +49,7 @@ typedef struct { unsigned long *updateFlags; int startOk; char *sendCmd; + int tmo; } EaseBase; typedef struct { diff --git a/euro2kdriv.c b/euro2kdriv.c index 636e5e6..8d715f5 100644 --- a/euro2kdriv.c +++ b/euro2kdriv.c @@ -32,6 +32,7 @@ Markus Zolliker, August 2005 #define EURO2K_SET 1 #define EURO2K_MODE 2 +#define EURO2K_PAR 3 typedef enum {read_only, settable, to_set} Euro2kAccess; @@ -49,13 +50,17 @@ typedef struct Euro2kPar { typedef struct { EaseDriv d; char *unit; - int mode, manual; + int mode; char *script; int warned; float temperature; float output; + float position; + float range; + float asymmetry; float setpoint; Euro2kPar *pars, *readPar; + Statistics *stat; } Euro2k; static ParClass euro2kClass = { "EURO2K", sizeof(Euro2k) }; @@ -68,7 +73,7 @@ static int Euro2kMakePar(void *object, void *userarg, int argc, char *argv[]) int iarg; assert(drv); - if (argc < 1) goto Usage; + if (argc < 2) goto Usage; last = &drv->pars; for (par = drv->pars; par != NULL; par = par->next) { if (strcasecmp(argv[0], par->name) == 0) { @@ -155,11 +160,17 @@ void Euro2kParDef(void *object) { ParName("mode"); ParEnum(modeList); ParList(0); EaseUpdate(EURO2K_MODE); ParInt(&drv->mode, 1); - ParName("manual"); ParEnum(modeList); - ParInt(&drv->manual, 1); - ParName("output"); ParTail("%"); ParFloat(&drv->output, PAR_NAN); + + ParName("position"); ParTail("%"); + ParFloat(&drv->position, PAR_NAN); + + ParName("asymmetry"); ParAccess(usUser); + ParFloat(&drv->asymmetry, PAR_NAN); + + ParName("range"); ParAccess(usUser); + ParFloat(&drv->range, PAR_NAN); ParName("set"); ParTail(drv->unit); EaseUpdate(EURO2K_SET); ParFloat(&drv->setpoint, PAR_NAN); @@ -206,7 +217,7 @@ void Euro2kParDef(void *object) { ParFmt(par->fmt); } if (par->set >= settable) { - if (EaseUpdate(EURO2K_SET)) { + if (EaseUpdate(EURO2K_PAR)) { par->set = to_set; } } @@ -217,7 +228,7 @@ void Euro2kParDef(void *object) { ParName("makepar"); ParAccess(usUser); ParCmd(Euro2kMakePar, NULL); EaseBasePar(drv); - EaseDrivPar(drv, "%#.5g", drv->unit); + EaseDrivPar(drv, "%.5g", drv->unit); ParStdDef(); EaseMsgPar(drv); if (ParActionIs(PAR_KILL)) { @@ -239,6 +250,9 @@ void Euro2kParDef(void *object) { free(par); } drv->pars = NULL; + if (drv->stat) { + StatisticsKill(drv->stat); + } } } /*----------------------------------------------------------------------------*/ @@ -249,13 +263,16 @@ static long Euro2kRead(long pc, void *object) { Tcl_Interp *pTcl = NULL; char *p; int l, m, iRet; - float dif; + float dif, a; char buf[4]; - + Statistics *old; + switch (pc) { default: /* FSM BEGIN *******************************/ if (drv->script && drv->script[0] != '\0' && 0 != strcmp(drv->script, "0")) { pTcl = InterpGetTcl(pServ->pSics); + old = StatisticsBegin(drv->stat); iRet = Tcl_Eval(pTcl,drv->script); + StatisticsEnd(old); if (iRet == TCL_OK) { if (drv->warned > 0) drv->warned--; } else if (drv->warned<3) { @@ -263,13 +280,18 @@ static long Euro2kRead(long pc, void *object) { ParPrintf(drv, eError, "ERROR: %s in %s.task '%s'", pTcl->result, eab->p.name, drv->script); } } - ModBusRequestValue(eab, 273); /* get manual or auto */ + if (EaseGetUpdate(drv, EURO2K_MODE)) goto skipMode; + ModBusRequestValue(eab, 273, modBusInt); /* get manual or auto */ return __LINE__; case __LINE__: /**********************************/ - m = ModBusGetValue(eab, modBusInt); - if (m != drv->manual) { /* mode changed manually */ - drv->mode = m; + if (!EaseGetUpdate(drv, EURO2K_MODE)) { + m = ModBusGetValue(eab, modBusInt); + if (m != drv->mode) { /* mode changed manually -> change disp */ + drv->mode = m; + EaseSetUpdate(drv, EURO2K_MODE, 1); + } } - drv->manual= m; + skipMode: + ModBusRequestFloats(eab, 1, 3); return __LINE__; case __LINE__: /**********************************/ drv->temperature = ModBusGetFloat(eab, 1); @@ -277,11 +299,19 @@ static long Euro2kRead(long pc, void *object) { drv->setpoint = ModBusGetFloat(eab, 2); } drv->output = ModBusGetFloat(eab, 3); + a = drv->output * eab->p.period / drv->range; + if ((drv->position > 50.) == (drv->output > 0)) { + drv->position += a * (1 - drv->asymmetry * 0.01); + } else { + drv->position += a * (1 + drv->asymmetry * 0.01); + } + if (drv->position < 0) drv->position = 0; + if (drv->position > 100) drv->position = 100; par = drv->pars; loop: if (par == NULL) goto finish; if (par->adr == 0 || par->set == to_set) goto skipPar; - ModBusRequestValue(eab, par->adr); + ModBusRequestValue(eab, par->adr, par->type); drv->readPar = par; return __LINE__; case __LINE__: /**********************************/ par = drv->readPar; @@ -333,8 +363,10 @@ static long Euro2kSet(long pc, void *object) { if (drv->mode == 0) goto loop; drv->mode = 0; mode: - drv->manual = drv->mode; - ModBusPutValue(eab, 273, 1, drv->manual); /* set manual to 0 */ + if (drv->mode) drv->mode = 1; + ModBusPutValue(eab, 106, modBusInt, drv->mode*5); /* set display std or blank */ + return __LINE__; case __LINE__: /**********************************/ + ModBusPutValue(eab, 273, modBusInt, drv->mode); /* set manual to 0 */ setIt: return __LINE__; case __LINE__: /**********************************/ goto loop; @@ -347,13 +379,17 @@ static long Euro2kStart(long pc, void *object) { EaseBase *eab = object; switch (pc) { default: /* FSM BEGIN *******************************/ - ModBusRequestValue(eab, 1); + ModBusRequestValue(eab, 1, modBusFloat); return __LINE__; case __LINE__: /**********************************/ if (0 == ModBusGetValue(eab, modBusFloat)) { ParPrintf(drv, eError, "bad or no response on ModBus"); goto quit; } ParPrintf(drv, eStatus, "connected to euro2k"); + ModBusPutValue(eab, 111, modBusFloat, drv->d.upperLimit); + return __LINE__; case __LINE__: /**********************************/ + ModBusPutValue(eab, 112, modBusFloat, drv->d.lowerLimit); + return __LINE__; case __LINE__: /**********************************/ FsmCall(Euro2kRead); return __LINE__; case __LINE__: /**********************************/ @@ -367,19 +403,21 @@ static int Euro2kInit(SConnection *con, int argc, char *argv[], int dynamic) { */ Euro2k *drv; + char sn[64]; drv = EaseMakeDriv(con, &euro2kClass, argc, argv, dynamic, 7, Euro2kParDef, ModBusHandler, Euro2kStart, NULL, Euro2kRead, Euro2kSet); if (drv == NULL) return 0; drv->pars = NULL; + snprintf(sn, sizeof sn, "%s task", argv[1]); + drv->stat = StatisticsNew(sn); setRS232ReplyTerminator(drv->d.b.ser,""); setRS232SendTerminator(drv->d.b.ser,""); - ParPrintf(drv, eValue, "Eurotherm 2xxx"); return 1; } /*----------------------------------------------------------------------------*/ void Euro2kStartup(void) { ParMakeClass(&euro2kClass, EaseDrivClass()); - MakeDriver("EURO2K", Euro2kInit, 0); + MakeDriver("EURO2K", Euro2kInit, 0, "Eurotherm 2xxx"); } diff --git a/ighdriv.c b/ighdriv.c index 0d6a7e7..66a7195 100644 --- a/ighdriv.c +++ b/ighdriv.c @@ -34,11 +34,12 @@ Markus Zolliker, May 2005 #define OLDIGH -8 #define SORBS_FLAG 1 #define MIXP_FLAG 2 -#define STILL_FLAG 3 -#define SORBP_FLAG 4 -#define MOT_FLAGS 5 -#define VALVE_FLAGS 8 -#define MAX_FLAG 31 +#define MAXP_FLAG 3 +#define STILL_FLAG 4 +#define SORBP_FLAG 5 +#define MOT_FLAGS 6 +#define VALVE_FLAGS 9 +#define MAX_FLAG 32 static char *valves[]={"V9", "V8", "V7", "V11A", "V13A", "V13B", "V11B", "V12B", " He4", "V1", "V5", "V4", "V3", "V14", "V10", "V2", @@ -60,6 +61,7 @@ static char *closedOrOpen[]={"closed", "open", NULL}; typedef struct { EaseDriv d; + float setT; float sorbS; float mixT; float onekT; @@ -69,6 +71,8 @@ typedef struct { float sorbP; float press[n_PRESS]; float mv[n_MOTOR]; + float v6pos; + time_t v6time; int pdig; int v[n_VALVES]; int e; /* heater range */ @@ -82,12 +86,40 @@ static ParClass ighClass = { "IGH", sizeof(Igh) }; static long IghSet(long pc, void *object); /*----------------------------------------------------------------------------*/ +static int IghPower2Range(float p) { + int e; + if (p <= 0) return 0; + for (e = 1; e < 5; e++) { + if (p < 1.9994) break; + p /= 10; + } + return e; +} +/*----------------------------------------------------------------------------*/ +static float IghRange2Max(int e) { + static float elist[]={0,2,20,200,2000,20000}; + if (e < 0) { + e = 0; + } else if (e > 5) { + e = 5; + } + return elist[e]; +} +/*----------------------------------------------------------------------------*/ static void IghParDef(void *object) { Igh *drv = ParCast(&ighClass, object); EaseBase *eab = object; int i, flag, l, changed; - char *vPos; + char *vPos, *val; char fmt[8], vList[80]; + float maxP; + + ParName(""); ParTail("K"); ParFmt("%.4f"); + ParFloat(&drv->mixT, PAR_NAN); + + ParName("Tset"); ParTail("K"); ParFmt("%.4f"); + if (eab->syntax == OLDIGH) ParList("all"); + ParFloat(&drv->setT, PAR_NAN); ParName("TsorbSet"); EaseUpdate(SORBS_FLAG); ParTail("K"); ParFmt("%.1f"); @@ -106,8 +138,7 @@ static void IghParDef(void *object) { ParFloat(&drv->sorbT, PAR_NAN); ParName("Pmix"); - if (drv->e < 1 || drv->e > 5) drv->e=1; - if (drv->e == 5) { + if (drv->e >= 5 || drv->e < 1) { strcpy(fmt, "%.0f"); } else { snprintf(fmt, sizeof fmt, "%%.%df", 4 - drv->e); @@ -115,6 +146,14 @@ static void IghParDef(void *object) { EaseUpdate(MIXP_FLAG); ParTail("uW"); ParFmt(fmt); ParFloat(&drv->mixP, PAR_NAN); + ParName("Pmax"); + EaseUpdate(MAXP_FLAG); ParTail("uW"); ParFmt("%g"); + if ((val = ParGetValueArg())) { + drv->e = IghPower2Range(atof(val) * 0.9); + } + maxP = IghRange2Max(drv->e); + ParFloat(&maxP, PAR_NAN); + ParName("Pstill"); EaseUpdate(STILL_FLAG); ParTail("mW"); ParFmt("%.3f"); ParFloat(&drv->stillP, PAR_NAN); @@ -144,11 +183,16 @@ static void IghParDef(void *object) { flag = MOT_FLAGS; for (i=0; imv[i], PAR_NAN); } + + ParName("v6pos"); ParFmt("%.1f"); ParTail("%"); + ParFloat(&drv->v6pos, PAR_NAN); + assert(flag == VALVE_FLAGS); l = 0; for (i=0; ia = ans[3] - '0'; drv->s = ans[16] - '0'; drv->o = ans[18] - '0'; - drv->e = ans[20] - '0'; + if (EaseGetUpdate(drv, MAXP_FLAG) == 0) { + if (drv->a == 0) { + drv->e = 0; + } else { + drv->e = ans[20] - '0'; + } + } if (ans[5] != '3' && drv->remote == 2) { ParPrintf(drv, eError, "IGH switched to local"); *code = EASE_FAULT; @@ -243,7 +293,8 @@ static long IghRead(long pc, void *object) { EaseBase *eab = object; char *p; int l; - time_t thisPeriod; + time_t now; + float delta; switch (pc) { default: /* FSM BEGIN *******************************/ EaseWrite(eab, "X"); @@ -285,6 +336,12 @@ static long IghRead(long pc, void *object) { } if (EaseCheckDoit(eab)) goto quit; + if (eab->syntax == OLDIGH) goto noSetTemp; + EaseWrite(eab, "R33"); + return __LINE__; case __LINE__: /**********************************/ + drv->setT = OxiGet(eab, 4, NULL, drv->setT); + + noSetTemp: EaseWrite(eab, "R1"); return __LINE__; case __LINE__: /**********************************/ drv->sorbT = OxiGet(eab, 1, NULL, drv->sorbT); @@ -297,6 +354,10 @@ static long IghRead(long pc, void *object) { if (EaseCheckDoit(eab)) goto quit; + if (drv->e == 0) { + drv->mixP = 0; + goto skip4; + } if (EaseGetUpdate(drv, MIXP_FLAG)) goto skip4; EaseWrite(eab, "R4"); return __LINE__; case __LINE__: /**********************************/ @@ -325,6 +386,16 @@ static long IghRead(long pc, void *object) { EaseWrite(eab, "R7"); return __LINE__; case __LINE__: /**********************************/ drv->mv[V6] = OxiGet(eab, 1, NULL, drv->mv[V6]); + time(&now); + delta = (now - drv->v6time) / 2.64; /* speed: 1/2.64 %/sec */ + drv->v6time = now; + if (drv->v6pos > drv->mv[V6] + delta) { + drv->v6pos -= delta; + } else if (drv->v6pos < drv->mv[V6] - delta) { + drv->v6pos += delta; + } else { + drv->v6pos = drv->mv[V6]; + } skip7: if (EaseCheckDoit(eab)) goto quit; @@ -424,6 +495,7 @@ static long IghSet(long pc, void *object) { if (upd == EASE_RUN) goto set_temp; if (upd == SORBS_FLAG) goto set_sorb_temp; if (upd == MIXP_FLAG) goto set_mix_pow; + if (upd == MAXP_FLAG) goto set_max_pow; if (upd == STILL_FLAG) goto set_still_pow; if (upd == SORBP_FLAG) goto set_sorb_pow; goto finish; @@ -482,33 +554,44 @@ static long IghSet(long pc, void *object) { goto loop; set_mix_pow: + EaseWrite(eab, "A0"); + return __LINE__; case __LINE__: /**********************************/ + if (drv->e <= 1) goto skipe; EaseWrite(eab, "E1"); return __LINE__; case __LINE__: /**********************************/ + + skipe: if (drv->mixP > 0) { - mp = drv->mixP * 0.1; - for (i=2; i<6; i++) { - if (mp > 199) { - break; - } - mp = mp * 10; - } - if (mp > 1999) mp = 1999; - drv->e = 7-i; + drv->e = IghPower2Range(drv->mixP); + mp = drv->mixP / IghRange2Max(drv->e) * 2000; } else { - mp = 0; + mp = 0; /* range unchanged for external heater signal */ } OxiSet(eab, "M", mp, 0); return __LINE__; case __LINE__: /**********************************/ + if (drv->e == 0) goto loop; + + EaseWrite(eab, "A1"); + return __LINE__; case __LINE__: /**********************************/ + + set_max_pow: + if (drv->e == 0) goto seta0; snprintf(buf, sizeof buf, "E%d", drv->e); EaseWrite(eab, buf); return __LINE__; case __LINE__: /**********************************/ - EaseWrite(eab, "A1"); + goto loop; + + seta0: + EaseWrite(eab, "A0"); return __LINE__; case __LINE__: /**********************************/ goto loop; - + set_temp: - /* unknown yet */ - goto loop; + EaseWrite(eab, "A2"); + return __LINE__; case __LINE__: /**********************************/ + if (drv->d.targetValue < 0) drv->d.targetValue = 0; + if (drv->d.targetValue > 1.999) drv->d.targetValue = 1.999; + OxiSet(eab, "T", drv->d.targetValue, 4); return __LINE__; case __LINE__: /**********************************/ goto loop; @@ -521,6 +604,11 @@ static long IghSet(long pc, void *object) { set_mot: i = upd - MOT_FLAGS; + if (drv->mv[i] > 99.9) { + drv->mv[i]=99.9; + } else if (drv->mv[i] < 0) { + drv->mv[i]=0; + } OxiSet(eab, motorCommands[i], drv->mv[i], 1); return __LINE__; case __LINE__: /**********************************/ goto loop; @@ -544,11 +632,10 @@ static int IghInit(SConnection *con, int argc, char *argv[], int dynamic) { IghParDef, OxiHandler, IghStart, NULL, IghRead, IghSet); if (drv == NULL) return 0; - ParPrintf(drv, eValue, "OI Gas Handling System"); return 1; } /*----------------------------------------------------------------------------*/ void IghStartup(void) { ParMakeClass(&ighClass, EaseDrivClass()); - MakeDriver("IGH", IghInit, 0); + MakeDriver("IGH", IghInit, 0, "OI Gas Handling System"); } diff --git a/ilmdriv.c b/ilmdriv.c index 5725dc6..1ac668a 100644 --- a/ilmdriv.c +++ b/ilmdriv.c @@ -186,11 +186,10 @@ static int IlmInit(SConnection *con, int argc, char *argv[], int dynamic) { drv = EaseMakeBase(con, &ilmClass, argc, argv, dynamic, 0, IlmParDef, OxiHandler, IlmStart, NULL, IlmRead); if (drv == NULL) return 0; - ParPrintf(drv, eValue, "OI Level Meter"); return 1; } /*----------------------------------------------------------------------------*/ void IlmStartup(void) { ParMakeClass(&ilmClass, EaseBaseClass()); - MakeDriver("ILM", IlmInit, 0); + MakeDriver("ILM", IlmInit, 0, "OI Level Meter"); } diff --git a/ipsdriv.c b/ipsdriv.c index d85e87b..ce4cc3d 100644 --- a/ipsdriv.c +++ b/ipsdriv.c @@ -496,12 +496,11 @@ static int IpsInit(SConnection *con, int argc, char *argv[], int dynamic) { IpsParDef, OxiHandler, IpsStart, NULL, IpsRead, IpsChangeField); if (drv == NULL) return 0; - ParPrintf(drv, eValue, "OI Power Supply"); drv->d.maxwait = 999999; return 1; } /*----------------------------------------------------------------------------*/ void IpsStartup(void) { ParMakeClass(&ipsClass, EaseDrivClass()); - MakeDriver("IPS", IpsInit, 0); + MakeDriver("IPS", IpsInit, 0, "OI Power Supply"); } diff --git a/itcdriv.c b/itcdriv.c index 7ad248e..8a0a02a 100644 --- a/itcdriv.c +++ b/itcdriv.c @@ -721,7 +721,6 @@ static int ItcInit(SConnection *con, int argc, char *argv[], int dynamic) { ItcSet); if (drv == NULL) return 0; drv->d.b.syntax = 0; - ParPrintf(drv, eValue, "OI Temperature Controller"); return 1; } /*----------------------------------------------------------------------------*/ @@ -740,12 +739,11 @@ static int ItcInitLc(SConnection *con, int argc, char *argv[], int dynamic) { drv->lastCtrl = 0; drv->lastTdiff = 0; drv->lastPdiff = 0; - ParPrintf(drv, eValue, "OI Lambda Controller"); return 1; } /*----------------------------------------------------------------------------*/ void ItcStartup(void) { ParMakeClass(&itcClass, EaseDrivClass()); - MakeDriver("ITC", ItcInit, 0); - MakeDriver("LC", ItcInitLc, 0); + MakeDriver("ITC", ItcInit, 0, "OI Temperature Controller"); + MakeDriver("LC", ItcInitLc, 0, "OI Lambda Controller"); } diff --git a/logger.c b/logger.c index dd8274d..b3fc2c9 100644 --- a/logger.c +++ b/logger.c @@ -220,7 +220,7 @@ int LoggerWrite0(Logger *log, time_t now, int period, char *value) { } pos1 = ftell(fil); strftime(stim, sizeof stim,"%H:%M:%S", tm); - fprintf(fil, "%s\t%s%s\n", stim, value, buf); + fprintf(fil, "%s\t%s\n", stim, value); for (p = ftell(fil); p < endPos; p++) { /* overwrite dirt after last line */ fprintf(fil, " "); } diff --git a/logreader.c b/logreader.c index 227202f..1d0f31f 100644 --- a/logreader.c +++ b/logreader.c @@ -9,6 +9,7 @@ #define LOGGER_NAN -999999. #define ONE_YEAR (366*24*3600) +#define LLEN 1024 typedef enum { NUMERIC, TEXT } CompType; @@ -21,8 +22,8 @@ typedef struct { time_t tlim; time_t tmin, tmax, tlast, told; float ymin, ymax, ylast, yold; - char slast[256]; - char set[256]; + char slast[LLEN]; + /* char set[LLEN]; */ int np; char *none; } Compressor; @@ -43,7 +44,7 @@ static void InitCompressor(Compressor *c, SConnection *pCon, time_t step) { } static void OutString(Compressor *c, time_t t, char *str) { - char line[256]; + char line[LLEN]; /* printf("out %ld %g\n", t, y); */ if (0 != strcmp(str, c->slast)) { @@ -173,7 +174,7 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData, int yday=0; time_t t, startim; struct tm tm; - char stim[32], path[256], line[256], lastval[256]; + char stim[32], path[LLEN], line[LLEN], lastval[LLEN]; char *lin, *val, *stp; FILE *fil; Compressor c={0}; diff --git a/make_gen b/make_gen index 1e6f345..6b2b5e3 100644 --- a/make_gen +++ b/make_gen @@ -20,7 +20,8 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \ dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o julcho.o MZOBJ=fsm.o logger.o sugar.o pardef.o ease.o strobj.o oxinst.o logreader.o \ - ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o arrobj.o + ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o arrobj.o \ + lscsupport.o lsc370driv.o libpsi.a: $(OBJ) rm -f libpsi.a diff --git a/modbus.c b/modbus.c index 95d3eb6..40c0bdc 100644 --- a/modbus.c +++ b/modbus.c @@ -337,12 +337,17 @@ float ModBusGetFloat(EaseBase *eab, int adr) { return ieee2double(eab->ans + 3 + i * 4); } /*----------------------------------------------------------------------------*/ -void ModBusRequestValue(EaseBase *eab, int adr) { +void ModBusRequestValue(EaseBase *eab, int adr, int type) { eab->cmd[0] = 1; /* device address */ eab->cmd[1] = 3; /* read n words */ - fadr2word(adr, eab->cmd + 2); - uint2word(2, eab->cmd + 4); + if (type == modBusInt) { + uint2word(adr, eab->cmd + 2); + uint2word(1, eab->cmd + 4); + } else { + fadr2word(adr, eab->cmd + 2); + uint2word(2, eab->cmd + 4); + } ModBusWrite(eab, 6); } /*----------------------------------------------------------------------------*/ @@ -351,13 +356,11 @@ void ModBusPutValue(EaseBase *eab, int adr, int type, float val) { eab->cmd[0] = 1; /* device address */ eab->cmd[1] = 16; /* write n words */ - if (type == modBusTime+9) { + if (type == modBusInt) { uint2word(adr, eab->cmd + 2); - eab->cmd[4] = 2; - eab->cmd[5] = 0; - eab->cmd[6] = 1; - eab->cmd[7] = (int)(val) / 256; - eab->cmd[8] = (int)(val) % 256; + uint2word(1, eab->cmd + 4); + eab->cmd[6] = 2; + uint2word((int)(val), eab->cmd+7); ModBusWrite(eab, 9); return; } diff --git a/modbus.h b/modbus.h index 618f8dc..8655f25 100644 --- a/modbus.h +++ b/modbus.h @@ -19,7 +19,7 @@ int ModBusHandler(void *eab); void ModBusPutFloats(EaseBase *eab, int adr, int npar, float val[]); void ModBusRequestFloats(EaseBase *eab, int adr, int npar); float ModBusGetFloat(EaseBase *eab, int adr); -void ModBusRequestValue(EaseBase *eab, int adr); +void ModBusRequestValue(EaseBase *eab, int adr, int type); float ModBusGetValue(EaseBase *eab, int type); void ModBusPutValue(EaseBase *eab, int adr, int type, float val); diff --git a/oxinst.c b/oxinst.c index 8e05e7b..9481b37 100644 --- a/oxinst.c +++ b/oxinst.c @@ -92,10 +92,11 @@ int OxiHandler(void *object) { goto quit; } else if (eab->cmd[2] == 'k') { /* ?ck */ } else { + eab->tmo = 120; if (eab->syntax <= -8) { corr = OxiCorrect(eab->ans); if (corr) { - ParPrintf(eab, eWarning, "corrected bad response from IGH: %s", corr); +// ParPrintf(eab, eWarning, "corrected bad response from IGH: %s", corr); } } if (eab->cmd[0] != eab->ans[0]) { @@ -110,7 +111,7 @@ int OxiHandler(void *object) { } eab->state = EASE_read; } else if (eab->state == EASE_expect) { - if (time(NULL) > eab->cmdtime+20) { + if (time(NULL) > eab->cmdtime + eab->tmo) { eab->state = EASE_lost; } } else if (eab->state == EASE_lost) { diff --git a/pardef.c b/pardef.c index 6082fc1..85c18a4 100644 --- a/pardef.c +++ b/pardef.c @@ -31,11 +31,12 @@ typedef enum { NO_OP, FMT_OP, SET_OP, GET_OP, INIT_OP } ParOp; typedef struct Context { struct Context *next; ParData *obj; - ParAct act; - ParAct action; + ParAct act; /* action called */ + ParAct action; /* copy of act, but set to PAR_NOOP when name does not match */ char *parName; int argc; char **argv; + char *valueArg; char *thisPar; int returnValue; SConnection *con; @@ -283,6 +284,19 @@ int ParLog(void *object) { ParEnd(); return next; } +/*--------------------------------------------------------------------------*/ +void ParLogForced(void *object) { + ParData *o = ParCheck(&parClass, object); + int next; + + ParBegin(); + ctx->now = time(NULL); + showTime = 1; + ParDo(0, o, PAR_LOG, NULL); + o->logTime = ctx->now; + o->logPending = 0; + ParEnd(); +} /*-------------------------------------------------------------------------*/ static int ParCallBack(int event, void *eventData, void *userData, commandContext cc) { @@ -307,7 +321,7 @@ static int ParOutError(SConnection *con, ParData *o) { SCPrintf(con, eError, "ERROR: insufficient privilege for %s.%s", o->name, ctx->thisPar); break; case ILLNUM: - SCPrintf(con, eError, "ERROR: illegal value", o->name, ctx->argv[0]); + SCPrintf(con, eError, "ERROR: illegal value", o->name, ctx->valueArg); break; case ILLARGC: SCPrintf(con, eError, "ERROR: illegal number of arguments for %s %s", o->name, ctx->thisPar); @@ -434,6 +448,7 @@ static int ParExecute(SConnection *con, SicsInterp *sics, void *object, int argc if (strcmp(argv[1], "=") == 0) { ctx->argc = argc - 2; ctx->argv = argv + 2; + ctx->valueArg = argv[2]; ParDo(con, o, PAR_SET, ""); logIt = 1; } else { @@ -442,6 +457,7 @@ static int ParExecute(SConnection *con, SicsInterp *sics, void *object, int argc } else { ctx->argc = argc - 2; ctx->argv = argv + 2; + ctx->valueArg = argv[2]; ParDo(con, o, PAR_SET, argv[1]); logIt = 1; } @@ -465,7 +481,7 @@ static int ParExecute(SConnection *con, SicsInterp *sics, void *object, int argc ctx->returnValue = UNKPAR; } iret = ParOutError(con, o); - if (logIt) ParLog(o); /* log changes */ + if (logIt) ParLogForced(o); /* log changes */ ParEnd(); return iret; } @@ -984,15 +1000,17 @@ void ParFloat(float *value, float defValue) { ctx->returnValue = ILLARGC; return; } - f = strtod(ctx->argv[0], &endp); - if (endp == ctx->argv[0]) { - f = ParText2Int(ctx->argv[0]); - if (f < 0) { - ctx->returnValue = ILLNUM; - break; + if (ctx->valueArg) { + f = strtod(ctx->valueArg, &endp); + if (endp == ctx->valueArg) { + f = ParText2Int(ctx->valueArg); + if (f < 0) { + ctx->returnValue = ILLNUM; + break; + } } + *value = f; } - *value = f; ParHasChanged(); /* fall through */ case FMT_OP: @@ -1030,15 +1048,17 @@ void ParInt(int *value, int defValue) { ctx->returnValue = ILLARGC; return; } - i = strtol(ctx->argv[0], &endp, 0); - if (endp == ctx->argv[0]) { - i = ParText2Int(ctx->argv[0]); - if (i < 0) { - ctx->returnValue = ILLNUM; - break; + if (ctx->valueArg) { + i = strtol(ctx->valueArg, &endp, 0); + if (endp == ctx->valueArg) { + i = ParText2Int(ctx->valueArg); + if (i < 0) { + ctx->returnValue = ILLNUM; + break; + } } + *value = i; } - *value = i; ParHasChanged(); /* fall through */ case FMT_OP: @@ -1128,6 +1148,17 @@ int ParActionIs(ParAct a) { return 0; } /*----------------------------------------------------------------------------*/ +char *ParGetValueArg() { + char *ret; + if (ctx->action == PAR_SET) { + ret = ctx->valueArg; + ctx->valueArg = NULL; + return ret; + } else { + return NULL; + } +} +/*----------------------------------------------------------------------------*/ void *ParObject(void) { return ctx->obj; } diff --git a/pardef.h b/pardef.h index b51b47b..4351f49 100644 --- a/pardef.h +++ b/pardef.h @@ -195,6 +195,9 @@ typedef struct ParData { list */ void ParLogReady(ReadyState state); /* set ready state for log */ FILE *ParSaveFile(void); /* get the save-file name when action is PAR_SAVE */ + char *ParGetValueArg(); /* get the set argument for floats and ints. If this function + is called, the caller is reponsible for assigning the value + to the object parameter */ /* functions to be used outside pardef: @@ -237,5 +240,6 @@ typedef struct ParData { void ParInitPar(void *object, char *name); /* inititalize dynamic parameter */ + #endif diff --git a/psi.c b/psi.c index 64e7aa8..8363ed6 100644 --- a/psi.c +++ b/psi.c @@ -80,6 +80,7 @@ void SiteInit(void) { INIT(StrObjStartup); INIT(LogReaderInit); INIT(ArrayObjStartup); + INIT(Lsc370Startup); } diff --git a/strobj.c b/strobj.c index 77b17e3..2676327 100644 --- a/strobj.c +++ b/strobj.c @@ -46,5 +46,5 @@ static int StrObjInit(SConnection *con, int argc, char *argv[], int dynamic) { /*----------------------------------------------------------------------------*/ void StrObjStartup(void) { ParMakeClass(&strObjClass, NULL); - MakeDriver("string", StrObjInit, 0); + MakeDriver("string", StrObjInit, 0, "String Object"); } diff --git a/tecsdriv.c b/tecsdriv.c index 8b91faf..390ce4a 100644 --- a/tecsdriv.c +++ b/tecsdriv.c @@ -95,6 +95,7 @@ void outFunc(char *str, void *arg) { pTecsDriv pMe; float fVal; Buffer buffer; + ObPar *pPar; self = (pEVControl)pData; assert(self); @@ -136,7 +137,10 @@ void outFunc(char *str, void *arg) { iRet = EVCGetPar(self, "upperlimit", &fVal); if (abs(fVal - atof(result)) > 1.0e-4 * abs(fVal)) { fVal = atof(result); - iRet = EVCSetPar(self, "upperlimit", fVal,pCon); + pPar = ObParFind(self->pParam,"upperlimit"); + if (pPar != NULL) { + pPar->fVal = fVal; + } } iRet = EVControlWrapper(pCon,pSics,pData,argc,argv); if (iRet != 0) { @@ -161,7 +165,15 @@ void outFunc(char *str, void *arg) { sprintf(pBueffel,"WARNING: upper limit reduced to maximal allowed value: %g", fVal); SCWrite(pCon,pBueffel,eWarning); } - iRet = EVCSetPar(self, "upperlimit", fVal,pCon); + if (argc == 3) { + iRet = EVCSetPar(self, "upperlimit", fVal,pCon); + } else { + pPar = ObParFind(self->pParam,"upperlimit"); + if (pPar != NULL) { + pPar->fVal = fVal; + } + iRet = 1; + } if (iRet) { sprintf(pBueffel,"%s.%s = %s\n",self->pName, argv[1],result); @@ -478,5 +490,5 @@ void outFunc(char *str, void *arg) { pMe->EVLimits=pEvc->pDrivInt->CheckLimits; /* save original CheckLimits function */ pEvc->pDrivInt->CheckLimits=TecsLimits; EVCSetPar(pEvc,"upperlimit",1800.0,pCon); - EVCSetPar(pEvc,"lowerlimit",0.01,pCon); + EVCSetPar(pEvc,"lowerlimit",0.0,pCon); }