/*----- PROTECTED REGION ID(Mks651d.cpp) ENABLED START -----*/
static const char *RcsId = "$Id: Mks651d.cpp,v 1.2 2012-03-08 09:50:01 mdm Exp $";
//=============================================================================
//
// file :        Mks651d.cpp
//
// description : C++ source for the Mks651d and its commands.
//               The class is derived from Device. It represents the
//               CORBA servant object which will be accessed from the
//               network. All commands which can be executed on the
//               Mks651d are implemented in this file.
//
// project :     Mks651d.
//
// $Author: mdm $
//
// $Revision: 1.2 $
// $Date: 2012-03-08 09:50:01 $
//
// SVN only:
// $HeadURL:  $
//
// CVS only:
// $Source: /home/cvsadm/cvsroot/fermi/servers/651d/src/Mks651d.cpp,v $
// $Log: Mks651d.cpp,v $
// Revision 1.2  2012-03-08 09:50:01  mdm
// New version of server
//
//
//=============================================================================
//                This file is generated by POGO
//        (Program Obviously used to Generate tango Object)
//=============================================================================


#include <Mks651d.h>
#include <Mks651dClass.h>
#include "ThreadGuard.h"

/*----- PROTECTED REGION END -----*/


/**
 *	Mks651d class description:
 *	
 */

//================================================================
//
//  The following table gives the correspondence
//  between command and method names.
//
//  Command name    |  Method name
//----------------------------------------------------------------
//  State           |  Inherited (no method)
//  Status          |  Inherited (no method)
//  Open            |  open
//  Close           |  close
//  Stop            |  stop
//  SelectSP        |  select_sp
//  ReadSPLevel     |  read_splevel
//  WriteSPLevel    |  write_splevel
//  ReadSPType      |  read_sptype
//  WriteSPType     |  write_sptype
//  ReadSoftStart   |  read_soft_start
//  WriteSoftStart  |  write_soft_start
//  ReadSPGain      |  read_spgain
//  WriteSPGain     |  write_spgain
//  ReadSPLead      |  read_splead
//  WriteSPLead     |  write_splead
//  ReadThreshold   |  read_threshold
//  WriteThreshold  |  write_threshold
//  StartLearning   |  start_learning
//  StopLearning    |  stop_learning
//  LearnAnalog     |  learn_analog
//  CalibrateAdc    |  calibrate_adc
//  ZeroSensor      |  zero_sensor
//  RemoveZero      |  remove_zero
//  SetZero         |  set_zero
//  LearnZero       |  learn_zero
//  DirectCommand   |  direct_command
//================================================================

namespace Mks651d_ns
{
	/*----- PROTECTED REGION ID(Mks651d::namespace_starting) ENABLED START -----*/

	//	static initializations

