new version of TecsServer and conversion utility M.Z.
This commit is contained in:
231
tecs/tecs.c
231
tecs/tecs.c
@@ -21,6 +21,7 @@
|
||||
#endif
|
||||
|
||||
#define TABLE_FILE "tecs.cfg"
|
||||
#define LSC_CODES "lsc.codes"
|
||||
#define LOGLIFETIME 24*3600
|
||||
|
||||
static SerChannel *ser=NULL;
|
||||
@@ -36,17 +37,18 @@ typedef struct {
|
||||
char ch[4];
|
||||
float t, t0, t1, t2, min, max, band; /* temperatures */
|
||||
float scale; /* scale for extreme ranges */
|
||||
float kink; /* for T > kink scale is used
|
||||
float kink; /* for T > kink values are scaled
|
||||
kink > RT for thermocouples going to more than 1500 K */
|
||||
float lim; /* range limit (used when two sensors present) */
|
||||
float lim; /* precise range limit (used when two sensors are present) */
|
||||
float alarm;
|
||||
int customAlarm;
|
||||
int stat1, stat2; /* reading status summary */
|
||||
int present; /* 0: sensor inactive, 1: sensor configured, -1: sensor parameters read */
|
||||
int readStat; /* reading status */
|
||||
int dispfld;
|
||||
char dispfmt;
|
||||
char curve[32]; /* name of curve file */
|
||||
char type[4];
|
||||
char dispfmt;
|
||||
char typ;
|
||||
} SensorT;
|
||||
|
||||
@@ -88,6 +90,7 @@ typedef struct _Plug {
|
||||
int codChanged; /* code has changed */
|
||||
int codDefined; /* code is not yet confirmed */
|
||||
char device[16]; /* device name */
|
||||
char descr[80];
|
||||
} Plug;
|
||||
|
||||
static Plug
|
||||
@@ -107,7 +110,7 @@ static float
|
||||
powFact=1, /* power factor (for external power supplies) */
|
||||
resist=10, /* heater resistance */
|
||||
tShift=0, /* setpoint shift */
|
||||
full, /* full value for helium level */
|
||||
empty, full, /* empty/full value for helium level */
|
||||
prop, integ, deriv, /* pid */
|
||||
maxShift=2, /* maximal shift in when controlMode=2 */
|
||||
maxOver=0, /* maximal overshoot in when controlMode=2 */
|
||||
@@ -189,9 +192,9 @@ static char
|
||||
alarmHistory[N_SENSORS],
|
||||
swap[4],
|
||||
dev[80],
|
||||
dev0[80],
|
||||
dev1[80],
|
||||
devHelp[10000],
|
||||
update[32], /* update script option */
|
||||
lscfg[256], /* lsc commands for configuration */
|
||||
controlChannel[4]="A";
|
||||
|
||||
static char
|
||||
@@ -283,6 +286,7 @@ int InstalCurve(SensorT *sensor, char *devArg) {
|
||||
*e, /* cache part after found entry */
|
||||
*res, *t;
|
||||
int i, n, c1, c2;
|
||||
char ch;
|
||||
char used[60];
|
||||
FILE *fil;
|
||||
|
||||
@@ -394,6 +398,16 @@ int InstalCurve(SensorT *sensor, char *devArg) {
|
||||
if (e!=NULL) { *e='\0'; e++; }
|
||||
}
|
||||
}
|
||||
|
||||
if (num > 20 && strlen(chead) > 10) { /* replace name by a more meaningful */
|
||||
for (i=0; i<10 && i<strlen(nam); i++) {
|
||||
chead[i]=nam[i];
|
||||
}
|
||||
for (i=strlen(nam); i<10; i++) {
|
||||
chead[i]=' ';
|
||||
}
|
||||
}
|
||||
|
||||
i=0;
|
||||
if (num>20) i=12; /* check only from 12th character (CRC) for user curves */
|
||||
if (head[0]!='\0' && LscEqPar(head+i, chead+i)) { /* header matches: select sensor type and curve */
|
||||
@@ -534,34 +548,53 @@ int ReadTable(void) {
|
||||
OnError: return -1;
|
||||
}
|
||||
|
||||
void InitSensor(SensorT *s) {
|
||||
s->t=DATA_UNDEF;
|
||||
s->scale=1;
|
||||
s->kink=0;
|
||||
s->lim=0;
|
||||
s->alarm=0;
|
||||
s->customAlarm=0;
|
||||
s->present=0;
|
||||
s->curve[0]='\0';
|
||||
s->type[0]='\0';
|
||||
}
|
||||
|
||||
int PrepInput(char *label) {
|
||||
char *t, *e;
|
||||
char nam[16], chans[8], typ;
|
||||
char buf[256];
|
||||
int i, j, l;
|
||||
SensorT *s;
|
||||
char *cfg;
|
||||
|
||||
ERR_I(ReadTable());
|
||||
t=strstr(table, label);
|
||||
if (t==NULL) ERR_MSG("device not found");
|
||||
e=strchr(t, '\'');
|
||||
if (e==NULL || e>strchr(t,'\n')) ERR_MSG("missing ' or device name in table file");
|
||||
t=e+1;
|
||||
if (label[0]=='\'') {
|
||||
str_copy(nam, label+1);
|
||||
nam[strlen(nam)-1]='\0'; /* strip off quote */
|
||||
} else {
|
||||
str_copy(nam, label);
|
||||
}
|
||||
str_copy(buf, binDir);
|
||||
str_append(buf, nam);
|
||||
str_append(buf, ".cfg");
|
||||
cfg=str_read_file(buf);
|
||||
if (cfg==NULL) { /* will be obsolete */
|
||||
ERR_I(ReadTable());
|
||||
t=strstr(table, label);
|
||||
if (t==NULL) ERR_MSG("device not found");
|
||||
e=strchr(t, '\'');
|
||||
if (e==NULL || e>strchr(t,'\n')) ERR_MSG("missing ' or device name in table file");
|
||||
t=e+1;
|
||||
}
|
||||
if (plug==&plug0) {
|
||||
sensA.present=0;
|
||||
sensB.present=0;
|
||||
sensA.scale=1;
|
||||
sensB.scale=1;
|
||||
sensA.kink=0;
|
||||
sensB.kink=0;
|
||||
sensA.lim=0;
|
||||
sensB.lim=0;
|
||||
sensA.alarm=0;
|
||||
sensB.alarm=0;
|
||||
InitSensor(&sensA);
|
||||
InitSensor(&sensB);
|
||||
slope=0;
|
||||
ramp=0;
|
||||
controlMode=0;
|
||||
powFact=1;
|
||||
config[0]='\0';
|
||||
lscfg[0]='\0';
|
||||
tLimit=0;
|
||||
tMaxLimit=0;
|
||||
keepT=0;
|
||||
@@ -570,43 +603,49 @@ int PrepInput(char *label) {
|
||||
initMaxPower=1;
|
||||
resist=10;
|
||||
} else {
|
||||
sensC.present=0;
|
||||
sensD.present=0;
|
||||
sensC.scale=1;
|
||||
sensD.scale=1;
|
||||
sensC.kink=0;
|
||||
sensD.kink=0;
|
||||
sensC.lim=0;
|
||||
sensD.lim=0;
|
||||
sensC.alarm=0;
|
||||
sensD.alarm=0;
|
||||
InitSensor(&sensC);
|
||||
InitSensor(&sensD);
|
||||
}
|
||||
empty=0;
|
||||
dev[0]='\0';
|
||||
str_copy(heUnits, "%");
|
||||
|
||||
i=sscanf(t, "%12s%n", nam, &l);
|
||||
if (i<1) ERR_MSG("missing device name");
|
||||
nam[strlen(nam)-1]='\0'; /* strip off quote */
|
||||
t+=l;
|
||||
str_copy(chans, "____");
|
||||
i=sscanf(t, "%8s%n", chans, &l);
|
||||
if (i<1) ERR_MSG("missing chans");
|
||||
t+=l;
|
||||
if (cfg==NULL) { /* will be obsolete */
|
||||
i=sscanf(t, "%12s%n", nam, &l);
|
||||
if (i<1) ERR_MSG("missing device name");
|
||||
nam[strlen(nam)-1]='\0'; /* strip off quote */
|
||||
t+=l;
|
||||
str_copy(chans, "____");
|
||||
i=sscanf(t, "%8s%n", chans, &l);
|
||||
if (i<1) ERR_MSG("missing chans");
|
||||
t+=l;
|
||||
|
||||
/* interprete settings until '+' appeares (after whitespace) */
|
||||
ERR_P(CocReadVars(t, '+'));
|
||||
/* interprete settings until '+' appeares (after whitespace) */
|
||||
ERR_P(CocReadVars(t, '+'));
|
||||
if (strlen(chans)>4) ERR_MSG("no more than 4 channels allowed");
|
||||
} else {
|
||||
ERR_P(CocReadVars(cfg, '\0'));
|
||||
}
|
||||
if (loop!=2) loop=1;
|
||||
if (strlen(chans)>4) ERR_MSG("no more than 4 channels allowed");
|
||||
|
||||
if (plug==&plug0) {
|
||||
j=0;
|
||||
str_copy(dev0, dev);
|
||||
} else {
|
||||
j=2;
|
||||
str_copy(dev1, dev);
|
||||
}
|
||||
if (chans[0]>'0' && chans[0]<='4') {
|
||||
nScan=chans[0]-'0';
|
||||
str_copy(plug->descr, dev);
|
||||
if (cfg==NULL) { /* will be obsolete */
|
||||
sensA.type[0]=chans[0];
|
||||
sensA.type[1]='\0';
|
||||
sensB.type[0]=chans[1];
|
||||
sensB.type[1]='\0';
|
||||
sensC.type[0]=chans[2];
|
||||
sensC.type[1]='\0';
|
||||
sensD.type[0]=chans[3];
|
||||
sensD.type[1]='\0';
|
||||
}
|
||||
if (sensA.type[0]>'0' && sensA.type[0]<='4') {
|
||||
nScan=sensA.type[0]-'0';
|
||||
for (i=4;i<4+nScan;i++) {
|
||||
s=sensors[i];
|
||||
s->present=-1;
|
||||
@@ -614,7 +653,7 @@ int PrepInput(char *label) {
|
||||
if (s->scale==0.0) s->scale=1.0;
|
||||
s->typ='1'+i-4;
|
||||
}
|
||||
chans[0]='_';
|
||||
sensA.type[0]='\0';
|
||||
for (i=4+nScan; i<N_SENSORS; i++) {
|
||||
sensors[i]->t=DATA_UNDEF;
|
||||
sensors[i]->present=0;
|
||||
@@ -634,7 +673,7 @@ int PrepInput(char *label) {
|
||||
}
|
||||
for (i=j; i<j+2; i++) {
|
||||
s=sensors[i];
|
||||
typ=chans[i];
|
||||
typ=s->type[0];
|
||||
if (typ=='_') typ='\0';
|
||||
if (NULL==strchr("mnslhxftk", typ)) ERR_MSG("unknown channel type code");
|
||||
if (typ!='\0') {
|
||||
@@ -976,9 +1015,10 @@ int ReadTemp(void) {
|
||||
|
||||
if (s->typ=='h') {
|
||||
hlev = s->t1; /* take minimum only */
|
||||
if (full>0) {
|
||||
if (hlev<full && hlev>0) {
|
||||
he=hlev*100.0/full;
|
||||
if (full!=empty) {
|
||||
hlev=(hlev-empty)/(full-empty);
|
||||
if (hlev<1.0 && hlev>0.0) {
|
||||
he=hlev*100.0;
|
||||
s->t=he;
|
||||
tfill = tim % (24*3600) / 60; /* min since midnight */
|
||||
dfill = mycDate(tim) % 10000; /* fill date without year */
|
||||
@@ -1266,11 +1306,11 @@ void CalcMaxPower(void) {
|
||||
pr=pa;
|
||||
for (j=5; j>0; j--) {
|
||||
if (p<pr) {
|
||||
if (p/pr>quo) {
|
||||
if (p/pr>=quo) {
|
||||
quo=p/pr; pw=pr; iAmp=i; iRange=j;
|
||||
}
|
||||
} else if (p<plim || pw==0) {
|
||||
if (pr/p>quo) {
|
||||
} else if (p<=plim || pw==0) {
|
||||
if (pr/p>=quo) {
|
||||
quo=pr/p; pw=pr; iAmp=i; iRange=j;
|
||||
}
|
||||
}
|
||||
@@ -1506,9 +1546,10 @@ void AssignTypes(void) {
|
||||
}
|
||||
} else {
|
||||
cryo.sensor1=samp.sensor1;
|
||||
cryo.sensor2=samp.sensor2;
|
||||
}
|
||||
} else if (samp.sensor1==NULL) {
|
||||
cryo.sensor2=cryo.sensor1;
|
||||
}
|
||||
if (samp.sensor1==NULL) {
|
||||
samp.sensor1=cryo.sensor1;
|
||||
samp.sensor2=cryo.sensor2;
|
||||
}
|
||||
@@ -1608,7 +1649,7 @@ int Settings(void) {
|
||||
str_append(buf, "DISPLAY:[maxfld]");
|
||||
ERR_P(LscCmd(ser, buf));
|
||||
}
|
||||
if (config[0] != '\0') {
|
||||
if (config[0] != '\0') { /* obsolete */
|
||||
str_copy(buf, binDir);
|
||||
str_append(buf, config);
|
||||
cfg=str_read_file(buf);
|
||||
@@ -1622,6 +1663,9 @@ int Settings(void) {
|
||||
FREE(cfg);
|
||||
}
|
||||
}
|
||||
if (lscfg[0] != '\0') {
|
||||
ERR_P(LscCmd(ser, lscfg));
|
||||
}
|
||||
|
||||
if (settingsFlag) return 0;
|
||||
str_copy(statusBuf, "reading temperatures");
|
||||
@@ -1638,8 +1682,11 @@ int Settings(void) {
|
||||
}
|
||||
|
||||
int ConfigByCode(int plugNr) {
|
||||
char buf[16];
|
||||
|
||||
char buf[256], nam[16];
|
||||
int c1, c2;
|
||||
char *p;
|
||||
FILE *fil;
|
||||
|
||||
plug=plugs[plugNr];
|
||||
str_copy(plug->device,"");
|
||||
plug->devcmd=0;
|
||||
@@ -1649,8 +1696,23 @@ int ConfigByCode(int plugNr) {
|
||||
plug->sensor1->present=0;
|
||||
plug->sensor2->present=0;
|
||||
} else {
|
||||
logfileOut(LOG_MAIN+LOG_STAT ,"configure plug%d for cod %+d\n", plugNr, plug->code);
|
||||
sprintf(buf, "%+d,", plug->code);
|
||||
str_copy(buf, binDir);
|
||||
str_append(buf, LSC_CODES);
|
||||
ERR_SP(fil=fopen(buf, "r"));
|
||||
p=fgets(buf, sizeof(buf), fil);
|
||||
c1=0; c2=0;
|
||||
while (p!=NULL && plug->code != c1 && plug->code != c2) {
|
||||
if (*p != '#') {
|
||||
c1=0; c2=0;
|
||||
sscanf(buf, "%15s %d %d", &nam, &c1, &c2);
|
||||
}
|
||||
p=fgets(buf, sizeof(buf), fil);
|
||||
}
|
||||
fclose(fil);
|
||||
logfileOut(LOG_MAIN+LOG_STAT ,"configure plug%d for %s (code %d)\n", plugNr, nam, plug->code);
|
||||
str_copy(buf, "'");
|
||||
str_append(buf, nam);
|
||||
str_append(buf, "'");
|
||||
ERR_I(PrepInput(buf));
|
||||
}
|
||||
settingsFlag=1;
|
||||
@@ -1683,7 +1745,7 @@ int PeriodicTask(void) {
|
||||
char buf[256], lbuf[16];
|
||||
char *next, *alms;
|
||||
int i, k, iret, cnt;
|
||||
float t3[3], p, d, w, t, dif, htr0, mstep;
|
||||
float t3[3], p, d, w, t, dif, htr0, mstep, fdif;
|
||||
|
||||
if (nScan==0) {
|
||||
ERR_P(LscCmd(ser, "DIOST?>cod1,out1;DOUT 3,29;BUSY?>busy"));
|
||||
@@ -1892,11 +1954,12 @@ int PeriodicTask(void) {
|
||||
}
|
||||
logfileOut(LOG_MAIN, "adjusted mout=%.2f\n", mout);
|
||||
}
|
||||
fbuf=htr-mout-prop/6*(setH-t); /* value of integrator (assume deriv=0) */
|
||||
if (fbuf > 99.8 && mout < 0 ||
|
||||
fbuf < 0.2 && mout > 0) { /* probably integrator overflow */
|
||||
fdif=FakeScale(ctlSens, tr)-t;
|
||||
fbuf=htr-mout-prop/6*fdif; /* value of integrator (assume deriv=0) */
|
||||
if (fbuf > 99.8 && mout < 0 && fdif > 0 ||
|
||||
fbuf < 0.2 && mout > 0 && fdif < 0) { /* probably integrator overflow */
|
||||
if (lastIntTim > 0) {
|
||||
mout += (setH-t)*prop*integ/3000*(rdTim-lastIntTim); /* use mout for integral */
|
||||
mout += fdif*prop*integ/3000*(rdTim-lastIntTim); /* use mout for integral */
|
||||
if (mout < -100) mout=-100;
|
||||
if (mout > 100) mout=100;
|
||||
ERR_P(LscCmd(ser, "MOUT [loop],[mout]"));
|
||||
@@ -1911,7 +1974,7 @@ int PeriodicTask(void) {
|
||||
}
|
||||
}
|
||||
if (cryo.sensor1!=samp.sensor1 && controlMode==2) {
|
||||
d=(setH-t)/t; /* relative difference */
|
||||
d=fdif/t; /* relative difference */
|
||||
w=exp(-d*d*230); /* gaussian */
|
||||
/* if (w<0.1) tInt=0; reset when far from setpoint (more than 10 %) */
|
||||
if (int2<1) int2=1;
|
||||
@@ -1965,6 +2028,7 @@ int PeriodicTask(void) {
|
||||
plug->codChanged=0;
|
||||
if (plug->code1==0) {
|
||||
logfileOut(LOG_MAIN, "plug%d unplugged\n", i);
|
||||
str_copy(plug->descr,"unplugged");
|
||||
} else {
|
||||
logfileOut(LOG_MAIN, "plugged %d on plug%d\n", plug->code1, i);
|
||||
}
|
||||
@@ -2428,14 +2492,14 @@ int StatusHdl(int mode, void *base, int fd) {
|
||||
} else {
|
||||
ERR_I(StrPut(&buf, device, ' '));
|
||||
}
|
||||
ERR_I(StrPut(&buf, dev0, StrNONE));
|
||||
ERR_I(StrPut(&buf, plug0.descr, StrNONE));
|
||||
if (plug0.devcmd) {
|
||||
ERR_I(StrPut(&buf, " ", '*'));
|
||||
}
|
||||
if (p!=NULL) {
|
||||
ERR_I(StrPut(&buf, "\n ", ' '));
|
||||
ERR_I(StrPut(&buf, p, ' '));
|
||||
ERR_I(StrPut(&buf, dev1, StrNONE));
|
||||
ERR_I(StrPut(&buf, plug1.descr, StrNONE));
|
||||
if (plug1.devcmd) {
|
||||
ERR_I(StrPut(&buf, " ", '*'));
|
||||
}
|
||||
@@ -2448,7 +2512,7 @@ int StatusHdl(int mode, void *base, int fd) {
|
||||
} else {
|
||||
ERR_I(StrPut(&buf, "\ntarget", '='));
|
||||
ERR_I(PutFloat(&buf, 5, set));
|
||||
if (ramp==0 || tr==setH) {
|
||||
if (ramp==0 || tr==TrueScale(ctlSens, setH)) {
|
||||
ERR_I(StrPut(&buf, " K,", ' '));
|
||||
} else {
|
||||
ERR_I(StrPut(&buf, " K ramping at", ' '));
|
||||
@@ -2579,6 +2643,25 @@ int DevHelpHdl(int mode, void *base, int fd) {
|
||||
OnError: return -1;
|
||||
}
|
||||
|
||||
int UpdateHdl(int mode, void *base, int fd) {
|
||||
char cmd[128];
|
||||
if (mode==COC_WR) {
|
||||
return COC_DRD;
|
||||
} else if (mode==COC_DRD) {
|
||||
str_copy(cmd, "tecsinstall ");
|
||||
str_lowcase(update, update);
|
||||
str_append(cmd, update);
|
||||
str_append(cmd, " ");
|
||||
if (NULL==strstr(" cfg server sync ", cmd+11)) {
|
||||
str_copy(update, "unknown");
|
||||
} else {
|
||||
system(cmd);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
OnError: return -1;
|
||||
}
|
||||
|
||||
int RemoteHdl(int mode, void *base, int fd) {
|
||||
if (mode==COC_WR) {
|
||||
return COC_DWR;
|
||||
@@ -2738,6 +2821,7 @@ int main(int argc, char *argv[]) {
|
||||
CocIntFld(SensorT, stat2, RD);
|
||||
CocStrFld(SensorT, ch, RD);
|
||||
CocStrFld(SensorT, curve, RD);
|
||||
CocStrFld(SensorT, type, RD);
|
||||
|
||||
CocDefFlt(maxPower, RW); CocHdl(MaxPowerHdl);
|
||||
CocDefFlt(slope, RW); CocHdl(MaxPowerHdl);
|
||||
@@ -2758,6 +2842,7 @@ int main(int argc, char *argv[]) {
|
||||
CocDefFlt(htr, RD);
|
||||
CocDefFlt(setH, RD);
|
||||
CocDefFlt(full, RW);
|
||||
CocDefFlt(empty, RW);
|
||||
CocDefFlt(maxShift, RW);
|
||||
CocDefFlt(maxOver, RW);
|
||||
CocDefFlt(tm, RD);
|
||||
@@ -2798,9 +2883,9 @@ int main(int argc, char *argv[]) {
|
||||
CocDefStr(config, RD);
|
||||
CocDefStr(swap, RW); CocHdl(SwapHdl);
|
||||
CocDefStr(dev, RD);
|
||||
CocDefStr(dev0, RD);
|
||||
CocDefStr(dev1, RD);
|
||||
CocDefStr(devHelp, RD); CocHdl(DevHelpHdl);
|
||||
CocDefStr(update, RW); CocHdl(UpdateHdl);
|
||||
CocDefStr(lscfg, RD);
|
||||
|
||||
CocDefInt(cod1, RD);
|
||||
CocDefInt(cod2, RD);
|
||||
|
||||
Reference in New Issue
Block a user