/***************************************************************************
* E.S.O. - VLT project - 1994
*
* waShowValue.c
*
* HISTORY
*
* who       when        what
* --------  ----------  ----------------------------------------------
* eallaert  1999-03-27  created (based on wsappShowValue.c)
*
*/
/***************************************************************************
*
*  NAME 
* 
*   waShowValue - continuously display a specific value from the DB
* 
* SYNOPSIS 
*
*   waShowValue  [<AttributePath>]
* 
*
* DESCRIPTION 
*
*   This program is part of the VLT Release 1 installation verification 
*   test.
*
*   The program reads a point attribute from the local environment and
*   diaplays it continuously.
*
*   Press 'q' to terminate display.
*
*   <AttributePath>   the full path of the atrribute to be displayed.
*                     Default: @PARAMS:SCALARS.scalar_int32
*
*   RETURN VALUES 
*   none              
*
*   ENVIRONMENT
*   RTAPENV   	READ    the WS local environment.
*
*   SEE ALSO
*   waSetValue, lcuappStoreData
*
*
*************************************************************************/
                 
#define _POSIX_SOURCE 1
#include <vltPort.h>

static char *rcsId="@(#) $Id: waShowValue.c,v 1.5 1997/10/17 14:02:01 vltsccm Exp $"; 
static void *use_rcsId = ((void)&use_rcsId,(void *) &rcsId);

/*
 * System Headers
 */
#include <signal.h>                  /* tty_*    */
#include <termios.h>                 /* tty_*    */
#include <time.h>                    /* strftime */

/* 
 * application headers
 */
#include "wa.h"

/*
 * Local Functions
 */

/*
 * These pieces have been taken from "Advanced Programming in the UNIX 
 * Environment"  by W. Richard Stevens
 * They set the terminal to non canonical mode and allow thus getchar to
 * return without a char if none currently in the buffer
 * The original term state is saved and restored with "tty_reset"
 *
 */
static int ttysavefd = -1;
static struct termios save_termios;

int tty_raw (int fd)
{
    struct termios buf;
    
    if(tcgetattr(fd,&save_termios) < 0)
       return(-1);
    buf = save_termios;
    buf.c_lflag &= ~(ECHO | ICANON | IEXTEN );
    buf.c_iflag &= ~(INPCK | ISTRIP | IXON | ICRNL );
    buf.c_cc[VMIN] = 0;
    buf.c_cc[VTIME] = 10;
    if(tcsetattr(fd, TCSAFLUSH, &buf) <0 )
       return(-1);
    ttysavefd = fd;
    return(0);
}


int tty_reset(int fd)
{
  if(tcsetattr(fd, TCSAFLUSH, &save_termios) < 0)
     return(-1);
  return(0);
}


/*
 * MAIN
 */
 