	/*----- PROTECTED REGION END -----*/	//	Mks651d::namespace_starting



//--------------------------------------------------------
/**
 *	Method      : Mks651d::Mks651d()
 *	Description : Constructors for a Tango device
 *	              implementing the class Mks651d
 */
//--------------------------------------------------------
Mks651d::Mks651d(Tango::DeviceClass *cl, string &s)
 	: Tango::Device_4Impl(cl, s.c_str())
{
	/*----- PROTECTED REGION ID(Mks651d::constructor_1) ENABLED START -----*/

	init_device();

	/*----- PROTECTED REGION END -----*/	//	Mks651d::constructor_1
}
//--------------------------------------------------------
Mks651d::Mks651d(Tango::DeviceClass *cl, const char *s)
 	: Tango::Device_4Impl(cl, s)
{
	/*----- PROTECTED REGION ID(Mks651d::constructor_2) ENABLED START -----*/

	init_device();

	/*----- PROTECTED REGION END -----*/	//	Mks651d::constructor_2
}
//--------------------------------------------------------
Mks651d::Mks651d(Tango::DeviceClass *cl, const char *s, const char *d)
 	: Tango::Device_4Impl(cl, s, d)
{
	/*----- PROTECTED REGION ID(Mks651d::constructor_3) ENABLED START -----*/

	init_device();

	/*----- PROTECTED REGION END -----*/	//	Mks651d::constructor_3
}


//--------------------------------------------------------
/**
 *	Method      : Mks651d::delete_device()()
 *	Description : will be called at device destruction or at init command
 */
//--------------------------------------------------------
void Mks651d::delete_device()
{
	/*----- PROTECTED REGION ID(Mks651d::delete_device) ENABLED START -----*/

	if(device_proxy)
	{
		delete device_proxy;
		device_proxy = 0;
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::delete_device
	delete[] attr_Pressure_read;
	delete[] attr_Position_read;
	delete[] attr_ControlType_read;
	delete[] attr_SensorType_read;
	delete[] attr_SensorVoltage_read;
	delete[] attr_SensorRange_read;
	delete[] attr_ControlMode_read;
	delete[] attr_ValveType_read;
	delete[] attr_AnalogSPRange_read;
	delete[] attr_SelectedSP_read;
	delete[] attr_PowerFailResponse_read;
	
}


//--------------------------------------------------------
/**
 *	Method      : Mks651d::init_device()
 *	Description : //	will be called at device initialization.
 */
//--------------------------------------------------------
void Mks651d::init_device()
{
	DEBUG_STREAM << "Mks651d::init_device() create device " << device_name << endl;

	/*----- PROTECTED REGION ID(Mks651d::init_device_before) ENABLED START -----*/

	set_state(Tango::INIT);
	set_status("Initializing device");

	device_proxy = 0;

	init_completed = false;

	/*----- PROTECTED REGION END -----*/	//	Mks651d::init_device_before
	
	//	Get the device properties (if any) from database
	get_device_property();
	
	attr_Pressure_read = new Tango::DevDouble[1];
	attr_Position_read = new Tango::DevDouble[1];
	attr_ControlType_read = new Tango::DevShort[1];
	attr_SensorType_read = new Tango::DevShort[1];
	attr_SensorVoltage_read = new Tango::DevShort[1];
	attr_SensorRange_read = new Tango::DevShort[1];
	attr_ControlMode_read = new Tango::DevShort[1];
	attr_ValveType_read = new Tango::DevShort[1];
	attr_AnalogSPRange_read = new Tango::DevShort[1];
	attr_SelectedSP_read = new Tango::DevShort[1];
	attr_PowerFailResponse_read = new Tango::DevShort[1];
	
	/*----- PROTECTED REGION ID(Mks651d::init_device) ENABLED START -----*/

	if(get_state() != Tango::FAULT)
	{
		try
		{
			device_proxy = new Tango::DeviceProxy(serialDevice);
			device_proxy->set_timeout_millis(timeout);

			init_completed = true;
		}
		catch(Tango::DevFailed& ex)
		{
			exception_handler(ex, Tango::FAULT, "init_device");
		}
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::init_device
}



//--------------------------------------------------------
/**
 *	Method      : Mks651d::get_device_property()
 *	Description : //	Add your own code to initialize
 */
//--------------------------------------------------------
void Mks651d::get_device_property()
{
	/*----- PROTECTED REGION ID(Mks651d::get_device_property_before) ENABLED START -----*/

	//	Initialize property data members

	/*----- PROTECTED REGION END -----*/	//	Mks651d::get_device_property_before


	//	Read device properties from database.
	Tango::DbData	dev_prop;
	dev_prop.push_back(Tango::DbDatum("SerialDevice"));
	dev_prop.push_back(Tango::DbDatum("Timeout"));
	dev_prop.push_back(Tango::DbDatum("MaxBackOff"));
	dev_prop.push_back(Tango::DbDatum("ShowPressure"));

	//	is there at least one property to be read ?
	if (dev_prop.size()>0)
	{
		//	Call database and extract values
		if (Tango::Util::instance()->_UseDb==true)
			get_db_device()->get_property(dev_prop);
	
		//	get instance on Mks651dClass to get class property
		Tango::DbDatum	def_prop, cl_prop;
		Mks651dClass	*ds_class =
			(static_cast<Mks651dClass *>(get_device_class()));
		int	i = -1;

		//	Try to initialize SerialDevice from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  serialDevice;
		else {
			//	Try to initialize SerialDevice from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  serialDevice;
		}
		//	And try to extract SerialDevice value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  serialDevice;

		//	Try to initialize Timeout from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  timeout;
		else {
			//	Try to initialize Timeout from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  timeout;
		}
		//	And try to extract Timeout value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  timeout;

		//	Try to initialize MaxBackOff from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  maxBackOff;
		else {
			//	Try to initialize MaxBackOff from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  maxBackOff;
		}
		//	And try to extract MaxBackOff value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  maxBackOff;

		//	Try to initialize ShowPressure from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  showPressure;
		else {
			//	Try to initialize ShowPressure from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  showPressure;
		}
		//	And try to extract ShowPressure value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  showPressure;


	}
	/*----- PROTECTED REGION ID(Mks651d::get_device_property_after) ENABLED START -----*/

	if (dev_prop[0].is_empty())
	{
		set_state(Tango::FAULT);
		set_status("SerialDevice property not defined");
		return;
	}

	if(serialDevice.empty() || serialDevice.compare("undefined")==0)
	{
		set_state(Tango::FAULT);
		set_status("SerialDevice property is empty");
		return;
	}

	if (dev_prop[1].is_empty())
	{
		WARN_STREAM << "Timeout property not defined, default: " << timeout << endl;
	}

	if(timeout < 1 || timeout > 10000)
	{
		set_state(Tango::FAULT);
		set_status("Timeout invalid value [valid: 1-10000]");
		return;
	}

	if (dev_prop[2].is_empty())
	{
		WARN_STREAM << "MaxBackOff property not defined, default: " << maxBackOff << endl;
	}

	if(maxBackOff < 1 || maxBackOff > 1000)
	{
		set_state(Tango::FAULT);
		set_status("MaxBackOff invalid value [valid: 1-1000]");
		return;
	}

	if (dev_prop[3].is_empty())
	{
		WARN_STREAM << "ShowPressure property not defined, default: " << showPressure << endl;
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::get_device_property_after

}

//--------------------------------------------------------
/**
 *	Method      : Mks651d::always_executed_hook()
 *	Description : method always executed before any command is executed
 */
//--------------------------------------------------------
void Mks651d::always_executed_hook()
{
	INFO_STREAM << "Mks651d::always_executed_hook()  " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::always_executed_hook) ENABLED START -----*/

	if(update_state_allowed())
	{
		update_state();
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::always_executed_hook
}



//--------------------------------------------------------
/**
 *	Method      : Mks651d::read_attr_hardware()
 *	Description : Hardware acquisition for attributes.
 */
//--------------------------------------------------------
void Mks651d::read_attr_hardware(vector<long> &attr_list)
{
	DEBUG_STREAM << "Mks651d::read_attr_hardware(vector<long> &attr_list) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_attr_hardware) ENABLED START -----*/

	//	Add your own code

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_attr_hardware

}


//--------------------------------------------------------
/**
 *	Read Pressure attribute
 *	Description: 
 *
 *	Data type:	Tango::DevDouble
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_Pressure(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_Pressure(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_Pressure) ENABLED START -----*/

	if(showPressure)
	{
		string result = serial_in_out("R5", false);

		strip_first(result, 'P', 1);

		*attr_Pressure_read = strtod(result.c_str(), NULL);
		attr.set_value(attr_Pressure_read);
	}
	else
	{
		attr.set_quality(Tango::ATTR_INVALID, false);
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_Pressure
}
//--------------------------------------------------------
/**
 *	Read Position attribute
 *	Description: 
 *
 *	Data type:	Tango::DevDouble
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_Position(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_Position(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_Position) ENABLED START -----*/

	attr.set_value(attr_Position_read);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_Position
}
//--------------------------------------------------------
/**
 *	Read ControlType attribute
 *	Description: Control type
 *	             0 = self tuning
 *	             1 = PID
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_ControlType(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_ControlType(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_ControlType) ENABLED START -----*/

	string result = serial_in_out("R51", false);

	strip_first(result, 'V', 1);

	*attr_ControlType_read = atoi(result.c_str());
	attr.set_value(attr_ControlType_read);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_ControlType
}

//--------------------------------------------------------
/**
 *	Write ControlType attribute values to hardware.
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::write_ControlType(Tango::WAttribute &attr)
{
	DEBUG_STREAM << "Mks651d::write_ControlType(Tango::Attribute &attr) entering... " << endl;
	
	//	Retrieve write value
	Tango::DevShort	w_val;
	attr.get_write_value(w_val);
	
	/*----- PROTECTED REGION ID(Mks651d::write_ControlType) ENABLED START -----*/

	switch(w_val)
	{
	case 0:
		serial_in_out("V0", true);
		break;
	case 1:
		serial_in_out("V1", true);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 0-1", "write_ControlType");
		break;
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_ControlType
}

//--------------------------------------------------------
/**
 *	Read SensorType attribute
 *	Description: Sensor type
 *	             0 = Absolute
 *	             1 = Differential
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_SensorType(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_SensorType(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_SensorType) ENABLED START -----*/

	string result = serial_in_out("R36", false);

	strip_first(result, 'U', 1);

	*attr_SensorType_read = atoi(result.c_str());
	attr.set_value(attr_SensorType_read);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_SensorType
}

//--------------------------------------------------------
/**
 *	Write SensorType attribute values to hardware.
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::write_SensorType(Tango::WAttribute &attr)
{
	DEBUG_STREAM << "Mks651d::write_SensorType(Tango::Attribute &attr) entering... " << endl;
	
	//	Retrieve write value
	Tango::DevShort	w_val;
	attr.get_write_value(w_val);
	
	/*----- PROTECTED REGION ID(Mks651d::write_SensorType) ENABLED START -----*/

	switch(w_val)
	{
	case 0:
		serial_in_out("U0", true);
		break;
	case 1:
		serial_in_out("U1", true);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 0-1", "write_SensorType");
		break;
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_SensorType
}

//--------------------------------------------------------
/**
 *	Read SensorVoltage attribute
 *	Description: Sensor voltage range:
 *	             0 = 1 Volt
 *	             1 = 5 Volts
 *	             2 = 10 Volts
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_SensorVoltage(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_SensorVoltage(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_SensorVoltage) ENABLED START -----*/

	string result = serial_in_out("R35", false);

	strip_first(result, 'G', 1);

	*attr_SensorVoltage_read = atoi(result.c_str());
	attr.set_value(attr_SensorVoltage_read);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_SensorVoltage
}

//--------------------------------------------------------
/**
 *	Write SensorVoltage attribute values to hardware.
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::write_SensorVoltage(Tango::WAttribute &attr)
{
	DEBUG_STREAM << "Mks651d::write_SensorVoltage(Tango::Attribute &attr) entering... " << endl;
	
	//	Retrieve write value
	Tango::DevShort	w_val;
	attr.get_write_value(w_val);
	
	/*----- PROTECTED REGION ID(Mks651d::write_SensorVoltage) ENABLED START -----*/

	switch(w_val)
	{
	case 0:
		serial_in_out("G0", true);
		break;
	case 1:
		serial_in_out("G1", true);
		break;
	case 2:
		serial_in_out("G2", true);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 0-2", "write_SensorVoltage");
		break;
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_SensorVoltage
}

//--------------------------------------------------------
/**
 *	Read SensorRange attribute
 *	Description: Sensor range:
 *	             00 = 0.1
 *	             01 = 0.2
 *	             02 = 0.5
 *	             03 = 1
 *	             04 = 2
 *	             05 = 5
 *	             06 = 10
 *	             07 = 50
 *	             08 = 100
 *	             09 = 500
 *	             10 = 1000
 *	             11 = 5000
 *	             12 = 10000
 *	             13 = 1.3
 *	             14 = 2.66
 *	             15 = 13.33
 *	             16 = 133.3
 *	             17 = 1333
 *	             18 = 6666
 *	             19 = 13332
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_SensorRange(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_SensorRange(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_SensorRange) ENABLED START -----*/

	string result = serial_in_out("R33", false);

	strip_first(result, 'E', 1);

	*attr_SensorRange_read = atoi(result.c_str());
	attr.set_value(attr_SensorRange_read);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_SensorRange
}

//--------------------------------------------------------
/**
 *	Write SensorRange attribute values to hardware.
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::write_SensorRange(Tango::WAttribute &attr)
{
	DEBUG_STREAM << "Mks651d::write_SensorRange(Tango::Attribute &attr) entering... " << endl;
	
	//	Retrieve write value
	Tango::DevShort	w_val;
	attr.get_write_value(w_val);
	
	/*----- PROTECTED REGION ID(Mks651d::write_SensorRange) ENABLED START -----*/

	stringstream command;

	if(w_val >= 0 || w_val <= 9)
	{
		command << "E0" << w_val;
	}
	else if(w_val >= 10 || w_val <= 19)
	{
		command << "E" << w_val;
	}
	else
	{
		Tango::Except::throw_exception("", "Valid argument 0-19", "write_SensorRange");
	}

	serial_in_out(command.str(), true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_SensorRange
}

//--------------------------------------------------------
/**
 *	Read ControlMode attribute
 *	Description: Control type:
 *	             0 = direct
 *	             1 = reverse
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_ControlMode(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_ControlMode(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_ControlMode) ENABLED START -----*/

	string result = serial_in_out("R32", false);

	strip_first(result, 'N', 1);

	*attr_ControlMode_read = atoi(result.c_str());
	attr.set_value(attr_ControlMode_read);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_ControlMode
}

//--------------------------------------------------------
/**
 *	Write ControlMode attribute values to hardware.
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::write_ControlMode(Tango::WAttribute &attr)
{
	DEBUG_STREAM << "Mks651d::write_ControlMode(Tango::Attribute &attr) entering... " << endl;
	
	//	Retrieve write value
	Tango::DevShort	w_val;
	attr.get_write_value(w_val);
	
	/*----- PROTECTED REGION ID(Mks651d::write_ControlMode) ENABLED START -----*/

	switch(w_val)
	{
	case 0:
		serial_in_out("N0", true);
		break;
	case 1:
		serial_in_out("N1", true);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 0-1", "write_ControlMode");
		break;
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_ControlMode
}

