Skip to content
Snippets Groups Projects
Commit 0c2940d8 authored by Jacques Gouno's avatar Jacques Gouno
Browse files

TANGODEVIC-1636: add CryoCooler Interface for the PLCServerProxy

parent ef59121c
Branches
Tags v2.10.2
No related merge requests found
//- Project : Cryocooler, ACCEL/CRYOTHERM cryogenic cooler for optics at SOLEIL
//- file : CryoCoolerInterface.cpp
//- threaded reading of the PLC Data Block
//- Writes on the PLC
//- Local CryoCoolerInterface (not the 1 in PLCServerProxyHelper!)
#include "CryoCoolerInterface.h"
#include <DBOffsets.h>
#include "TypesAndConsts.h"
namespace CryoCooler_ns
{
//-----------------------------------------------
//- Ctor ----------------------------------------
CryoCoolerInterface::CryoCoolerInterface ( Tango::DeviceImpl * _host_device,
std::string _plc_name,
short _dbread,
short _dbwrite,
size_t _periodic_exec_ms)
:yat4tango::DeviceTask(_host_device),
host_dev(_host_device),
plc_name(_plc_name),
db_read_number(_dbread),
db_write_number(_dbwrite),
periodic_timeout_ms(_periodic_exec_ms)
{
DEBUG_STREAM << "CryoCoolerInterface::CryoCoolerInterface <- " << std::endl;
#ifdef _DB_SEGMENTATION_BY_104_
hwp_rd_start = NULL;
hwp_rd_end = NULL;
#else
hwp = NULL;
#endif
hwp_wr = NULL;
//- yat::Task configure optional msg handling
this->enable_timeout_msg(false);
this->enable_periodic_msg(true);
this->set_periodic_msg_period(periodic_timeout_ms);
this->com_error = 0;
this->com_success = 0;
this->com_state = HWProxy_ns::HWP_NO_ERROR;
this->com_status = "HWP_NO_ERROR";
}
//-----------------------------------------------
//- Dtor ----------------------------------------
CryoCoolerInterface::~CryoCoolerInterface (void)
{
DEBUG_STREAM << "CryoCoolerInterface::~CryoCoolerInterface <- " << std::endl;
#ifdef _DB_SEGMENTATION_BY_104_
if (hwp_rd_start)
{
this->hwp_rd_start->exit();
hwp_rd_start = NULL;
}
if (hwp_rd_end)
{
this->hwp_rd_end->exit();
hwp_rd_end = NULL;
}
#else
if (hwp)
{
this->hwp->exit();
hwp = NULL;
}
#endif
if (hwp_wr)
{
this->hwp_wr->exit();
hwp_wr = NULL;
}
}
//------------------------------------------------------
//- initialize
//-------------------------------------------------------
void CryoCoolerInterface::initialize()
throw(Tango::DevFailed)
{
DEBUG_STREAM << " CryoCoolerInterface::initialize_DB try to get device proxy on " << plc_name << std::endl;
#ifdef _DB_SEGMENTATION_BY_104_
if (hwp_rd_start)
return;
try
{
DEBUG_STREAM << "CryoCoolerInterface::initialize trying to create hwp_rd_start" << std::endl;
HWProxy_ns:: HWProxy::Config conf;
//- this one gets the 50 first WORDS
conf.url = plc_name;
//- Give a specific name to plc client on the same DB number
conf.device_name = host_dev->get_name() + "_start";
conf.db_number = db_read_number;
conf.input_offset = DB_START_INPUT_OFFSET;
conf.input_length = DB_START_INPUT_LEN;
conf.output_offset = DB_START_OUTPUT_OFFSET;
conf.output_length = DB_START_OUTPUT_LEN;
// conf.periodic_timeout_ms = periodic_timeout_ms;
hwp_rd_start = new HWProxy_ns::HWProxy (host_dev, conf);
if (!hwp_rd_start)
{
ERROR_STREAM << "CryoCoolerInterface::initialize could not instanciate hwp_rd_start ..." << std::endl;
throw std::bad_alloc();
}
hwp_rd_start->go ();
}
catch (std::bad_alloc)
{
FATAL_STREAM << "CryoCoolerInterface::initialize () catched bad_alloc" << std::endl;
this->com_state = HWProxy_ns::HWP_INITIALIZATION_ERROR;
this->last_error = "could not instanciate hwp_rd_start class catched bad_alloc";
return;
}
catch (...)
{
FATAL_STREAM << "CryoCoolerInterface::initialize () catched ..." << std::endl;
this->com_state = HWProxy_ns::HWP_INITIALIZATION_ERROR;
this->last_error = "could not instanciate hwp_rd_start class catched (...)";
return;
}
if (hwp_rd_end)
return;
try
{
DEBUG_STREAM << "CryoCoolerInterface::initialize trying to create hwp_rd_end" << std::endl;
HWProxy_ns:: HWProxy::Config conf;
//- this one gets the 50 last WORDS (from 100 to 200)
conf.url = plc_name;
//- Give a specific name to plc client on the same DB number
conf.device_name = host_dev->get_name() + "_end";
conf.db_number = db_read_number;
conf.input_offset = DB_END_INPUT_OFFSET;
conf.input_length = DB_END_INPUT_LEN;
conf.output_offset = DB_END_OUTPUT_OFFSET;
conf.output_length = DB_END_OUTPUT_LEN;
// conf.periodic_timeout_ms = periodic_timeout_ms;
hwp_rd_end = new HWProxy_ns::HWProxy (host_dev, conf);
if (!hwp_rd_end)
{
ERROR_STREAM << "CryoCoolerInterface::initialize could not instanciate hwp_rd_end ..." << std::endl;
throw std::bad_alloc();
}
hwp_rd_end->go ();
}
catch (std::bad_alloc)
{
FATAL_STREAM << "CryoCoolerInterface::initialize () catched bad_alloc" << std::endl;
this->com_state = HWProxy_ns::HWP_INITIALIZATION_ERROR;
this->last_error = "could not instanciate hwp_rd_end class catched bad_alloc";
return;
}
catch (...)
{
FATAL_STREAM << "CryoCoolerInterface::initialize () catched ..." << std::endl;
this->com_state = HWProxy_ns::HWP_INITIALIZATION_ERROR;
this->last_error = "could not instanciate hwp_rd_end class catched (...)";
return;
}
#else
if (hwp)
return;
try
{
DEBUG_STREAM << "CryoCoolerInterface::initialize trying to create hwp" << std::endl;
HWProxy_ns:: HWProxy::Config conf;
//- this one gets the 100 last WORDS (from 0 to 200)
conf.url = plc_name;
conf.device_name = host_dev->get_name ();
conf.db_number = db_read_number;
conf.input_offset = DB_START_INPUT_OFFSET;
conf.input_length = (DB_START_INPUT_LEN + DB_END_INPUT_LEN);
conf.output_offset = DB_END_OUTPUT_OFFSET;
conf.output_length = DB_END_OUTPUT_LEN;
// conf.periodic_timeout_ms = periodic_timeout_ms;
hwp = new HWProxy_ns::HWProxy (host_dev, conf);
if (!hwp)
{
ERROR_STREAM << "CryoCoolerInterface::initialize could not instanciate hwp_rd_end ..." << std::endl;
throw std::bad_alloc();
}
hwp->go ();
}
catch (std::bad_alloc)
{
FATAL_STREAM << "CryoCoolerInterface::initialize () catched bad_alloc" << std::endl;
this->com_state = HWProxy_ns::HWP_INITIALIZATION_ERROR;
this->last_error = "could not instanciate hwp_rd_end class catched bad_alloc";
return;
}
catch (...)
{
FATAL_STREAM << "CryoCoolerInterface::initialize () catched ..." << std::endl;
this->com_state = HWProxy_ns::HWP_INITIALIZATION_ERROR;
this->last_error = "could not instanciate hwp_rd_end class catched (...)";
return;
}
#endif
if (hwp_wr)
return;
try
{
DEBUG_STREAM << "CryoCoolerInterface::initialize trying to create hwp_wr" << std::endl;
HWProxy_ns:: HWProxy::Config conf;
//- Write DB Data the 100 WORDS (from 0 to 100)
conf.url = plc_name;
conf.device_name = host_dev->get_name ();
conf.db_number = db_write_number;
conf.input_offset = DB_WRITE_INPUT_OFFSET;
conf.input_length = DB_WRITE_INPUT_LEN;
conf.output_offset = DB_WRITE_OUTPUT_OFFSET;
conf.output_length = DB_WRITE_OUTPUT_LEN;
// conf.periodic_timeout_ms = periodic_timeout_ms;
hwp_wr = new HWProxy_ns::HWProxy (host_dev,conf);
if (!hwp_wr)
{
ERROR_STREAM << "CryoCoolerInterface::initialize could not instanciate hwp_wr ..." << std::endl;
throw std::bad_alloc();
}
hwp_wr->go ();
}
catch (std::bad_alloc)
{
FATAL_STREAM << "CryoCoolerInterface::initialize () catched bad_alloc" << std::endl;
this->com_state = HWProxy_ns::HWP_INITIALIZATION_ERROR;
this->last_error = "could not instanciate hwp_wr class catched bad_alloc";
return;
}
catch (...)
{
FATAL_STREAM << "CryoCoolerInterface::initialize () catched ..." << std::endl;
this->com_state = HWProxy_ns::HWP_INITIALIZATION_ERROR;
this->last_error = "could not instanciate hwp_rd_end class catched (...)";
return;
}
}
//------------------------------------------------------
//------------------------------------------------------
HWProxy_ns::HWProxy * CryoCoolerInterface::get_hw_proxy_instance(unsigned int byte_offset)
{
#ifdef _DB_SEGMENTATION_BY_104_
//- evaluate the offset range
if ((byte_offset >= DB_START_INPUT_OFFSET) &&
(byte_offset < DB_END_INPUT_OFFSET) )
return hwp_rd_start;
else if ((byte_offset >= DB_END_INPUT_OFFSET) &&
(byte_offset < (DB_END_INPUT_OFFSET + DB_END_INPUT_LEN)))
return hwp_rd_end;
else
return NULL;
#else
return hwp;
#endif
}
//-----------------------------------------------
//- the user core of the Task -------------------
void CryoCoolerInterface::process_message (yat::Message& _msg)
throw (Tango::DevFailed)
{
//- The DeviceTask's lock_ -------------
DEBUG_STREAM << "CryoCoolerInterface::process_message::receiving msg " << _msg.to_string() << std::endl;
//- handle msg
switch (_msg.type())
{
//- THREAD_INIT =======================
case yat::TASK_INIT:
{
DEBUG_STREAM << "CryoCoolerInterface::process_message::THREAD_INIT::thread is starting up" << std::endl;
}
break;
//- TASK_EXIT =======================
case yat::TASK_EXIT:
{
DEBUG_STREAM << "CryoCoolerInterface::process_message handling TASK_EXIT thread is quitting" << std::endl;
}
break;
//- TASK_PERIODIC ===================
case yat::TASK_PERIODIC:
{
DEBUG_STREAM << "CryoCoolerInterface::process_message handling TASK_PERIODIC msg" << std::endl;
//- code relative to the task's periodic job goes here
// this->periodic_job_i();
}
break;
//- TASK_TIMEOUT ===================
case yat::TASK_TIMEOUT:
{
//- code relative to the task's tmo handling goes here
DEBUG_STREAM << "CryoCoolerInterface::process_message handling TASK_TIMEOUT msg" << std::endl;
}
break;
//- USER_DEFINED_MSG ================
//- WRITE A REAL ----------------
case HWProxy_ns::SET_REAL_MSG:
{
DEBUG_STREAM << "CryoCoolerInterface::process_message handling SET_REAL_MSG user msg" << std::endl;
//- get msg data...
struct HWProxy_ns::WReal * wr = 0;
_msg.detach_data(wr);
if (wr)
{
try
{
DEBUG_STREAM << "CryoCoolerInterface::process_message (1) trying to write REAL value " << wr->value << " at offset " << wr->byte_offset << std::endl;
if (hwp_wr)
{
hwp_wr->write_real ("CryoCoolerInterface::process_message (1) trying to write REAL value",wr->byte_offset, wr->value);
hwp_wr->write_bit ("CryoCoolerInterface::process_message (1) trying to write REAL value", ACTION_REQUEST_BYTE_OFFSET, ACTION_REQUEST_BIT_OFFSET, true);
}
}
catch (...)
{
this->com_status = hwp_wr->get_com_status();
this->com_state = hwp_wr->get_com_state();
this->last_error = hwp_wr->get_last_error();
this->com_error++;
delete wr;
break;
}
delete wr;
if (hwp_wr)
{
//- The normal state/status (HWP_NO_ERROR/"HWP_NO_ERROR")
this->com_status = hwp_wr->get_com_status();
this->com_state = hwp_wr->get_com_state();
this->com_success++;
}
}
break;
}
//- WRITE AN INT ----------------
case HWProxy_ns::SET_INT_MSG:
{
DEBUG_STREAM << "CryoCoolerInterface::process_message handling SET_INT_MSG user msg" << std::endl;
//- get msg data...
struct HWProxy_ns::WInt * wi = 0;
_msg.detach_data(wi);
if (wi)
{
try
{
DEBUG_STREAM << "CryoCoolerInterface::process_message (1) trying to write INT value " << wi->value << " at offset " << wi->byte_offset << std::endl;
if (hwp_wr)
{
hwp_wr->write_short ("CryoCoolerInterface::process_message (1) trying to write INT value ", wi->byte_offset, wi->value);
hwp_wr->write_bit ("CryoCoolerInterface::process_message (1) trying to write INT value ", ACTION_REQUEST_BYTE_OFFSET, ACTION_REQUEST_BIT_OFFSET, true);
}
}
catch (...)
{
this->com_status = hwp_wr->get_com_status();
this->com_state = hwp_wr->get_com_state();
this->last_error = hwp_wr->get_last_error();
this->com_error++;
delete wi;
break;
}
delete wi;
if (hwp_wr)
{
//- The normal state/status (HWP_NO_ERROR/"HWP_NO_ERROR")
this->com_status = hwp_wr->get_com_status();
this->com_state = hwp_wr->get_com_state();
this->com_success++;
}
}
break;
}
//- WRITE A BOOL ----------------
case HWProxy_ns::SET_BOOL_MSG:
{
DEBUG_STREAM << "CryoCoolerInterface::process_message handling SET_BOOL_MSG user msg" << std::endl;
//- get msg data...
struct HWProxy_ns::WBool * wb = 0;
_msg.detach_data(wb);
if (wb)
{
try
{
DEBUG_STREAM << "CryoCoolerInterface::process_message (1) trying to write BOOL value " << wb->value << " at offset " << wb->byte_offset << "." << wb->bit_offset << std::endl;
if (hwp_wr)
{
hwp_wr->write_bit ("CryoCoolerInterface::process_message (1) trying to write BOOL value",wb->byte_offset, wb->bit_offset, wb->value);
hwp_wr->write_bit ("CryoCoolerInterface::process_message (1) trying to write BOOL value",ACTION_REQUEST_BYTE_OFFSET, ACTION_REQUEST_BIT_OFFSET, true);
}
}
catch (...)
{
this->com_status = hwp_wr->get_com_status();
this->com_state = hwp_wr->get_com_state();
this->last_error = hwp_wr->get_last_error();
this->com_error++;
delete wb;
break;
}
delete wb;
if (hwp_wr)
{
//- The normal state/status (HWP_NO_ERROR/"HWP_NO_ERROR")
this->com_status = hwp_wr->get_com_status();
this->com_state = hwp_wr->get_com_state();
this->com_success++;
}
}
break;
}
}
} //- CryoCoolerInterface::process_message
//-----------------------------------------------
//- Acces to REAL -------------------------------
float CryoCoolerInterface::get_real (unsigned int byte_offset)
{
DEBUG_STREAM << "CryoCoolerInterface::get_real get REAL value at offset " << byte_offset << std::endl;
if (!(this->get_hw_proxy_instance(byte_offset)))
{
this->com_state = HWProxy_ns::HWP_SOFTWARE_ERROR;
this->com_status = "HWP_SOFTWARE_ERROR";
std::stringstream s;
s << "CryoCoolerInterface::get_real last error occured trying to get hwp proxy instance " << std::endl;
this->last_error = s.str ();
this->com_error++;
Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
_CPTC (s.str().c_str()),
_CPTC ("CryoCoolerInterface::get_real ()"));
}
//- processing
try
{
float fval = (this->get_hw_proxy_instance(byte_offset))->get_real(byte_offset);
this->com_success++;
return fval;
}
catch(...)
{
this->com_state = HWProxy_ns::HWP_SOFTWARE_ERROR;
this->com_status = "HWP_SOFTWARE_ERROR";
std::stringstream s;
s << "CryoCoolerInterface::get_real last error occured trying to read a REAL " << " at offset " << byte_offset << std::endl;
this->last_error = s.str ();
this->com_error++;
Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
_CPTC (s.str().c_str()),
_CPTC ("CryoCoolerInterface::get_real ()"));
}
}
//-----------------------------------------------
//- Acces to INT --------------------------------
short CryoCoolerInterface::get_int (unsigned int byte_offset)
{
DEBUG_STREAM << "CryoCoolerInterface::get_int get INT value at offset " << byte_offset << std::endl;
if (!(this->get_hw_proxy_instance(byte_offset)))
{
this->com_state = HWProxy_ns::HWP_SOFTWARE_ERROR;
this->com_status = "HWP_SOFTWARE_ERROR";
std::stringstream s;
s << "CryoCoolerInterface::get_int last error occured trying to get hwp proxy instance " << std::endl;
this->last_error = s.str ();
this->com_error++;
Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
_CPTC (s.str().c_str()),
_CPTC ("CryoCoolerInterface::get_int ()"));
}
//- processing
try
{
short shval = (this->get_hw_proxy_instance(byte_offset))->get_word(byte_offset);
this->com_success++;
return shval;
}
catch(...)
{
this->com_state = HWProxy_ns::HWP_SOFTWARE_ERROR;
this->com_status = "HWP_SOFTWARE_ERROR";
std::stringstream s;
s << "CryoCoolerInterface::get_int last error occured trying to read an INT " << " at offset " << byte_offset << std::endl;
this->last_error = s.str ();
this->com_error++;
Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
_CPTC (s.str().c_str()),
_CPTC ("CryoCoolerInterface::get_int ()"));
}
}
//-----------------------------------------------
//- Acces to BOOL -------------------------------
bool CryoCoolerInterface::get_bool (unsigned int bit_offset, unsigned int byte_offset)
{
DEBUG_STREAM << "CryoCoolerInterface::get_bool trying to get BOOL value at offset " << byte_offset << "." << bit_offset << std::endl;
if (!(this->get_hw_proxy_instance(byte_offset)))
{
this->com_state = HWProxy_ns::HWP_SOFTWARE_ERROR;
this->com_status = "HWP_SOFTWARE_ERROR";
std::stringstream s;
s << "CryoCoolerInterface::get_bool last error occured trying to get hwp proxy instance " << std::endl;
this->last_error = s.str ();
this->com_error++;
Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
_CPTC (s.str().c_str()),
_CPTC ("CryoCoolerInterface::get_bool ()"));
}
//- processing
try
{
short bval = (this->get_hw_proxy_instance(byte_offset))->get_bool(byte_offset, bit_offset);
this->com_success++;
return bval;
}
catch(...)
{
this->com_state = HWProxy_ns::HWP_SOFTWARE_ERROR;
this->com_status = "HWP_SOFTWARE_ERROR";
std::stringstream s;
s << "CryoCoolerInterface::get_bool last error occured trying to read a BOOL " << " at offset " << byte_offset << "."<<bit_offset<<std::endl;
this->com_error++;
Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
_CPTC (s.str().c_str()),
_CPTC ("CryoCoolerInterface::get_bool ()"));
}
}
//-----------------------------------------------
//- Acces to HW ---------------------------------
//-----------------------------------------------
void CryoCoolerInterface::periodic_job_i (void)
{
DEBUG_STREAM << "CryoCoolerInterface::periodic_job_i trying to read PLC Data " << std::endl;
}
} //- namespace
//- Project : Cryocooler, ACCEL/CRYOTHERM cryogenic cooler for optics at SOLEIL
//- file : CryoCoolerIneterface.h
//- threaded reading of the PLC Data Block
//- Writes on the PLC
#ifndef __CRYOCOOLER_INTERFACE_H__
#define __CRYOCOOLER_INTERFACE_H__
#include <tango.h>
#include <yat4tango/DeviceTask.h>
#include <yat/time/Timer.h>
#include <DeviceProxyHelper.h>
#include <PLCServerProxy.h>
#include <HWProxy.h>
namespace CryoCooler_ns
{
// ============================================================================
// some defines enums and constants
// ============================================================================
//------------------------------------------------------------------------
//- CryoCoolerIneterface Class
//- read /write in the PLC with the help of HWProxy class
//------------------------------------------------------------------------
class CryoCoolerInterface : public yat4tango::DeviceTask
{
public :
//- Constructeur/destructeur
CryoCoolerInterface (Tango::DeviceImpl * _host_device,
std::string _plc_name,
short _dbread,
short _dbwrite,
size_t _periodic_exec_ms);
virtual ~CryoCoolerInterface ();
//- Initialize all DB -----------------------
void initialize ()
throw(Tango::DevFailed);
//- retrieve the data from the PLC
//- we write in the PLC thanks to the task message service
float get_real (unsigned int byte_offset);
short get_int (unsigned int byte_offset);
bool get_bool (unsigned int bit_offset, unsigned int byte_offset);
//- the last error string
std::string get_last_error (void) { return last_error;}
//- the number of communication errors
unsigned long get_com_error (void) { return com_error;}
//- the number of communication successfully done
unsigned long get_com_success (void){ return com_success;}
//- the state and status of communication
HWProxy_ns::ComState get_com_state (void){ return com_state;}
std::string get_com_status (void){ return com_status;}
protected:
//- process_message (implements yat4tango::DeviceTask pure virtual method)
virtual void process_message (yat::Message& msg) throw (Tango::DevFailed);
private :
//- members
//------------------------------------------
//- the host device
Tango::DeviceImpl * host_dev;
std::string plc_name;
short db_read_number;
short db_write_number;
size_t periodic_timeout_ms;
#ifdef _DB_SEGMENTATION_BY_104_
//- Due to the 104 words limit max, the DB is too large to get it in one plc buffer
HWProxy_ns::HWProxy * hwp_rd_start;
HWProxy_ns::HWProxy * hwp_rd_end;
#else
HWProxy_ns::HWProxy * hwp;
#endif
//- DB write hwp proxy
HWProxy_ns::HWProxy * hwp_wr;
//- the state and status stuff
HWProxy_ns::ComState com_state;
std::string com_status;
//- last error
std::string last_error;
//- for CryoCooler Com error attribute
unsigned long com_error;
//- for CryoCooler Com OK attribute
unsigned long com_success;
//- periodic job
void periodic_job_i (void);
//- get the hwp proxy associated with the specific DB_start, DB_end, DB_write
HWProxy_ns::HWProxy * get_hw_proxy_instance(unsigned int byte_offset);
};
}
#endif //- __CRYOCOOLER_INTERFACE_H__
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment