/*----- 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