 1Content-type: application/x-Unknown; charset=UTF8package nmc.sidekick;

import javax.comm.SerialPort;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.lang.Exception;

import nmc.common.*;

//(klh)
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Date;

// The emeter driver belongs to a class of drivers
// that handle synchronously streaming data. The GPS
// is another such driver.
// The strategy for collecting a sample from synchronously
// streaming instruments is to open the stream, wait for 
// (syncronize to) the end of a record, then read up to the
// next delimiter; it is a passive process.
// 
// The emeter outputs a string (<100 bytes) once per second.
// The string is terminated with CRLF.
//
// The emeter is the simplest case of such an instrument, 
// because it only puts out a single kind of record, and it
// requires no parsing of the record; it just dips into
// the stream to catch one record, and it's done.
// In contrast, the GPS potentially puts out several types
// of records, so the driver must parse the record to make
// sure it is the correct type. Furthermore, the GPS driver
// may have to do additional parsing and processing to find
// whether or not the record is valid, to perform averaging,
// etc.

public class eMeter extends StdInstrumentSensorDriver {
    eMeter ( ) {

        _name     = "TheEMeterDriverRev2.0";
        
   	  // None of these are needed for eMeter...
   	  // we will use prompt as the record delimiter
        //_enter              = "none"  .getBytes();
        _prompt             = "\r\n"  .getBytes();
        //_sampleRequest      = "none"  .getBytes();
        //_sampleRequestEcho  = "none"  .getBytes();
        //_cfgEol             = "none"  .getBytes();

        _timeout          = 10000;
        _maxTries         = 3;
        _maxAttnBytes     = 250;
        _maxSampleBytes   = 200;
        _initMaxTries     = 3;
        _maxSkipBytes     = 200;
        _cfgBufSize       = 200;
        _currentLimit	  = 1000;
       _callCount = 0;
       _powerPolicy=POWER_NEVER;
       
    }// end emeter()

    public void initialize(){
    	// This should put it into lowest power state according
    	// to the powerPolicy set in the ctor
	super.initialize();
	if(_dpaChannel != null){
	   DebugMessage.println("Instrument specific initialization for  "+_name);
	   DebugMessage.println("Setting current limit = "+_currentLimit);
	   _dpaChannel.setCurrentLimit(_currentLimit);
		
	   // this should now be set in super.initialize based on powerPolicy	
	   //DebugMessage.println("Switching Instrument power OFF");
	   //_dpaChannel.channelCtrlReg.setInstrumentPowerOff();//set off, do in drvr	
	   //DebugMessage.println("Switching comms power OFF");
	   //_dpaChannel.channelCtrlReg.setCommPowerOff();//set off, turn on in drvr
	   //_dpaChannel.channelCtrlReg.write();
	   	   
	}else{
	   DebugMessage.println("Driver: "+ _name+" initialize(): DPA channel is NULL");	
	}
	DebugMessage.println("Done with initialization");

    }// end initialize()

    /** Read a data sample from device communications interface. */
    //public TimestampedData poll() throws Exception {
    public void poll(PollCmd m) throws Exception{
        int tries = 0;
        TimestampedData retVal;

       // turn on communications power
       managePowerWake();

        while (tries < _maxTries) {
            tries++;
            try {
                byte[] theSample = getEMeterSample();
                TimestampedData retval = new TimestampedData(theSample);
	        // Now we put the message into an outbound MessageQ, 
	        // instead of returning the TimestampedData.
	        // We may need some Message packetizing here...
                
                PolledDataReply pdr = new PolledDataReply(m,retval);
                _outbound.put(pdr);

               // turn off communications power
               managePowerSleep();

                return;

            } catch (TimeoutException e) {
                DebugMessage.println("Driver: '"
                                   + _name
                                   + "' got timeout");
            } // other Exceptions fly past into the caller
        }
        // turn off communications power
        managePowerSleep();
        
       // throw new Exception("Retry limit exceeded (retries=" + tries + ")");
        DebugMessage.println(_name+": Retry limit exceeded (retries=" + tries + ")");
        byte[] retryMsg=(_name+": Retry limit exceeded (retries=" + tries + ")").getBytes();
        TimestampedData retryOut=new TimestampedData(retryMsg);
        PolledDataReply edr = new PolledDataReply(m,retryOut);
        _outbound.put(edr);
    }//end poll()

    private byte[] getEMeterSample() throws Exception {
/*
      DebugMessage.println("Bypassing actual instrument code...");
      byte[] sampleBuf = new byte[_maxSampleBytes];
      sampleBuf=(new String(("This is some fake Emeter data; callCount ="+(_callCount++)))).getBytes();
      int bytesCaptured =sampleBuf.length;
     DebugMessage.println("The data is "+sampleBuf+" len="+bytesCaptured);

      // copy the sample into the exactly-right-sized byte array
      byte[] retval = new byte[bytesCaptured];
      for (int i = 0; i < bytesCaptured; i++) {
          retval[i] = sampleBuf[i];
       }
	
       DebugMessage.println(_name+" Returning...");
       return retval;
       */
	
	// This is test code for flash boot debugging
	//boolean z=true;
	//DebugMessage.println("Be sure to remove this from Emeter");
	//while(z==true){
            //   write(_output, "Using the Emeter to say Hello...\n".getBytes());
            //   Instantiator.delay(1000);
            //   //Instantiator.flashGreenLed();	
	//}
            

	// Synchronize to record end...
	// Note: uses prompt as record terminator
	DebugMessage.println("Synchronizing...");
	flushInput();
	skipUntil( _input,_prompt);

	// Get data sample
	DebugMessage.println("Collecting Sample...");
      byte[] sampleBuf = new byte[_maxSampleBytes];
      int bytesCaptured = readUntil( _input, sampleBuf, _prompt );

	// Do any data processing here...
        if(bytesCaptured <=0){
           byte[] noData="bytesCaptured<=0".getBytes();
           DebugMessage.println(_name+" done..."+noData);
           return noData;
        }

      // copy the sample into the exactly-right-sized byte array
      byte[] retval = new byte[bytesCaptured];
      for (int i = 0; i < bytesCaptured; i++) {
          retval[i] = sampleBuf[i];
       }
	
	DebugMessage.println(_name+" Returning...");
      
      return retval;
      
    }//end getEMeterSample()

    //public TimestampedData configure(byte[] cfgData) throws Exception {
    public void configure(ConfigurationCmd m) throws Exception{
        DebugMessage.println("We are in the driver \""
                           + _name
                           + "\" with configuration data="
                           + new String(m.data));
	  // The EMeter has no configuration and does not return
	  // and status/meta data...
        byte[] result = "EMeter has no configurable options".getBytes();
        TimestampedData retval = new TimestampedData( result );

         // Now we put the message into an outbound MessageQ, 
         // instead of returning the TimestampedData.
         // We may need some Message packetizing here...   
         ConfigurationReply cr=new ConfigurationReply(m,retval);
        _outbound.put(cr);
      
         return;
    }


}// end class eMeter
