From 267d16908a737ba8ffb8c20e41558bc856816f84 Mon Sep 17 00:00:00 2001 From: cvs Date: Mon, 10 Jun 2002 12:45:24 +0000 Subject: [PATCH] *** empty log message *** --- tecs/Makefile | 6 +- tecs/coc_client.c | 50 +++- tecs/coc_client.h | 7 +- tecs/coc_logfile.c | 67 +++-- tecs/coc_server.c | 81 +++-- tecs/coc_server.h | 52 ++-- tecs/coc_util.h | 6 +- tecs/instr_hosts.c | 5 +- tecs/myc_buf.c | 90 ++++++ tecs/myc_buf.h | 2 + tecs/myc_err.c | 8 - tecs/sys_util.h | 4 +- tecs/tecs.c | 714 +++++++++++++++++++++++++++++---------------- tecs/tecs_cli.c | 107 +------ tecs/tecs_client.f | 4 +- tecs/tecs_data.c | 87 ++---- tecs/tecs_data.h | 7 +- tecs/tecs_plot.f90 | 77 ++++- tecs/tecs_serial.c | 26 +- tecs/tecs_serial.h | 1 + 20 files changed, 863 insertions(+), 538 deletions(-) diff --git a/tecs/Makefile b/tecs/Makefile index b68a1ecb..e21bd847 100644 --- a/tecs/Makefile +++ b/tecs/Makefile @@ -12,7 +12,7 @@ TECLI_LIB_alpha_osf1=-L/data/lnslib/lib -lpgplot -lX11 -lXm -so_archive SYS_FILE_alpha_osf1=sys_aunix #CFLAGS_alpha_osf1= -std1 -g -warnprotos -I../ -I. -I../hardsup -DFORTIFY -#---------- for Redhat linux (change redhat_linux to the corresponding $OSTYPE) +#---------- for Redhat linux (change i386_linux to the corresponding $OSTYPE) CC_i386_linux= gcc CFLAGS_i386_linux= -I/usr/local/include -I. -I../ -I../hardsup -DLINUX -g TECS_PLOT_i386_linux=f77 -c -u -g tecs_plot.for @@ -61,8 +61,8 @@ bin/TecsClient: $(TECLI_OBJ) f77 -o bin/TecsClient -g $(TECLI_OBJ) \ $(TECLI_LIB) -lreadline -ltermcap -six: six.c term.c sys_select.c $(LIBR_OBJ) - $(CC) $(CFLAGS) -o six six.c term.c sys_select.c $(LIBR_OBJ) +six: six.c term.c sys_select.c libtecsl.a + $(CC) $(CFLAGS) -o six six.c term.c sys_select.c -L. -ltecsl rstart: rstart.c myc_str.o myc_err.o instr_hosts.o $(CC) $(CFLAGS) -o rstart rstart.c myc_str.o myc_err.o instr_hosts.o diff --git a/tecs/coc_client.c b/tecs/coc_client.c index 3373411c..338b79fa 100644 --- a/tecs/coc_client.c +++ b/tecs/coc_client.c @@ -19,6 +19,11 @@ #define COC_NETTMO 5 #define COC_RESTMO 60 +#define ARG_CHAR 1 +#define ARG_INT 2 +#define ARG_FLT 3 +#define ARG_ARR 4 + /*-------------------------------------------------------------------------*/ int CocConnect(CocConn *conn) { @@ -185,7 +190,7 @@ void CocReset(CocConn *conn) { /*-------------------------------------------------------------------------*/ -int CocPushArg(CocConn *conn, const char *name, void *value, int type) { +int CocPushArg(CocConn *conn, const char *name, void *value, int type, int size) { StrBuf *buf; int n; @@ -196,6 +201,7 @@ int CocPushArg(CocConn *conn, const char *name, void *value, int type) { if (n>=sizeof(conn->args)) ERR_MSG("too many return arguments"); conn->args[n].adr=value; conn->args[n].type=type; + conn->args[n].size=size; conn->args[n].cmd=buf->buf + buf->wrpos; conn->nargs=n+1; if (value==NULL) { @@ -212,7 +218,7 @@ int CocPushArg(CocConn *conn, const char *name, void *value, int type) { int CocPutStr(CocConn *conn, const char *name, const char *value) { StrBuf *buf; - ERR_I(CocPushArg(conn, name, NULL, 4)); + ERR_I(CocPushArg(conn, name, NULL, ARG_CHAR, 0)); ERR_I(StrPut(&conn->cmdbuf, value, COC_SEP)); return(0); OnError: return(-1); @@ -222,7 +228,7 @@ int CocPutStr(CocConn *conn, const char *name, const char *value) { int CocPutFloat(CocConn *conn, const char *name, float value) { - ERR_I(CocPushArg(conn, name, NULL, COC_FLT)); + ERR_I(CocPushArg(conn, name, NULL, ARG_FLT, 0)); ERR_I(StrPutFloat(&conn->cmdbuf, value, COC_SEP)); return(0); OnError: return(-1); @@ -230,9 +236,19 @@ int CocPutFloat(CocConn *conn, const char *name, float value) { /*-------------------------------------------------------------------------*/ +int CocPutArray(CocConn *conn, const char *name, float *value, int value_size) { + + ERR_I(CocPushArg(conn, name, NULL, ARG_ARR, 0)); + ERR_I(StrPutArray(&conn->cmdbuf, value, value_size)); + return(0); + OnError: return(-1); +} + +/*-------------------------------------------------------------------------*/ + int CocPutInt(CocConn *conn, const char *name, int value) { - ERR_I(CocPushArg(conn, name, NULL, COC_INT)); + ERR_I(CocPushArg(conn, name, NULL, ARG_INT, 0)); ERR_I(StrPutInt(&conn->cmdbuf, value, COC_SEP)); return(0); OnError: return(-1); @@ -242,21 +258,28 @@ int CocPutInt(CocConn *conn, const char *name, int value) { int CocGetStr(CocConn *conn, const char *name, char *value, int value_len) { - return(CocPushArg(conn, name, value, value_len)); + return(CocPushArg(conn, name, value, ARG_CHAR, value_len)); } /*-------------------------------------------------------------------------*/ int CocGetFloat(CocConn *conn, const char *name, float *value) { - return(CocPushArg(conn, name, value, COC_FLT)); + return(CocPushArg(conn, name, value, ARG_FLT, 0)); } /*-------------------------------------------------------------------------*/ int CocGetInt(CocConn *conn, const char *name, int *value) { - return(CocPushArg(conn, name, value, COC_INT)); + return(CocPushArg(conn, name, value, ARG_INT, 0)); +} + +/*-------------------------------------------------------------------------*/ + +int CocGetArray(CocConn *conn, const char *name, float *value, int value_size) { + + return(CocPushArg(conn, name, value, ARG_ARR, value_size)); } /*-------------------------------------------------------------------------*/ @@ -310,16 +333,19 @@ int CocDoIt(CocConn *conn, char *res, int res_len) { } else { str_ncat(res, a->cmd, res_len); str_ncat(res, "=", res_len); - if (a->type==COC_INT) { + if (a->type==ARG_INT) { ERR_I(StrGetInt(buf, (int *)a->adr, COC_SEP)); - } else if (a->type==COC_FLT) { + } else if (a->type==ARG_FLT) { ERR_I(StrGetFloat(buf, (float *)a->adr, COC_SEP)); - } else if (a->type>1) { - ERR_P(StrNGet(buf, (char *)a->adr, a->type, COC_SEP)); + } else if (a->type==ARG_ARR) { + ERR_I(StrGetArray(buf, (float *)a->adr, a->size)); + resp=""; + } else if (a->type==ARG_CHAR) { + ERR_P(StrNGet(buf, (char *)a->adr, a->size, COC_SEP)); } else { ERR_MSG("unknown type"); } - a->type=0; + a->type=0; /* done */ } } str_ncat(res, resp, res_len); diff --git a/tecs/coc_client.h b/tecs/coc_client.h index 5ea34acb..a08ea558 100644 --- a/tecs/coc_client.h +++ b/tecs/coc_client.h @@ -6,13 +6,14 @@ typedef struct { void *adr; - int type; + int type, size; char *cmd; } CocArg; typedef struct { + int fd; /* private */ - int fd, port; + int port; StrBuf cmdbuf; /* for sending command */ StrBuf resbuf; /* for response */ char cmdbuf_[COC_CMD_LEN]; @@ -37,9 +38,11 @@ void CocReset(CocConn *conn); int CocPutStr(CocConn *conn, const char *name, const char *value); int CocPutFloat(CocConn *conn, const char *name, float value); int CocPutInt(CocConn *conn, const char *name, int value); +int CocPutArray(CocConn *conn, const char *name, float *value, int value_size); int CocGetStr(CocConn *conn, const char *name, char *value, int value_len); int CocGetFloat(CocConn *conn, const char *name, float *value); int CocGetInt(CocConn *conn, const char *name, int *value); +int CocGetArray(CocConn *conn, const char *name, float *value, int value_size); int CocDoIt(CocConn *conn, char *error, int error_len); int CocCheck(CocConn *conn); diff --git a/tecs/coc_logfile.c b/tecs/coc_logfile.c index dfc1200d..aa7b986d 100644 --- a/tecs/coc_logfile.c +++ b/tecs/coc_logfile.c @@ -9,7 +9,8 @@ #include "myc_str.h" static FILE *fil=NULL; -static char lnam[224]="", filnam[256]=""; +static char lnam[224]=""; +static char filnam[256]=""; static char ebuf[20000]=""; static char *statusBuf=NULL; static int statusSize; @@ -93,9 +94,35 @@ char *logfileInit(char *path, int nodate, int use_stdout, int write_all) { return(filnam); } +void logfileStamp(char *text) { + int time, date, stamp; + + time = mycNow(); + date = mycDate(time); /* date in yyyymmdd decimal encoding */ + time = time % (24*3600); /* seconds since midnight */ + + stamp=time / 60; + if (date != openDate ) { /* day has changed -> new logfile */ + if (fil!=NULL) { fclose(fil); fil=NULL; } + lastpos=0; + lastline=1; + logfileOpen(1); + } + if (text==NULL) { + if (stamp>lastStamp+1) { + fprintf(fil, "---\t%02d:%02d:%02d\n", stamp / 60, stamp % 60, time % 60, text); + } + } else { + fprintf(fil, "\t%02d:%02d:%02d %s", stamp / 60, stamp % 60, time % 60, text); + } + dirty=0; + lastStamp=stamp; +} + void logfileOut(int mask, const char *fmt, ...) { va_list ap; char buf[8192], *p; + int l; va_start(ap, fmt); @@ -125,7 +152,7 @@ void logfileOut(int mask, const char *fmt, ...) if (writeAll) { vfprintf(fil, fmt, ap); wrtMask=LOG_ALL; - } else { + } else if ((mask | LOG_NET) != LOG_NET) { /* do not store LOG_NET info */ if (eptr!=NULL) { if (eptr-ebuf > sizeof(ebuf)-512) { sprintf(eptr, "... buffer full ... \1\1"); @@ -134,7 +161,12 @@ void logfileOut(int mask, const char *fmt, ...) vsprintf(eptr, fmt, ap); p=strchr(eptr, '\1'); if (p==NULL) { - eptr+=strlen(eptr); + l=strlen(eptr); + if (l>256) { + sprintf(buf, "unusual long output %.32s... (%d chars)\n", eptr, l); + logfileStamp(buf); + } + eptr+=l; } else { eptr=p; /* is in fact an error */ } @@ -153,31 +185,6 @@ void logfileMask(int mask) { logMask=logMask | mask; } -void logfileStamp(char *text) { - int time, date, stamp; - - time = mycNow(); - date = mycDate(time); /* date in yyyymmdd decimal encoding */ - time = time % (24*3600); /* seconds since midnight */ - - stamp=time / 60; - if (date != openDate ) { /* day has changed -> new logfile */ - if (fil!=NULL) { fclose(fil); fil=NULL; } - lastpos=0; - lastline=1; - logfileOpen(1); - } - if (text==NULL) { - if (stamp>lastStamp+1) { - fprintf(fil, "---\t%02d:%02d:%02d\n", stamp / 60, stamp % 60, time % 60, text); - } - } else { - fprintf(fil, "\t%02d:%02d:%02d %s", stamp / 60, stamp % 60, time % 60, text); - } - dirty=0; - lastStamp=stamp; -} - void logfileWrite0(int mask) { char *s, *next; @@ -217,8 +224,8 @@ void logfileScan(int date, void (*scanLine)(void*, char*), void *arg) { sFile=fil; rewind(sFile); } else { - sprintf(filnam, "%s%02d-%02d.log", lnam, date % 10000 / 100, date % 100); - sFile=fopen(filnam, "r+"); + sprintf(buf, "%s%02d-%02d.log", lnam, date % 10000 / 100, date % 100); + sFile=fopen(buf, "r+"); if (sFile==NULL) return; } res=fgets(buf, sizeof(buf), sFile); diff --git a/tecs/coc_server.c b/tecs/coc_server.c index c37c5fae..a56f0c9b 100644 --- a/tecs/coc_server.c +++ b/tecs/coc_server.c @@ -25,8 +25,9 @@ typedef struct _CocVar { void *var; int access; int type; + int size; void *strucType; - int (*hdl)(int, void *); + int (*hdl)(int, void *, int); int pending; } CocVar; @@ -76,8 +77,7 @@ void CocVarList(void **varList) { } } -void CocList() { - CocVar *p; +void CocList() { CocVar *p; p=*varListHandle; while (p!=NULL) { @@ -140,7 +140,7 @@ void *CocIntPtr(int *ptr) { return(ptr); } void *CocFltPtr(float *ptr) { return(ptr); } void *CocChrPtr(char *ptr) { return(ptr); } -void *CocDefVar(const char *name, void *var, int type, int access) { +void *CocDefVar(const char *name, void *var, int type, int size, int access) { CocVar *p; const char *f; void *adr; @@ -153,6 +153,7 @@ void *CocDefVar(const char *name, void *var, int type, int access) { *varListHandle=p; str_copy(p->name, name); p->type=type; + p->size=size; } else { assert(p->type==type); } @@ -165,17 +166,22 @@ void *CocDefVar(const char *name, void *var, int type, int access) { assert(0); } -void CocHdl(int (*handler)(int, void *)) { +void CocHdl(int (*handler)(int, void *, int)) { assert(lastDef!=NULL); lastDef->hdl=handler; } +int *CocSizePtr(void) { + assert(lastDef!=NULL && lastDef->type==COC_ARRAY); + return &lastDef->size; +} + void CocDefVarS(const char *name, const char *tname, void *var, int type) { CocVar *p, *t; assert(type==COC_PTR || type==COC_STRUCT); - p=CocDefVar(name, var, type, COC_RDONLY); - p->strucType=CocDefVar(tname, NULL, COC_TYPE, COC_RDONLY); + p=CocDefVar(name, var, type, 0, COC_RDONLY); + p->strucType=CocDefVar(tname, NULL, COC_TYPE, 0, COC_RDONLY); } char err_name[64]; @@ -192,12 +198,14 @@ int CocGetThisVar(CocVar *var, void *base, StrBuf *buf, int separator) { adr=(char *)base + (int)var->var; } /* printf("get %s %d\n", name, (int)adr); */ - if (var->type==-1) { + if (var->type==COC_CHAR) { + ERR_P(StrNGet(buf, (char *)adr, var->size, separator)); + } else if (var->type==COC_INT) { ERR_I(StrGetInt(buf, (int *)adr, separator)); - } else if (var->type==-2) { + } else if (var->type==COC_FLT) { ERR_I(StrGetFloat(buf, (float *)adr, separator)); - } else if (var->type>1) { - ERR_P(StrNGet(buf, (char *)adr, var->type, separator)); + } else if (var->type==COC_ARRAY) { + ERR_I(StrGetArray(buf, (float *)adr, var->size)); } else { ERR_MSG("unknown type"); } @@ -217,12 +225,14 @@ int CocPutThisVar(CocVar *var, void *base, StrBuf *buf, int separator) { adr=(char *)base + (int)var->var; } /* printf("put %s %d\n", name, (int)adr); */ - if (var->type==-1) { - ERR_I(StrPutInt(buf, *(int *)adr, separator)); - } else if (var->type==-2) { - ERR_I(StrPutFloat(buf, *(float *)adr, separator)); - } else if (var->type>1) { + if (var->type==COC_CHAR) { ERR_I(StrPut(buf, adr, separator)); + } else if (var->type==COC_INT) { + ERR_I(StrPutInt(buf, *(int *)adr, separator)); + } else if (var->type==COC_FLT) { + ERR_I(StrPutFloat(buf, *(float *)adr, separator)); + } else if (var->type==COC_ARRAY) { + ERR_I(StrPutArray(buf, (float *)adr, var->size)); } else { ERR_MSG("unknown type"); } @@ -265,6 +275,32 @@ void CocFreeVarList(void) { *varListHandle=NULL; } +char *CocReadVars(char *str, char stop){ + int i, l; + char *eql, *cr, buf[80]; + StrBuf sbuf; + + /* interprete variables until stop character appeares */ + i=sscanf(str, "%79s%n", buf, &l); + while (i>0 && buf[0]!=stop) { + if (buf[0]=='!') { + cr=strchr(str, '\n'); + if (cr==NULL) return strchr(str, '\0'); + str=cr+1; + } else { + str+=l; + eql=strchr(buf,'='); + if (eql==NULL) ERR_MSG("syntax error"); + *eql='\0'; + StrLink(&sbuf, eql+1); + ERR_I(CocGetVar(buf, &sbuf, ' ')); + } + i=sscanf(str, "%79s%n", buf, &l); + } + return str; + OnError: return NULL; +} + void CocToClients(int mask, char *str) { int iret; CocClient *cl; @@ -310,11 +346,11 @@ int CocInitServer(void *(*setDataRtn)(void *), int port) { OnError: return(-1); } -int CocHandleThis(CocVar *var, void *base, StrBuf *outBuf, int mode) { +int CocHandleThis(CocVar *var, void *base, StrBuf *outBuf, int mode, int fd) { int iret; if (var->hdl!=NULL) { - iret=var->hdl(mode, base); + iret=var->hdl(mode, base, fd); if (iret<0) { /* error */ ErrShow(var->name); ERR_I(StrPut(outBuf, "", COC_ERR)); /* signal error message */ @@ -375,7 +411,7 @@ int CocCallHandlers(void) { assert(var!=NULL && var->hdl!=NULL); if (mode==COC_DWR) { var->pending=0; - ERR_I(var->hdl(mode, p->base)); + ERR_I(var->hdl(mode, p->base, cl->fd)); p->mode=0; } else { delayedRead=1; @@ -391,7 +427,7 @@ int CocCallHandlers(void) { var=p->var; assert(var!=NULL && var->hdl!=NULL); if (mode==COC_DRD) { - iret=var->hdl(mode, p->base); + iret=var->hdl(mode, p->base, cl->fd); if (iret<0) { /* error */ ERR_I(StrPut(&bufr, "", COC_ERR)); /* signal error message */ ERR_I(StrPut(&bufr, ErrMessage, COC_SEP)); @@ -455,6 +491,7 @@ int CocHandle1Request(int tmo_msec, int fd) { if (i==0) return(0); /* timeout */ if (FD_ISSET(mainFd, &rmask)) { + cadrlen=sizeof(cadr); ERR_SI(newfd=accept(mainFd, (struct sockaddr *)&cadr, &cadrlen)); FD_SET(newfd, &mask); if (newfd>=maxfd) maxfd=newfd+1; @@ -545,14 +582,14 @@ int CocHandle1Request(int tmo_msec, int fd) { if (NULL!=strchr(loglist,'M')) lmask = lmask | LOG_MAIN; ERR_I(StrPut(&bufo, "", COC_NUL)); /* o.k. */ } else { - ERR_I(iret=CocHandleThis(var, base, &bufo, COC_WR)); + ERR_I(iret=CocHandleThis(var, base, &bufo, COC_WR, cl->fd)); if (iret) ERR_I(CocPushThisHandler(var, cl, base, iret)); } modified=1; } } else { ERR_P(StrGet(&buf, NULL, COC_NUL)); /* skip separator */ - ERR_I(iret=CocHandleThis(var, base, &bufo, COC_RD)); + ERR_I(iret=CocHandleThis(var, base, &bufo, COC_RD, cl->fd)); if (iret) ERR_I(CocPushThisHandler(var, cl, base, iret)); } } diff --git a/tecs/coc_server.h b/tecs/coc_server.h index f3986989..bf29eee0 100644 --- a/tecs/coc_server.h +++ b/tecs/coc_server.h @@ -28,32 +28,44 @@ int CocGetVar(const char *name, StrBuf *buf, int separator); get a variable named of variable list from the buffer */ -void CocHdl(int (*handler)(int, void *)); +char *CocReadVars(char *str, char stop); +/* + read variables from the string str until a word starts with the stop character + the string has the form [ whitespace var=value ] whitespace stop-character + any text between an exclamation character and the next line break is treated as comment +*/ + +void CocHdl(int (*handler)(int, void *, int)); /* define handler for last defined item */ +int *CocSizePtr(void); +/* + get size pointer from last defined item (only valid when an array) +*/ + void *CocIntPtr(int *ptr); void *CocFltPtr(float *ptr); void *CocChrPtr(char *ptr); -void *CocDefVar(const char *name, void *var, int type, int access); +void *CocDefVar(const char *name, void *var, int type, int size, int access); void CocDefVarS(const char *name, const char *tname, void *var, int type); /* Define variables. Call this routines not directly, but through one of the macros below. */ -#define CocDefInt(V,A) CocDefVar(#V,CocIntPtr(&V),COC_INT,A) -#define CocDefFlt(V,A) CocDefVar(#V,CocFltPtr(&V),COC_FLT,A) -#define CocDefStr(V,A) CocDefVar(#V,CocChrPtr(V),sizeof(V),A) -#define CocDefPtr(V,S) CocDefVarS(#V,#S,&V,(V!=(S *)NULL,COC_PTR)); -#define CocDefStruct(V,S) CocDefVarS(#V,#S,&V,(&V!=(S *)NULL,COC_STRUCT)); -#define CocIntFld(S,V,A) CocDefVar(#S":"#V,CocIntPtr(&((S *)NULL)->V),COC_INT,A); -#define CocFltFld(S,V,A) CocDefVar(#S":"#V,CocFltPtr(&((S *)NULL)->V),COC_FLT,A); -#define CocStrFld(S,V,A) CocDefVar(#S":"#V,CocChrPtr(((S *)NULL)->V),sizeof(((S *)NULL)->V),A); -#define CocDefCmd(V) CocDefVar("$",V,sizeof(V),0) -#define CocDefStrPtr(V,S,A) CocDefVar(#V,V,S,A) -#define CocAlias(A,V) CocDefVar(#A, #V, COC_ALIAS,0); +#define CocDefInt(V,A) CocDefVar(#V,CocIntPtr(&V),COC_INT,0,A) +#define CocDefFlt(V,A) CocDefVar(#V,CocFltPtr(&V),COC_FLT,0,A) +#define CocDefStr(V,A) CocDefVar(#V,CocChrPtr(V),COC_CHAR,sizeof(V),A) +#define CocDefArr(V,A) CocDefVar(#V,CocFltPtr(V),COC_ARRAY,sizeof(V)/sizeof(float),A) +#define CocDefPtr(V,S) CocDefVarS(#V,#S,&V,(V!=(S *)NULL,0,COC_PTR)); +#define CocDefStruct(V,S) CocDefVarS(#V,#S,&V,(&V!=(S *)NULL,0,COC_STRUCT)); +#define CocIntFld(S,V,A) CocDefVar(#S":"#V,CocIntPtr(&((S *)NULL)->V),COC_INT,0,A); +#define CocFltFld(S,V,A) CocDefVar(#S":"#V,CocFltPtr(&((S *)NULL)->V),COC_FLT,0,A); +#define CocStrFld(S,V,A) CocDefVar(#S":"#V,CocChrPtr(((S *)NULL)->V),COC_CHAR,sizeof(((S *)NULL)->V),A); +#define CocArrFld(S,V,A) CocDefVar(#S":"#V,CocFltPtr(((S *)NULL)->V),COC_FLT,sizeof(((S *)NULL)->V)/sizeof(float),A); +#define CocAlias(A,V) CocDefVar(#A, #V, COC_ALIAS,0,0); #define COC_RDONLY 3 #define COC_RDWR 2 @@ -65,12 +77,14 @@ void CocDefVarS(const char *name, const char *tname, void *var, int type); #define COC_DRD 4 #define COC_SHOW 5 -#define COC_INT -1 -#define COC_FLT -2 -#define COC_PTR -3 -#define COC_STRUCT -4 -#define COC_TYPE -5 -#define COC_ALIAS -6 +#define COC_CHAR 1 +#define COC_INT 2 +#define COC_FLT 3 +#define COC_ARRAY 4 +#define COC_PTR 5 +#define COC_STRUCT 6 +#define COC_TYPE 7 +#define COC_ALIAS 8 int CocInitServer(void *(*setDataRtn)(void *), int port); diff --git a/tecs/coc_util.h b/tecs/coc_util.h index 04af7c18..c022d2e3 100644 --- a/tecs/coc_util.h +++ b/tecs/coc_util.h @@ -5,7 +5,7 @@ #include "myc_buf.h" #define COC_CMD_LEN 256 -#define COC_RES_LEN 8192 +#define COC_RES_LEN 16384 int CocCreateSockAdr( struct sockaddr_in *sockaddrPtr, /* Socket address */ @@ -32,10 +32,6 @@ int CocRecv(int fd, StrBuf *buf, int timeout, int *flag); else *flag is set to zero between the select and the recv command */ -#define COC_INT -1 -#define COC_FLT -2 -#define COC_PTR -3 - #define COC_SEP '\0' #define COC_DELAYED '\1' #define COC_ERR '\2' diff --git a/tecs/instr_hosts.c b/tecs/instr_hosts.c index ecbdd5ab..35f9bfc8 100644 --- a/tecs/instr_hosts.c +++ b/tecs/instr_hosts.c @@ -11,10 +11,11 @@ static Instrument list[]={ { "TOPSI", "lnsa07.psi.ch", "TOPSI" , 1}, { "SANS", "lnsa10.psi.ch", "SANS" , 1}, { "HRPT", "lnsa11.psi.ch", "HRPT" , 1}, - { "TASP", "lnsa12.psi.ch", "TASP" , 1}, { "TRICS", "lnsa18.psi.ch", "TRICS" , 1}, { "AMOR", "lnsa14.psi.ch", "AMOR" , 1}, { "FOCUS", "lnsa16.psi.ch", "FOCUS" , 1}, + { "TASP", "lnsa12.psi.ch", "TASP", 1}, + { "TASP0", "lnsa09.psi.ch", NULL , 0}, { "RITA", "lnsa08.psi.ch", NULL , 0}, { "PREP", "lnsa01.psi.ch", NULL , 0}, { "TEST", "lnsa15.psi.ch", "lnslib", 2} @@ -68,8 +69,6 @@ int InstrHost(char *input, char *instr, char *host, char *user, char *pcod #ifdef __VMS #define instr_host_ instr_host -#elif defined __linux -#define instr_host_ instr_host__ #endif int instr_host_(F_CHAR(input), F_CHAR(instr), F_CHAR(host), F_CHAR(user), F_CHAR(pcod) diff --git a/tecs/myc_buf.c b/tecs/myc_buf.c index a5f2f901..192edfa1 100644 --- a/tecs/myc_buf.c +++ b/tecs/myc_buf.c @@ -216,3 +216,93 @@ void StrNLink(StrBuf *buf, char *str, int length) { buf->wrpos=l; buf->dsize=buf->wrpos; } + +#define TWO_23 8388608 +#define EXP_OFFS 128 + +void flt_to_char4(double f, char buf[4]) { + double m; + int e, res, ir; + + m=frexp(f, &e); + e=e+EXP_OFFS; + if (e<0 || m==0) { + res=0; m=0; + } else { + if (e>255) { + res=255*TWO_23+(TWO_23-1); /* max. representable number */ + } else { + res=e*TWO_23+(int)(0.5+(fabs(m*2)-1.0)*TWO_23); + } + } + buf[0]=res % 256; res=res/256; + buf[1]=res % 256; res=res/256; + buf[2]=res % 256; res=res/256; + if (m<0) { + buf[3]=res-128; + } else { + buf[3]=res; + } +} + +double flt_from_char4(char buf[4]) { + int s, i, b0, b1, b2, b3; + + b0=buf[0]; if (b0<0) b0+=256; + b1=buf[1]; if (b1<0) b1+=256; + b2=buf[2]; if (b2<0) b2+=256; + b3=buf[3]; if (b3<0) b3+=256; + if (b3>=128) { + i=(b3-128)*(256*65536)+b2*65536+b1*256+b0; + if (i==0) return 0.0; + return -ldexp((i % TWO_23)*1.0/(TWO_23)*0.5+0.5, i/TWO_23-EXP_OFFS); + } else { + i=b3*(256*65536)+b2*65536+b1*256+b0; + if (i==0) return 0.0; + return ldexp((i % TWO_23)*1.0/(TWO_23)*0.5+0.5, i/TWO_23-EXP_OFFS); + } +} + +int StrPutArray(StrBuf *buf, float val[], int size) { + int i, pos; + char *b; + + pos=buf->wrpos; + if (pos < 0 || pos >= buf->dsize || buf->buf==NULL) + ERR_MSG("buffer corrupt"); + if (pos+4*size >= buf->dsize) + ERR_MSG("buffer too short"); + b=buf->buf+pos; + flt_to_char4((float)size, b); + b+=4; + for (i=0; iwrpos=b - buf->buf; + return(0); + OnError: + buf->wrpos=-1; + return(-1); +} + +int StrGetArray(StrBuf *buf, float val[], int maxsize) { + int size, i; + char *b; + double gg; + + if (buf->rdpos < 0 || buf->rdpos >= buf->dsize || buf->buf==NULL) + ERR_MSG("buffer corrupt"); + b=buf->buf + buf->rdpos; + size=flt_from_char4(b); b+=4; + buf->rdpos+=4*(size+1); + if (maxsizerdpos=buf->dsize; /* illegal value */ + return(-1); +} diff --git a/tecs/myc_buf.h b/tecs/myc_buf.h index ec28b39a..e7f442b2 100644 --- a/tecs/myc_buf.h +++ b/tecs/myc_buf.h @@ -19,6 +19,7 @@ typedef struct { char *buf; int dsize, rdpos, wrpos, seen; } StrBuf; int StrPut(StrBuf *buf, const char *str, int sep); int StrPutInt(StrBuf *buf, int val, int sep); int StrPutFloat(StrBuf *buf, float val, int sep); +int StrPutArray(StrBuf *buf, float val[], int size); /*------------------------------------------------------------------------ Read from the buffer until separator sep. @@ -31,6 +32,7 @@ char *StrNGet(StrBuf *buf, char *result, int reslen, int sep); #define StrGet(BUF,RES,SEP) StrNGet(BUF,RES,sizeof(RES),SEP) int StrGetInt(StrBuf *buf, int *res, int sep); int StrGetFloat(StrBuf *buf, float *res, int sep); +int StrGetArray(StrBuf *buf, float val[], int maxsize); #define StrEnd(BUF) ((BUF)->rdpos>=(BUF)->wrpos) /*------------------------------------------------------------------------ diff --git a/tecs/myc_err.c b/tecs/myc_err.c index db63fb30..ec890c5a 100644 --- a/tecs/myc_err.c +++ b/tecs/myc_err.c @@ -110,14 +110,6 @@ void ERR_EXIT(char *text) { #define err_msg_ err_msg #define err_set_outrtn_ err_set_outrtn #define err_short_ err_short - -#elif defined __linux -#define err_show_ err_show__ -#define err_txt_ err_txt__ -#define err_msg_ err_msg__ -#define err_set_outrtn_ err_set_outrtn__ -#define err_short_ err_short__ - #endif void err_show_(F_CHAR(text), int text_len) { diff --git a/tecs/sys_util.h b/tecs/sys_util.h index 7d3c4e4a..691c8ba4 100644 --- a/tecs/sys_util.h +++ b/tecs/sys_util.h @@ -24,8 +24,8 @@ typedef struct { short size, dummy; char *text; } SysVmsChar; #define F_CHAR(VAR) SysVmsChar *VAR##_desc -#define STR_TO_C(DST,SRC) str_ntrim(DST, SRC##_desc->text, sizeof(DST), SRC##_len=SRC##_desc->size) -#define STR_TO_F(DST,SRC) str_npad(DST##_desc->text, SRC, DST##_len=DST##_desc->size) +#define STR_TO_C(DST,SRC) str_ntrim(DST, SRC##_desc->text, sizeof(DST), SRC##_desc->size) +#define STR_TO_F(DST,SRC) str_npad(DST##_desc->text, SRC, DST##_desc->size) typedef size_t sys_adr_len; /* argument of accept and gethostbyadr */ diff --git a/tecs/tecs.c b/tecs/tecs.c index 853f9c2b..6236a2c3 100644 --- a/tecs/tecs.c +++ b/tecs/tecs.c @@ -24,9 +24,13 @@ #define LOGLIFETIME 24*3600 static SerChannel *ser=NULL; -static char *serverId=NULL; -static char *binDir=NULL; -static char *logDir=NULL; +static char binDir[256]=""; +static char logDir[256]=""; +static int logIt=0, use_stdout=0; +static char serverId[32]="tecs"; +static int msecTmo=5000; +static char host[64]=""; +static int port=9753; typedef struct { char ch[4]; @@ -40,12 +44,18 @@ typedef struct { char type; } SensorT; +enum Sensors { A, B, C, D, A1, A2, A3, A4, N_SENSORS }; + static SensorT sensA={"A"}, sensB={"B"}, sensC={"C"}, sensD={"D"}, - *sensors[4]={&sensA, &sensB, &sensC, &sensD }, + sensA1={"A1", DATA_UNDEF}, + sensA2={"A2", DATA_UNDEF}, + sensA3={"A3", DATA_UNDEF}, + sensA4={"A4", DATA_UNDEF}, + *sensors[N_SENSORS]={&sensA, &sensB, &sensC, &sensD, &sensA1, &sensA2, &sensA3, &sensA4 }, *ctlSens=NULL, /* control sensor */ *heliumSens=NULL, *auxSens=NULL, @@ -59,8 +69,8 @@ typedef struct { } Testpoint; static Testpoint /* C standard guarantees initialization to zero */ - cryo, /* = {&sensA, &sensB }, /* data for heat exchanger, or the only sensors */ - samp, /* = {&sensC, &sensD }, /* data for sensors on sample stick */ + cryo, /* data for heat exchanger, or the only sensors */ + samp, /* data for sensors on sample stick */ *tpoints[2]={&cryo, &samp}, *tpoint=&cryo; @@ -85,7 +95,9 @@ static float htr, power=DATA_UNDEF, /* heater current percentage, heater power */ tLimit, /* temperature limit */ maxPower, /* max. Power */ + scalPower, powFact=1, /* power factor (for external power supplies) */ + resist, /* heater resistance */ tShift=0, /* setpoint shift */ full, /* full value for helium level */ prop, integ, deriv, /* pid */ @@ -101,10 +113,11 @@ static float smooth=0, fbuf, /* float buffer */ r1, r2, /* temporary values */ + still=0, tInt=0; /* integral time (sec.) for setpoint shift */ static int - logPeriod=0, /* data logging period (sec.) */ + logPeriod=5, /* data logging period (sec.) */ period=5000, /* default read interval (msec.) */ logTime, /* next logging time */ settingsFlag, /* settings to be done */ @@ -121,7 +134,6 @@ static int num, /* curve number */ key, /* key status */ serialNo, - resist, /* heater resistance */ readTemp, /* client requested readTemp */ cod1, cod2, out1, out2, /* codes read from digital input/output */ iRange, iAmp, /* max. range and max. current code */ @@ -131,6 +143,8 @@ static int tim0, /* msec Time */ per, /* effective period */ mmInt, mmTime, /* interval and time for next min-max logging */ + nScan=0, /* number of scanned channels */ + alarmListSize=0, lockAlarm, cntError, tableTime; /* last time when table was read */ @@ -142,33 +156,37 @@ static int decod[8]={21,20,17,16,5,4,1,0}; /* for code conversion */ static char statusBuf[132], /* phase status */ status[1000], /* status summary */ + pid[128], /* PID summary */ device[64], /* concatenated device names */ buf1[256], buf2[256], buf3[256], buf4[256], /* buffers for temporary use */ head[64], /* curve header */ intype[64], /* input configuration */ - chan[2], /* actual channel */ + chan[4], /* actual channel */ alarmStatus[20], /* alarm status */ - alarmChannels[8]="", - alarmList[8], /* enabled alarms */ - alarmHistory[8]="", config[256], /* special configuration commands */ helium[80], /* helium level status */ heUnits[4], /* helium level units */ - controlChannel[2]="A"; + alarmChannels[N_SENSORS], + alarmHistory[N_SENSORS], + controlChannel[4]="A"; static char + *alarmList[N_SENSORS], /* enabled alarms */ *table=NULL, /* environment devices table */ *cache=NULL, /* curve list cache */ *logfile=""; -static int logMask; +static int logMask=LOG_MAIN; + +static float gradata[7200]; +static char grapar[128]; +static int* grasize; typedef struct { char cmd[COC_CMD_LEN]; int logstart; long int logpos; char logline[COC_RES_LEN]; - char pltdata[COC_RES_LEN]; } ClientData; /* @@ -261,9 +279,9 @@ int InstalCurve(SensorT *sensor, char *dev) { sens->present=0; if (sens->type=='x' || sens->type=='h' || sens->type=='f') { if (chan[0]>='C') { - ERR_P(LscCmd(ser, "INTYPE [chan]:0,1,2,1,13")); /* 7.5 V Range */ + ERR_P(LscCmd(ser, "INTYPE [chan]:0,1,2,1,13;INSET [chan],1")); /* 7.5 V Range */ } else { - ERR_P(LscCmd(ser, "INTYPE [chan]:0,1,2,1,12")); /* 5 V Range */ + ERR_P(LscCmd(ser, "INTYPE [chan]:0,1,2,1,12;INSET [chan],1")); /* 5 V Range */ } if (sens->type=='f') { ERR_P(LscCmd(ser, "MNMX [chan]:1,4;INCRV [chan]:0")); @@ -354,10 +372,15 @@ int InstalCurve(SensorT *sensor, char *dev) { } if (head[0]!='\0' && LscEqPar(head, chead)) { /* header matches: select sensor type and curve */ - ERR_P(LscCmd(ser, "INTYPE?[chan]>buf1;INCRV?[chan]>buf2")); - if (!LscEqPar(buf1, intype) || atoi(buf2)!=num) { - ERR_P(LscCmd(ser, "ANALOG 2:0,3")); - ERR_P(LscCmd(ser, "RANGE:0;INTYPE [chan]:[intype]")); + if (chan[1]>'1') { /* scanned inputs A2...A4 */ + ERR_P(LscCmd(ser, "INCRV?[chan]>buf2;INSET?[chan]>buf3")); + str_copy(buf1, intype); + } else { + ERR_P(LscCmd(ser, "INTYPE?[chan]>buf1;INCRV?[chan]>buf2;INSET?[chan]>buf3")); + } + if (!LscEqPar(buf1, intype) || atoi(buf2)!=num || buf3[0]!='1') { + ERR_P(LscCmd(ser, "ANALOG 2:0,3;INSET [chan],1")); + if (chan[1]<='1') ERR_P(LscCmd(ser, "RANGE:0;INTYPE [chan]:[intype]")); ERR_P(LscCmd(ser, "INCRV [chan]:[num];MNMX [chan]:1,1")); logfileOut(LOG_MAIN, "curve %d on channel %s selected\n", num, chan); } else { @@ -370,9 +393,9 @@ int InstalCurve(SensorT *sensor, char *dev) { if (num<=20) ERR_MSG("standard curve does not match"); if (busy) ERR_MSG("busy"); logfileOut(LOG_MAIN+LOG_STAT, "download curve %d\n", num); + ERR_P(LscCmd(ser, "ANALOG 2:0,3;INSET [chan],1")); /* select sensor type first */ - ERR_P(LscCmd(ser, "ANALOG 2:0,3")); - ERR_P(LscCmd(ser, "RANGE:0;INTYPE [chan]:[intype]")); + if (chan[1]<='1') ERR_P(LscCmd(ser, "RANGE:0;INTYPE [chan]:[intype]")); n=3; do { @@ -397,7 +420,7 @@ int InstalCurve(SensorT *sensor, char *dev) { ERR_I(str_substitute(buf, nbuf, "#0", lbuf)); ERR_P(LscCmd(ser, buf)); i++; - if (i%10==0) sprintf(statusBuf, "downloading curve at line %d", i); + sprintf(statusBuf, "downloading curve %d at line %d", num, i); } points=t; } while (t!=NULL); @@ -405,7 +428,7 @@ int InstalCurve(SensorT *sensor, char *dev) { /* write header, select curve */ str_upcase(head, chead); ERR_P(LscCmd(ser, "CRVHDR [num]:[head];INCRV [chan]:[num];MNMX [chan]:1,1")); - logfileOut(LOG_MAIN, "curve selected on channel %s\n", chan); + logfileOut(LOG_MAIN, "curve %d selected on channel %s\n", num, chan); saveTime=tim+30; } FREE(crv); crv=NULL; @@ -466,9 +489,8 @@ int InstalCurve(SensorT *sensor, char *dev) { int PrepInput(char *label) { char *t, *e; - char buf[80], nam[16], chans[8], nbuf[256], typ; + char nam[16], chans[8], nbuf[256], typ; int i, j, l; - StrBuf sbuf; SensorT *s; if (table!=NULL && tim>tableTime+60) { FREE(table); table=NULL; }; /* clear old table */ @@ -517,21 +539,12 @@ int PrepInput(char *label) { nam[strlen(nam)-1]='\0'; /* strip off quote */ t+=l; str_copy(chans, "____"); - i=sscanf(t, "%4s%n", chans, &l); + i=sscanf(t, "%8s%n", chans, &l); if (i<1) ERR_MSG("missing chans"); t+=l; /* interprete settings until '+' appeares */ - i=sscanf(t, "%64s%n", buf, &l); - while (i>0 && buf[0]!='+') { - t+=l; - e=strchr(buf,'='); - if (e==NULL) ERR_MSG("syntax error"); - *e='\0'; - StrLink(&sbuf, e+1); - ERR_I(CocGetVar(buf, &sbuf, ' ')); - i=sscanf(t, "%64s%n", buf, &l); - } + ERR_P(CocReadVars(t, '+')); if (loop!=2) loop=1; if (strlen(chans)>4) ERR_MSG("no more than 4 channels allowed"); @@ -539,6 +552,21 @@ int PrepInput(char *label) { j=0; if (plug==&plug1) j=2; + if (chans[0]>'0' && chans[0]<='4') { + nScan=chans[0]-'0'; + for (i=4;i<4+nScan;i++) { + s=sensors[i]; + s->present=-1; + s->band=10; + if (s->scale==0.0) s->scale=1.0; + s->type='1'+i-4; + } + chans[0]='_'; + for (i=4+nScan; it=DATA_UNDEF; + sensors[i]->present=0; + } + } for (i=j; i0) { + sprintf(buf, "@"); + } else { + return; + } + for (i=4; i<4+nScan; i++) { + s1=sensors[i]; + if (s1->t!=DATA_UNDEF) { + sprintf(buf1, " T%c %.5g", s1->ch[1], s1->t); str_append(buf, buf1); } - if (he!=DATA_UNDEF) { - sprintf(buf1, " He %.4g", he); - str_append(buf, buf1); - } - if (aux!=DATA_UNDEF) { - sprintf(buf1, " Aux %.5g", aux); - str_append(buf, buf1); - } - if (new==2) { - mmTime=mmTime+30; - first=1; + } + if (power!=DATA_UNDEF) { + sprintf(buf1, " P %.4g", power); + str_append(buf, buf1); + } + if (he!=DATA_UNDEF) { + sprintf(buf1, " He %.4g", he); + str_append(buf, buf1); + } + if (aux!=DATA_UNDEF) { + sprintf(buf1, " Aux %.5g", aux); + str_append(buf, buf1); + } + if (new==2) { + mmTime=mmTime+30; + first=1; + } else { + if (first==0) { + logfileOut(LOG_MAIN, "%s\n", buf); } else { - if (first==0) { - logfileOut(LOG_MAIN, "%s\n", buf); - } else { - first=0; - } - if (new) { - mmInt=30; - } else { - mmInt=60; - } - mmTime=((tim+mmInt/2)/mmInt+1)*mmInt-logPeriod; + first=0; } + if (new) { + mmInt=30; + } else { + mmInt=60; + } + mmTime=((tim+mmInt/2)/mmInt+1)*mmInt-logPeriod; } } float CtlScale(void) { - if (ctlSens==NULL) ctlSens=cryo.sensor1; if (controlMode==1) { tShift=0; - if (ctlSens==samp.sensor1) { + if (ctlSens==NULL) { + ctlSens=samp.sensor1; + } else if (ctlSens==samp.sensor1) { if (set < ctlSens->lim) { ctlSens=samp.sensor2; } @@ -714,7 +754,9 @@ float CtlScale(void) { } } else { if (controlMode!=2) tShift=0; - if (ctlSens==cryo.sensor1) { + if (ctlSens==NULL) { + ctlSens=cryo.sensor1; + } else if (ctlSens==cryo.sensor1) { if (set < ctlSens->lim) { ctlSens=cryo.sensor2; } @@ -737,21 +779,40 @@ int ReadTemp(void) { char buf[256], typ, *err; int i, doit, stat; int tfill, dfill; + static int iScan=0; float hlev; SensorT *s; readTemp=0; doit=0; + if (nScan>0) { + while (1) { /* read until a non-selected channel found */ + if (iScan>=nScan) iScan=0; + s=sensors[iScan+4]; + if (s->present<1) break; + str_copy(chan, s->ch); + ERR_P(LscCmd(ser, "KRDG?[chan]>fbuf;DIOST?>,out1")); + if (out1==iScan) break; + s->t=fbuf; + iScan++; + } + } for (i=0; i<4; i++) { s=sensors[i]; s->stat1=0; s->stat2=0; if (s->present) { if (doit) ERR_P(LscCmd(ser, buf)); - str_substitute(buf - , "KRDG?#>sens#.t0;MDAT?#>sens#.t1,sens#.t2;MDATST?#>sens#.stat1,sens#.stat2" - , "#", s->ch); + if (i<4) { + str_substitute(buf + , "KRDG?#>sens#.t0;MDAT?#>sens#.t1,sens#.t2;MDATST?#>sens#.stat1,sens#.stat2" + , "#", s->ch); + } else { + str_substitute(buf + , "KRDG?#>sens#.t1;RDGST?#>sens#.stat1;DIOST?>,sens#.stat2" + , "#", s->ch); + } if (s->type=='h' || s->type=='x') { buf[0]='S'; /* change KRDG to SRDG */ typ='S'; @@ -773,22 +834,29 @@ int ReadTemp(void) { if (ramp!=0) { tr=fbuf*CtlScale(); } else { - tr=setH; + tr=setH*CtlScale(); } if (tr==0) tr=DATA_UNDEF; } - /* check for reading errors */ + /* check for reading errors, determine legal value */ for (i=0; i<4; i++) { s=sensors[i]; if (s->present) { + if (i>=4) { + if (s->stat2==i-4) { /* ignore reading, if channel was active (may be noisy) */ + s->t1 = s->t; + } + s->t2 = s->t1; + s->stat2 = s->stat1; + } if (s->t1 == 63.0 || s->t2 == 63.0 || s->t0 == 63.0) { /* probably noisy values */ logfileOut(LOG_MAIN, "magic %s: %g %g %g\n", s->ch, s->t1, s->t2, s->t0); } - stat=(s->stat1 | s->stat2) & (255-3); /* ignore "old reading" and "invalid reading" */ + stat=(s->stat1 & s->stat2) & (255-3); /* ignore "old reading" and "invalid reading", error must be on min & max */ if (stat != s->readStat) { s->readStat=stat; err=LscReadStat(stat); @@ -830,10 +898,10 @@ int ReadTemp(void) { s->band = s->max - s->min; } } else { - s->t=0; + s->t=DATA_UNDEF; } } else { - s->t=0; + s->t=DATA_UNDEF; } } @@ -851,7 +919,7 @@ int ReadTemp(void) { if (samp.temp==0.0) { samp.temp=cryo.temp; } - } else { + } else if (nScan==0) { tm=(rdTim % 3600) * 1.0e-4; ts=(rdTim % 60) * 60.0e-4+0.5; } @@ -887,7 +955,8 @@ int ReadHeater(void) { if (set == 0) { power=DATA_UNDEF; } else { - power=htr*htr*maxPower*1e-4; + power=htr*htr*scalPower*1e-4; + if (power>maxPower) power=maxPower; } return 0; OnError: return -1; @@ -905,37 +974,9 @@ int SetTemp(int switchOn) { ERR_I(ReadTemp()); LogMinMax(switchOn); } - if (cryo.sensor1==NULL) return 0; scale=CtlScale(); + if (ctlSens==NULL) return 0; - if (ctlSens==NULL) ctlSens=cryo.sensor1; - if (controlMode==1) { - tShift=0; - if (ctlSens==samp.sensor1) { - if (set < ctlSens->lim) { - ctlSens=samp.sensor2; - } - } else if (ctlSens==samp.sensor2) { - if (set > ctlSens->lim) { - ctlSens=samp.sensor1; - } - } else { - ctlSens=samp.sensor1; - } - } else { - if (controlMode!=2) tShift=0; - if (ctlSens==cryo.sensor1) { - if (set < ctlSens->lim) { - ctlSens=cryo.sensor2; - } - } else if (ctlSens==cryo.sensor2) { - if (set > ctlSens->lim) { - ctlSens=cryo.sensor1; - } - } else { - ctlSens=cryo.sensor1; - } - } str_copy(chan, ctlSens->ch); if (tShift>maxShift) { tShift=maxShift; @@ -1033,41 +1074,64 @@ int SetTemp(int switchOn) { OnError: return -1; } +void CalcMaxPower(void) { + int i, j, vmax; + float pa, pr, pw, dif, p, pl, plim; + + iAmp=1; iRange=0; + if (scalPower==0) scalPower=maxPower; + if (maxPower>0) { + p=scalPower/powFact; + plim=2500/resist; + /* power limited by 50 V output. U*U/R=2500/R */ + if (p>plim) p=plim; + pa=resist*4; /* max. maxPower R*I*I (I=2 A) */ + pw=0; dif=1.0e6; + for (i=4; i>0; i--) { + pr=pa; + for (j=5; j>0; j--) { + if (pr>p) { + if (pr/p0) { - p=maxPower/powFact; - pa=resist*4; /* max. maxPower */ - pw=0; dif=1.0e6; - for (i=4; i>0; i--) { - pr=pa; - for (j=5; j>0; j--) { - if (pr>p) { - if (pr/p,,,iAmp,iRange")); + if (iRange>0) { + p0=resist*pow(4.0,iAmp)*pow(10.0,iRange)/6.4e6*powFact; } - maxPower=pw*powFact; + CalcMaxPower(); } - logfileOut(LOG_MAIN, "maxPower %g\n", maxPower, iAmp, iRange); + logfileOut(LOG_MAIN, "maxPower changed from %g to %g\n", p0, maxPower); ERR_P(LscCmd(ser, "CDISP 1:[loop],[resist],1;MOUT [loop]:0;CMODE [loop]:1")); if (slope<0) slope=-slope; if (slope!=0 && slope<0.1) slope=0.1; fbuf=tLimit/CtlScale(); if (loop==1) { - ERR_P(LscCmd(ser, "CLIMIT 1:[fbuf],[slope],0,[iAmp],[iRange]")); + prop=sqrt(p0/scalPower)*prop; + ERR_P(LscCmd(ser, "CLIMIT 1:[fbuf],[slope],0,[iAmp],[iRange];PID [loop],[prop]")); } else { ERR_P(LscCmd(ser, "CLIMIT 2:[fbuf],[slope],0")); } + p0=scalPower; return 0; OnError: return -1; } @@ -1094,19 +1158,28 @@ int ConfigAlarms(void) { ERR_P(LscCmd(ser, "RELAY 1:1;BEEP:0")); relay=0; k=0; - for (i=0;i<4;i++) { + for (i=0;i<4+nScan;i++) { s=sensors[i]; str_copy(buf1, s->ch); if (s->present==1 && s->alarm>0) { r1=s->alarm/s->scale; ERR_P(LscCmd(ser, "ALARM [buf1]:1,1,[r1],0,1,1")); - alarmList[k]=s->ch[0]; + alarmList[k]=s->ch; k++; } else { ERR_P(LscCmd(ser, "ALARM [buf1]:0")); /* switch off unused alarms */ } } - alarmList[k]='\0'; + alarmListSize=k; + return 0; + OnError: return -1; +} + +int LoadFromLsc(void) { + ERR_P(LscCmd(ser, "PID?[loop]>prop,integ,deriv")); + ERR_P(LscCmd(ser, "RAMP?[loop]>,ramp")); + ERR_P(LscCmd(ser, "ANALOG?1>,,,,,,fbuf")); + still=fbuf*fbuf/70; return 0; OnError: return -1; } @@ -1120,20 +1193,34 @@ int Settings(void) { if (remoteMode!=2) { remoteMode=2; /* set to remote mode */ - ERR_P(LscCmd(ser, "PID?[loop]>prop,integ,deriv")); - ERR_P(LscCmd(ser, "RAMP?[loop]>,ramp")); + ERR_I(LoadFromLsc()); ERR_P(LscCmd(ser, "MODE:[remoteMode]")); } else { ERR_P(LscCmd(ser, "PID [loop],[prop],[integ],[deriv]")); } - for (i=0; i<4; i++) { + for (i=0; i<4+nScan; i++) { s=sensors[i]; - plug=plugs[i/2]; + if (i<4) { + plug=plugs[i/2]; + } else { + plug=&plug0; + } if (s->present < 0) { if (settingsFlag) return 0; + if (i==4) { + ERR_P(LscCmd(ser, "DOUT:2;XSCAN:2,,2")); + } ERR_I(InstalCurve(s, plug->device)); } } + if (nScan>0) { + for (out1=nScan+1;out1<=4;out1++) { + ERR_P(LscCmd(ser, "INSET A[out1],0")); + } + ERR_P(LscCmd(ser, "INSET A5,0;INSET A6,0;INSET A7,0;INSET A8,0")); + ERR_P(LscCmd(ser, "INSET A9,0;INSET A10,0;INSET A11,0;INSET A12,0")); + ERR_P(LscCmd(ser, "INSET A13,0;INSET A14,0;INSET A15,0;INSET A16,0")); + } cryo.sensor1=NULL; cryo.sensor2=NULL; @@ -1142,7 +1229,7 @@ int Settings(void) { heliumSens=NULL; auxSens=NULL; testSens=NULL; - for (i=0; i<4; i++) { + for (i=0; i<4+nScan; i++) { s=sensors[i]; if (s->present==1) { typ=s->type; @@ -1323,8 +1410,13 @@ int PeriodicTask(void) { int i, k; float t3[3], p, d, w, t; - ERR_P(LscCmd(ser, "DIOST?>cod1,out1;DOUT 3,29;BUSY?>busy")); - if (plug0.codDefined && plug1.codDefined) { + if (nScan==0) { + ERR_P(LscCmd(ser, "DIOST?>cod1,out1;DOUT 3,29;BUSY?>busy")); + } else { + cod1=0; + ERR_P(LscCmd(ser, "BUSY?>busy")); + } + if (plug0.codDefined && plug1.codDefined || nScan>0) { per=period; /* no timeout on above command and codes are defined: normal period */ if (per>logPeriod*1000) per=logPeriod*1000; } @@ -1391,29 +1483,26 @@ int PeriodicTask(void) { ERR_I(ReadHeater()); if (relay || loop !=1) { - if (alarmList[0]!='\0') { + if (alarmListSize!=0) { buf[0]='\0'; - for (k=0;(k<4) && alarmList[k]!='\0';k++) { - str_copy(buf1,";ALARMST?*"); - buf1[9]=alarmList[k]; - str_append(buf, buf1); + for (k=0;k=logTime) { ERR_I(DataPutAll(NULL, rdTim)); logTime=(rdTim / logPeriod + 1) * logPeriod; - if (rdTim>mmTime && cryo.sensor1 != NULL) LogMinMax(0); + if (rdTim>mmTime && (cryo.sensor1 != NULL || nScan>0)) LogMinMax(0); } if (set!=0 && remoteMode==2) { if (cryo.sensor1!=samp.sensor1 && controlMode==2) { @@ -1488,16 +1577,21 @@ int PeriodicTask(void) { } } - ERR_P(LscCmd(ser, "KEYST?>key;DIOST?>cod2,out2;DOUT 3,30")); - + if (nScan==0) { + ERR_P(LscCmd(ser, "KEYST?>key;DIOST?>cod2,out2;DOUT 3,30")); + } else { + ERR_P(LscCmd(ser, "KEYST?>key")); + } if (busy==0) { - if (out1!=30) { - ERR_P(LscCmd(ser, "DOUT:3,30")); - ERR_P(LscCmd(ser, "DIOST?>cod1,out1")); - } - if (out2!=29) { - ERR_P(LscCmd(ser, "DOUT:3,29")); - ERR_P(LscCmd(ser, "DIOST?>cod2,out2;DOUT 3,30")); + if (nScan==0) { + if (out1!=30) { + ERR_P(LscCmd(ser, "DOUT:3,30")); + ERR_P(LscCmd(ser, "DIOST?>cod1,out1")); + } + if (out2!=29) { + ERR_P(LscCmd(ser, "DOUT:3,29")); + ERR_P(LscCmd(ser, "DIOST?>cod2,out2;DOUT 3,30")); + } } if (out1==30 && out2==29) { @@ -1540,7 +1634,7 @@ int PeriodicTask(void) { if (remoteMode==2) { logfileOut(LOG_MAIN ,"user switched to remote\n"); touched=0; - ERR_P(LscCmd(ser, "PID?[loop]>prop,integ,deriv")); + ERR_I(LoadFromLsc()); if (controlMode==2) { ERR_P(LscCmd(ser, "RANGE?>iRange")); if (iRange==0) set=0; @@ -1568,7 +1662,7 @@ int PeriodicTask(void) { OnError: return -1; } -int DeviceHdl(int mode, void *base) { +int DeviceHdl(int mode, void *base, int fd) { char *t, *res; int do0, do1; @@ -1577,6 +1671,7 @@ int DeviceHdl(int mode, void *base) { t=strchr(device, '/'); if (t==NULL) { if (0==strcmp(device, "0") || 0==strcasecmp(device, "auto")) { + nScan=0; ERR_I(ConfigByCode(0)); ERR_I(ConfigByCode(1)); } else { @@ -1608,7 +1703,7 @@ int DeviceHdl(int mode, void *base) { OnError: return -1; } -int SetHdl(int mode, void *base) { +int SetHdl(int mode, void *base, int fd) { if (mode==COC_WR) { if (remoteMode!=2) { ERR_MSG("controller is in local mode, enter 'remote' first"); @@ -1635,7 +1730,7 @@ int SetHdl(int mode, void *base) { OnError: return -1; } -int PidHdl(int mode, void *base) { +int PidHdl(int mode, void *base, int fd) { if (mode==COC_WR) { return COC_DWR; } else if (mode==COC_DWR) { @@ -1645,7 +1740,7 @@ int PidHdl(int mode, void *base) { OnError: return -1; } -int AlarmHdl(int mode, void *base) { +int AlarmHdl(int mode, void *base, int fd) { if (mode==COC_WR) { return COC_DWR; } else if (mode==COC_DWR) { @@ -1655,8 +1750,10 @@ int AlarmHdl(int mode, void *base) { OnError: return -1; } -int MaxPowerHdl(int mode, void *base) { +int MaxPowerHdl(int mode, void *base, int fd) { if (mode==COC_WR) { + scalPower=maxPower; + CalcMaxPower(); if (remoteMode!=2) { ERR_MSG("controller is in local mode, enter 'remote' first"); } else if (relay) { @@ -1675,7 +1772,18 @@ int MaxPowerHdl(int mode, void *base) { OnError: return -1; } -int SendHdl(int mode, void *base) { +int StillHdl(int mode, void *base, int fd) { + if (mode==COC_WR) { + return COC_DWR; + } else if (mode==COC_DWR) { + fbuf=sqrt(still*70); + ERR_P(LscCmd(ser,"ANALOG 1:0,2,,,,,[fbuf]")); + } + return 0; + OnError: return -1; +} + +int SendHdl(int mode, void *base, int fd) { char *res; ClientData *data; @@ -1692,7 +1800,7 @@ int SendHdl(int mode, void *base) { OnError: return -1; } -int LogHdl(int mode, void *base) { +int LogHdl(int mode, void *base, int fd) { ClientData *data; if (mode==COC_RD) { @@ -1707,17 +1815,26 @@ int LogHdl(int mode, void *base) { OnError: return -1; } -int PltHdl(int mode, void *base) { +int PltHdl(int mode, void *base, int fd) { + if (mode==COC_RD) { + ERR_MSG("Tecs client version not up to date"); + } + return 0; + OnError: return -1; +} + +int GraHdl(int mode, void *base, int fd) { ClientData *data; int l; char names[64]; long startTime, endTime, step; if (mode==COC_RD) { - data=base; - ERR_SI(sscanf(data->pltdata, "%ld %ld %ld %n", &startTime, &endTime, &step, &l)-2); - str_copy(names, data->pltdata+l); - ERR_I(l=DataGetCoded(names, startTime, endTime, step, 30, data->pltdata, sizeof(data->pltdata))); + ERR_SI(sscanf(grapar, "%ld %ld %ld %n", &startTime, &endTime, &step, &l)-2); + str_copy(names, grapar+l); + ERR_I(l=DataGetMult(names, startTime, endTime, step, 30, gradata, sizeof(gradata)/sizeof(float))); + assert(l*sizeof(float)0) { ERR_I(StrPut(&buf, "\ntest", ':')); + } + if (testSens!=NULL) { ERR_I(ShowSensor(&buf, testSens, "T", "K", 0)); } + for (i=4; i<4+nScan; i++) { + ERR_I(ShowSensor(&buf, sensors[i], "T", "K", 0)); + } if (auxSens!=NULL) { ERR_I(StrPut(&buf, "\nauxilliary", ':')); ERR_I(ShowSensor(&buf, auxSens, "U", "V", 0)); @@ -1886,6 +2010,11 @@ int StatusHdl(int mode, void *base) { ERR_I(StrPut(&buf, "\nhelium:", ' ')); ERR_I(StrPut(&buf, helium, StrNONE)); } + if (still!=0) { + ERR_I(StrPut(&buf, "\nstill:", ' ')); + ERR_I(PutFloat(&buf, 1, still)); + ERR_I(StrPut(&buf, " mW", ' ')); + } EndStatus: ERR_I(StrPut(&buf, "", '\0')); return 0; @@ -1893,7 +2022,30 @@ EndStatus: return -1; } -int RemoteHdl(int mode, void *base) { +int PidSumHdl(int mode, void *base, int fd) { + StrBuf buf; + + readTemp=1; + StrLink(&buf, pid); + StrClear(&buf); + ERR_I(PutFloat(&buf, 5, prop)); + ERR_I(StrPut(&buf, " ", StrNONE)); + ERR_I(PutFloat(&buf, 5, integ)); + ERR_I(StrPut(&buf, " ", StrNONE)); + ERR_I(PutFloat(&buf, 4, deriv)); + ERR_I(StrPut(&buf, " /", ' ')); + ERR_I(PutFloat(&buf, 4, prop*sqrt(scalPower/resist)/600)); + ERR_I(StrPut(&buf, " A/K,", ' ')); + ERR_I(PutFloat(&buf, 4, 1000.0/integ)); + ERR_I(StrPut(&buf, " sec,", ' ')); + ERR_I(PutFloat(&buf, 4, deriv)); + ERR_I(StrPut(&buf, " sec", StrNONE)); + return 0; + OnError: + return -1; +} + +int RemoteHdl(int mode, void *base, int fd) { if (mode==COC_WR) { return COC_DWR; } else if (mode==COC_DWR) { @@ -1903,7 +2055,7 @@ int RemoteHdl(int mode, void *base) { OnError: return -1; } -int RelayHdl(int mode, void *base) { +int RelayHdl(int mode, void *base, int fd) { if (mode==COC_WR) { if (alarmChannels[0]!='\0') ERR_MSG("alarm is still active"); return COC_DWR; @@ -1927,6 +2079,38 @@ int RelayHdl(int mode, void *base) { OnError: return -1; } +int TmoHdl(int mode, void *base, int fd) { + if (mode==COC_WR) { + ERR_I(SerSetTmo(ser, msecTmo)); + } + return 0; + OnError: return -1; +} + +int SerHdl(int mode, void *base, int fd) { + if (mode==COC_WR) { + return COC_DRD; + } else if (mode==COC_DRD) { + SerClose(ser); + noResp=1; + ERR_P(ser=SerOpen(host, msecTmo, IdleHdl)); + } + return 0; + OnError: return -1; +} + +int LogfileHdl(int mode, void *base, int fd) { + char buf[256]; + if (mode==COC_WR) { + logfileClose(); + str_copy(buf, logDir); + str_append(buf, serverId); + logfile=logfileInit(buf, logIt, use_stdout, logIt && use_stdout); + } + return 0; +} + + int ExecuteRequest(void) { if (readTemp) ERR_I(ReadTemp()); ERR_I(CocCallHandlers()); @@ -1989,77 +2173,11 @@ int MainBody(void) { } int main(int argc, char *argv[]) { - int logIt=0; - int i, iret, use_stdout=0; - char *host; + int i, iret; + char *inistr; char buf[256], opt; - int port, msecTmo; signal(SIGPIPE, ignore_forever); - logMask=LOG_MAIN; - binDir="bin/"; - logDir="log/"; - serverId="tecs"; - host="lnsp26:4000/0"; - port=0; - msecTmo=0; - logfileOut(LOG_MAIN ,"%s ", argv[0]); - for (i=1;i0 && host[0]!='\0' && port!=0 && msecTmo>0); + + str_copy(statusBuf, "starting up"); + logfileStatusBuf(statusBuf); + + str_copy(buf, logDir); + str_append(buf, serverId); + logfile=logfileInit(buf, logIt, use_stdout, logIt && use_stdout); + logfileOut(LOG_MAIN ,"\n"); + logfileWrite(logMask); + + ERR_I(CocInitServer(SetClientData, port)); + ser=SerOpen(host, msecTmo, IdleHdl); if (ser==NULL) { + str_copy(statusBuf, "can not connect to serial port server or terminal server"); logfileShowErr("error in SerOpen"); } ERR_I(iret=CocHandleRequests(100, 0)); @@ -2191,6 +2400,10 @@ int main(int argc, char *argv[]) { ERR_P(DataCreateSet(NULL, "Tr", &tr, 5, LOGLIFETIME, tim)); ERR_P(DataCreateSet(NULL, "Te", &te, 5, LOGLIFETIME, tim)); ERR_P(DataCreateSet(NULL, "He", &he, 5, LOGLIFETIME, tim)); + ERR_P(DataCreateSet(NULL, "T1", &sensA1.t, 5, LOGLIFETIME, tim)); + ERR_P(DataCreateSet(NULL, "T2", &sensA2.t, 5, LOGLIFETIME, tim)); + ERR_P(DataCreateSet(NULL, "T3", &sensA3.t, 5, LOGLIFETIME, tim)); + ERR_P(DataCreateSet(NULL, "T4", &sensA4.t, 5, LOGLIFETIME, tim)); ERR_P(DataCreateSet(NULL, "Aux", &aux, 5, LOGLIFETIME, tim)); ERR_P(DataCreateSet(NULL, "P", &power, 5, LOGLIFETIME, tim)); @@ -2200,7 +2413,7 @@ int main(int argc, char *argv[]) { deriv=0; if (ser!=NULL) { LscCmd(ser, "MODE?>remoteMode"); - LscCmd(ser, "PID?[loop]>prop,integ,deriv"); + LoadFromLsc(); } per=1; /* advance fast when initializing */ cntError=0; @@ -2212,6 +2425,7 @@ int main(int argc, char *argv[]) { if (0==strcmp(ErrMessage, "asynsrv error")) { if (ser!=NULL) SerClose(ser); ser=NULL; + noResp=1; } if (cntError<4) { if (iret<0) { @@ -2225,9 +2439,11 @@ int main(int argc, char *argv[]) { if (ser==NULL) { CocHandleRequests(msecTmo, 0); ser=SerOpen(host, msecTmo, IdleHdl); - if (ser!=NULL) { + if (ser==NULL) { + str_copy(statusBuf, "can not connect to serial port server or terminal server"); + } else { LscCmd(ser, "MODE?>remoteMode"); - LscCmd(ser, "PID?[loop]>prop,integ,deriv"); + LoadFromLsc(); } } } else { diff --git a/tecs/tecs_cli.c b/tecs/tecs_cli.c index a2b87ff7..5f3a71e7 100644 --- a/tecs/tecs_cli.c +++ b/tecs/tecs_cli.c @@ -123,22 +123,6 @@ void TeccClose(pTecsClient conn) { #define tecs_date_ tecs_date #define tecs_time_ tecs_time #define tecs_rights_ tecs_rights -#elif defined __linux -#define tecs_get_par_ tecs_get_par__ -#define tecs_get_mult_ tecs_get_mult__ -#define tecs_set_par_ tecs_set_par__ -#define tecs_init_ tecs_init__ -#define tecs_get3_ tecs_get3__ -#define tecs_get_ tecs_get__ -#define tecs_set_ tecs_set__ -#define tecs_is_open_ tecs_is_open__ -#define tecs_close_ tecs_close__ -#define tecs_quit_server_ tecs_quit_server__ -#define tecs_watch_log_ tecs_watch_log__ -#define tecs_get_data_ tecs_get_data__ -#define tecs_date_ tecs_date__ -#define tecs_time_ tecs_time__ -#define tecs_rights_ tecs_rights__ #endif static pTecsClient conn=NULL; @@ -271,82 +255,13 @@ int tecs_watch_log_(F_CHAR(list), int list_len) { OnError: return(-1); } -static char *encode=DATA_CODE; - -int DataDecode(float *data, int dataSize, char *coded, int *retSize) { - int i, p, gap, dig1, dig2; - float minD, range; - char ch, *q; - static int decode[256]; - static int init=1; - - if (coded[0] == '\0') { - *retSize=0; - return 0; - } - if (init) { - init=0; - for (i=0; i<256; i++) { - decode[i]=-1; - } - i=0; - while (encode[i]!=0) { - decode[encode[i]]=i; - i++; - } - } - p=0; - ERR_SI(sscanf(coded, "%d %e %e %n", retSize, &minD, &range, &p)-3); - if (*retSize < dataSize) dataSize = *retSize; - i=0; - while (i < dataSize) { - ch=coded[p++]; - dig1=decode[ch]; - if (dig1 < 0) { /* code is no 64-digit */ - if (ch=='\0' || ch==',') break; - if (ch=='/') { - data[i++] = DATA_UNDEF; - } else if (ch=='.') { - data[i++] = DATA_GAP; - } - } else { - ch=coded[p++]; - dig2=decode[ch]; - while (dig2<0) { - if (ch=='\0' || ch==',') break; - ch=coded[p++]; - dig2=decode[ch]; - } - if (ch=='\0' || ch==',') break; - data[i++] = (dig1 + dig2 * 64) / 4095.0 * range + minD; - } - } - while (i < dataSize) { - data[i++] = DATA_UNDEF; - } - if (ch=='\0') { - return p-1; - } else if (ch!=',') { - q=strchr(coded+p, ','); - if (q==NULL) return strlen(coded); - return q-coded+1; - } - return p; - OnError: - *retSize=0; - return -1; -} - - int tecs_get_data_(F_CHAR(names), int *startTime, int *endTime, int *step, int *tbase , float xdata[], float ydata[], int *maxLen, int *width , int retLen[], int names_len) { char nam[64]; char str[128]; - char res[COC_RES_LEN]; - char *cod; - float offset, fact, *py; - int i, j, k, l, iret, retSize; + float offset, fact, *py, data[8192]; + int i, j, k, l, iret; if (*endTime - *startTime > *step * (*maxLen-1)) { printf("maxLen too small\n"); @@ -358,34 +273,34 @@ int tecs_get_data_(F_CHAR(names), int *startTime, int *endTime, int *step, int * sprintf(str, "%d %d %d %s", *startTime, *endTime, *step, nam); CocReset(conn); - ERR_I(CocPutStr(conn, "pltdata", str)); - ERR_I(CocGetStr(conn, "pltdata", res, sizeof(res))); + ERR_I(CocPutStr(conn, "grapar", str)); + ERR_I(CocGetArray(conn, "gradata", data, sizeof(data)/sizeof(float))); ERR_I(iret=CocDoIt(conn, response, sizeof(response))); if (iret) ERR_MSG(response); - cod=res; + py=data; for (i=0; i < *width; i++) { - py = ydata + i * *maxLen; - ERR_I(l=DataDecode(py, *maxLen, cod, retLen+i)); - if (retLen[i]>0) { - fact = (float)(*endTime - *startTime) / retLen[i]; + l=*py; py++; + if (l>0) { + fact = (float)(*endTime - *startTime) / l; } offset = *startTime - *tbase; k = i * *maxLen; - for (j=0; j= (codedLen-26)/2) ERR_MSG("codedLen too small"); - minD=DATA_UNDEF; - maxD=DATA_UNDEF; - for (i=0; i maxD) maxD=data[i]; - if (data[i] < minD) minD=data[i]; - } - } - } - range = maxD - minD; - if (range == 0) range=1; - ERR_SI(p=sprintf(coded, "%d %5g %5g ", dataSize, minD, range)); - gap=0; - for (i=0; i=0 && n <4096); - coded[p++]=encode[n % 64]; - coded[p++]=encode[n / 64]; - } - } - coded[p++]=','; - coded[p]='\0'; - assert(p < codedLen); - return p; - OnError: - return -1; -} - -int DataGetCoded(char *names, int startTime, int endTime, int step, int stdStep, char *coded, int codedLen) { +int DataGetMult(char *names, int startTime, int endTime, int step, int stdStep, float *data, int data_len) { Base base; Set *set, *s; int stp, minStep, period, s1; char *nams, nam[32]; int p, l, n, i, j, siz1, siz2, halfsiz, start; - float data[SET_LEN]; base.head = NULL; period = endTime - startTime; + if (period<=0) period=1; n=0; nams = names; - while (nams != NULL) { + while (nams != NULL) { /* count names */ nams = str_split(nam, nams, ' '); if (nam[0] != '\0') n++; } @@ -505,7 +462,7 @@ int DataGetCoded(char *names, int startTime, int endTime, int step, int stdStep, stp=step; if (stpstep; stp = step; @@ -560,40 +515,44 @@ int DataGetCoded(char *names, int startTime, int endTime, int step, int stdStep, if (startTime + minStep * halfsiz * 2 > endTime) { if (stp < minStep) stp = minStep; halfsiz = period / (2 * stp) + 1; - if (halfsiz * 2 > SET_LEN) halfsiz = SET_LEN / 2; - if (halfsiz * 4 + 32 * n > codedLen) { - halfsiz = ((codedLen - p) / n - 32) / 4; + if (halfsiz * 2 + n > data_len) { /* check if enough space */ + halfsiz = ((data_len - p) / n - 1) / 2; } } siz1 = (s1 - startTime) * halfsiz / period * 2; siz2 = halfsiz * 2 - siz1; s1 = startTime + (siz1 * period + halfsiz) / halfsiz / 2; + p++; if (siz1 > 0) { halfsiz = (s1 - startTime) / set->step / 2; if (halfsiz * 2 < siz1 && halfsiz > 0) { - ERR_I(GetSet(set, startTime, s1, halfsiz*2, data)); + ERR_I(GetSet(set, startTime, s1, halfsiz*2, data+p)); j = siz1 - 1; for (i = halfsiz * 2-1; i >= 0; i--) { /* expand data */ while (j > siz1 / 2 * i / halfsiz) { - data[j]=DATA_GAP; j--; + data[p+j]=DATA_GAP; j--; } - data[j]=data[i]; j--; + data[p+j]=data[p+i]; j--; } } else { - ERR_I(GetSet(set, startTime, s1, siz1, data)); + ERR_I(GetSet(set, startTime, s1, siz1, data+p)); } + l=siz1; + } else { + l=0; } if (siz2 > 0) { - ERR_I(GetSet(s, s1, endTime, siz2, data+siz1)); + ERR_I(GetSet(s, s1, endTime, siz2, data+p+siz1)); + l+=siz2; } - ERR_I(l=DataEncode(data, siz1+siz2, coded+p, codedLen-p)); + data[p-1]=l; + p+=l; } - p+=l; n--; } } FreeBase(&base); - return (0); + return p; OnError: - return(-1); + return -1; } diff --git a/tecs/tecs_data.h b/tecs/tecs_data.h index 5d588ff5..75bc1124 100644 --- a/tecs/tecs_data.h +++ b/tecs/tecs_data.h @@ -35,14 +35,15 @@ int DataPutAll(DataBase *dBase, int time); put all variables in a set to their dataset */ -int DataDecode(float *data, int dataSize, char *coded, int *retLen); -int DataGetCoded(char *names, int startTime, int endTime, int step, int stdStep, char *coded, int codedLen); +int DataGetMult(char *names, int startTime, int endTime, int step, int stdStep, float *data, int data_len); +/* + get multiple datasets +*/ /* define DATA_UNDEF as a binary and decimal well defined, hopefully rarely used number */ #define DATA_UNDEF MYC_NAN #define DATA_GAP (MYC_NAN*2) -#define DATA_CODE "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[]abcdefghijklmnopqrstuvwxyz" #endif /* TECS_DATA_H_ */ diff --git a/tecs/tecs_plot.f90 b/tecs/tecs_plot.f90 index 68ac8c76..bf0c6242 100644 --- a/tecs/tecs_plot.f90 +++ b/tecs/tecs_plot.f90 @@ -2,7 +2,7 @@ subroutine tecs_plot(auxpar) character(len=*) auxpar - integer, parameter :: dmax=800, nmax=5, tmax=4, amax=3, nmenu=13, chartperiod=5, naux=1 + integer, parameter :: dmax=400, nmax=9, tmax=8, amax=3, nmenu=13, chartperiod=5, naux=1 integer, parameter :: minRange=60, maxRange=7*24*3600 integer, parameter :: oneDay = 24*3600 integer, parameter :: zoom=1, right=2, live=3 @@ -15,7 +15,7 @@ subroutine tecs_plot(auxpar) integer l,j,i,n,t,leng,i1,i2,rl,startday,thisday integer ncol, nset, mode integer first,last,step,tbase,lastj - integer colorList(nmax)/5,3,2,4,8/ + integer colorList(nmax)/5,3,2,4,6,8,14,15,8/ integer color(nmax) integer retLen(nmax) integer sel/0/, sel1, sel2, auxsel/1/ @@ -36,7 +36,7 @@ subroutine tecs_plot(auxpar) ,'q' ,'quit'/ character weekdays(7)*4/'Mon','Tue','Wed','Thu','Fri','Sat','Sun'/ character buf*8, device*8, name*40, filnam*128, numb*16, title*64, pars*64 - character(len=4) tpar(tmax)/'Te', 'Tr', 'Tm', 'Ts'/ + character(len=4) tpar(tmax)/'Te', 'Tr', 'Tm', 'Ts', 'T1', 'T2', 'T3', 'T4'/ character(len=4) apar(amax)/'P', 'He', 'Aux'/ character(len=16) parnam(nmax) logical gap, done @@ -44,7 +44,7 @@ subroutine tecs_plot(auxpar) integer iret, lund, numl, mon, day ! functions - integer sys_gmt_off, myc_now, myc_time, myc_date, tecs_get_data, tecs_get_mult, tecs_get_par + integer sys_gmt_off, myc_now, myc_time, myc_date, get_data, tecs_get_mult, tecs_get_par data window/0./ @@ -74,6 +74,7 @@ subroutine tecs_plot(auxpar) endif call pgask(.false.) + call pgupdt l=0 x1=0 step=0 @@ -92,7 +93,7 @@ subroutine tecs_plot(auxpar) pars=trim(pars)//' '//parnam(nset) enddo nset=nset+1 - color(nset)=colorList(5) + color(nset)=colorList(3) parnam(nset)=apar(auxsel) pars=trim(pars)//' '//parnam(nset) @@ -104,23 +105,34 @@ subroutine tecs_plot(auxpar) window=maxRange first=t-min(dmax*step-1,maxRange-step) else if (mode >= right) then - step=window/(dmax-1)+0.99 + step=window/(dmax-2)+0.99 last=t - first=t-min(dmax*step-1,nint(window)-step) + first=t-min(dmax*step-1,nint(window)) else if (mode==zoom) then x2=(x1+x2+window)/2 x1=x2-window endif if (x1 .gt. x2-minRange) x1=x2-minRange - step=(x2-x1)/(dmax-1)+0.99 - last=nint(x2)+tbase - first=nint(x1)+tbase + step=(x2-x1)/(dmax-2)+0.99 + last=x2+tbase + first=x1-step+tbase endif if (step == 0) step=1 + if (step>60) then ! normalize step + step=(step+59)/60*60 + else if (step>30) then + step=60 + elseif (step>20) then + step=30 + else + step=(step+4)/5*5 + endif + first=last-(last-first+step-1)/step*step ! round first +! print *,step,last-first tbase=first-mod(first,7*oneDay) - iret=tecs_get_data(pars, first, last, step, tbase, xd, yd, dmax, nmax, retLen) + iret=get_data(pars, first, last, step, tbase, xd, yd, dmax, nmax, retLen) if (iret < 0) goto 99 x2 = last - tbase @@ -216,6 +228,7 @@ subroutine tecs_plot(auxpar) do i=i1,i2 call pgsci(color(i)) + l=0 lastj=1 do j=1,retLen(i) if (yd(j,i)==undef) then @@ -223,9 +236,12 @@ subroutine tecs_plot(auxpar) call pgline(j-lastj, xd(lastj,i), yd(lastj,i)) endif lastj=j+1 + else + l=j endif enddo if (retLen(i) > lastj) call pgline(retLen(i)+1-lastj, xd(lastj,i), yd(lastj,i)) + retLen(i)=l enddo call pgsci(1) if (rl == 1) then @@ -635,3 +651,42 @@ subroutine set_win(rl, x1, x2, y1, y2) call pgswin(x1,x2,y1,y2) end subroutine + +integer function get_data(pars, first, last, step, tbase, xd, yd, dmax, nmax, retlen) + character pars*(*) + integer first, last, step, tbase, dmax, nmax, retlen(nmax) + real*4 xd(dmax,nmax), yd(dmax,nmax) + + integer, parameter :: oneDay = 24*3600, maxn=9 + integer tecs_get_data + + integer i,j,rl(maxn),m,k,n,mm + + if (nmax > maxn) stop 'get_data: nmax>maxn' + if (last-first <= oneDay) then + get_data=tecs_get_data(pars, first, last, step, tbase, xd, yd, dmax, nmax, retLen) + else + do j=1,nmax + retlen(j)=0 + enddo + m=0 + do i=first/oneDay,last/oneDay + get_data=tecs_get_data(pars, max(first,i*oneDay), min(last,(i+1)*oneDay-step), step, tbase & + , xd(m+1, 1), yd(m+1, 1), dmax, nmax, rl) + if (get_data<0) return + mm=0 + do j=1,nmax + n=retlen(j) + do k=m+1,m+rl(j) + n=n+1 + xd(n,j)=xd(k,j) + yd(n,j)=yd(k,j) + enddo + retlen(j)=n + mm=max(mm,n) + enddo +! print *,mm-m,' points read' + m=mm + enddo + endif +end function diff --git a/tecs/tecs_serial.c b/tecs/tecs_serial.c index a8b13398..8b75ad01 100644 --- a/tecs/tecs_serial.c +++ b/tecs/tecs_serial.c @@ -82,10 +82,7 @@ SerChannel *SerOpen(const char *hostPort, int msecTmo, int (*idleHdl)(int,int)) if (iret==1) { iret=AsynSrv_Config(&aser->asyn_info, "msecTmo", msecTmo, "idleHdl", idleHdl, NULL); } - if (iret!=1) { - SerA_error(); - goto OnError; - } + if (iret!=1) { SerA_error(); goto OnError; } time(&t2); ecnt=0; logfileOut(LOG_MAIN, "connection to %s:%d/%d opened (%d sec)\n", @@ -102,10 +99,6 @@ SerChannel *SerOpen(const char *hostPort, int msecTmo, int (*idleHdl)(int,int)) } ERR_I(CocCreateSockAdr(&sadr, host, atoi(p))); ERR_SI(tser->fd=socket(AF_INET, SOCK_STREAM, 0)); - /* do we need this really as a client ? - i = 1; - ERR_SI(setsockopt(conn->fd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int))); - */ /* allow quick port reuse */ ERR_SI(connect(tser->fd, (struct sockaddr *)&sadr, sizeof(sadr))); time(&t2); ecnt=0; @@ -121,6 +114,23 @@ SerChannel *SerOpen(const char *hostPort, int msecTmo, int (*idleHdl)(int,int)) return(NULL); } +int SerSetTmo(SerChannel *serch, int msecTmo) { + AsynSrvChan *aser; + TermSrvChan *tser; + int iret; + + if (serch->type==ASYNSRV_TYPE) { + aser=(AsynSrvChan *)serch; + iret=AsynSrv_Config(&aser->asyn_info, "msecTmo", msecTmo, NULL); + if (iret!=1) { SerA_error(); goto OnError; } + } else if (serch->type==TERMSRV_TYPE) { + tser=(TermSrvChan *)serch; + tser->tmo=msecTmo; + } + return 0; + OnError: return -1; +} + void SerClose(SerChannel *serch) { AsynSrvChan *aser; TermSrvChan *tser; diff --git a/tecs/tecs_serial.h b/tecs/tecs_serial.h index 75a8c1f0..661b0bf5 100644 --- a/tecs/tecs_serial.h +++ b/tecs/tecs_serial.h @@ -10,6 +10,7 @@ typedef struct { SerChannel *SerOpen(const char *host, int msecTmo, int (*idleHdl)(int,int)); char *SerCmd(SerChannel *ser, char *cmnd); +int SerSetTmo(SerChannel *ser, int msecTmo); SerChannel *SerCheck(SerChannel *ser); void SerClose(SerChannel *ser);