/*----- PROTECTED REGION ID(AttributeCombiner.cpp) ENABLED START -----*/
//=============================================================================
//
// file : AttributeCombiner.cpp
//
// description : C++ source for the AttributeCombiner class 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
// AttributeCombiner are implemented in this file.
//
// project : AttributeCombiner
//
// This file is part of Tango device class.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Tango. If not, see .
//
//
// Copyright (C): 2018
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// France
//
//=============================================================================
// This file is generated by POGO
// (Program Obviously used to Generate tango Object)
//=============================================================================
#include
#include
#define SAFE_FREE(x) if(x) {free(x);x=NULL;}
/*----- PROTECTED REGION END -----*/ // AttributeCombiner.cpp
/**
* AttributeCombiner class description:
* A class to combine attributes coming from several devices
*/
//================================================================
// The following table gives the correspondence
// between command and method names.
//
// Command name | Method name
//================================================================
// State | Inherited (no method)
// Status | Inherited (no method)
// ResetError | reset_error
// UpdateSetpoint | update_setpoint
// EnableDevice | enable_device
// DisableDevice | disable_device
// Indice2Devicename | indice2_devicename
// Devicename2Indice | devicename2_indice
// DisableAll | disable_all
// EnableAll | enable_all
//================================================================
//================================================================
// Attributes managed are:
//================================================================
// Errors | Tango::DevString Spectrum ( max = 2048)
// DeviceList | Tango::DevString Spectrum ( max = 4096)
//================================================================
namespace AttributeCombiner_ns
{
/*----- PROTECTED REGION ID(AttributeCombiner::namespace_starting) ENABLED START -----*/
// static initializations
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::namespace_starting
//--------------------------------------------------------
/**
* Method : AttributeCombiner::AttributeCombiner()
* Description : Constructors for a Tango device
* implementing the classAttributeCombiner
*/
//--------------------------------------------------------
AttributeCombiner::AttributeCombiner(Tango::DeviceClass *cl, string &s)
: TANGO_BASE_CLASS(cl, s.c_str())
{
/*----- PROTECTED REGION ID(AttributeCombiner::constructor_1) ENABLED START -----*/
init_device();
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::constructor_1
}
//--------------------------------------------------------
AttributeCombiner::AttributeCombiner(Tango::DeviceClass *cl, const char *s)
: TANGO_BASE_CLASS(cl, s)
{
/*----- PROTECTED REGION ID(AttributeCombiner::constructor_2) ENABLED START -----*/
init_device();
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::constructor_2
}
//--------------------------------------------------------
AttributeCombiner::AttributeCombiner(Tango::DeviceClass *cl, const char *s, const char *d)
: TANGO_BASE_CLASS(cl, s, d)
{
/*----- PROTECTED REGION ID(AttributeCombiner::constructor_3) ENABLED START -----*/
init_device();
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::constructor_3
}
//--------------------------------------------------------
/**
* Method : AttributeCombiner::delete_device()
* Description : will be called at device destruction or at init command
*/
//--------------------------------------------------------
void AttributeCombiner::delete_device()
{
DEBUG_STREAM << "AttributeCombiner::delete_device() " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::delete_device) ENABLED START -----*/
delete deviceGroup;
if (Tango::Util::instance()->is_svr_shutting_down() ||
Tango::Util::instance()->is_device_restarting(get_name())) {
attMap.clear();
}
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::delete_device
delete[] attr_DeviceList_read;
}
//--------------------------------------------------------
/**
* Method : AttributeCombiner::init_device()
* Description : will be called at device initialization.
*/
//--------------------------------------------------------
void AttributeCombiner::init_device()
{
DEBUG_STREAM << "AttributeCombiner::init_device() create device " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::init_device_before) ENABLED START -----*/
// Initialization before get_device_property() call
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::init_device_before
// Get the device properties from database
get_device_property();
attr_DeviceList_read = new Tango::DevString[4096];
/*----- PROTECTED REGION ID(AttributeCombiner::init_device) ENABLED START -----*/
set_state(Tango::ON);
set_status("ON");
// Create BLM group
deviceGroup = new Tango::Group("DEVGROUP");
errorStack.clear();
for (int i = 0; i < (int)deviceList.size(); i++) {
// Populate error vector
ERRITEM it;
errorStack.push_back(it);
}
deviceGroup->add(deviceList);
deviceGroup->set_timeout_millis(timeout);
//TangoSys_OMemStream ss;
//blmGroup->dump(ss);
//cout << ss.str() << endl;
Tango::GroupReply::enable_exception(false);
self = new Tango::DeviceProxy(device_name);
// Read disabled BLM
Tango::DbData dbd;
dbd.push_back(Tango::DbDatum("DisabledDevices"));
get_db_device()->get_property(dbd);
vector values;
dbd[0] >> values;
for(int i=0;i<(int)values.size();i++) {
cout << "Disable: " << values[i] << endl;
deviceGroup->disable(values[i]);
}
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::init_device
}
//--------------------------------------------------------
/**
* Method : AttributeCombiner::get_device_property()
* Description : Read database to initialize property data members.
*/
//--------------------------------------------------------
void AttributeCombiner::get_device_property()
{
/*----- PROTECTED REGION ID(AttributeCombiner::get_device_property_before) ENABLED START -----*/
// Initialize property data members
deviceList.clear();
attributeList.clear();
attributeRefList.clear();
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::get_device_property_before
// Read device properties from database.
Tango::DbData dev_prop;
dev_prop.push_back(Tango::DbDatum("AttributeList"));
dev_prop.push_back(Tango::DbDatum("AttributeRefList"));
dev_prop.push_back(Tango::DbDatum("DeviceList"));
dev_prop.push_back(Tango::DbDatum("CommandList"));
dev_prop.push_back(Tango::DbDatum("Timeout"));
// 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 AttributeCombinerClass to get class property
Tango::DbDatum def_prop, cl_prop;
AttributeCombinerClass *ds_class =
(static_cast(get_device_class()));
int i = -1;
// Try to initialize AttributeList from class property
cl_prop = ds_class->get_class_property(dev_prop[++i].name);
if (cl_prop.is_empty()==false) cl_prop >> attributeList;
else {
// Try to initialize AttributeList from default device value
def_prop = ds_class->get_default_device_property(dev_prop[i].name);
if (def_prop.is_empty()==false) def_prop >> attributeList;
}
// And try to extract AttributeList value from database
if (dev_prop[i].is_empty()==false) dev_prop[i] >> attributeList;
// Try to initialize AttributeRefList from class property
cl_prop = ds_class->get_class_property(dev_prop[++i].name);
if (cl_prop.is_empty()==false) cl_prop >> attributeRefList;
else {
// Try to initialize AttributeRefList from default device value
def_prop = ds_class->get_default_device_property(dev_prop[i].name);
if (def_prop.is_empty()==false) def_prop >> attributeRefList;
}
// And try to extract AttributeRefList value from database
if (dev_prop[i].is_empty()==false) dev_prop[i] >> attributeRefList;
// Try to initialize DeviceList from class property
cl_prop = ds_class->get_class_property(dev_prop[++i].name);
if (cl_prop.is_empty()==false) cl_prop >> deviceList;
else {
// Try to initialize DeviceList from default device value
def_prop = ds_class->get_default_device_property(dev_prop[i].name);
if (def_prop.is_empty()==false) def_prop >> deviceList;
}
// And try to extract DeviceList value from database
if (dev_prop[i].is_empty()==false) dev_prop[i] >> deviceList;
// Try to initialize CommandList from class property
cl_prop = ds_class->get_class_property(dev_prop[++i].name);
if (cl_prop.is_empty()==false) cl_prop >> commandList;
else {
// Try to initialize CommandList from default device value
def_prop = ds_class->get_default_device_property(dev_prop[i].name);
if (def_prop.is_empty()==false) def_prop >> commandList;
}
// And try to extract CommandList value from database
if (dev_prop[i].is_empty()==false) dev_prop[i] >> commandList;
// 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;
}
/*----- PROTECTED REGION ID(AttributeCombiner::get_device_property_after) ENABLED START -----*/
// Check device property data members init
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::get_device_property_after
}
//--------------------------------------------------------
/**
* Method : AttributeCombiner::always_executed_hook()
* Description : method always executed before any command is executed
*/
//--------------------------------------------------------
void AttributeCombiner::always_executed_hook()
{
DEBUG_STREAM << "AttributeCombiner::always_executed_hook() " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::always_executed_hook) ENABLED START -----*/
// code always executed before all requests
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::always_executed_hook
}
//--------------------------------------------------------
/**
* Method : AttributeCombiner::read_attr_hardware()
* Description : Hardware acquisition for attributes
*/
//--------------------------------------------------------
void AttributeCombiner::read_attr_hardware(TANGO_UNUSED(vector &attr_list))
{
DEBUG_STREAM << "AttributeCombiner::read_attr_hardware(vector &attr_list) entering... " << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::read_attr_hardware) ENABLED START -----*/
// Add your own code
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::read_attr_hardware
}
//--------------------------------------------------------
/**
* Read attribute Errors related method
* Description:
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 2048
*/
//--------------------------------------------------------
void AttributeCombiner::read_Errors(Tango::Attribute &attr)
{
DEBUG_STREAM << "AttributeCombiner::read_Errors(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::read_Errors) ENABLED START -----*/
int nbError = 0;
attr_Errors_read = new Tango::DevString[MAXERROR * deviceList.size()];
for (int i = 0; i < (int) errorStack.size(); i++) {
for (int j = 0; j < (int) errorStack[i].errList.size(); j++)
attr_Errors_read[nbError++] = Tango::string_dup(errorStack[i].errList[j].c_str());
}
attr.set_value(attr_Errors_read, nbError, 0, true);
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::read_Errors
}
//--------------------------------------------------------
/**
* Read attribute DeviceList related method
* Description:
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 4096
*/
//--------------------------------------------------------
void AttributeCombiner::read_DeviceList(Tango::Attribute &attr)
{
DEBUG_STREAM << "AttributeCombiner::read_DeviceList(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::read_DeviceList) ENABLED START -----*/
for (int i = 0; i < (int)deviceList.size(); i++) {
attr_DeviceList_read[i] = CORBA::string_dup(deviceList[i].c_str());
}
attr.set_value(attr_DeviceList_read, deviceList.size());
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::read_DeviceList
}
//--------------------------------------------------------
/**
* Method : AttributeCombiner::add_dynamic_attributes()
* Description : Create the dynamic attributes if any
* for specified device.
*/
//--------------------------------------------------------
void AttributeCombiner::add_dynamic_attributes()
{
/*----- PROTECTED REGION ID(AttributeCombiner::add_dynamic_attributes) ENABLED START -----*/
// Attribute List
string usage = "9 fields expected name;attName list;type;readwrite;spectrum;grouped;lengthattname;expert;alarm";
for (int i = 0; i < (int) attributeList.size(); i++) {
vector fields;
split(fields, attributeList[i], ';');
if (fields.size() != 9) {
cerr << "ERROR: Wrong attribute configuration property for " << attributeList[i] << endl;
cerr << "ERROR: " << usage << endl;
exit(0);
}
string name = fields[0];
vector attNames;
split(attNames, fields[1], ',');
if (attNames.size() == 0) {
cerr << "ERROR: Empty attribute list for " << attributeList[i] << endl;
cerr << "ERROR: " << usage << endl;
exit(0);
}
if (attNames.size() > MAXATTRIBUTE) {
cerr << "ERROR: Attribute list too long for " << attributeList[i] << endl;
exit(0);
}
int type = ToTangoType(name, fields[2]);
tolower(fields[3]);
Tango::AttrWriteType rwType;
if (fields[3].compare("true") == 0) {
rwType = Tango::READ_WRITE;
} else {
rwType = Tango::READ;
}
tolower(fields[4]);
bool isSpectrum = fields[4].compare("true") == 0;
tolower(fields[5]);
bool grouped = fields[5].compare("true") == 0;
string lengthAttName = fields[6];
tolower(fields[7]);
bool expert = fields[7].compare("true") == 0;
tolower(fields[8]);
bool alarm = fields[8].compare("true") == 0;
if (grouped) {
if (isSpectrum) {
cerr << "ERROR: Wrong attribute configuration property for " << attributeList[i] << endl;
cerr << "ERROR: Cannot group spectrum attribute" << endl;
exit(0);
}
// We group all blm attribute in only one (for scalar only)
DynAttribute *att = new DynAttribute(name.c_str(), type, rwType,expert);
add_attribute(att);
if( type==Tango::DEV_ENUM ) {
// Retrieve the enum list from the first attribute
// All grouped attributes must have the same list
// get_device starts at one !!!!!
Tango::AttributeInfoEx ae = deviceGroup->get_device(1)->get_attribute_config(attNames[0]);
Tango::Attribute &eAtt = get_device_attr()->get_attr_by_name(name.c_str());
Tango::MultiAttrProp presetProps;
eAtt.get_properties(presetProps);
presetProps.enum_labels = ae.enum_labels;
eAtt.set_properties(presetProps);
}
} else {
DynSpectrumAttribute *att;
if (!isSpectrum) {
// Map scalar attritbute to spectrum (convert all type to double except state)
if (type != Tango::DEV_STATE)
att = new DynSpectrumAttribute(name.c_str(), Tango::DEV_DOUBLE, deviceList.size() * attNames.size(), rwType, expert);
else
att = new DynSpectrumAttribute(name.c_str(), Tango::DEV_STATE, deviceList.size() * attNames.size(), rwType, expert);
} else {
// Map spectrum attritbute to mulitple spectrum
if (rwType == Tango::READ_WRITE) {
cerr << "ERROR: Wrong attribute configuration property for " << attributeList[i] << endl;
cerr << "ERROR: ReadWrite mode not supported for multiple spectrum" << endl;
exit(0);
}
att = new DynSpectrumAttribute(name.c_str(), Tango::DEV_DOUBLE, deviceList.size() * attNames.size() * MAXVALUELENGTH, rwType, expert);
}
add_attribute(att);
}
attMap.add(name, attNames, grouped, type, rwType, isSpectrum, lengthAttName, alarm);
}
// Attribute ref list
for (int i = 0; i < (int) attributeRefList.size(); i++) {
DynSpectrumAttribute *att;
att = new DynSpectrumAttribute(attributeRefList[i].c_str(), Tango::DEV_DOUBLE, MAXVALUELENGTH, Tango::READ_WRITE, true);
add_attribute(att);
attMap.addRef(attributeRefList[i].c_str());
}
// States attribute
if( deviceList.size()>0 ) {
vector stateName;
stateName.push_back("State");
DynSpectrumAttribute *stateAtt = new DynSpectrumAttribute("States", Tango::DEV_STATE, deviceList.size(),Tango::READ, false);
add_attribute(stateAtt);
attMap.add("States", stateName, false, Tango::DEV_STATE, Tango::READ, false, "None", false);
}
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::add_dynamic_attributes
}
//--------------------------------------------------------
/**
* Command ResetError related method
* Description: Reset Error stack
*
*/
//--------------------------------------------------------
void AttributeCombiner::reset_error()
{
DEBUG_STREAM << "AttributeCombiner::ResetError() - " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::reset_error) ENABLED START -----*/
for (int i = 0; i < (int) errorStack.size(); i++)
errorStack[i].errList.clear();
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::reset_error
}
//--------------------------------------------------------
/**
* Command UpdateSetpoint related method
* Description: Update local setpoints from device setpoints
*
*/
//--------------------------------------------------------
void AttributeCombiner::update_setpoint()
{
DEBUG_STREAM << "AttributeCombiner::UpdateSetpoint() - " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::update_setpoint) ENABLED START -----*/
// Force update of setpoints at the next reading
for(int i=0;i<(int)attMap.size();i++) {
ATTITEM *item = attMap.get(i);
item->setInit = false;
}
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::update_setpoint
}
//--------------------------------------------------------
/**
* Command EnableDevice related method
* Description: Enable device
*
* @param argin Enable device #i
*/
//--------------------------------------------------------
void AttributeCombiner::enable_device(Tango::DevShort argin)
{
DEBUG_STREAM << "AttributeCombiner::EnableDevice() - " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::enable_device) ENABLED START -----*/
if(argin<0 || argin>=(short)deviceList.size()) {
Tango::Except::throw_exception(
(const char *) "AttributeCombiner::error_write",
(const char *) "Invalid device index",
(const char *) "AttributeCombiner::disable_device");
}
deviceGroup->enable(deviceList[argin]);
saveDisabledBLM();
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::enable_device
}
//--------------------------------------------------------
/**
* Command DisableDevice related method
* Description: Disable device
*
* @param argin Disable device #i
*/
//--------------------------------------------------------
void AttributeCombiner::disable_device(Tango::DevShort argin)
{
DEBUG_STREAM << "AttributeCombiner::DisableDevice() - " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::disable_device) ENABLED START -----*/
if(argin<0 || argin>=(short)deviceList.size()) {
Tango::Except::throw_exception(
(const char *) "AttributeCombiner::error_write",
(const char *) "Invalid device index",
(const char *) "AttributeCombiner::disable_device");
}
deviceGroup->disable(deviceList[argin]);
saveDisabledBLM();
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::disable_device
}
//--------------------------------------------------------
/**
* Command Indice2Devicename related method
* Description: Return the devicename associated to the input indice
*
* @param argin indice of device (from 0)
* @returns
*/
//--------------------------------------------------------
Tango::DevString AttributeCombiner::indice2_devicename(Tango::DevShort argin)
{
Tango::DevString argout;
DEBUG_STREAM << "AttributeCombiner::Indice2Devicename() - " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::indice2_devicename) ENABLED START -----*/
if(argin<0 || argin>=(short)deviceList.size()) {
Tango::Except::throw_exception(
(const char *) "AttributeCombiner::error_write",
(const char *) "Invalid device index",
(const char *) "AttributeCombiner::indice2_devicename");
}
argout = CORBA::string_dup(deviceList[argin].c_str());
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::indice2_devicename
return argout;
}
//--------------------------------------------------------
/**
* Command Devicename2Indice related method
* Description:
*
* @param argin Devicename
* @returns indice of device (from 0) if the devicename is found. -1 otherwise
*/
//--------------------------------------------------------
Tango::DevShort AttributeCombiner::devicename2_indice(Tango::DevString argin)
{
Tango::DevShort argout;
DEBUG_STREAM << "AttributeCombiner::Devicename2Indice() - " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::devicename2_indice) ENABLED START -----*/
string devicename = argin;
for (argout=0; argout <(short)deviceList.size(); argout++) {
if (deviceList[argout] == devicename) return argout;
}
argout = -1;
Tango::Except::throw_exception(
(const char *) "AttributeCombiner::error_write",
(const char *) "devicename not found",
(const char *) "AttributeCombiner::disable_device");
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::devicename2_indice
return argout;
}
//--------------------------------------------------------
/**
* Command DisableAll related method
* Description:
*
*/
//--------------------------------------------------------
void AttributeCombiner::disable_all()
{
DEBUG_STREAM << "AttributeCombiner::DisableAll() - " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::disable_all) ENABLED START -----*/
for(int i=0;i<(int)deviceList.size();i++)
deviceGroup->disable(deviceList[i]);
saveDisabledBLM();
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::disable_all
}
//--------------------------------------------------------
/**
* Command EnableAll related method
* Description:
*
*/
//--------------------------------------------------------
void AttributeCombiner::enable_all()
{
DEBUG_STREAM << "AttributeCombiner::EnableAll() - " << device_name << endl;
/*----- PROTECTED REGION ID(AttributeCombiner::enable_all) ENABLED START -----*/
for(int i=0;i<(int)deviceList.size();i++)
deviceGroup->enable(deviceList[i]);
saveDisabledBLM();
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::enable_all
}
//--------------------------------------------------------
/**
* Method : AttributeCombiner::add_dynamic_commands()
* Description : Create the dynamic commands if any
* for specified device.
*/
//--------------------------------------------------------
void AttributeCombiner::add_dynamic_commands()
{
/*----- PROTECTED REGION ID(AttributeCombiner::add_dynamic_commands) ENABLED START -----*/
for(int i=0;i<(int)commandList.size();i++) {
// Create command
DynCommandClass *cmd = new DynCommandClass(commandList[i].c_str(),Tango::DEV_VOID,Tango::DEV_VOID);
add_command(cmd);
}
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::add_dynamic_commands
}
/*----- PROTECTED REGION ID(AttributeCombiner::namespace_ending) ENABLED START -----*/
template
void AttributeCombiner::READG(Tango::Attribute &attr,inType &value,ATTITEM *item,Tango::GroupAttrReplyList arl[]) {
// READ grouped attribute
// Set to alarm if not all value are equal
string &attName = attr.get_name();
bool allEqual = true;
bool firstValue = true;
int nbAtt = (int)item->attNames.size();
int nbDev = (int)deviceGroup->get_size();
for (int i = 0; i < nbDev; i++) {
for (int j = 0; j < nbAtt; j++) {
if (!arl[j][i].has_failed() && arl[j][i].group_element_enabled()) {
inType val;
arl[j][i] >> val;
if (firstValue) {
value = val;
firstValue = false;
} else {
allEqual = allEqual && (val == value);
}
} else {
if(arl[j][i].group_element_enabled()) {
addError(i, arl[j][i]);
allEqual = false;
}
}
}
}
if (firstValue) {
/* All reading failed */
attr.set_quality(Tango::ATTR_INVALID);
} else {
attr.set_value(&value);
if (!allEqual && item->manageAlarm)
attr.set_quality(Tango::ATTR_ALARM);
if (!item->setInit &&
item->rwType == Tango::READ_WRITE) {
Tango::WAttribute &att = getAtt(attName);
att.set_write_value(value);
item->setInit = true;
}
}
}
/* ------------------------------------------------------------------------------- */
void AttributeCombiner::read_dyn_attributes(Tango::Attribute &attr, DynAttribute *src) {
string &attName = attr.get_name();
ATTITEM *item = attMap.get(attName);
if (item == NULL) {
Tango::Except::throw_exception(
(const char *) "BLMAll::error_read",
(const char *) "Unknown attribute",
(const char *) "BLMAll::read_dyn_attributes");
}
// Read all values
Tango::GroupAttrReplyList arl[MAXATTRIBUTE];
int nbAtt = (int)item->attNames.size();
for(int i=0;iread_attribute(item->attNames[i]);
switch (item->type) {
case Tango::DEV_BOOLEAN:
READG(attr,item->bVal,item,arl);
break;
case Tango::DEV_USHORT:
READG(attr,item->usVal,item,arl);
break;
case Tango::DEV_SHORT:
READG(attr,item->sVal,item,arl);
break;
case Tango::DEV_ULONG:
READG(attr,item->ulVal,item,arl);
break;
case Tango::DEV_LONG:
READG(attr,item->lVal,item,arl);
break;
case Tango::DEV_LONG64:
READG(attr,item->lVal64,item,arl);
break;
case Tango::DEV_ULONG64:
READG(attr,item->ulVal64,item,arl);
break;
case Tango::DEV_DOUBLE:
READG(attr,item->dVal,item,arl);
break;
case Tango::DEV_ENUM:
READG(attr,item->eVal,item,arl);
break;
}
}
/* ------------------------------------------------------------------------------- */
template
void AttributeCombiner::WRITEG(Tango::WAttribute &attr,ATTITEM *item,Tango::GroupReplyList arl[]) {
// WRITE grouped attribute
T w_val;
attr.get_write_value(w_val);
int nbAtt = (int)item->attNames.size();
for(int i=0;iattNames[i], w_val);
arl[i] = deviceGroup->write_attribute(da);
}
}
void AttributeCombiner::write_dyn_attributes(Tango::WAttribute &attr, DynAttribute *src) {
ATTITEM *item = attMap.get(attr.get_name());
if (item == NULL) {
Tango::Except::throw_exception(
(const char *) "AttributeCombiner::error_write",
(const char *) "Unknown attribute",
(const char *) "AttributeCombiner::write_dyn_attributes");
}
Tango::GroupReplyList arl[MAXATTRIBUTE];
int nbAtt = (int)item->attNames.size();
int nbDev = (int)deviceGroup->get_size();
switch (item->type) {
case Tango::DEV_BOOLEAN:
WRITEG(attr,item,arl);
break;
case Tango::DEV_USHORT:
WRITEG(attr,item,arl);
break;
case Tango::DEV_SHORT:
WRITEG(attr,item,arl);
break;
case Tango::DEV_ENUM:
WRITEG(attr,item,arl);
break;
case Tango::DEV_LONG:
WRITEG(attr,item,arl);
break;
case Tango::DEV_LONG64:
WRITEG(attr,item,arl);
break;
case Tango::DEV_ULONG:
WRITEG(attr,item,arl);
break;
case Tango::DEV_ULONG64:
WRITEG(attr,item,arl);
break;
case Tango::DEV_DOUBLE:
WRITEG(attr,item,arl);
break;
}
// Check results
for(int j=0;jattNames[0].c_str(),
(const char *) arl[j][i].get_err_stack().get_buffer()[0].desc);
Tango::Except::throw_exception(
(const char *) "AttributeCombiner::error_write",
(const char *) errStr,
(const char *) "AttributeCombiner::write_dyn_attributes");
}
}
}
}
/* ------------------------------------------------------------------------------- */
template
void AttributeCombiner::READSCALAR(Tango::Attribute &attr,ATTITEM *item,Tango::GroupAttrReplyList arl[],outType invalid,outType disableValue) {
string& attName = attr.get_name();
int nbAtt = (int) item->attNames.size();
int nbDev = deviceGroup->get_size();
int size = nbDev * nbAtt;
// Read scalar attribute and combime them to spectrum
outType *result = new outType[size];
for (int i = 0; i < nbDev; i++) {
for (int j = 0; j < nbAtt; j++) {
if (arl[j][i].has_failed()) {
result[i * nbAtt + j] = invalid;
addError(i, arl[j][i]);
} else {
if(arl[j][i].group_element_enabled()) {
inType v;
arl[j][i] >> v;
result[i * nbAtt + j] = (outType) v;
} else {
result[i * nbAtt + j] = disableValue;
}
}
}
}
if (!item->setInit &&
item->rwType == Tango::READ_WRITE) {
Tango::WAttribute &att = getAtt(attName);
att.set_write_value(result, size);
item->setInit = true;
}
attr.set_value(result, size, 0, true);
}
/* ------------------------------------------------------------------------------- */
template
void AttributeCombiner::READSPECTRUM(Tango::Attribute &attr,ATTITEM *item,Tango::GroupAttrReplyList arl[]) {
// Read spectrum attribute and combime them to multiple spectrum
Tango::DevULong length;
int nbAtt = (int) item->attNames.size();
int nbDev = deviceGroup->get_size();
int size = nbDev * nbAtt;
if(isNumber(item->lengthAttName))
length = atol(item->lengthAttName.c_str());
else
self->read_attribute(item->lengthAttName) >> length;
int blockSize = length * nbAtt;
Tango::DevDouble *result = new Tango::DevDouble[length * size];
for (int i = 0; i < nbDev; i++) {
for (int j = 0; j < nbAtt; j++) {
if (arl[j][i].has_failed()) {
for (int k = 0; k < (int) length; k++)
result[i * blockSize + j * length + k] = NAN;
addError(i, arl[j][i]);
} else {
if(arl[j][i].group_element_enabled()) {
int k = 0;
vector v;
arl[j][i] >> v;
for (k = 0; k < (int) length && k < (int) v.size(); k++)
result[i * blockSize + j * length + k] = (Tango::DevDouble) v[k];
for (; k < (int) length; k++)
result[i * length * nbAtt + j * length + k] = NAN;
} else {
// Disabled device
for (int k = 0; k < (int) length; k++)
result[i * blockSize + j * length + k] = NAN;
}
}
}
}
attr.set_value(result, length * size, 0, true);
}
/* ------------------------------------------------------------------------------- */
void AttributeCombiner::read_dynspec_attributes(Tango::Attribute &attr,DynSpectrumAttribute *src) {
string& attName = attr.get_name();
ATTITEM *item = attMap.get(attName);
if( item==NULL ) {
Tango::Except::throw_exception(
(const char *)"BLMAll::error_read",
(const char *)"Unknown attribute",
(const char *)"BLMAll::read_dynspec_attributes");
}
// Attribute ref
if(item->isRef) {
if(item->refData!=NULL)
attr.set_value(item->refData, item->refSize);
return;
}
Tango::GroupAttrReplyList arl[MAXATTRIBUTE];
// Read all attribute
int nbAtt = (int)item->attNames.size();
for(int i=0;iread_attribute(item->attNames[i]);
switch (item->type) {
case Tango::DEV_BOOLEAN:
if(item->isSpectrum)
READSPECTRUM(attr,item,arl);
else
READSCALAR(attr,item,arl,NAN,NAN);
break;
case Tango::DEV_ENUM:
if(item->isSpectrum)
READSPECTRUM(attr,item,arl);
else
READSCALAR(attr,item,arl,NAN,NAN);
break;
case Tango::DEV_USHORT:
if(item->isSpectrum)
READSPECTRUM(attr,item,arl);
else
READSCALAR(attr,item,arl,NAN,NAN);
break;
case Tango::DEV_SHORT:
if(item->isSpectrum)
READSPECTRUM(attr,item,arl);
else
READSCALAR(attr,item,arl,NAN,NAN);
break;
case Tango::DEV_LONG:
if(item->isSpectrum)
READSPECTRUM(attr,item,arl);
else
READSCALAR(attr,item,arl,NAN,NAN);
break;
case Tango::DEV_ULONG:
if(item->isSpectrum)
READSPECTRUM(attr,item,arl);
else
READSCALAR(attr,item,arl,NAN,NAN);
break;
case Tango::DEV_LONG64:
if(item->isSpectrum)
READSPECTRUM(attr,item,arl);
else
READSCALAR(attr,item,arl,NAN,NAN);
break;
case Tango::DEV_ULONG64:
if(item->isSpectrum)
READSPECTRUM(attr,item,arl);
else
READSCALAR(attr,item,arl,NAN,NAN);
break;
case Tango::DEV_STATE:
if(item->isSpectrum)
READSPECTRUM(attr,item,arl);
else {
if( attName == "States" ) {
READSCALAR(attr, item, arl, Tango::UNKNOWN,Tango::DISABLE);
} else {
READSCALAR(attr, item, arl, Tango::UNKNOWN,Tango::UNKNOWN);
}
}
break;
case Tango::DEV_DOUBLE:
if(item->isSpectrum)
READSPECTRUM(attr,item,arl);
else
READSCALAR(attr,item,arl,NAN,NAN);
break;
}
}
/* ------------------------------------------------------------------------------- */
template
void AttributeCombiner::WRITES(Tango::WAttribute &attr,ATTITEM *item,Tango::GroupReplyList arl[]) {
// Write scalar attributes from combined spectrum
int nbAtt = (int)item->attNames.size();
int nbDev = deviceGroup->get_size();
int size = nbAtt*nbDev;
const inType *w_val;
attr.get_write_value(w_val);
int length = attr.get_write_value_length();
if (length != size) {
char errStr[256];
sprintf(errStr, "Invalid argument size (%d expected)", size);
Tango::Except::throw_exception(
(const char *) "AttributeCombiner::error_write",
(const char *) errStr,
(const char *) "AttributeCombiner::write_dynspec_attributes");
}
for (int k = 0; k < nbAtt; k++) {
vector cw_val;
for (int i = 0; i < nbDev; i++)
cw_val.push_back((outType) w_val[i * nbAtt + k]);
arl[k] = deviceGroup->write_attribute(item->attNames[k], cw_val);
}
}
void AttributeCombiner::write_dynspec_attributes(Tango::WAttribute &attr,DynSpectrumAttribute *src) {
ATTITEM *item = attMap.get(attr.get_name());
if( item==NULL ) {
Tango::Except::throw_exception(
(const char *)"AttributeCombiner::error_read",
(const char *)"Unknown attribute",
(const char *)"AttributeCombiner::read_dynspec_attributes");
}
// Attribute ref
if(item->isRef) {
const Tango::DevDouble *w_val;
attr.get_write_value(w_val);
int length = attr.get_write_value_length();
SAFE_FREE(item->refData);
item->refData = (double *)malloc( length* sizeof(double) );
memcpy(item->refData,w_val,length*sizeof(double));
item->refSize = length;
return;
}
Tango::GroupReplyList arl[MAXATTRIBUTE];
// Read all attributes
switch (item->type) {
case Tango::DEV_USHORT:
WRITES(attr,item,arl);
break;
case Tango::DEV_SHORT:
WRITES(attr,item,arl);
break;
case Tango::DEV_LONG:
WRITES(attr,item,arl);
break;
case Tango::DEV_ULONG:
WRITES(attr,item,arl);
break;
case Tango::DEV_LONG64:
WRITES(attr,item,arl);
break;
case Tango::DEV_ULONG64:
WRITES(attr,item,arl);
break;
case Tango::DEV_STATE:
WRITES(attr,item,arl);
break;
case Tango::DEV_DOUBLE:
WRITES(attr,item,arl);
break;
}
// Check results
int nbAtt = (int)item->attNames.size();
int nbDev = deviceGroup->get_size();
for(int j=0;jattNames[0].c_str(),
(const char *) arl[j][i].get_err_stack().get_buffer()[0].desc);
Tango::Except::throw_exception(
(const char *) "AttributeCombiner::error_write",
(const char *) errStr,
(const char *) "AttributeCombiner::write_dynspec_attributes");
}
}
}
}
void AttributeCombiner::read_dynimg_attributes(Tango::Attribute &attr,DynImageAttribute *src) {
ATTITEM *item = attMap.get(attr.get_name());
if( item==NULL ) {
Tango::Except::throw_exception(
(const char *)"AttributeCombiner::error_write",
(const char *)"Unknown attribute",
(const char *)"AttributeCombiner::write_dynspec_attributes");
}
Tango::Except::throw_exception(
(const char *)"AttributeCombiner::error_write",
(const char *)"Image attribute not supported",
(const char *)"AttributeCombiner::write_dynspec_attributes");
}
void AttributeCombiner::write_dynimg_attributes(Tango::WAttribute &attr,DynImageAttribute *src) {
}
void AttributeCombiner::split(vector &tokens, const string &text, char sep) {
size_t start = 0, end = 0;
tokens.clear();
while ((end = text.find(sep, start)) != string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
}
void AttributeCombiner::tolower(string &s) {
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
}
bool AttributeCombiner::isNumber(std::string value) {
bool ok = true;
int lgth = value.length();
int i = 0;
while(ok && i='0' && value[i]<='9';
i++;
}
return ok;
}
bool AttributeCombiner::isDisabled(int idx) {
return !deviceGroup->is_enabled(deviceList[idx]);
}
int AttributeCombiner::ToTangoType(string name,string type) {
if( type.compare("DevBoolean")==0 ) {
return Tango::DEV_BOOLEAN;
} if( type.compare("DevState")==0 ) {
return Tango::DEV_STATE;
} else if ( type.compare("DevLong")==0 ) {
return Tango::DEV_LONG;
} else if ( type.compare("DevLong64")==0 ) {
return Tango::DEV_LONG64;
} else if ( type.compare("DevUShort")==0 ) {
return Tango::DEV_USHORT;
} else if ( type.compare("DevShort")==0 ) {
return Tango::DEV_SHORT;
} else if ( type.compare("DevULong")==0 ) {
return Tango::DEV_ULONG;
} else if ( type.compare("DevULong64")==0 ) {
return Tango::DEV_ULONG64;
} else if ( type.compare("DevDouble")==0 ) {
return Tango::DEV_DOUBLE;
} else if ( type.compare("DevEnum")==0 ) {
return Tango::DEV_ENUM;
} else {
cerr << "ERROR: Wrong attribute configuration property for " << name << endl;
cerr << "Data type " << type << " not supported" << endl;
exit(0);
}
}
Tango::WAttribute& AttributeCombiner::getAtt(string name) {
return dev_attr->get_w_attr_by_name(name.c_str());
}
void AttributeCombiner::saveDisabledBLM() {
Tango::DbData dbd;
Tango::DbDatum dbt("DisabledDevices");
vector values;
for(int i=0;i<(int)deviceList.size();i++)
if(!deviceGroup->is_enabled(deviceList[i]))
values.push_back(deviceList[i]);
dbt << values;
dbd.push_back(dbt);
get_db_device()->put_property(dbd);
}
void AttributeCombiner::addError(int devIdenx,Tango::GroupAttrReply &reply) {
// Ignore "has not been updated" errors
string errMsg(reply.get_err_stack().get_buffer()[0].desc.in());
if(errMsg.find("has not been updated")!=string::npos)
return;
// Add date
time_t now = time(NULL);
char *dateStr = ctime(&now);
char tmp[128];
tmp[0] = dateStr[8];
tmp[1] = dateStr[9];
tmp[2] = '/';
tmp[3] = dateStr[4];
tmp[4] = dateStr[5];
tmp[5] = dateStr[6];
tmp[6] = '/';
tmp[7] = dateStr[20];
tmp[8] = dateStr[21];
tmp[9] = dateStr[22];
tmp[10] = dateStr[23];
tmp[11] = ' ';
tmp[12] = dateStr[11];
tmp[13] = dateStr[12];
tmp[14] = dateStr[13];
tmp[15] = dateStr[14];
tmp[16] = dateStr[15];
tmp[17] = dateStr[16];
tmp[18] = dateStr[17];
tmp[19] = dateStr[18];
tmp[20] = 0;
string err = string(tmp)+" "+ reply.dev_name() + " " +
string(reply.get_err_stack().get_buffer()[0].desc);
//cout << devIdenx << " " << err << endl;
errorStack[devIdenx].errList.push_back(err);
if(errorStack[devIdenx].errList.size()>MAXERROR)
errorStack[devIdenx].errList.erase(errorStack[devIdenx].errList.begin());
}
void AttributeCombiner::execute_command(string cmdName) {
deviceGroup->command_inout(cmdName);
}
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::namespace_ending
} // namespace