Files
sics/tecs/tecs.c
2000-03-16 16:16:24 +00:00

805 lines
22 KiB
C

#include <math.h>
#include <assert.h>
#include <sys/timeb.h>
#include <ctype.h>
#include "server.h"
#include "logfile.h"
#include "util.h"
#include "lsc.h"
#include "dlog.h"
#define TABLE_FILE "lsc.tab"
#define NO_CODE 999
static SerChannel *ser=NULL;
static char *serverId=NULL;
static char *binDir=NULL;
static char *logDir=NULL;
static DlogSet dset;
static float
tempP=0, /* sample T */
tempX=0, /* heat exch. T */
tempC=0, /* set T */
tempH=0, /* set T on heater */
htr; /* heat power */
static int
logPeriod=10, /* logging period (sec.) */
period=1000, /* default read interval (msec.) */
logTime=0, /* next logging time */
setFlag=0, /* temperature to be set */
remoteFlag=0, /* to be set to remote mode */
dirtyX=0, /* reload input config for heat exch. */
dirtyP=0, /* reload input config for sample */
tryP=0, /* trial count for sample */
tryX=0, /* trial count for heat exch */
saveIt=0, /* CRVSAV command */
noResp=1, /* no response */
manualX=0, /* X device was given manually */
manualP=0, /* P device was given manually */
quit=0, /* quit server */
controlMode=2, /* 0: control on heater, 1: control on sample, 3: 2nd loop for difference heater-sample */
serialNo=0;
static int busy, mode=0;
static int nX=0, nP=0; /* number of sensors */
static int maxfld; /* last used display field */
static float tLimit, resist=0.0, power; /* heater parameters */
static float tLow=0, tHigh=0; /* lower limit of high-T sensor, upper limit of low-T sensor */
static float tShift=0; /* setpoint shift */
static float tInt=0; /* integral time (sec.) for setpoint shift */
static time_t auto_remote_time=0; /* time for automatic reload */
static time_t tim; /* actual time */
static time_t tableTime; /* last time when table was read */
static int codX=-1, codP=0; /* codes for heat exchanger and sample */
static int decod[8]={21,20,17,16,5,4,1,0}; /* for code conversion */
static char channel[5]="ACBD"; /* sensor channels for heater and sample (main, lowT) */
static char device[32], deviceX[16], deviceP[16];
static int deviceFlag=0;
static char *table=NULL; /* environment devices table */
static char *cache=NULL; /* curve list cache */
void idleHdl(int tmo, int fd) {
int iRet;
iRet=CocHandleRequests(tmo, fd);
if (iRet<0) logfileShowErr("CocHandleRequests");
}
void concatDevice() {
str_copy(device, deviceX);
if (0!=strcmp(deviceX, deviceP)) {
str_append(device, "/");
str_append(device, deviceP);
}
}
int instCurve(char *nam, char chan) {
/*
install sensor nam on channel chan
*/
char *args[2];
char buf[256], head[64], nbuf[256], lbuf[16];
char *crv, *entry, *points, *intype, *start,
*s, /* start of found entry */
*e, /* cache part after found entry */
*res, *t;
int i, num, n, fld;
char used[60];
FILE *fil;
int retstat;
logfileOut("install curve %s\n", nam);
retstat=-2; /* errors in following section are severe */
fil=NULL;
crv=NULL;
strcpy(buf, ":");
str_append(buf, nam);
str_append(buf, " ");
str_upcase(buf);
if (cache==NULL) { cache=malloc(1); *cache='\0'; } /* create empty cache if undefined */
start=strchr(cache, '\n'); /* skip device names */
if (start==NULL) { start=cache; } else { start++; }
entry=strstr(start, buf);
if (entry==NULL) { /* sensor not found in cache */
entry=start;
for (i=60;i>20;i--) used[i]=0;
n=40; num=0;
while (entry!=NULL && n>0) {
i=0;
sscanf(entry, "%d", &i);
if (i>20 && i<=60) { num=i; s=entry; used[i]=1; n--; }
entry=strchr(entry, '\n');
if (entry !=NULL) entry++;
}
if (n>0) {
for (num=60;num>20;num--) { if (used[num]==0) break; }
s=NULL;
e=NULL;
} else {
e=strchr(s, '\n');
if (e!=NULL) { *e='\0'; e++; }
if (s>start) { s--; *s='\0'; }
}
head[0]='\0';
} else {
s=entry; entry++;
while (s>start && *s!='\n') s--;
if (s>start) { *s='\0'; s++; }
num=0;
sscanf(s, "%d", &num);
if (num<21 || num>60) ERR_MSG("illegal curve number");
sprintf(buf, "CRVHDR?%d", num);
retstat=-1; /* errors in following section are not severe */
ERR_P(res=SerCmd(ser, buf));
e=strchr(entry, '\n');
if (e!=NULL) { *e='\0'; e++; }
str_copy(head, res);
}
/* read and substitute curve file */
sprintf(buf, "CRVPT %d", num);
args[0]=buf;
retstat=-2; /* errors in following section are severe */
str_copy(nbuf, binDir);
str_append(nbuf, nam);
ERR_P(crv=str_read_arg(nbuf, args, 1));
intype=str_split1(crv, '\n');
if (intype==NULL) {
points=NULL;
} else {
points=str_split1(intype, '\n');
}
if (points==NULL) {
ERR_MSG("illegal curve file");
}
res=strchr(channel, chan);
if (res!=NULL) { fld=res-channel+1; } else { fld=1; }
if (fld>maxfld) maxfld=fld;
retstat=-1; /* errors in following section are not severe */
if (LscEqPar(crv, head)) { /* header matches: select sensor type and curve */
sprintf(buf, "INTYPE %c:%s;INCRV %c:%d;DISPFLD %d:%c,1;DISPLAY:%d"
, chan, intype, chan, num, fld, chan, maxfld);
ERR_I(LscCmdChk(ser, buf));
logfileOut("curve %d on channel %c selected\n", num, chan);
} else { /* header does not match -> download */
if (busy) ERR_MSG("busy");
logfileOut("download curve %d\n", num);
sprintf(buf, "INTYPE %c:%s;DISPFLD %d:%c,3;DISPLAY:%d"
, chan, intype, fld, chan, maxfld); /* select sensor type first to display sensor units */
ERR_I(LscCmdChk(ser, buf));
sprintf(buf, "CRVDEL %d;CRVHDR?%d", num, num);
n=3;
do {
ERR_P(res=SerCmd(ser, buf));
res[4]='\0';
i=strcmp(res, "User");
n--;
} while (i!=0 && n!=0);
if (i!=0) ERR_MSG("can not delete curve");
do { /* download curve */
t=str_split1(points, '\n');
if (*points!='\0') ERR_I(LscCmdChk(ser, points));
points=t;
} while (t!=NULL);
sprintf(buf, "CRVHDR %d:%s;INCRV %c:%d;DISPFLD %d:%c,1", num, crv, chan, num, fld, chan); /* write header, select curve */
ERR_I(LscCmdChk(ser, buf));
logfileOut("curve selected on channel %c\n", chan);
str_copy(head, crv);
str_upcase(head);
saveIt=1;
}
free(crv); crv=NULL;
/* rewrite cache with actual entry at beginning */
retstat=-2; /* errors in following section are severe */
sprintf(lbuf, "lsc.%d", serialNo);
str_copy(nbuf, logDir);
str_append(nbuf, lbuf);
fil=fopen(nbuf, "r+");
if (fil==NULL) ERR_SP(fil=fopen(nbuf, "w"));
if (manualX) ERR_SI(fputs(deviceX, fil));
ERR_SI(fputs("/", fil));
if (manualP) ERR_SI(fputs(deviceP, fil));
ERR_SI(fputs("\n", fil));
sprintf(buf, "%d:%s", num, head);
ERR_SI(fputs(buf, fil)); /* write actual entry */
if (start!=s) { /* write content before replaced entry */
ERR_SI(fputs("\n", fil));
ERR_SI(fputs(start, fil));
}
if (e!=NULL) { /* write content after replaced entry */
ERR_SI(fputs("\n", fil));
ERR_SI(fputs(e, fil));
}
ERR_SI(fclose(fil));
fil=NULL;
free(cache);
/* re-read it */
ERR_P(cache=str_read_arg(nbuf, NULL, 0));
return(0);
OnError:
if (crv!=NULL) free(crv);
if (fil!=NULL) fclose(fil);
return(retstat);
}
int configInput(int sampleStick) {
char *t;
char buf[80], nam[16], nbuf[256];
int i, j, n, nn;
int retstat;
retstat=-2; /* errors in following section are severe */
if (sampleStick) {
if (manualP) {
sprintf(buf, ".%s.", deviceP);
} else {
sprintf(buf, "%+d ", codP);
if (codP==0) return(0);
}
} else {
if (manualX) {
sprintf(buf, ".%s.", deviceX);
} else {
sprintf(buf, "%+d ", codX);
if (codX==0) return(0);
}
}
if (table!=NULL && tim>tableTime+60) { free(table); table=NULL; }; /* clear old table */
if (table==NULL) { /* read table */
str_copy(nbuf, binDir);
str_append(nbuf, TABLE_FILE);
ERR_P(table=str_read_arg(nbuf, NULL, 0));
tableTime=tim;
str_replace_char(table, 9, ' '); /* replace TAB (9) by space in order to find codes terminated by tab */
}
t=strstr(table, buf);
if (t==NULL) ERR_MSG("device not found");
i=sscanf(t, "%79[^\n!]", buf); /* read line */
t=strchr(buf, '.');
if (t==NULL) ERR_MSG("missing '.' in table file");
t++;
n=1;
if (sampleStick) {
nP=0;
i=sscanf(t, "%12s%d%d", nam, &nn, &n);
if (i<1) ERR_MSG("missing sensor name");
j=1;
if (n<0 || n>2) ERR_MSG("illegal value for nsensor");
if (n==0) return(0);
if (!manualP) { /* set device name */
str_copy(deviceP, nam);
deviceP[strlen(deviceP)-1]='\0'; /* strip off '.' */
concatDevice();
}
str_append(nam,"s");
} else {
nX=0;
tLow=0; tHigh=0;
controlMode=0;
i=sscanf(t, "%12s%d%d%d%f%f%f%f%f", nam, &n, &nn, &controlMode, &tLimit, &resist, &power, &tLow, &tHigh);
if (i<7) ERR_MSG("missing some sensor parameters");
j=0;
if (n<0 || n>2) ERR_MSG("illegal value for nsensor");
if (n==0) return(0);
if (!manualX) { /* set device name */
str_copy(deviceX, nam);
deviceX[strlen(deviceX)-1]='\0'; /* strip off '.' */
concatDevice();
}
str_append(nam, "x");
}
ERR_I(retstat=instCurve(nam, channel[j]));
if (n==2) {
str_append(nam, "l");
ERR_I(retstat=instCurve(nam, channel[j+2]));
}
if (sampleStick) {
nP=n;
} else {
nX=n;
}
return(0);
OnError: return(retstat);
}
int loadCache() {
int i, j;
char *res, *p;
char buf[256], nbuf[256], lbuf[16];
FILE *fil;
fil=NULL;
sprintf(lbuf, "lsc.%d", serialNo);
str_copy(nbuf, logDir);
str_append(nbuf, lbuf);
ERR_SP(fil=fopen(nbuf, "w"));
if (manualX) ERR_SI(fputs(deviceX, fil));
ERR_SI(fputs("/", fil));
if (manualP) ERR_SI(fputs(deviceP, fil));
ERR_SI(fputs("\n", fil));
for (i=60; i>21; i-=4) {
sprintf(buf, "CRVHDR?%d;CRVHDR?%d;CRVHDR?%d;CRVHDR?%d", i, i-1, i-2, i-3);
ERR_P(res=SerCmd(ser, buf));
for (j=i; j>i-4; j--) {
p=str_split1(res, ';');
if (res[1]=='s') { i=0; break;} /* s of "User", must be empty slot, lowercase letters are not programmable */
sprintf(buf, "%d:%s", j, res);
ERR_SI(fputs(buf, fil));
ERR_SI(fputs("\n", fil));
if (p==NULL) break;
res=p;
}
}
ERR_SI(fclose(fil));
/* re-read cache */
ERR_P(cache=str_read_arg(nbuf, NULL, 0));
return(0);
OnError:
if (fil!=NULL) fclose(fil);
return(-1);
}
float WeightedAverage(int n, float t1, float t2) {
float p,q;
if (n==0) {
return(0.0);
} else if (n<2) {
return(t1);
} else {
if (t2<tLow) {
return(t2);
} else if (t1<tHigh) {
p=tHigh-t1;
q=t2-tLow;
return((t1*p*p+t2*q*q)/(p*p+q*q));
} else {
return(t1);
}
}
}
int SetTemp(int switchOn) {
char buf[32];
char ch;
ch=channel[0];
if (nX>1 && tempC<(tLow+tHigh)/2) ch=channel[2];
if (nP>0) {
if (controlMode==1) { /* control directly on sample sensor */
tShift=0;
ch=channel[1];
if (nX>1 && tempC<(tLow+tHigh)/2) ch=channel[3];
} else if (controlMode!=2) {
tShift=0;
}
} else {
tShift=0;
}
tempH=tempC+tShift;
if (switchOn) {
sprintf(buf, "CSET 1:%c,1;RANGE:5;SETP 1:%f", ch, tempH);
} else {
sprintf(buf, "CSET 1:%c,1;SETP 1:%f", ch, tempH);
}
ERR_I(LscCmdChk(ser, buf));
return(0);
OnError: return(-1);
}
int ReadTemp() {
char buf[256], lbuf[16];
char *res;
int i, key, k;
int cod1, cod2, out1, out2; /* codes read from digital input/output */
int codX1, codP1;
float t2[2], t4[4], p, d;
ERR_P(res=SerCmdC(ser, "DIOST?;HTR?;BUSY?;DOUT 3,29"));
if (0==strcmp(res, "?TMO")) {
if (0==noResp) logfileOut("no response\n");
noResp=1;
return(0);
}
i=sscanf(res, "%d%*c%d%*c%f%*c%d", &cod1, &out1, &htr, &busy);
if (i!=4) ERR_MSG("bad answer 0");
if (noResp) { /* check serial number */
ERR_P(res=SerCmdC(ser, "*IDN?"));
if (0!=strncmp(res, "LSCI,MODEL340,", 14)) return(0);
res+=14;
k=0;
sscanf(res, "%d", &k);
if (k!=0 && k!=serialNo) {
serialNo=k;
dirtyX=1; dirtyP=1;
ERR_I(LscCmdChkC(ser, "RANGE:0")); /* switch off heater */
/* reload curve cache: */
if (cache!=NULL) free(cache);
sprintf(lbuf, "lsc.%d", serialNo);
str_copy(buf, logDir);
str_append(buf, lbuf);
cache=str_read_arg(buf, NULL, 0);
if (cache==NULL && 0==strcmp(ErrMessage, "file not found")) ERR_I(loadCache());
deviceX[0]='\0';
deviceP[0]='\0';
sscanf(cache, "%15[^/!]%*c%15[^\n!]", deviceX, deviceP); /* read device names separated by '/' */
if (deviceX[0]!='\0') manualX=1;
if (deviceP[0]!='\0') manualP=1;
concatDevice();
}
noResp=0;
}
sprintf(buf, "KRDG?%c;KRDG?%c;KRDG?%c;KRDG?%c", channel[0], channel[1], channel[2], channel[3]);
ERR_P(res=SerCmd(ser, buf));
i=sscanf(res, "%f%*c%f%*c%f%*c%f", &t4[0], &t4[1], &t4[2], &t4[3]);
if (i!=4) ERR_MSG("bad answer 1");
tempX=WeightedAverage(nX, t4[0], t4[2]);
tempP=WeightedAverage(nP, t4[1], t4[3]);
if (tempP==0.0) tempP=tempX;
if (dirtyX==0 && dirtyP==0 && noResp==0 && tim>logTime) {
t2[0]=tempX;
t2[1]=tempP;
DlogPut(&dset, tim, 2, t2); DlogUpd(&dset);
logTime=(tim/logPeriod+1)*logPeriod;
}
if (nP>0 && nX>0 && controlMode==2) {
d=tempH-tempX; d=exp(-d*d); /* if d is small, we are far from setpoint */
if (tInt<60000/period) tInt+=d; /* increase integral time until 60 sec. */
p=d/tInt;
tShift=tShift*(1.0-p)+p*(tempX-tempP);
ERR_I(SetTemp(0));
}
ERR_P(res=SerCmdC(ser, "KEYST?;DIOST?;DOUT 3,30"));
i=sscanf(res, "%d%*c%d%*c%d", &key, &cod2, &out2);
if (i!=3) ERR_MSG("bad answer 2");
if (busy==0) {
while (out1!=30) {
ERR_I(LscCmdChkC(ser, "DOUT:3,30"));
ERR_P(res=SerCmdC(ser, "DIOST?"));
i=sscanf(res, "%d%*c%d", &cod1, &out1);
}
while (out2!=29) {
ERR_I(LscCmdChkC(ser, "DOUT:3,29"));
ERR_P(res=SerCmdC(ser, "DIOST?;DOUT 3,30"));
i=sscanf(res, "%d%*c%d", &cod2, &out2);
}
/* code conversion */
codX1=3*decod[cod2 % 8] ^ 2*decod[cod1 % 8]; /* ^ is exclusive OR */
codP1=-(3*decod[cod2 / 8] ^ 2*decod[cod1 / 8]);
if (codX<0) { codX=codX1; codP=codP1; } /* first time after restart */
if (codP1!=codP) {
dirtyP=1;
codP=codP1; manualP=0;
}
if (codX1!=codX) {
dirtyX=1;
codX=codX1; manualX=0;
}
}
if (key!=0) {
auto_remote_time=tim+600;
if (!(dirtyX || dirtyP)) {
logfileOut("user touched keys\n");
}
dirtyX=1; dirtyP=1;
ERR_P(res=SerCmdC(ser, "MODE?"));
mode=0;
sscanf(res, "%d", &mode);
if (mode==2) auto_remote_time=tim; /* user switched to remote mode */
}
return(0);
OnError: return(-1);
}
int Settings() {
char buf[256];
char *res;
int i, j, k, ia, ir;
float pa, pr, pw, dif;
if (dirtyX || dirtyP) {
if (busy==0 || dirtyX>=0 && dirtyP>=0) { /* do not enter when busy and dirtyX/P indicates error on last time */
if (device[0]=='\0') {
logfileOut("configure inputs for codes %d %d\n", codX, codP);
} else {
logfileOut("configure inputs for %s\n", device);
}
if (dirtyP) {
sprintf(buf, "DISPFLD 2:%c,1;DISPFLD 4:%c,1", channel[1], channel[3]);
ERR_I(LscCmdChk(ser, buf));
}
if (dirtyX) {
if (dirtyX>0) tryX=0;
sprintf(buf, "DISPFLD 1:%c,1;DISPFLD 3:%c,1", channel[0], channel[2]);
ERR_I(LscCmdChk(ser, buf));
nX=0;
if (!manualX) { deviceX[0]='\0'; concatDevice(); }
dirtyX=configInput(0);
if (dirtyX<0) {
tryX++;
if (dirtyX!=-1 || tryX>3) {
logfileShowErr("fatal error X");
dirtyX=0; deviceX[0]='\0'; concatDevice();
} else {
logfileShowErr("try again X");
}
} else {
/* control settings */
sprintf(buf, "CDISP 1:1,%d,1;MOUT 1:0;CMODE 1:1", (int)(resist+0.5));
ERR_I(LscCmdChk(ser, buf));
ia=1; ir=0;
if (power>0) {
pa=resist*4; /* max. power */
pw=0; dif=1.0e6;
for (i=4; i>0; i--) {
pr=pa;
for (j=5; j>0; j--) {
if (pr>power) {
if (pr/power<dif) { dif=pr/power; pw=pr; ia=i; ir=j; }
} else {
if (power/pr<dif) { dif=power/pr; pw=pr; ia=i; ir=j; }
}
pr=pr/10;
}
pa=pa/4;
}
}
power=pw;
sprintf(buf, "CLIMIT 1:%f,0,0,%d,%d;CSET 1:%c,1,1,0", tLimit, ia, ir, channel[0]);
ERR_I(LscCmdChk(ser, buf));
sprintf(buf, "ALARM %c:%d,1,%f,0,0,1;ALARM %c:0;RELAY 1:1;BEEP:0"
, channel[0], (nX>0), tLimit, channel[2]);
ERR_I(LscCmdChk(ser, buf));
}
}
if (dirtyP) {
if (dirtyP>0) tryP=0;
nP=0;
if (!manualP) { deviceP[0]='\0'; concatDevice(); }
dirtyP=configInput(1);
if (dirtyP<0) {
tryP++;
if (dirtyP!=-1 || tryP>3) {
logfileShowErr("fatal error P");
dirtyP=0; deviceP[0]='\0'; concatDevice();
} else {
logfileShowErr("try again P");
}
} else {
sprintf(buf, "ALARM %c:%d,1,%f,0,0,1;ALARM %c:0;RELAY 1:1;BEEP:0"
, channel[1], (nP>0), tLimit, channel[3]);
ERR_I(LscCmdChk(ser, buf));
}
}
if (nP>=nX) {
maxfld=2*nP;
} else {
maxfld=2*nX-1;
}
if (maxfld>0) {
sprintf(buf, "MODE:2;DISPLAY:%d", maxfld);
} else {
maxfld=1;
sprintf(buf, "MODE:2;DISPLAY:1;DISPFLD 1:A,3", maxfld);
}
ERR_I(LscCmdChkC(ser, buf));
mode=2;
if (saveIt) {
ERR_P(res=SerCmdC(ser, "CRVSAV;BUSY?"));
do {
idleHdl(200, 0); /* wait 200 ms */
ERR_P(res=SerCmdC(ser, "BUSY?"));
sscanf(res, "%d", &busy);
} while (!busy);
saveIt=0;
}
}
}
return(0);
OnError: return(-1);
}
int ExecuteRequest() {
char *res, *t;
int iRet;
struct CocClient *client;
if (tim>auto_remote_time || setFlag) ERR_I(Settings());
if (setFlag) {
if (nX>0) {
tInt=0; /* reset integral time */
ERR_I(SetTemp(1));
logfileOut("set point\n");
} else {
logfileOut("flag reset\n");
}
setFlag=0;
}
client=CocGetNextCmd();
if (client!=NULL) {
if (NULL==strchr(client->cmd, ':')) {
res=SerCmdC(ser, client->cmd);
if (res==NULL) {
res=ErrMessage;
if (res==NULL) res="empty error message";
}
str_copy(client->res, res);
} else {
iRet=LscCmdChkC(ser, client->cmd);
if (iRet<0 && ErrMessage!=NULL) {
str_copy(client->res, ErrMessage);
} else {
str_copy(client->res, "o.k.");
}
}
client->cmd[0]='\0';
}
if (deviceFlag) {
t=strchr(device, '/');
if (t==NULL) {
str_copy(deviceX, device);
str_copy(deviceP, device);
manualX=1; dirtyX=1;
manualP=1; dirtyP=1;
} else {
if (t!=device) {
*t='\0';
str_copy(deviceX, device);
*t='/';
manualX=1; dirtyX=1;
}
t++;
if (*t!='\0') {
str_copy(deviceP, t);
manualP=1; dirtyP=1;
}
}
concatDevice();
deviceFlag=0;
}
return(0);
OnError: return(-1);
}
int main(int argc, char *argv[])
{ int logIt=0;
struct timeb tim1, tim0;
int i, tdif, iret;
char *host;
char buf[256], opt;
int port, msecTmo;
binDir="";
logDir="";
serverId="tecs";
host="lnsp26";
port=0;
msecTmo=0;
logfileOutTmp("%s ", argv[0]);
for (i=1;i<argc;i++) {
if (argv[i]!=NULL) {
if (argv[i][0]=='-') {
opt=tolower(argv[i][1]);
} else {
opt=' ';
}
if ('l'==opt) {
logIt=1;
period=5000;
opt=' ';
} else if ('s'==opt) {
logfileStd=1;
opt=' ';
} else if ('n'==opt) {
i++;
serverId=argv[i];
} else if ('b'==opt) {
i++;
binDir=argv[i];
} else if ('d'==opt) {
i++;
logDir=argv[i];
} else if ('t'==opt) {
i++;
msecTmo=atoi(argv[i]);
} else if ('h'==opt) {
i++;
host=argv[i];
} else if ('p'==opt) {
i++;
port=atoi(argv[i]);
} else {
logfileOutTmp("?");
}
if (opt!=' ') logfileOutTmp("-%c ", opt);
logfileOutTmp("%s ", argv[i]);
}
}
if (port==0) port=9753;
if (msecTmo==0) msecTmo=4000;
str_copy(buf, logDir);
str_append(buf, serverId);
logfileInit(buf, logIt);
logfileOutTmp("\n");
logfileWriteTmp();
ERR_I(CocInitServer(1024, port));
CocDefFlt(tempX, CocRD);
CocDefFlt(tempP, CocRD);
CocDefFlt(htr, CocRD);
CocDefFlt(tempC, setFlag);
CocDefStr(device, deviceFlag);
CocDefInt(controlMode, CocWR);
CocDefInt(quit, CocWR);
ERR_P(ser=SerOpen(host, logIt, msecTmo, idleHdl));
ERR_I(CocHandleRequests(100, 0));
ftime(&tim0);
str_copy(buf, logDir);
str_append(buf, serverId);
str_append(buf, ".dlog");
iret=DlogOpen(&dset, buf, 1);
if (iret<0) {
ERR_I(DlogCreate(&dset, buf, tim0.time, 2, 24*60*60/logPeriod, logPeriod, 0.0));
}
while (!quit) {
logfileStamp("");
if (logIt) {
logfileWriteTmp();
} else {
logfilePurge();
}
/* read & control temp */
iret=ReadTemp();
if (iret<0) logfileShowErr("ReadTemp");
if (tim>=auto_remote_time) {
iret=Settings();
if (iret<0) logfileShowErr("Settings");
}
while (!quit) {
ftime(&tim1);
tdif=period-((tim1.time-tim0.time)*1000+tim1.millitm-tim0.millitm);
if (tdif<0) { tim=tim1.time; break; } /* timeout */
iret=CocHandleRequests(tdif, 0);
if (iret!=2) { time(&tim); break; } /* timeout */
if (iret<0) logfileShowErr("CocHandleRequests");
tim=tim1.time;
iret=ExecuteRequest();
if (iret<0) logfileShowErr("ExecuteRequest");
}
ftime(&tim1);
tdif=((tim1.time-tim0.time)*1000+tim1.millitm-tim0.millitm)/period;
i=period*tdif+tim0.millitm;
tim0.time+=i / 1000;
tim0.millitm=i % 1000;
if (tdif>1) {
logfileOut("%d cycles lost\n", tdif-1);
}
}
logfileOut("%s got quit command\n", serverId);
DlogClose(&dset);
return(1);
OnError:
SerClose(ser);
CocCloseServer();
ERR_EXIT("TECS");
}