751 lines
19 KiB
C
751 lines
19 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:
|
|
strlcpy(pError, "No Connection to Bruker Controller", iErrLen);
|
|
break;
|
|
case MISERABLE:
|
|
case BADSTATE:
|
|
strlcpy(pError, "The LTC-11 is in a very bad state", iErrLen);
|
|
break;
|
|
case BADANSWER:
|
|
strlcpy(pError, "The LTC-11 returned a bad reply", iErrLen);
|
|
break;
|
|
case BADCONFIRM:
|
|
strlcpy(pError, "The LTC-11 did not accept the new set point",
|
|
iErrLen);
|
|
break;
|
|
case TIMEOUT:
|
|
strlcpy(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);
|
|
}
|