int main (int argc, char **argv)
{
/* 
 * some local declarations
 */ 
char	    	date[64];
dbTYPE          dataType[200];
dbSYMADDRESS    pointName;
vltINT32        actual;
dbITEM	    	attrNameP;
dbATTRTYPE      attrType;
vltUINT8        fieldCnt;
vltUINT16       recCnt;
vltUINT16	recsUsed;
vltUINT32	recSize;
char		pBuf[256];
char		outString[256];
dbDIRADDRESS	attr_dirAdd;
rtNumericDeType	readValue;
ccsPROCNAME     myProcess = "waShowValue";
char            halloMessage[80] = "WS application example - $Revision: 1.5 $";

/*
 * declarations for ccs in common s/w
 */
ccsENVNAME		envName;
ccsPROCNUM		procNum;
ccsPROCNAME		procName;
ccsERROR		error;
ccsTIMEVAL		timeStamp;
timsMODE		mode;
int		 	key;
time_t                  auxTime;

/*
 * say hello to the word
 */
printf("%s - %s \n", myProcess, halloMessage);            /* on the terminal */
logData (myProcess, WA_LOG_START, halloMessage);       /* on the log file */

/*
 * check input parameter
 */
if ( argc > 2) 
    {
    printf("\n\tusage: %s [<AttributePath>]\n\n", argv[0]);
    exit(1);
    }

if (argc == 2)
    {
    strcpy ((char *)pointName, argv[1]);
    }
else
    {
    strcpy ((char *)pointName, "PARAMS:SCALARS.scalar_int32");
    }
attrNameP = dbEMPTY;

/*
 * connect with the data base
 */
if (ccsInit (argv[0], 0, NULL, NULL, &error) == FAILURE)
    ABORT("ccsInit");

if (ccsGetMyProcId (envName, &procNum, procName, &error) == FAILURE)
    CLEAN("ccsGetMyProcId");

/*
 * Get Direct address as well as some more info on the point to be read
 */
if (dbGetDirAddr(pointName,attrNameP,&attr_dirAdd,&error) == FAILURE)
    CLEAN("dbGetDirAddr");
 
if (dbGetAttrInfo(pointName,attrNameP,&attrType,&fieldCnt,
                      &recCnt,&recSize,&recsUsed,
	 	      dataType,&error) == FAILURE)
    CLEAN("dbGetAttrInfo");

/*
 * start continuous display
 */
printf ("\n\n");
printf ("Display DataBase variable (press 'q' to quit).\n");
printf ("==============================================\n\n");
printf ("Reading from: @%s:%s\n\n\n", envName, pointName);
    	
/*
 * Display value until 'q' is pressed
 */
while (1)
    {
    /*
     * prepare the time to be displayed
     */
    if (timsGetUTC (&timeStamp, &mode, &error) == FAILURE)
        CLEAN("timsGetUTC");

    auxTime=timeStamp.tv_sec;

    strftime (date, 64, "%X", localtime ((const time_t *)&auxTime));

    /*
     * read the current value
     */
    if (dbReadDirect( &attr_dirAdd, dataType, pBuf, recSize, &actual, &recCnt,
                      &attrType, &error) == FAILURE)
        CLEAN("dbReadDirect");

    memcpy (&readValue, pBuf, rtDataElemSize[(rtInt)dataType[0]]);

    /*
     * format the value according to type
     */
    switch ((rtInt) dataType[0])
        {
        case dbUINT8:	sprintf (outString, "%12d", readValue.deUByte);  break;
	case dbINT8:	sprintf (outString, "%12d", readValue.deByte);   break;
	case dbUINT16:	sprintf (outString, "%12d", readValue.deUShort); break;
	case dbINT16:	sprintf (outString, "%12d", readValue.deShort);  break;
	case dbUINT32:	sprintf (outString, "%12d", readValue.deULong);  break;
	case dbINT32:   sprintf (outString, "%12d", readValue.deLong);   break;
	case dbFLOAT:	sprintf (outString, "%12f", readValue.deFloat);  break; 
	case dbDOUBLE:	sprintf (outString, "%12f", readValue.deDouble); break;
	default:        CLEAN("Undefined Data Type");
	}

    /*
     * display time and value 
     * (use carriage return to have a nicer display)
     */
    printf("     Time:  %s      Value:  %s",date,outString);
    printf("\r");

    /*
     * get possible input (q=exit)
     */
    tty_raw(STDIN_FILENO);
    key = getchar();
    tty_reset(STDIN_FILENO);        
    rtNap(100000);
    if (key == 'q')
        {
        break;             /* q=terminate*/
        }
    }  /* end while */

/*
 * normal termination: close environment and exit
 */
if (ccsExit(&error) != SUCCESS) 
    ABORT("ccsExit");

printf("\n\n %s terminated.\n\n", myProcess);         /* on the terminal */
logData (myProcess, WA_LOG_END, "terminated");     /* on the log file */
exit(EXIT_SUCCESS);


/*
 * error handlers
 */
clean:
    /*
     * try to close the connection
     */
    if (ccsExit (&error) == FAILURE)
        {
        printf("CLEAN: Unable to close db.\n"); 
        }

abort:
    /*
     * just exit with error code
     */
    exit(EXIT_FAILURE);

}  /* end of main */

/*___oOo___*/




