829 lines
23 KiB
C
829 lines
23 KiB
C
/*-------------------------------------------------------------------------
|
|
L T C 1 1
|
|
an environment control device driver for a Neocera LTC-11 temperature
|
|
controller.
|
|
|
|
copyright: see copyright.h
|
|
|
|
Mark Koennecke, November 1998
|
|
---------------------------------------------------------------------------*/
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <tcl.h>
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "obpar.h"
|
|
#include "evcontroller.h"
|
|
#include "evcontroller.i"
|
|
#include "evdriver.i"
|
|
#include "hardsup/serialsinq.h"
|
|
#include "hardsup/el734_errcodes.h"
|
|
#include "hardsup/el734fix.h"
|
|
#include "ltc11.h"
|
|
|
|
/*
|
|
#define debug 1
|
|
*/
|
|
/*-----------------------------------------------------------------------
|
|
The LTC11 Data Structure
|
|
*/
|
|
typedef struct {
|
|
void *pData;
|
|
char *pHost;
|
|
int iPort;
|
|
int iChannel;
|
|
int iMode;
|
|
int iSensor;
|
|
int iControlHeat;
|
|
int iControlAnalog;
|
|
int iLastError;
|
|
time_t lastRequest;
|
|
float fLast;
|
|
} LTC11Driv, *pLTC11Driv;
|
|
/*-----------------------------------------------------------------------
|
|
A couple of defines for LTC11 modes and special error conditions
|
|
*/
|
|
#define ANALOG 2
|
|
#define HEATER 1
|
|
#define MISERABLE 3
|
|
|
|
/* errors */
|
|
#define BADSTATE -920
|
|
#define NOCONN -921
|
|
#define BADANSWER -923
|
|
#define BADCONFIRM -924
|
|
/*-----------------------------------------------------------------------*/
|
|
static void LTC11Unlock(pLTC11Driv self)
|
|
{
|
|
SerialNoReply(&(self->pData),"SLLOCK 0;");
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
The LTC11 can either control a heater or an analog output. It is a common
|
|
task to figure out which mode is active. If the value returned from QOUT
|
|
is 3, no sensor is defined, if it is 6 it is in monitor mode, in both cases
|
|
control is NOT there.
|
|
*/
|
|
int LTC11GetMode(pEVDriver pEva, int *iMode)
|
|
{
|
|
pLTC11Driv self = NULL;
|
|
int iRet, iiMode;
|
|
char pBueffel[80];
|
|
|
|
self = (pLTC11Driv)pEva->pPrivate;
|
|
assert(self);
|
|
|
|
if(self->pData == NULL)
|
|
{
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
/* query the state, it can be in an invalid mode */
|
|
iRet = SerialWriteRead(&(self->pData),"QISTATE?;",pBueffel,79);
|
|
LTC11Unlock(self);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
if(strcmp(pBueffel,"?TMO") == 0)
|
|
{
|
|
self->iLastError = TIMEOUT;
|
|
return 0;
|
|
}
|
|
if(sscanf(pBueffel,"%d",&iiMode) != 1)
|
|
{
|
|
self->iLastError = EL734__BAD_ILLG;
|
|
return 0;
|
|
}
|
|
if( (iiMode != 1) && (iiMode != 2) )
|
|
{
|
|
self->iLastError = BADSTATE;
|
|
*iMode = MISERABLE;
|
|
return 0;
|
|
}
|
|
|
|
/* check the sensor in heater mode */
|
|
iRet = SerialWriteRead(&(self->pData),"QOUT?1;",pBueffel,79);
|
|
LTC11Unlock(self);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
if(strcmp(pBueffel,"?TMO") == 0)
|
|
{
|
|
self->iLastError = TIMEOUT;
|
|
return 0;
|
|
}
|
|
if(sscanf(pBueffel,"%d",&iiMode) != 1)
|
|
{
|
|
self->iLastError = EL734__BAD_ILLG;
|
|
return 0;
|
|
}
|
|
if( (iiMode != 3) && (iiMode != 6 ) )
|
|
{
|
|
*iMode = HEATER;
|
|
self->iControlHeat = iiMode;
|
|
return 1;
|
|
}
|
|
|
|
/* check the sensor in analog mode */
|
|
iRet = SerialWriteRead(&(self->pData),"QOUT?2;",pBueffel,79);
|
|
LTC11Unlock(self);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
if(strcmp(pBueffel,"?TMO") == 0)
|
|
{
|
|
self->iLastError = TIMEOUT;
|
|
return 0;
|
|
}
|
|
if(sscanf(pBueffel,"%d",&iiMode) != 1)
|
|
{
|
|
self->iLastError = EL734__BAD_ILLG;
|
|
return 0;
|
|
}
|
|
if( (iiMode != 3) && (iiMode != 6 ) )
|
|
{
|
|
*iMode = ANALOG;
|
|
self->iControlAnalog = iiMode;
|
|
return 1;
|
|
}
|
|
/* if we are here something is very bad */
|
|
self->iLastError = BADSTATE;
|
|
return 0;
|
|
}
|
|
/*-----------------------------------------------------------------------
|
|
iMode below 10 will be interpreted as heater control, above 10 as analog
|
|
control.
|
|
*/
|
|
int LTC11SetMode(pEVDriver pEva, int iMode)
|
|
{
|
|
pLTC11Driv self = NULL;
|
|
int iRet, iiMode;
|
|
char pBueffel[80], pCommand[20];
|
|
|
|
self = (pLTC11Driv)pEva->pPrivate;
|
|
assert(self);
|
|
|
|
if(self->pData == NULL)
|
|
{
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
if(iMode < 10) /* heater mode */
|
|
{
|
|
sprintf(pCommand,"SHCONT%1.1d;",iMode);
|
|
iRet = SerialNoReply(&(self->pData),pCommand);
|
|
LTC11Unlock(self);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
iMode -= 10;
|
|
sprintf(pCommand,"SACONT%1.1d;",iMode);
|
|
iRet = SerialNoReply(&(self->pData),pCommand);
|
|
LTC11Unlock(self);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
/* should not get here */
|
|
self->iLastError = BADSTATE;
|
|
return 0;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int LTC11Get(pEVDriver pEva, float *fValue)
|
|
{
|
|
pLTC11Driv self = NULL;
|
|
int iRet;
|
|
char pBueffel[80];
|
|
char pCommand[46];
|
|
char c;
|
|
float fVal;
|
|
|
|
self = (pLTC11Driv)pEva->pPrivate;
|
|
assert(self);
|
|
|
|
if(self->pData == NULL)
|
|
{
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
if(time(NULL) < self->lastRequest)
|
|
{
|
|
*fValue = self->fLast;
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
self->lastRequest = time(NULL) + 5; /* buffer 5 seconds */
|
|
}
|
|
sprintf(pCommand,"QSAMP?%1.1d;",self->iSensor);
|
|
iRet = SerialWriteRead(&(self->pData),pCommand,pBueffel,79);
|
|
LTC11Unlock(self);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
if(strcmp(pBueffel,"?TMO") == 0)
|
|
{
|
|
self->iLastError = TIMEOUT;
|
|
return 0;
|
|
}
|
|
iRet = sscanf(pBueffel,"%f%c",fValue,&c);
|
|
if(iRet != 2)
|
|
{
|
|
self->iLastError = BADANSWER;
|
|
return 0;
|
|
}
|
|
if( (c != 'K') && (c != 'C') && (c != 'F') && (c != 'N')
|
|
&& (c != 'V') && (c != 'O') )
|
|
{
|
|
self->iLastError = BADANSWER;
|
|
return 0;
|
|
}
|
|
self->fLast = *fValue;
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int LTC11Run(pEVDriver pEva, float fVal)
|
|
{
|
|
pLTC11Driv self = NULL;
|
|
int iRet, iMode;
|
|
char pBueffel[80];
|
|
char pCommand[40];
|
|
float fTest = 0.0, fDelta;
|
|
|
|
self = (pLTC11Driv)pEva->pPrivate;
|
|
assert(self);
|
|
|
|
if(self->pData == NULL)
|
|
{
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
/* find our operation mode */
|
|
iRet = LTC11GetMode(pEva,&iMode);
|
|
if( (iRet < 1) || (iMode == MISERABLE) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* format command */
|
|
sprintf(pCommand,"SETP %d,%f;",iMode, fVal);
|
|
|
|
/* send command */
|
|
iRet = SerialNoReply(&(self->pData),pCommand);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
LTC11Unlock(self);
|
|
return 0;
|
|
}
|
|
|
|
/* read back */
|
|
sprintf(pCommand,"QSETP?%d;", iMode);
|
|
iRet = SerialWriteRead(&(self->pData),pCommand,pBueffel,79);
|
|
LTC11Unlock(self);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
|
|
/* check confirmation */
|
|
if(strcmp(pBueffel,"?TMO") == 0)
|
|
{
|
|
self->iLastError = TIMEOUT;
|
|
return 0;
|
|
}
|
|
sscanf(pBueffel,"%f",&fTest);
|
|
fDelta = fVal - fTest;
|
|
if(fDelta < 0.0)
|
|
fDelta = -fDelta;
|
|
|
|
if(fDelta > 0.1)
|
|
{
|
|
self->iLastError = BADCONFIRM;
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int LTC11Error(pEVDriver pEva, int *iCode, char *pError,
|
|
int iErrLen)
|
|
{
|
|
pLTC11Driv self = NULL;
|
|
|
|
self = (pLTC11Driv)pEva->pPrivate;
|
|
assert(self);
|
|
|
|
*iCode = self->iLastError;
|
|
switch(*iCode)
|
|
{
|
|
case NOCONN:
|
|
strncpy(pError,"No Connection to Bruker Controller",iErrLen);
|
|
break;
|
|
case MISERABLE:
|
|
case BADSTATE:
|
|
strncpy(pError,"The LTC-11 is in a very bad state",iErrLen);
|
|
break;
|
|
case BADANSWER:
|
|
strncpy(pError,"The LTC-11 returned a bad reply",iErrLen);
|
|
break;
|
|
case BADCONFIRM:
|
|
strncpy(pError,"The LTC-11 did not accept the new set point",iErrLen);
|
|
break;
|
|
case TIMEOUT:
|
|
strncpy(pError,"Timeout receiving data from LTC-11",iErrLen);
|
|
break;
|
|
default:
|
|
SerialError(*iCode,pError,iErrLen);
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
static int LTC11Send(pEVDriver pEva, char *pCommand, char *pReply,
|
|
int iReplyLen)
|
|
{
|
|
pLTC11Driv self = NULL;
|
|
int iRet;
|
|
|
|
self = (pLTC11Driv)pEva->pPrivate;
|
|
assert(self);
|
|
|
|
if(self->pData == NULL)
|
|
{
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
|
|
iRet = SerialWriteRead(&(self->pData),pCommand, pReply, iReplyLen);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int LTC11Init(pEVDriver pEva)
|
|
{
|
|
pLTC11Driv self = NULL;
|
|
int iRet;
|
|
char pBueffel[80], pCommand[20];
|
|
|
|
self = (pLTC11Driv)pEva->pPrivate;
|
|
assert(self);
|
|
|
|
/* open port connection */
|
|
self->pData = NULL;
|
|
iRet = SerialOpen(&(self->pData),self->pHost, self->iPort, self->iChannel);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
/* configure serial port terminators */
|
|
SerialSendTerm(&(self->pData),";");
|
|
SerialATerm(&(self->pData),"1;");
|
|
SerialConfig(&(self->pData),30000);
|
|
|
|
self->iSensor = 1;
|
|
|
|
/* initialize control sensors to unknown, then call GetMode
|
|
to get real values
|
|
*/
|
|
self->iControlHeat = 6;
|
|
self->iControlAnalog = 6;
|
|
LTC11GetMode(pEva,&iRet);
|
|
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int LTC11Close(pEVDriver pEva)
|
|
{
|
|
pLTC11Driv self = NULL;
|
|
|
|
self = (pLTC11Driv)pEva->pPrivate;
|
|
assert(self);
|
|
|
|
SerialClose(&(self->pData));
|
|
self->pData = 0;
|
|
|
|
return 1;
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
static int LTC11Fix(pEVDriver self, int iError)
|
|
{
|
|
pLTC11Driv pMe = NULL;
|
|
int iRet;
|
|
char pCommand[20], pBueffel[80];
|
|
|
|
assert(self);
|
|
pMe = (pLTC11Driv )self->pPrivate;
|
|
assert(pMe);
|
|
|
|
switch(iError)
|
|
{
|
|
/* network errors */
|
|
case EL734__BAD_FLUSH:
|
|
case EL734__BAD_RECV:
|
|
case EL734__BAD_RECV_NET:
|
|
case EL734__BAD_RECV_UNKN:
|
|
case EL734__BAD_RECVLEN:
|
|
case EL734__BAD_RECV1:
|
|
case EL734__BAD_RECV1_PIPE:
|
|
case EL734__BAD_RNG:
|
|
case EL734__BAD_SEND:
|
|
case EL734__BAD_SEND_PIPE:
|
|
case EL734__BAD_SEND_NET:
|
|
case EL734__BAD_SEND_UNKN:
|
|
case EL734__BAD_SENDLEN:
|
|
LTC11Close(self);
|
|
iRet = LTC11Init(self);
|
|
if(iRet)
|
|
{
|
|
return DEVREDO;
|
|
}
|
|
else
|
|
{
|
|
return DEVFAULT;
|
|
}
|
|
break;
|
|
case EL734__FORCED_CLOSED:
|
|
case NOCONN:
|
|
iRet = LTC11Init(self);
|
|
if(iRet)
|
|
{
|
|
return DEVREDO;
|
|
}
|
|
else
|
|
{
|
|
return DEVFAULT;
|
|
}
|
|
break;
|
|
/* fixable LTC11 Errors */
|
|
case MISERABLE:
|
|
case BADSTATE:
|
|
iRet = SerialNoReply(&(pMe->pData),"SCONT;");
|
|
LTC11Unlock(pMe);
|
|
return DEVREDO;
|
|
break;
|
|
case BADANSWER:
|
|
case BADCONFIRM:
|
|
case TIMEOUT:
|
|
return DEVREDO;
|
|
break;
|
|
default:
|
|
return DEVFAULT;
|
|
break;
|
|
}
|
|
return DEVFAULT;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
void KillLTC11(void *pData)
|
|
{
|
|
pLTC11Driv pMe = NULL;
|
|
|
|
pMe = (pLTC11Driv)pData;
|
|
assert(pMe);
|
|
|
|
if(pMe->pHost)
|
|
{
|
|
free(pMe->pHost);
|
|
}
|
|
free(pMe);
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
pEVDriver CreateLTC11Driver(int argc, char *argv[])
|
|
{
|
|
pEVDriver pNew = NULL;
|
|
pLTC11Driv pSim = NULL;
|
|
|
|
/* check for arguments */
|
|
if(argc < 3)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pNew = CreateEVDriver(argc,argv);
|
|
pSim = (pLTC11Driv)malloc(sizeof(LTC11Driv));
|
|
memset(pSim,0,sizeof(LTC11Driv));
|
|
if(!pNew || !pSim)
|
|
{
|
|
return NULL;
|
|
}
|
|
pNew->pPrivate = pSim;
|
|
pNew->KillPrivate = KillLTC11;
|
|
|
|
/* initalise LTC11Driver */
|
|
pSim->iLastError = 0;
|
|
pSim->pHost = strdup(argv[0]);
|
|
pSim->iPort = atoi(argv[1]);
|
|
pSim->iChannel = atoi(argv[2]);
|
|
|
|
|
|
/* initialise function pointers */
|
|
pNew->SetValue = LTC11Run;
|
|
pNew->GetValue = LTC11Get;
|
|
pNew->Send = LTC11Send;
|
|
pNew->GetError = LTC11Error;
|
|
pNew->TryFixIt = LTC11Fix;
|
|
pNew->Init = LTC11Init;
|
|
pNew->Close = LTC11Close;
|
|
|
|
return pNew;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int LTC11AssignControl(pEVDriver pEva, int iMode, int iSensor)
|
|
{
|
|
pLTC11Driv self = NULL;
|
|
int iRet, iRead = 0;
|
|
char pBueffel[80], pCommand[50];
|
|
|
|
self = (pLTC11Driv)pEva->pPrivate;
|
|
assert(self);
|
|
assert( (iMode == HEATER) || (iMode == ANALOG) );
|
|
|
|
if(!self->pData)
|
|
{
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
sprintf(pCommand,"SOSEN %d,%d;",iMode,iSensor);
|
|
iRet = SerialNoReply(&(self->pData),pCommand);
|
|
if(iRet != 1)
|
|
{
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
sprintf(pCommand,"QOUT?%d;",iMode);
|
|
iRet = SerialWriteRead(&(self->pData),pCommand,pBueffel,79);
|
|
LTC11Unlock(self);
|
|
if(strcmp(pBueffel,"?TMO") == 0)
|
|
{
|
|
self->iLastError = TIMEOUT;
|
|
return 0;
|
|
}
|
|
sscanf(pBueffel,"%d;",&iRead);
|
|
if(iRead != iSensor)
|
|
{
|
|
self->iLastError = BADCONFIRM;
|
|
return 0;
|
|
}
|
|
if(iMode == ANALOG)
|
|
{
|
|
self->iControlAnalog = iSensor;
|
|
}
|
|
else
|
|
{
|
|
self->iControlHeat = iSensor;
|
|
}
|
|
/* switch back to control mode */
|
|
SerialNoReply(&(self->pData),"SCONT;");
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------
|
|
handle LTC11 specific commands:
|
|
- sensor requests or sets read sensor
|
|
- mode requests or sets operation mode
|
|
- controlheat requests or sets sensor for heater control
|
|
- controlanalog requests or sets sensor for analog control
|
|
in all other cases fall back and call EVControllerWrapper to handle it or
|
|
eventually throw an error.
|
|
*/
|
|
int LTC11Action(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
|
|
pEVControl self = NULL;
|
|
int iRet, iMode;
|
|
char pBueffel[256], pError[132];
|
|
pLTC11Driv pMe = NULL;
|
|
float fVal;
|
|
|
|
self = (pEVControl)pData;
|
|
assert(self);
|
|
pMe = (pLTC11Driv)self->pDriv->pPrivate;
|
|
assert(pMe);
|
|
|
|
if(argc > 1)
|
|
{
|
|
strtolower(argv[1]);
|
|
/*------ sensor */
|
|
if(strcmp(argv[1],"sensor") == 0)
|
|
{
|
|
if(argc > 2) /* set case */
|
|
{
|
|
/* check permission */
|
|
if(!SCMatchRights(pCon,usUser))
|
|
{
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iMode);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: needed integer, got %s",
|
|
argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
pMe->iSensor = iMode;
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
else /* get case */
|
|
{
|
|
sprintf(pBueffel,"%s.sensor = %d", argv[0],pMe->iSensor);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
/*------ controlanalog */
|
|
if(strcmp(argv[1],"controlanalog") == 0)
|
|
{
|
|
if(argc > 2) /* set case */
|
|
{
|
|
/* check permission */
|
|
if(!SCMatchRights(pCon,usUser))
|
|
{
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iMode);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: needed integer, got %s",
|
|
argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = LTC11AssignControl(self->pDriv,ANALOG,iMode);
|
|
if(iRet != 1)
|
|
{
|
|
self->pDriv->GetError(self->pDriv,&iMode,pError,131);
|
|
sprintf(pBueffel,"ERROR: failed to set sensor: %s",pError);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
else /* get case */
|
|
{
|
|
sprintf(pBueffel,"%s.controlanalog = %d", argv[0],pMe->iControlAnalog);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
/*------ controlheat */
|
|
if(strcmp(argv[1],"controlheat") == 0)
|
|
{
|
|
if(argc > 2) /* set case */
|
|
{
|
|
/* check permission */
|
|
if(!SCMatchRights(pCon,usUser))
|
|
{
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iMode);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: needed integer, got %s",
|
|
argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = LTC11AssignControl(self->pDriv,HEATER,iMode);
|
|
if(iRet != 1)
|
|
{
|
|
self->pDriv->GetError(self->pDriv,&iMode,pError,131);
|
|
sprintf(pBueffel,"ERROR: failed to set sensor: %s",pError);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
else /* get case */
|
|
{
|
|
sprintf(pBueffel,"%s.controlheat = %d", argv[0],pMe->iControlHeat);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
/*-------- mode */
|
|
else if(strcmp(argv[1],"mode") == 0)
|
|
{
|
|
if(argc > 2) /* set case */
|
|
{
|
|
/* check permission */
|
|
if(!SCMatchRights(pCon,usUser))
|
|
{
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iMode);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: needed integer, got %s",
|
|
argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = LTC11SetMode(self->pDriv,iMode);
|
|
if(iRet != 1)
|
|
{
|
|
self->pDriv->GetError(self->pDriv,&iMode,pError,131);
|
|
sprintf(pBueffel,"ERROR: failed to set mode %s",pError);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
}
|
|
else /* get case */
|
|
{
|
|
iRet = LTC11GetMode(self->pDriv,&iMode);
|
|
if(iRet != 1)
|
|
{
|
|
self->pDriv->GetError(self->pDriv,&iMode,pError,131);
|
|
sprintf(pBueffel,"ERROR: failed to get mode %s",pError);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
if(iMode == ANALOG)
|
|
{
|
|
sprintf(pBueffel,"%s.mode = Analog Control", argv[0]);
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"%s.mode = Heater Control", argv[0]);
|
|
}
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
/*--------- list */
|
|
else if(strcmp(argv[1],"list") == 0)
|
|
{
|
|
/* print generals first */
|
|
EVControlWrapper(pCon,pSics,pData,argc,argv);
|
|
/* print our add on stuff */
|
|
sprintf(pBueffel,"%s.sensor = %d",argv[0],pMe->iSensor);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
sprintf(pBueffel,"%s.controlanalog = %d",argv[0],pMe->iControlAnalog);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
sprintf(pBueffel,"%s.controlheat = %d",argv[0],pMe->iControlHeat);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
iRet = LTC11GetMode(self->pDriv,&iMode);
|
|
if(iRet != 1)
|
|
{
|
|
self->pDriv->GetError(self->pDriv,&iMode,pError,131);
|
|
sprintf(pBueffel,"ERROR: failed to get mode %s",pError);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
}
|
|
if(iMode == ANALOG)
|
|
{
|
|
sprintf(pBueffel,"%s.mode = Analog Control", argv[0]);
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"%s.mode = Heater Control", argv[0]);
|
|
}
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return EVControlWrapper(pCon,pSics,pData,argc,argv);
|
|
}
|
|
}
|
|
return EVControlWrapper(pCon,pSics,pData,argc,argv);
|
|
}
|