//--------------------------------------------------------
/**
 *	Read ValveType attribute
 *	Description: Valve type:
 *	             1 = Std 253
 *	             2 = Fast 253
 *	             3 = 653
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_ValveType(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_ValveType(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_ValveType) ENABLED START -----*/

	string result = serial_in_out("R23", false);

	strip_first(result, 'J', 1);

	*attr_ValveType_read = atoi(result.c_str());
	attr.set_value(attr_ValveType_read);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_ValveType
}
//--------------------------------------------------------
/**
 *	Read AnalogSPRange attribute
 *	Description: 0 = 5 Volts
 *	             1 = 10 Volts
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_AnalogSPRange(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_AnalogSPRange(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_AnalogSPRange) ENABLED START -----*/

	string result = serial_in_out("R24", false);

	strip_first(result, 'A', 1);

	*attr_AnalogSPRange_read = atoi(result.c_str());
	attr.set_value(attr_AnalogSPRange_read);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_AnalogSPRange
}

//--------------------------------------------------------
/**
 *	Write AnalogSPRange attribute values to hardware.
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::write_AnalogSPRange(Tango::WAttribute &attr)
{
	DEBUG_STREAM << "Mks651d::write_AnalogSPRange(Tango::Attribute &attr) entering... " << endl;
	
	//	Retrieve write value
	Tango::DevShort	w_val;
	attr.get_write_value(w_val);
	
	/*----- PROTECTED REGION ID(Mks651d::write_AnalogSPRange) ENABLED START -----*/

	switch(w_val)
	{
	case 0:
		serial_in_out("A0", true);
		break;
	case 1:
		serial_in_out("A1", true);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 0-1", "write_AnalogSPRange");
		break;
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_AnalogSPRange
}

//--------------------------------------------------------
/**
 *	Read SelectedSP attribute
 *	Description: 0 = setpoint analog
 *	             1 = setpoint A
 *	             2 = setpoint B
 *	             3 = setpoint C
 *	             4 = setpoint D
 *	             5 = setpoint E
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_SelectedSP(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_SelectedSP(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_SelectedSP) ENABLED START -----*/

	attr.set_value(attr_SelectedSP_read);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_SelectedSP
}
//--------------------------------------------------------
/**
 *	Read PowerFailResponse attribute
 *	Description: Power fail response:
 *	             0 = disabled
 *	             1 = open at power fail
 *	             2 = close at power fail
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::read_PowerFailResponse(Tango::Attribute &attr)
{
	DEBUG_STREAM << "Mks651d::read_PowerFailResponse(Tango::Attribute &attr) entering... " << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_PowerFailResponse) ENABLED START -----*/

	string result = serial_in_out("R40", false);

	strip_first(result, 'K', 1);

	*attr_PowerFailResponse_read = atoi(result.c_str());
	attr.set_value(attr_PowerFailResponse_read);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_PowerFailResponse
}

//--------------------------------------------------------
/**
 *	Write PowerFailResponse attribute values to hardware.
 *
 *	Data type:	Tango::DevShort
 *	Attr type:	Scalar 
 */
//--------------------------------------------------------
void Mks651d::write_PowerFailResponse(Tango::WAttribute &attr)
{
	DEBUG_STREAM << "Mks651d::write_PowerFailResponse(Tango::Attribute &attr) entering... " << endl;
	
	//	Retrieve write value
	Tango::DevShort	w_val;
	attr.get_write_value(w_val);
	
	/*----- PROTECTED REGION ID(Mks651d::write_PowerFailResponse) ENABLED START -----*/

	switch(w_val)
	{
	case 0:
		serial_in_out("K0", true);
		break;
	case 1:
		serial_in_out("K1", true);
		break;
	case 2:
		serial_in_out("K2", true);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 0-2", "write_PowerFailResponse");
		break;
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_PowerFailResponse
}


//--------------------------------------------------------
/**
 *	Method      : Mks651d::Mks651dClass::add_dynamic_attributes()
 *	Description : Create the dynamic attributes if any
 *	              for specified device.
 */
//--------------------------------------------------------
void Mks651d::add_dynamic_attributes()
{
	/*----- PROTECTED REGION ID(Mks651d::Class::add_dynamic_attributes) ENABLED START -----*/

	//	Add your own code to create and add dynamic attributes if any

	/*----- PROTECTED REGION END -----*/	//	Mks651d::Class::add_dynamic_attributes

}



//========================================================
//	Command execution methods
//========================================================

//--------------------------------------------------------
/**
 *	Execute the Open command:
 *	Description: 
 *
 *	@param argin 
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::open()
{
	DEBUG_STREAM << "Mks651d::Open()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::open) ENABLED START -----*/

	serial_in_out("O", true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::open

}

//--------------------------------------------------------
/**
 *	Execute the Close command:
 *	Description: 
 *
 *	@param argin 
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::close()
{
	DEBUG_STREAM << "Mks651d::Close()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::close) ENABLED START -----*/

	serial_in_out("C", true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::close

}

//--------------------------------------------------------
/**
 *	Execute the Stop command:
 *	Description: 
 *
 *	@param argin 
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::stop()
{
	DEBUG_STREAM << "Mks651d::Stop()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::stop) ENABLED START -----*/

	serial_in_out("H", true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::stop

}

//--------------------------------------------------------
/**
 *	Execute the SelectSP command:
 *	Description: Select given setpoint
 *
 *	@param argin 1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	             6 setpoint Analog
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::select_sp(Tango::DevShort argin)
{
	DEBUG_STREAM << "Mks651d::SelectSP()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::select_sp) ENABLED START -----*/

	switch(argin)
	{
	case 1:
		serial_in_out("D1", true);
		break;
	case 2:
		serial_in_out("D2", true);
		break;
	case 3:
		serial_in_out("D3", true);
		break;
	case 4:
		serial_in_out("D4", true);
		break;
	case 5:
		serial_in_out("D5", true);
		break;
	case 6:
		serial_in_out("D6", true);;
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 1-6", "select_sp");
		break;
	}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::select_sp

}

//--------------------------------------------------------
/**
 *	Execute the ReadSPLevel command:
 *	Description: Read setpoint level
 *
 *	@param argin 1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	             6 setpoint Analog
 *	@returns value is the % of FS
 *	         pressure for pressure setpoint
 *	         position for position setpoint
 */
//--------------------------------------------------------
Tango::DevDouble Mks651d::read_splevel(Tango::DevShort argin)
{
	Tango::DevDouble argout;
	DEBUG_STREAM << "Mks651d::ReadSPLevel()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_splevel) ENABLED START -----*/

	string result;

	switch(argin)
	{
	case 1:
		result = serial_in_out("R1", false);
		break;
	case 2:
		result = serial_in_out("R2", false);
		break;
	case 3:
		result = serial_in_out("R3", false);
		break;
	case 4:
		result = serial_in_out("R4", false);
		break;
	case 5:
		result = serial_in_out("R10", false);
		break;
	case 6:
		result = serial_in_out("R0", false);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 1-6", "read_splevel");
		break;
	}

	strip_first(result, 'S', 2);

	argout = strtod(result.c_str(), NULL);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_splevel

	return argout;
}

//--------------------------------------------------------
/**
 *	Execute the WriteSPLevel command:
 *	Description: Write setpoint level
 *
 *	@param argin argin = setpoint, value
 *	             
 *	             setpoint
 *	             1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	             6 setpoint Analog
 *	             
 *	             value 
 *	             (for setpoint A-E)
 *	             0-100  
 *	             (for analog setpoint)
 *	             0 = 100%
 *	             1 = 10%
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::write_splevel(const Tango::DevVarDoubleArray *argin)
{
	DEBUG_STREAM << "Mks651d::WriteSPLevel()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::write_splevel) ENABLED START -----*/

	if(argin->length() != 2)
		Tango::Except::throw_exception("", "Invalid argument, valid [setpoint, value] ", "write_splevel");

	if((*argin)[1] < 0 || (*argin)[1] > 100)
		Tango::Except::throw_exception("", "Invalid value, valid [0-100] ", "write_splevel");

	if((*argin)[0] == 6 &&
			(*argin)[1] != 0 &&
			(*argin)[1] != 1)
		Tango::Except::throw_exception("", "Invalid value for analog setpoint, valid [0-1] ", "write_splevel");

	stringstream command;

	switch( int( (*argin)[0] ) )
	{
	case 1:
		command << "S1" << (*argin)[1];
		break;
	case 2:
		command << "S2" << (*argin)[1];
		break;
	case 3:
		command << "S3" << (*argin)[1];
		break;
	case 4:
		command << "S4" << (*argin)[1];
		break;
	case 5:
		command << "S5" << (*argin)[1];
		break;
	case 6:
		command << "S6" << (*argin)[1];
		break;
	default:
		Tango::Except::throw_exception("", "Invalid argument, valid[1-6]", "write_splevel");
		break;
	}

	serial_in_out(command.str(), true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_splevel

}

//--------------------------------------------------------
/**
 *	Execute the ReadSPType command:
 *	Description: Read setpoint type
 *
 *	@param argin 1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	             6 setpoint Analog
 *	@returns 0 = position
 *	         1 = pressure
 */
//--------------------------------------------------------
Tango::DevShort Mks651d::read_sptype(Tango::DevShort argin)
{
	Tango::DevShort argout;
	DEBUG_STREAM << "Mks651d::ReadSPType()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_sptype) ENABLED START -----*/

	string result;

	switch(argin)
	{
	case 1:
		result = serial_in_out("R26", false);
		break;
	case 2:
		result = serial_in_out("R27", false);
		break;
	case 3:
		result = serial_in_out("R28", false);
		break;
	case 4:
		result = serial_in_out("R29", false);
		break;
	case 5:
		result = serial_in_out("R30", false);
		break;
	case 6:
		result = serial_in_out("R25", false);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 1-6", "read_sptype");
		break;
	}

	strip_first(result, 'T', 2);

	argout = atoi(result.c_str());

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_sptype

	return argout;
}

//--------------------------------------------------------
/**
 *	Execute the WriteSPType command:
 *	Description: Write setpoint type
 *
 *	@param argin argin = setpoint, value
 *	             
 *	             setpoint
 *	             1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	             6 setpoint Analog
 *	             
 *	             value 
 *	             0 = position
 *	             1 = control
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::write_sptype(const Tango::DevVarShortArray *argin)
{
	DEBUG_STREAM << "Mks651d::WriteSPType()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::write_sptype) ENABLED START -----*/

	if(argin->length() != 2)
		Tango::Except::throw_exception("", "Invalid argument, valid [setpoint, value] ", "write_sptype");

	if((*argin)[1] != 0 && (*argin)[1] != 1)
		Tango::Except::throw_exception("", "Invalid value, valid [0-1] ", "write_sptype");

	stringstream command;

	switch((*argin)[0])
	{
	case 1:
		command << "T1" << (*argin)[1];
		break;
	case 2:
		command << "T2" << (*argin)[1];
		break;
	case 3:
		command << "T3" << (*argin)[1];
		break;
	case 4:
		command << "T4" << (*argin)[1];
		break;
	case 5:
		command << "T5" << (*argin)[1];
		break;
	case 6:
		command << "T6" << (*argin)[1];
		break;
	default:
		Tango::Except::throw_exception("", "Invalid argument, valid[1-6]", "write_sptype");
		break;
	}

	serial_in_out(command.str(), true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_sptype

}

//--------------------------------------------------------
/**
 *	Execute the ReadSoftStart command:
 *	Description: Read softstart rate
 *
 *	@param argin 1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	             6 setpoint Analog
 *	             7 valve open
 *	             8 valve close
 *	@returns value is % of full speed
 */
//--------------------------------------------------------
Tango::DevDouble Mks651d::read_soft_start(Tango::DevShort argin)
{
	Tango::DevDouble argout;
	DEBUG_STREAM << "Mks651d::ReadSoftStart()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_soft_start) ENABLED START -----*/

	string result;

	switch(argin)
	{
	case 1:
		result = serial_in_out("R15", false);
		break;
	case 2:
		result = serial_in_out("R16", false);
		break;
	case 3:
		result = serial_in_out("R17", false);
		break;
	case 4:
		result = serial_in_out("R18", false);
		break;
	case 5:
		result = serial_in_out("R19", false);
		break;
	case 6:
		result = serial_in_out("R20", false);
		break;
	case 7:
		result = serial_in_out("R21", false);
		break;
	case 8:
		result = serial_in_out("R22", false);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 1-8", "read_soft_start");
		break;
	}

	strip_first(result, 'I', 2);

	argout = strtod(result.c_str(), NULL);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_soft_start

	return argout;
}

//--------------------------------------------------------
/**
 *	Execute the WriteSoftStart command:
 *	Description: Write softstart rate
 *
 *	@param argin argin = setpoint, value
 *	             
 *	             setpoint
 *	             1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	             6 setpoint Analog
 *	             7 valve open 
 *	             8 valve close
 *	             
 *	             value is % of full speed
 *	             0-100
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::write_soft_start(const Tango::DevVarDoubleArray *argin)
{
	DEBUG_STREAM << "Mks651d::WriteSoftStart()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::write_soft_start) ENABLED START -----*/

	if(argin->length() != 2)
		Tango::Except::throw_exception("", "Invalid argument, valid [setpoint, value] ", "write_soft_start");

	if((*argin)[1] < 0 || (*argin)[1] > 100)
		Tango::Except::throw_exception("", "Invalid value, valid [0-100] ", "write_soft_start");

	stringstream command;

	switch( int( (*argin)[0] ) )
	{
	case 1:
		command << "I1" << (*argin)[1];
		break;
	case 2:
		command << "I2" << (*argin)[1];
		break;
	case 3:
		command << "I3" << (*argin)[1];
		break;
	case 4:
		command << "I4" << (*argin)[1];
		break;
	case 5:
		command << "I5" << (*argin)[1];
		break;
	case 6:
		command << "I6" << (*argin)[1];
		break;
	case 7:
		command << "I7" << (*argin)[1];
		break;
	case 8:
		command << "I8" << (*argin)[1];
		break;
	default:
		Tango::Except::throw_exception("", "Invalid argument, valid[1-8]", "write_soft_start");
		break;
	}

	serial_in_out(command.str(), true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_soft_start

}

//--------------------------------------------------------
/**
 *	Execute the ReadSPGain command:
 *	Description: Read setpoint gain
 *
 *	@param argin 1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	@returns value is % of gain
 */
//--------------------------------------------------------
Tango::DevDouble Mks651d::read_spgain(Tango::DevShort argin)
{
	Tango::DevDouble argout;
	DEBUG_STREAM << "Mks651d::ReadSPGain()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_spgain) ENABLED START -----*/

	string result;

	switch(argin)
	{
	case 1:
		result = serial_in_out("R46", false);
		break;
	case 2:
		result = serial_in_out("R47", false);
		break;
	case 3:
		result = serial_in_out("R48", false);
		break;
	case 4:
		result = serial_in_out("R49", false);
		break;
	case 5:
		result = serial_in_out("R50", false);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 1-5", "read_spgain");
		break;
	}

	strip_first(result, 'M', 2);

	argout = strtod(result.c_str(), NULL);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_spgain

	return argout;
}

//--------------------------------------------------------
/**
 *	Execute the WriteSPGain command:
 *	Description: Write setpoint gain
 *
 *	@param argin argin = setpoint, value
 *	             
 *	             setpoint
 *	             1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	             
 *	             value is % of gain
 *	             0-100
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::write_spgain(const Tango::DevVarDoubleArray *argin)
{
	DEBUG_STREAM << "Mks651d::WriteSPGain()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::write_spgain) ENABLED START -----*/

	if(argin->length() != 2)
		Tango::Except::throw_exception("", "Invalid argument, valid [setpoint, value] ", "write_spgain");

	if((*argin)[1] < 0 || (*argin)[1] > 100)
		Tango::Except::throw_exception("", "Invalid value, valid [0-100] ", "write_spgain");

	stringstream command;

	switch( int( (*argin)[0] ) )
	{
	case 1:
		command << "M1" << (*argin)[1];
		break;
	case 2:
		command << "M2" << (*argin)[1];
		break;
	case 3:
		command << "M3" << (*argin)[1];
		break;
	case 4:
		command << "M4" << (*argin)[1];
		break;
	case 5:
		command << "M5" << (*argin)[1];
		break;
	default:
		Tango::Except::throw_exception("", "Invalid argument, valid[1-5]", "write_spgain");
		break;
	}

	serial_in_out(command.str(), true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_spgain

}

//--------------------------------------------------------
/**
 *	Execute the ReadSPLead command:
 *	Description: Read setpoint lead
 *
 *	@param argin 1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	@returns value is seconds
 */
//--------------------------------------------------------
Tango::DevLong Mks651d::read_splead(Tango::DevShort argin)
{
	Tango::DevLong argout;
	DEBUG_STREAM << "Mks651d::ReadSPLead()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_splead) ENABLED START -----*/

	string result;

	switch(argin)
	{
	case 1:
		result = serial_in_out("R41", false);
		break;
	case 2:
		result = serial_in_out("R42", false);
		break;
	case 3:
		result = serial_in_out("R43", false);
		break;
	case 4:
		result = serial_in_out("R44", false);
		break;
	case 5:
		result = serial_in_out("R45", false);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 1-5", "read_splead");
		break;
	}

	strip_first(result, 'X', 2);

	argout = atol(result.c_str());

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_splead

	return argout;
}

//--------------------------------------------------------
/**
 *	Execute the WriteSPLead command:
 *	Description: Write setpoint lead
 *
 *	@param argin argin = setpoint, value
 *	             
 *	             setpoint
 *	             1 setpoint A
 *	             2 setpoint B
 *	             3 setpoint C
 *	             4 setpoint D
 *	             5 setpoint E
 *	             
 *	             value is seconds
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::write_splead(const Tango::DevVarLongArray *argin)
{
	DEBUG_STREAM << "Mks651d::WriteSPLead()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::write_splead) ENABLED START -----*/

	if(argin->length() != 2)
		Tango::Except::throw_exception("", "Invalid argument, valid [setpoint, value] ", "write_splead");

	if((*argin)[1] < 0 || (*argin)[1] > 1000)
		Tango::Except::throw_exception("", "Invalid value, valid [0-1000] ", "write_splead");

	stringstream command;

	switch((*argin)[0])
	{
	case 1:
		command << "X1" << (*argin)[1];
		break;
	case 2:
		command << "X2" << (*argin)[1];
		break;
	case 3:
		command << "X3" << (*argin)[1];
		break;
	case 4:
		command << "X4" << (*argin)[1];
		break;
	case 5:
		command << "X5" << (*argin)[1];
		break;
	default:
		Tango::Except::throw_exception("", "Invalid argument, valid[1-5]", "write_splead");
		break;
	}

	serial_in_out(command.str(), true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_splead

}

//--------------------------------------------------------
/**
 *	Execute the ReadThreshold command:
 *	Description: Read threshold
 *
 *	@param argin 1 = Low threshold 1
 *	             2 = High threshold 1
 *	             3 = Low threshold 2
 *	             4 = High threshold 2
 *	@returns value is % of F.S.
 */
//--------------------------------------------------------
Tango::DevDouble Mks651d::read_threshold(Tango::DevShort argin)
{
	Tango::DevDouble argout;
	DEBUG_STREAM << "Mks651d::ReadThreshold()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::read_threshold) ENABLED START -----*/

	string result;

	switch(argin)
	{
	case 1:
		result = serial_in_out("R11", false);
		break;
	case 2:
		result = serial_in_out("R12", false);
		break;
	case 3:
		result = serial_in_out("R13", false);
		break;
	case 4:
		result = serial_in_out("R14", false);
		break;
	default:
		Tango::Except::throw_exception("", "Valid argument 1-4", "read_threshold");
		break;
	}

	strip_first(result, 'P', 2);

	argout = strtod(result.c_str(), NULL);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::read_threshold

	return argout;
}

//--------------------------------------------------------
/**
 *	Execute the WriteThreshold command:
 *	Description: Write threshold value
 *
 *	@param argin argin = limit, value
 *	             
 *	             limit
 *	             1 = Low threshold 1
 *	             2 = High threshold 1
 *	             3 = Low threshold 2
 *	             4 = High threshold 2
 *	             
 *	             value is % of F.S.
 *	             0-100
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::write_threshold(const Tango::DevVarDoubleArray *argin)
{
	DEBUG_STREAM << "Mks651d::WriteThreshold()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::write_threshold) ENABLED START -----*/

	if(argin->length() != 2)
		Tango::Except::throw_exception("", "Invalid argument, valid [setpoint, value] ", "write_threshold");

	if((*argin)[1] < 0 || (*argin)[1] > 100)
		Tango::Except::throw_exception("", "Invalid value, valid [0-100] ", "write_threshold");

	stringstream command;

	switch( int( (*argin)[0] ) )
	{
	case 1:
		command << "P1" << (*argin)[1];
		break;
	case 2:
		command << "P2" << (*argin)[1];
		break;
	case 3:
		command << "P3" << (*argin)[1];
		break;
	case 4:
		command << "P4" << (*argin)[1];
		break;
	default:
		Tango::Except::throw_exception("", "Invalid argument, valid[1-4]", "write_threshold");
		break;
	}

	serial_in_out(command.str(), true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::write_threshold

}

//--------------------------------------------------------
/**
 *	Execute the StartLearning command:
 *	Description: 
 *
 *	@param argin 
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::start_learning()
{
	DEBUG_STREAM << "Mks651d::StartLearning()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::start_learning) ENABLED START -----*/

	serial_in_out("L", true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::start_learning

}

//--------------------------------------------------------
/**
 *	Execute the StopLearning command:
 *	Description: 
 *
 *	@param argin 
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::stop_learning()
{
	DEBUG_STREAM << "Mks651d::StopLearning()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::stop_learning) ENABLED START -----*/

	serial_in_out("Q", true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::stop_learning

}

//--------------------------------------------------------
/**
 *	Execute the LearnAnalog command:
 *	Description: Learn the full scale of the analog set point
 *
 *	@param argin 
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::learn_analog()
{
	DEBUG_STREAM << "Mks651d::LearnAnalog()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::learn_analog) ENABLED START -----*/

	serial_in_out("Y2", true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::learn_analog

}

//--------------------------------------------------------
/**
 *	Execute the CalibrateAdc command:
 *	Description: Calibrate span of A/D converter
 *
 *	@param argin Assign the value to the converter reading of the pressure channel.
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::calibrate_adc(Tango::DevDouble argin)
{
	DEBUG_STREAM << "Mks651d::CalibrateAdc()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::calibrate_adc) ENABLED START -----*/

	serial_in_out("Y1", true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::calibrate_adc

}

//--------------------------------------------------------
/**
 *	Execute the ZeroSensor command:
 *	Description: 
 *
 *	@param argin 
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::zero_sensor()
{
	DEBUG_STREAM << "Mks651d::ZeroSensor()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::zero_sensor) ENABLED START -----*/

	serial_in_out("Z1", true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::zero_sensor

}

//--------------------------------------------------------
/**
 *	Execute the RemoveZero command:
 *	Description: 
 *
 *	@param argin 
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::remove_zero()
{
	DEBUG_STREAM << "Mks651d::RemoveZero()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::remove_zero) ENABLED START -----*/

	serial_in_out("Z3", true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::remove_zero

}

//--------------------------------------------------------
/**
 *	Execute the SetZero command:
 *	Description: 
 *
 *	@param argin value is %  F.S. of the base pressure reading
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::set_zero(Tango::DevDouble argin)
{
	DEBUG_STREAM << "Mks651d::SetZero()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::set_zero) ENABLED START -----*/

	if(argin < 0 || argin > 100)
		Tango::Except::throw_exception("", "Invalid value, valid [0-100] ", "write_threshold");

	stringstream command;
	command << "Z2" << argin;

	serial_in_out(command.str(), true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::set_zero

}

//--------------------------------------------------------
/**
 *	Execute the LearnZero command:
 *	Description: 
 *
 *	@param argin 
 *	@returns 
 */
//--------------------------------------------------------
void Mks651d::learn_zero()
{
	DEBUG_STREAM << "Mks651d::LearnZero()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::learn_zero) ENABLED START -----*/

	serial_in_out("Z4", true);

	/*----- PROTECTED REGION END -----*/	//	Mks651d::learn_zero

}

//--------------------------------------------------------
/**
 *	Execute the DirectCommand command:
 *	Description: Send a direct command to device
 *
 *	@param argin 
 *	@returns 
 */
//--------------------------------------------------------
Tango::DevString Mks651d::direct_command(Tango::DevString argin)
{
	Tango::DevString argout;
	DEBUG_STREAM << "Mks651d::DirectCommand()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(Mks651d::direct_command) ENABLED START -----*/

	string result, command(argin);

	if(command.find_first_of('R') != string::npos)
		result = serial_in_out(command, false);
	else
		serial_in_out(command, true);

	argout = CORBA::string_dup(result.c_str());

	/*----- PROTECTED REGION END -----*/	//	Mks651d::direct_command

	return argout;
}


	/*----- PROTECTED REGION ID(Mks651d::namespace_ending) ENABLED START -----*/

//========================================================
//	Private methods
//========================================================

//--------------------------------------------------------
/**
 *	Execute the update_state command:
 */
//--------------------------------------------------------
void Mks651d::update_state()
{
	DEBUG_STREAM << "Mks651d::update_state(): entering... !" << endl;

	string result = serial_in_out("R6", false);

	if(!result.empty())
	{
		strip_first(result, 'V', 1);
		*attr_Position_read = strtod(result.c_str(), NULL);

		if(*attr_Position_read > 0)
			set_state(Tango::OPEN);
		else
			set_state(Tango::CLOSE);
	}

	result = serial_in_out("R37", false);

	if(!result.empty())
	{
		strip_first(result, 'M', 1);
		int system_status = atoi(result.c_str());

		switch(system_status % 10)
		{
		case 3:
			*attr_SelectedSP_read = 1;
			break;
		case 4:
			*attr_SelectedSP_read = 2;
			break;
		case 5:
			*attr_SelectedSP_read = 3;
			break;
		case 6:
			*attr_SelectedSP_read = 4;
			break;
		case 7:
			*attr_SelectedSP_read = 5;
			break;
		case 8:
			*attr_SelectedSP_read = 6;
			break;
		default:
			*attr_SelectedSP_read = 0;
			break;
		}

		string status;
		if((system_status / 100) == 0)
			status.append("Local mode: ");
		else
			status.append("Remote mode: ");

		switch((system_status / 10) % 10)
		{
		case 0:
			status.append("not learning");
			break;
		case 1:
			status.append("learning system");
			break;
		case 2:
			status.append("learning valve");
			break;
		}

		set_status(status.c_str());
	}
}

//--------------------------------------------------------
/**
 *	Execute the update_state_allowed command:
 */
//--------------------------------------------------------
bool Mks651d::update_state_allowed()
{
	bool is_allowed = false;

	if(init_completed)
	{
		if(get_state() == Tango::FAULT)
		{
			time_t now;
			time(&now);

			double elapsed_t = difftime(now, last_exception_t);

			DEBUG_STREAM  << "Back off: " << elapsed_t << "/" << current_back_off << " : " << maxBackOff << endl;

			if(elapsed_t >= current_back_off)
			{
				is_allowed = true;
				current_back_off = current_back_off * 2;

				if(current_back_off > maxBackOff)
				{
					current_back_off = maxBackOff;
				}
			}
		}
		else
		{
			current_back_off = 1;
			is_allowed = true;
		}
	}

	return is_allowed;
}

//--------------------------------------------------------
/**
 *	Execute the serial_in_out command:
 */
//--------------------------------------------------------
string Mks651d::serial_in_out(string command_str, bool write_only)
{
	DEBUG_STREAM << "Mks651d::serial_in_out(): entering... !" << endl;

	Tango::DeviceData dd_flush, dd_in, dd_out;
	string result;

    Tango::DevLong flush = 2;
	dd_flush << flush;
	command_str += 0xD;

#ifdef _VERBOSE_DEBUG
	DEBUG_STREAM << ">>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl;
	for(unsigned int j=0; j<command_str.size(); j++)
	{
		DEBUG_STREAM << command_str[j] << " | " << int(command_str[j]) << endl;
	}
	DEBUG_STREAM << ">>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl;
#endif

	dd_in << command_str;

	try
	{
		ThreadGuard lock(proxy_mutex);

		device_proxy->command_inout("DevSerFlush", dd_flush);
		device_proxy->command_inout("DevSerWriteString", dd_in);

		if(!write_only)
		{
			dd_out = device_proxy->command_inout("DevSerReadLine");
			dd_out >> result;
		}
	}
    catch(Tango::DevFailed &ex)
    {
    	exception_handler(ex, Tango::FAULT, "serial_in_out");
    }

#ifdef _VERBOSE_DEBUG
	DEBUG_STREAM << "<<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl;
	for(unsigned int j=0; j<result.size(); j++)
	{
		DEBUG_STREAM << result[j] << " | " << int(result[j]) << endl;
	}
	DEBUG_STREAM << "<<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl;
#endif

	if(!write_only)
		strip_last(result, 0xD, 0);

	return result;
}

//--------------------------------------------------------
/**
 *	Execute the exception_handler command:
 */
//--------------------------------------------------------
void Mks651d::exception_handler(Tango::DevFailed &ex, Tango::DevState new_state, const string base_msg)
{
    time(&last_exception_t);

	std::stringstream error_msg;

	error_msg << base_msg << " : " << endl;
    for (unsigned int i=0; i<ex.errors.length(); i++)
    {
            error_msg << ex.errors[i].reason.in() << endl;
            error_msg << ex.errors[i].desc.in() << endl;
            error_msg << ex.errors[i].origin.in() << endl;
    }
    error_msg << ends;

    ERROR_STREAM << error_msg.str() << endl;

    set_state(new_state);
    set_status(error_msg.str());
}

//--------------------------------------------------------
/**
 *	Execute the strip_last command:
 */
//--------------------------------------------------------
void Mks651d::strip_last(std::string & result, char c, int n)
{
	size_t pos;
	if ((pos = result.find_last_of(c, result.length())) != string::npos)
		result = result.substr(0, pos + n);
}

//--------------------------------------------------------
/**
 *	Execute the strip_first command:
 */
//--------------------------------------------------------
void Mks651d::strip_first(std::string & result, char c, int n)
{
	size_t pos;
	if( (pos = result.find_first_of(c)) != string::npos )
	{
		result = result.substr(pos + n, result.length());
	}
}

	/*----- PROTECTED REGION END -----*/	//	Mks651d::namespace_ending
} //	namespace