diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f768f7909ca84a190cd6d52a1522bf55d0a7e55d --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +.pydevproject +.project +.cproject +.settings +obj +bin +core* +*~ +*.pyc +*.so +*.so* +.pylintrc +.metadata +.idea +.cvsignore +.nse_depinfo +software +oldsrc +CVS diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9d1f07d66b55c8e4d0cbad8f8e39bb2c388eb82a --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +NAME_SRV = tango-dev-mapper-srv + + +CXXFLAGS += -I/runtime/elettra/include + + +LDFLAGS += -L/runtime/elettra/lib -llpc -lnc + +include ../makefiles/Make-9.3.3.in + diff --git a/README.md b/README.md index 1eff59656cd21af47a78ad986e2c48ce0568a273..6135bb4ccee37224f8c67007928ad4b82fc6194c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,32 @@ -# tango-dev-mapper +# Project Name -Tango device server used to break up a vector of values into distinct attibutes. Used bi Elettra SCW system. \ No newline at end of file +tango-dev-mapper + +## Description + +Tango device server used to break up a vector of values into distinct attibutes. Used by Elettra SCW system. +The original server was named TangoDevMapper. + +## Installation + +See your institue guidelines for deploying and configuring a Tango device server. + +## Usage + +The server is designed for loggin SCW variables + +## History + +2020-05-04 : project created on gitlab, derived from CVS release_07 + +original development by Giacomo Strangolino + +## Credits + +Elettra-Sincrotrone Trieste S.C.p.A. di interesse nazionale +Strada Statale 14 - km 163,5 in AREA Science Park +34149 Basovizza, Trieste ITALY + +## License + +GPL 3 diff --git a/docs/conf-TangoDevMapper-3hc.txt b/docs/conf-TangoDevMapper-3hc.txt new file mode 100644 index 0000000000000000000000000000000000000000..fd4018acda62eaa20154068ba1d3cbc692c0996a --- /dev/null +++ b/docs/conf-TangoDevMapper-3hc.txt @@ -0,0 +1,56 @@ +# +# Resource backup , created Thu Jun 27 16:14:17 CEST 2013 +# + +#--------------------------------------------------------- +# SERVER tangodevmapper-srv/3hc, TangoDevMapper device declaration +#--------------------------------------------------------- + +tangodevmapper-srv/3hc/DEVICE/TangoDevMapper: "sr/devmapper/3hc" + + +# --- sr/devmapper/3hc properties + +sr/devmapper/3hc->Map: CAV3HC_S11.1_FRQREF_RR:s11.1_frqref,\ + CAV3HC_S11.1_VLT_RR:s11.1vlt,\ + CAV3HC_S11.2_FRQREF_RR:s11.2frqref,\ + CAV3HC_S11.2_VLT_RR:s11.2_vlt,\ + PI3HC_S11_PRES_RR:pi3hc_s11_pres,\ + PI3HCI_S11_PRES_RR:pi3hci_s11_pres,\ + SIP3HC_S11.1_PMEAS_RR:sip3hc_s11.1_pmeas,\ + SIP3HC_S11.1_VMEAS_RR:sip3hc_s11.1_vmeas,\ + "CRY3HC_S11_TEMP_RAR:TT812,TT813,TT814B,TT822,TT823,TT831,TT840,TT841,TT842,TT815C,TT816C,TT825C,TT826C,TT801,TT802,TT810,TT811,TT814A,TT820,TT821,TT830,TT815A,TT815B,TT816A,TT817A,TT825A,TT825B,TT826A,TT827A,TT708,TT707,TT709,TT710,SC1,SC2,SC3,SC4,SC5",\ + "CRY3HC_S11_FLUX_RAR:FT701,FT702,FT703,FT704,FT705",\ + "HEL3HC_S11_ANLGH_RAR:pt275,pt286,pt290,tt220,_1pt358,_1pt350,_1st350,_1tt450,_1tt459,_2pt358,_2pt350,_2st350,_2tt450,_2tt459,pt300,pt302,pt359,qt536,pt371,tt309,tt319,tt345,tt401,tt420,tt460,tt480,pt612,pt703,pt704,pt705,pt706,lt607,pt373,tt606,tt609,adt1,adt2,k1bcfcv450,k2bcfcv450,k3bcfcv450,apt2,ate2",\ + "CRYAL_S11_ANLGC_RAR:tt813,tt823,tt842,ft706,tt802,pt702,ht700,pt832,lt833,tt707,tt708,tt709,tt710,dpt701,dpt707",\ + "CRYAL_S11_VLACTC_RAR:tcv701,tcv702,tcv703,tcv706,fcv704,pcv708,eh834,pcv707",\ + "HEL3HC_S11_VLACTH_RAR:pcv275,pcv280,pcv289,fcv450,fcv465,fcv469,fcv470,fcv481,lcv705" +sr/devmapper/3hc->polled_attr: lcv705,\ + 3000 +sr/devmapper/3hc->TangoDevice: "rpcbridge/RPC2TangoBridge/3hc" +sr/devmapper/3hc->__SubDevices: "rpcbridge/rpc2tangobridge/3hc" + +# --- sr/devmapper/3hc attribute properties + +sr/devmapper/3hc/lcv705->abs_change: 0.7 +sr/devmapper/3hc/lcv705->description: "This attribute maps the element 8 (starting from 0) of the attribute HEL3HC_S11_VLACTH_RAR of the device rpcbridge/RPC2TangoBridge/3hc. Read attribute properties for a more detailed description" +sr/devmapper/3hc/lcv705->event_period: 1000 + +#--------------------------------------------------------- +# CLASS TangoDevMapper properties +#--------------------------------------------------------- + +CLASS/TangoDevMapper->cvs_location: "/home/cvsadm/cvsroot/elettra/server/TangoDevMapper/" +CLASS/TangoDevMapper->cvs_tag: release_05 +CLASS/TangoDevMapper->Description: "This is a mapper that can run on top of a Tango Server exporting attributes.",\ + "Those attributes can be mapped into other attributes, with other names",\ + "and other dimensions.",\ + "The configuration is made acting on the device properties." +CLASS/TangoDevMapper->doc_url: "http://www.esrf.fr/computing/cs/tango/tango_doc/ds_doc/" +CLASS/TangoDevMapper->InheritedFrom: Device_4Impl +CLASS/TangoDevMapper->ProjectTitle: "A mapper to map certain attributes into others" + + +# --- dserver/tangodevmapper-srv/3hc properties + +dserver/tangodevmapper-srv/3hc->polling_threads_pool_conf: "sr/devmapper/3hc" diff --git a/src/ClassFactory.cpp b/src/ClassFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7fb09b332b8d0db13dbbfa17073862d9f4a988f7 --- /dev/null +++ b/src/ClassFactory.cpp @@ -0,0 +1,47 @@ +static const char *RcsId = "$Header: /home/cvsadm/cvsroot/elettra/server/tangodevmapper/src/ClassFactory.cpp,v 1.1.1.1 2008-04-28 09:17:54 giacomo Exp $"; +//+============================================================================= +// +// file : ClassFactory.cpp +// +// description : C++ source for the class_factory method of the DServer +// device class. This method is responsible to create +// all class singletin for a device server. It is called +// at device server startup +// +// project : TANGO Device Server +// +// $Author: giacomo $ +// +// $Revision: 1.1.1.1 $ +// +// $Log: ClassFactory.cpp,v $ +// Revision 1.1.1.1 2008-04-28 09:17:54 giacomo +// Prima release di TangoDevMapper. Aprile 2008 +// +// +// copyleft : European Synchrotron Radiation Facility +// BP 220, Grenoble 38043 +// FRANCE +// +//-============================================================================= +// +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +// +// (c) - Software Engineering Group - ESRF +//============================================================================= + + +#include <tango.h> +#include <TangoDevMapperClass.h> + +/** + * Create TangoDevMapperClass singleton and store it in DServer object. + */ + +void Tango::DServer::class_factory() +{ + + add_class(TangoDevMapper_ns::TangoDevMapperClass::init("TangoDevMapper")); + +} diff --git a/src/MapAttributeAllocator.cpp b/src/MapAttributeAllocator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8049217e587ba521ef1321de7c48c8359584f0c2 --- /dev/null +++ b/src/MapAttributeAllocator.cpp @@ -0,0 +1,212 @@ +#include <tango.h> +#include "MappedAttr.h" +#include "MapAttributeAllocator.h" + +#define ELEMLEN 1024 + +using namespace std; +using namespace Tango; + +namespace TangoDevMapper_ns +{ + +MapAttributeAllocator::MapAttributeAllocator(string entry, string defaultDevname) +{ + //char failure[265]; + attrs.clear(); + err = "No error"; + string devname; + string attname; + string dev_and_att, attlist; + vector<string> devparts; + vector<string> attatt; + vector<string> elems; + bool error = false; + unsigned int i; + MappedAttr *attr = NULL; + + attatt = split(entry, ':'); + if(attatt.size() != 2) + { + _failure_reason = "there is no ':' separator between the device name and the\n" + " list of attributes or there are more than one ':' in the string \n \"" + + entry + "\""; + _invalid = error = true; + } + else /* two parts correctly separated by a ':' */ + { + dev_and_att = attatt[0]; + attlist = attatt[1]; + + devparts = split(dev_and_att, '/'); + if(devparts.size() == 1) /* only the attribute name */ + { + devname = defaultDevname; + attname = devparts[0]; + } + else if(devparts.size() == 4) /* device name specified, e.g. test/device/1 */ + { + devname = devparts[0] + "/" + devparts[1] + "/" + devparts[2]; + attname = devparts[3]; + } + else + { + error = _invalid = true; + _failure_reason = "device name/attribute name \"" + dev_and_att + "\"" + + "not in the format " + " \"domain/family/member/attrname\""; + } + + + /* if there are no errors, split the attribute list into the elements of + * the map. Until now there are attname and device name. + */ + if(!error) + { + elems = split(attlist, ','); + + for(i = 0; i < elems.size(); i++) + { +// printf("\e[1;32m* \e[0mcreating attribute \"%s\" that maps\n" +// " the attribute \"%s\" of the device \"%s\"\n", +// elems[i].c_str(), attname.c_str(), devname.c_str()); + attr = createAttribute(devname, attname, elems[i], i); + attrs.push_back(attr); + } + } + + } + +} + +MappedAttr* MapAttributeAllocator::createAttribute(string devname, string attname, + string map, int index) +{ + DeviceProxy* dev; + char failure[256]; + if(devname == "") + { + snprintf(failure, 256, + "Device name not specified for attribute \"%s\" " + " which should be mapped into \"%s\"" + " Try specifying the property \"TangoDevice\" in the device" + " properties or be sure to have provided a tango device name" + " for each attribute to be mapped" + " \"Map\" class property ",attname.c_str(),devname.c_str()); + _invalid = true; + _failure_reason = string(failure); + return NULL; + } + if(attname == "") + { +// printf("\e[1;4;36minfo\e[0m: skipping element %d of attribute \"%s\"\n" +// " of the device \"%s\"\n", index, attname.c_str(), +// devname.c_str()); + return NULL; /* but still valid */ + } + try + { + dev = new DeviceProxy(devname); + try + { + AttributeInfoEx ai = dev->attribute_query(attname); + AttrWriteType wt = ai.writable; + AttrDataFormat df = ai.data_format; + int data_t = ai.data_type; + int max_x = ai.max_dim_x; + + if(max_x < index) + { + snprintf(failure, 256, "the index %d is greater than the" + " attribute maximum x dimension (%d)", index, + max_x); + _invalid = true; + _failure_reason = string(failure); + return NULL; + } + MappedAttr *ma = new MappedAttr(map.c_str(), data_t, wt, df, + devname, attname, index); + _invalid = false; + delete dev; + return ma; + } + catch(DevFailed &e) + { + snprintf(failure, 256, "failed to obtain attribute information" + " about \"%s\" while mapping into \"%s\"" + "%s ", + attname.c_str(), map.c_str(), + MappedAttr::exception("", e).c_str()); + _invalid = true; + _failure_reason = string(failure); + return NULL; + } + } + catch(DevFailed &e) + { + snprintf(failure, 256, "failed to open device \"%s\"" + " while mapping \"%s\" into \"%s\"%s", devname.c_str(), + attname.c_str(), map.c_str(), + MappedAttr::exception("tango exception", e).c_str()); + _invalid = true; + _failure_reason = string(failure); + return NULL; + } + +} + +vector<string> MapAttributeAllocator::split(string s, const char delim) +{ + int *delimiters; + vector<string> ret; + char el[ELEMLEN]; + unsigned int i, delimcnt = 0; + for(i = 0; i < s.length(); i++) + { + if(s[i] == delim) + delimcnt++; + } + delimiters = new int[delimcnt+2]; + delimiters[0] = -1; + delimcnt = 1; + + for(i = 0; i < s.length(); i++) + { + if(s[i] == delim) + { + delimiters[delimcnt] = i; + delimcnt++; + } + } + delimiters[delimcnt] = s.length(); + + for(i = 0; i < delimcnt; i++) + { + memset(el, 0, ELEMLEN); + if(delimiters[i+1] - delimiters[i] - 1 < ELEMLEN) + { + strncpy(el, s.c_str() + delimiters[i] + 1, delimiters[i+1] - delimiters[i] - 1); + ret.push_back(el); + } + else + { +// printf("\e[1;31m*\e[0m the element %d (between positions %d and" +// " %d) is too long (%d characters)!\n" +// " The maximum size for an attribute name is %d\n", +// ret.size() + 1, delimiters[i] + 1, delimiters[i+1], +// delimiters[i+1] - delimiters[i] - 1, ELEMLEN); + exit(EXIT_FAILURE); + } + } + + delete delimiters; + return ret; +} + + + +} /* namespace */ + + + + diff --git a/src/MapAttributeAllocator.h b/src/MapAttributeAllocator.h new file mode 100644 index 0000000000000000000000000000000000000000..d00c7bbe13b82ede2833110889480d7c3d989e73 --- /dev/null +++ b/src/MapAttributeAllocator.h @@ -0,0 +1,44 @@ +#ifndef MAP_ATTRIBUTE_ALLOCATOR +#define MAP_ATTRIBUTE_ALLOCATOR + +#include <iostream> +#include <vector> +#include <map> + + +using namespace std; +using namespace Tango; + +namespace TangoDevMapper_ns +{ + +class MappedAttr; + +class MapAttributeAllocator +{ + public: + MapAttributeAllocator(string entry, string defaultDevname); + + vector<MappedAttr*> attributes() { return attrs; } + + string error() { return err; } + + bool isValid() { return !_invalid; } + string failureReason() { return _failure_reason; } + void setFailureReason(string _fail) { _failure_reason = _fail; } + + + private: + vector<MappedAttr*> attrs; + MappedAttr* createAttribute(string devname, string attname, + string map, int index); + vector<string> split(string s, const char delim); + string err, _failure_reason; + bool _invalid; + char failure[256]; +}; + +} /* namespace */ + +#endif + diff --git a/src/MappedAttr.cpp b/src/MappedAttr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..afef311e4d9c5be5198ac008e607051e6817d110 --- /dev/null +++ b/src/MappedAttr.cpp @@ -0,0 +1,58 @@ +#include <MappedAttr.h> +namespace TangoDevMapper_ns +{ + +MappedAttr::MappedAttr(const char *name,long data_type,Tango::AttrWriteType w_type, + AttrDataFormat data_f, + string devnam, string attnam, int index) : + Attr(name, data_type, w_type) +{ + char description[512]; + UserDefaultAttrProp default_att_prop; + devname = devnam; + attname = attnam; + _name = string(name); + _index = index; + _data_type = data_type; + _write_type = w_type; + _data_format = data_f; + if(_data_format == Tango::SCALAR) + snprintf(description, 512, "This attribute maps the" + " attribute %s of the device %s (one to one map)." + " Read attribute properties for a more detailed description", + attributeName().c_str(), deviceName().c_str()); + else if(_data_format == Tango::SPECTRUM) + snprintf(description, 512, "This attribute maps the element %d (starting from 0) of the " + " attribute %s of the device %s. Read attribute properties for a more detailed description", + index, attributeName().c_str(), deviceName().c_str()); + + default_att_prop.set_description(description); + set_default_properties(default_att_prop); +} + +MappedAttr::~MappedAttr() +{ +// printf("deleting \"%s\"\n", name.c_str()); +} + +string MappedAttr::exception(const char* msg, Tango::DevFailed &e) +{ + string err, descr, orig; + char exc[256]; + int i; + for(i = e.errors.length() - 1; i >= 0; i--) + { + err = e.errors[i].reason; + descr = e.errors[i].desc; + orig = e.errors[i].origin; + } + snprintf(exc, 256, "%s\n%s\n%s\n%s\n", msg, err.c_str(), + descr.c_str(), orig.c_str()); + return string(exc); +} + +} /* namespace ends */ + + + + diff --git a/src/MappedAttr.h b/src/MappedAttr.h new file mode 100644 index 0000000000000000000000000000000000000000..0b7921411511a8c58480cc7f1eb6b613d8147e7a --- /dev/null +++ b/src/MappedAttr.h @@ -0,0 +1,65 @@ +#ifndef _MAPPED_ATTR_H +#define _MAPPED_ATTR_H + +#include <tango.h> +#include <stdio.h> +#include <stdlib.h> +#include "TangoDevMapper.h" + +using namespace Tango; + + +namespace TangoDevMapper_ns +{ + +class MappedAttr : public Tango::Attr +{ + public: + MappedAttr(const char *name,long data_type,Tango::AttrWriteType w_type, + AttrDataFormat data_f, string devnam, string attnam, int ind); + + ~MappedAttr() ; + virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) + {(static_cast<TangoDevMapper *>(dev))->read_MappedAttr(att);} + virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) + {return (static_cast<TangoDevMapper *>(dev))->is_MappedAttr_allowed(ty);} + + string deviceName() { return devname; } + string attributeName() { return attname; } + string name() { return _name; } + + Tango::AttrWriteType writeType() { return _write_type; } + + /** dataType(): DEV_LONG, DEV_STRING... */ + long dataType() { return _data_type; } + + /** dataFormat() : SCALAR, SPECTRUM, IMAGE */ + Tango::AttrDataFormat dataFormat() { return _data_format; } + + int index() { return _index; } + + + + static string exception(const char* msg, Tango::DevFailed &e); + + private: + string devname, attname, _name; + int _index; + long _data_type; + Tango::AttrWriteType _write_type; + Tango::AttrDataFormat _data_format; +}; + + + + + + + + + + +} + +#endif + diff --git a/src/RPCMapperStateMachine.cpp b/src/RPCMapperStateMachine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..746d7cd69dc8bf4040bb90cd074ca59809f76045 --- /dev/null +++ b/src/RPCMapperStateMachine.cpp @@ -0,0 +1,60 @@ +static const char *RcsId = "$Header: /home/cvsadm/cvsroot/elettra/server/tangodevmapper/src/RPCMapperStateMachine.cpp,v 1.1.1.1 2008-04-28 09:17:54 giacomo Exp $"; +//+============================================================================= +// +// file : TangoDevMapperStateMachine.cpp +// +// description : C++ source for the TangoDevMapper and its alowed. +// method for commands and attributes +// +// project : TANGO Device Server +// +// $Author: giacomo $ +// +// $Revision: 1.1.1.1 $ +// +// $Log: RPCMapperStateMachine.cpp,v $ +// Revision 1.1.1.1 2008-04-28 09:17:54 giacomo +// Prima release di TangoDevMapper. Aprile 2008 +// +// +// copyleft : European Synchrotron Radiation Facility +// BP 220, Grenoble 38043 +// FRANCE +// +//-============================================================================= +// +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +// +// (c) - Software Engineering Group - ESRF +//============================================================================= + +#include <tango.h> +#include <TangoDevMapper.h> +#include <TangoDevMapperClass.h> + +/*==================================================================== + * This file contains the methods to allow commands and attributes + * read or write execution. + * + * If you wand to add your own code, add it between + * the "End/Re-Start of Generated Code" comments. + * + * If you want, you can also add your own methods. + *==================================================================== + */ + +namespace TangoDevMapper_ns +{ + +//================================================= +// Attributes Allowed Methods +//================================================= + + +//================================================= +// Commands Allowed Methods +//================================================= + + +} // namespace TangoDevMapper_ns diff --git a/src/TangoDevMapper.cpp b/src/TangoDevMapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..73dbd871b5c3f4253d1d9544667d702beeb2c360 --- /dev/null +++ b/src/TangoDevMapper.cpp @@ -0,0 +1,437 @@ +static const char *RcsId = "$Header: /home/cvsadm/cvsroot/elettra/server/tangodevmapper/src/TangoDevMapper.cpp,v 1.5 2017-07-31 13:01:10 claudio Exp $"; +//+============================================================================= +// +// file : TangoDevMapper.cpp +// +// description : C++ source for the TangoDevMapper 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 +// TangoDevMapper are implemented in this file. +// +// project : TANGO Device Server +// +// $Author: claudio $ +// +// $Revision: 1.5 $ +// +// $Log: TangoDevMapper.cpp,v $ +// Revision 1.5 2017-07-31 13:01:10 claudio +// ticket #1554: porting to tango-9.2.5.a/QTANGO_BASE_CLASS +// +// Revision 1.4 2013-06-27 15:17:41 claudio +// pulizia alcuni warning +// +// Revision 1.3 2013-04-03 13:34:25 claudio +// ticket 729: go to ON state after successufl init +// use tango log instead of printf +// +// Revision 1.2 2012-05-07 10:33:52 claudio +// tango-7.2.6 +// meno printf +// +// Revision 1.1.1.1 2008/04/28 09:17:53 giacomo +// Prima release di TangoDevMapper. Aprile 2008 +// +// +// copyleft : European Synchrotron Radiation Facility +// BP 220, Grenoble 38043 +// FRANCE +// +//-============================================================================= +// +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +// +// (c) - Software Engineering Group - ESRF +//============================================================================= + + + +//=================================================================== +// +// The following table gives the correspondence +// between commands and method name. +// +// Command name| Method name +// ---------------------------------------- +// State | dev_state() +// Status | dev_status() +// +//=================================================================== + + +#include <tango.h> +#include <TangoDevMapper.h> +#include <TangoDevMapperClass.h> +#include "MappedAttr.h" +#include "MapAttributeAllocator.h" + +using namespace std; + +namespace TangoDevMapper_ns +{ + + + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapper::TangoDevMapper(string &s) +// +// description : constructor for simulated TangoDevMapper +// +// in : - cl : Pointer to the DeviceClass object +// - s : Device name +// +//----------------------------------------------------------------------------- +TangoDevMapper::TangoDevMapper(Tango::DeviceClass *cl,string &s) +:TANGO_BASE_CLASS(cl,s.c_str()) +{ + init_device(); +} + +TangoDevMapper::TangoDevMapper(Tango::DeviceClass *cl,const char *s) +:TANGO_BASE_CLASS(cl,s) +{ + init_device(); +} + +TangoDevMapper::TangoDevMapper(Tango::DeviceClass *cl,const char *s,const char *d) +:TANGO_BASE_CLASS(cl,s,d) +{ + init_device(); +} +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapper::delete_device() +// +// description : will be called at device destruction or at init command. +// +//----------------------------------------------------------------------------- +void TangoDevMapper::delete_device() +{ + // Delete device's allocated object + set_state(Tango::CLOSE); + int cnt = 0; + set_status("deallocating attributes"); + std::map<string, MappedAttr *>::iterator iter; + Database *db = new Database(); + DbData db_data; + DbDatum header(" ----- "); + DbDatum attributeName("attributeName"), assocDevName("associatedDevice"), + assocAttributeName("assocAttName"), associatetIsSpectrum("assocAttrIsSpectrum"), + assocSpectrumIndex("assocSpectrumIndex"); + + for(iter = attributesMap.begin(); iter != attributesMap.end(); iter++) + { + cnt++; + MappedAttr *ma = iter->second; + if(ma != NULL) + { + DbDatum attName(iter->first.c_str()); + db_data.push_back(attName); + db_data.push_back(header); + db_data.push_back(attributeName); + db_data.push_back(assocDevName); + db_data.push_back(assocAttributeName); + db_data.push_back(associatetIsSpectrum); + db_data.push_back(assocSpectrumIndex); +// printf("\r \r"); +// printf("- \"%s\"\t", ma->name().c_str()); + fflush(stdout); +// printf("[\e[1;32mok\e[0m]"); + fflush(stdout); + db->delete_device_attribute_property(this->get_name().c_str(), db_data); + db_data.clear(); + } + } +// printf("\r \r"); +// printf(" \e[0m done deleting descriptive attribute properties"); +// printf(" (%d entries.)\n", cnt); + std::map<string, DeviceProxy*>::iterator iter2; + for(iter2 = namesDevsMap.begin(); iter2 != namesDevsMap.end(); iter2++) + { + if(iter2->second != NULL) + delete iter2->second; + } + namesDevsMap.clear(); + attributesMap.clear(); + delete db; +} + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapper::init_device() +// +// description : will be called at device initialization. +// +//----------------------------------------------------------------------------- +void TangoDevMapper::init_device() +{ + INFO_STREAM << "TangoDevMapper::TangoDevMapper() create device " << device_name << endl; + + // Initialise variables to default values + //-------------------------------------------- + unsigned int i, j, cnt = 0, mappednum = 0; + get_device_property(); + string device; + for(i = 0; i < map.size(); i++) + { + MapAttributeAllocator allocator(map[i], tangoDevice); + if(allocator.isValid()) + { + cnt++; + vector<MappedAttr *> mapped = allocator.attributes(); + for(j = 0; j < mapped.size(); j++) + { + if(mapped[j] != NULL) + { + if(addAttributeToAttributeMap(mapped[j])) + { + add_attribute(mapped[j]); + setupDevice(mapped[j]); + mappednum++; + } + else + { + FATAL_STREAM<< "duplicate attribute name "<<mapped[j]->attributeName()<<endl; + exit(EXIT_FAILURE); + } + } + } + } + else + { + ERROR_STREAM<<"error processing entry: "<<map[i]<<" "<<allocator.failureReason()<<endl; + } + } + set_state(Tango::ON); + +} + +void TangoDevMapper::setupAttributesProperties() +{ + //int i; + Tango::Database *db = new Tango::Database(); + long int index; + string deviceName = get_name(); + char *prop1, *prop2, *prop3, *prop4; + std::map<string, MappedAttr *>::iterator iter; + //char description[512]; + + for(iter = attributesMap.begin(); iter != attributesMap.end(); iter++) + { + MappedAttr *a = iter->second; + if(a == NULL) + { + INFO_STREAM<<"skipping a NULL attribute"<<endl; + continue; + } + //char ind[32]; + DbData db_data; + + DbDatum attName(a->name()); + DbDatum header(" ----- "); + DbDatum attributeName("attributeName"), assocDevName("associatedDevice"), + assocAttributeName("assocAttName"), associatetIsSpectrum("assocAttrIsSpectrum"), + assocSpectrumIndex("assocSpectrumIndex"); + prop1 = new char[a->name().length() + 1]; + strncpy(prop1, a->name().c_str(), a->name().length() + 1); + attributeName << a->name().c_str(); + prop2 = new char[a->deviceName().length() + 1]; + strncpy(prop2, a->deviceName().c_str(), a->deviceName().length() + 1); + assocDevName << prop2; + prop3 = new char[a->attributeName().length() + 1]; + strncpy(prop3, a->attributeName().c_str(), a->attributeName().length() + 1); + assocAttributeName << prop3; + + if(a->dataFormat() == Tango::SPECTRUM) + { + attName << (unsigned short) 6; + header << DevString("The following 5 properties are descriptive. Changes will be ignored and lost at next startup"); + db_data.push_back(attName); + db_data.push_back(header); + db_data.push_back(attributeName); + db_data.push_back(assocDevName); + db_data.push_back(assocAttributeName); + index = a->index(); + assocSpectrumIndex << index; + prop4 = new char[4]; + strncpy(prop4, "yes", 4); + associatetIsSpectrum<< prop4; + db_data.push_back(associatetIsSpectrum); + db_data.push_back(assocSpectrumIndex); + } + else + { + attName << (unsigned short) 5; + header << DevString("The following 4 properties are descriptive. Changes will be ignored and lost at next startup"); + db_data.push_back(attName); + db_data.push_back(header); + db_data.push_back(attributeName); + db_data.push_back(assocDevName); + db_data.push_back(assocAttributeName); + char isScalar[16] = "no, is scalar"; + prop4 = new char[strlen(isScalar) + 1]; + strncpy(prop4, isScalar, strlen(isScalar) + 1); + associatetIsSpectrum<< prop4; + db_data.push_back(associatetIsSpectrum); + + } + + try{ +// db->set_timeout_millis(10000); + db->put_device_attribute_property(deviceName.c_str(), db_data); + } + catch(DevFailed &e) + { + ERROR_STREAM<<"failed inserting attribute properties into" << deviceName <<" for "<< a->attributeName()<<endl; + } + + } +} + + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapper::get_device_property() +// +// description : Read the device properties from database. +// +//----------------------------------------------------------------------------- +void TangoDevMapper::get_device_property() +{ + // Initialize your default values here (if not done with POGO). + //------------------------------------------------------------------ + + // Read device properties from database.(Automatic code generation) + //------------------------------------------------------------------ + Tango::DbData dev_prop; + dev_prop.push_back(Tango::DbDatum("Map")); + dev_prop.push_back(Tango::DbDatum("TangoDevice")); + + // Call database and extract values + //-------------------------------------------- + if (Tango::Util::instance()->_UseDb==true) + get_db_device()->get_property(dev_prop); + Tango::DbDatum def_prop, cl_prop; + TangoDevMapperClass *ds_class = + (static_cast<TangoDevMapperClass *>(get_device_class())); + int i = -1; + + // Try to initialize Map from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> map; + else { + // Try to initialize Map from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> map; + } + // And try to extract Map value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> map; + + // Try to initialize TangoDevice from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> tangoDevice; + else { + // Try to initialize TangoDevice from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> tangoDevice; + } + // And try to extract TangoDevice value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> tangoDevice; + + + + // End of Automatic code generation + //------------------------------------------------------------------ + if(tangoDevice == ""){ +// printf("\e[1;33m*\e[0m warning: no generic device specified in the\n" +// " device property \"TangoDevice\": it is supposed that you\n" +// " provide a tango device for each \"Map\" element in the\n" +// " device properties, otherwise the server \e[1;4;37mwill not " +// "start\e[0m\n"); + } +} +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapper::always_executed_hook() +// +// description : method always executed before any command is executed +// +//----------------------------------------------------------------------------- +void TangoDevMapper::always_executed_hook() +{ + +} +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapper::read_attr_hardware +// +// description : Hardware acquisition for attributes. +// +//----------------------------------------------------------------------------- +void TangoDevMapper::read_attr_hardware(vector<long> &attr_list) +{ + DEBUG_STREAM << "TangoDevMapper::read_attr_hardware(vector<long> &attr_list) entering... "<< endl; + // Add your own code here +} + + +bool TangoDevMapper::is_MappedAttr_allowed(Tango::AttReqType type) +{ + return true; + +} + +void TangoDevMapper::setupDevice(MappedAttr * att) +{ + string devname = att->deviceName(); + DeviceProxy* dev = findOpenDevices(devname); + if(dev == NULL) + { + try + { + dev = new DeviceProxy(devname); + /* add it to the map */ + namesDevsMap[devname] = dev; + } + catch(DevFailed &e) + { + ERROR_STREAM<<"failed DevProxy for "<<devname<<e<<endl; + } + } + else{ + DEBUG_STREAM<< "device " <<devname <<" already open"<<endl; + } +} + +DeviceProxy *TangoDevMapper::findOpenDevices(string dname) +{ + std::map<string, DeviceProxy *>::iterator iter = namesDevsMap.find(dname); + if(iter != namesDevsMap.end()) + { + return iter->second; + } + return NULL; +} + +bool TangoDevMapper::addAttributeToAttributeMap(MappedAttr *att) +{ + std::map<string, MappedAttr*>::iterator iter = attributesMap.find(att-> + name()); + if(iter != attributesMap.end()) + { + /* found an attribute with that name: bad */ + return false; + } + else + { + attributesMap[att->name()] = att; + return true; + } +} + + + +} // namespace diff --git a/src/TangoDevMapper.h b/src/TangoDevMapper.h new file mode 100644 index 0000000000000000000000000000000000000000..e7d610f8cc0d82ff58b9ddac1d4fb3cb2ef7acef --- /dev/null +++ b/src/TangoDevMapper.h @@ -0,0 +1,222 @@ +//============================================================================= +// +// file : TangoDevMapper.h +// +// description : Include for the TangoDevMapper class. +// +// project : A mapper to map certain attributes into others +// +// $Author: claudio $ +// +// $Revision: 1.4 $ +// +// $Log: TangoDevMapper.h,v $ +// Revision 1.4 2017-07-31 13:01:10 claudio +// ticket #1554: porting to tango-9.2.5.a/QTANGO_BASE_CLASS +// +// Revision 1.3 2013-06-27 15:17:41 claudio +// pulizia alcuni warning +// +// Revision 1.2 2012-05-07 10:33:52 claudio +// tango-7.2.6 +// meno printf +// +// Revision 1.1.1.1 2008/04/28 09:17:53 giacomo +// Prima release di TangoDevMapper. Aprile 2008 +// +// +// copyleft : European Synchrotron Radiation Facility +// BP 220, Grenoble 38043 +// FRANCE +// +//============================================================================= +// +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +// +// (c) - Software Engineering Group - ESRF +//============================================================================= +#ifndef _TANGODEVMAPPER_H +#define _TANGODEVMAPPER_H + +#include <tango.h> +#include <map> + +//using namespace Tango; + +/** + * @author $Author: claudio $ + * @version $Revision: 1.4 $ + */ + + // Add your own constants definitions here. + //----------------------------------------------- + + + +namespace TangoDevMapper_ns +{ + + using namespace std; + using namespace Tango; + class MappedAttr; + +/** + * Class Description: + * This is a mapper that can run on top of a Tango Server exporting attributes. + * Those attributes can be mapped into other attributes, with other names + * and other dimensions. + * The configuration is made acting on the device properties. + */ + +/* + * Device States Description: + */ + + +class TangoDevMapper: public TANGO_BASE_CLASS +{ +public : + // Add your own data members here + //----------------------------------------- + + + // Here is the Start of the automatic code generation part + //------------------------------------------------------------- +/** + * @name attributes + * Attributs member data. + */ +//@{ +//@} + +/** + * @name Device properties + * Device properties member data. + */ +//@{ +/** + * Each line of the property describes how one attribute of the lower device + * server has to be mapped into one or more attributes of the device mapper.. + * As to the way they are built, the attributes are all scalars. + * Examples: + * + * CurrentArray:current1,current2,current3 + * SIP120_S2.10_PRES_RR:pressure + * + * In the first case, the attribute CurrentArray is split into three scalar attributes. + * The attribute CurrentArray must be long more than 3 elements. + * If it is greater, the first 3 elements are taken. + * If it is shorter, an error occurs. + * In the second case, the attribute is mapped one to one, and hopefully + * the SIP120_S2.10_PRES_RR is itself a scalar and, if spectrum, only its + * first element is mapped. + * + */ + vector<string> map; +/** + * The lower level tango device. + * The lower level tango device will have its attributes mapped into the + * attributes of this device. + * The device name must be in the usual form: + * domain/family/member, e.g.: + * test/device/1 + */ + string tangoDevice; +//@} + +/**@name Constructors + * Miscellaneous constructors */ +//@{ +/** + * Constructs a newly allocated Command object. + * + * @param cl Class. + * @param s Device Name + */ + TangoDevMapper(Tango::DeviceClass *cl,string &s); +/** + * Constructs a newly allocated Command object. + * + * @param cl Class. + * @param s Device Name + */ + TangoDevMapper(Tango::DeviceClass *cl,const char *s); +/** + * Constructs a newly allocated Command object. + * + * @param cl Class. + * @param s Device name + * @param d Device description. + */ + TangoDevMapper(Tango::DeviceClass *cl,const char *s,const char *d); +//@} + +/**@name Destructor + * Only one desctructor is defined for this class */ +//@{ +/** + * The object desctructor. + */ + ~TangoDevMapper() {delete_device();}; +/** + * will be called at device destruction or at init command. + */ + void delete_device(); +//@} + + +/**@name Miscellaneous methods */ +//@{ +/** + * Initialize the device + */ + virtual void init_device(); +/** + * Always executed method befor execution command method. + */ + virtual void always_executed_hook(); + +//@} + +/** + * @name TangoDevMapper methods prototypes + */ + +//@{ + +/** + * Read the device properties from database + */ + void get_device_property(); +//@} + + // Here is the end of the automatic code generation part + //------------------------------------------------------------- + + + void read_attr_hardware(vector<long> &attr_list); + void write_MappedAttr(Tango::WAttribute &attr); + void read_MappedAttr(Tango::Attribute &attr); + bool is_MappedAttr_allowed(Tango::AttReqType type); + + + +protected : + // Add your own data members here + //----------------------------------------- + + private: + vector<string> split_attmap(string s); + vector<string> split(string s, const char delim); + void setupAttributesProperties(); + std::map<string, DeviceProxy*> namesDevsMap; + std::map<string, MappedAttr *>attributesMap; + void setupDevice(MappedAttr *); + bool addAttributeToAttributeMap(MappedAttr *); + DeviceProxy * findOpenDevices(string dname); +}; + +} // namespace_ns + +#endif // _TANGODEVMAPPER_H diff --git a/src/TangoDevMapperClass.cpp b/src/TangoDevMapperClass.cpp new file mode 100644 index 0000000000000000000000000000000000000000..833c4c24f3f400a9281ade258ab781251480c29f --- /dev/null +++ b/src/TangoDevMapperClass.cpp @@ -0,0 +1,479 @@ +static const char *ClassId = "$Id: TangoDevMapperClass.cpp,v 1.2 2012-05-07 10:33:52 claudio Exp $"; +static const char *CvsPath = "$Source: /home/cvsadm/cvsroot/elettra/server/tangodevmapper/src/TangoDevMapperClass.cpp,v $"; +static const char *SvnPath = "$HeadURL: $"; +static const char *RcsId = "$Header: /home/cvsadm/cvsroot/elettra/server/tangodevmapper/src/TangoDevMapperClass.cpp,v 1.2 2012-05-07 10:33:52 claudio Exp $"; +static const char *TagName = "$Name: $"; +static const char *HttpServer= "http://www.esrf.fr/computing/cs/tango/tango_doc/ds_doc/"; +//+============================================================================= +// +// file : TangoDevMapperClass.cpp +// +// description : C++ source for the TangoDevMapperClass. A singleton +// class derived from DeviceClass. It implements the +// command list and all properties and methods required +// by the TangoDevMapper once per process. +// +// project : TANGO Device Server +// +// $Author: claudio $ +// +// $Revision: 1.2 $ +// +// $Log: TangoDevMapperClass.cpp,v $ +// Revision 1.2 2012-05-07 10:33:52 claudio +// tango-7.2.6 +// meno printf +// +// Revision 1.1.1.1 2008/04/28 09:17:54 giacomo +// Prima release di TangoDevMapper. Aprile 2008 +// +// +// copyleft : European Synchrotron Radiation Facility +// BP 220, Grenoble 38043 +// FRANCE +// +//-============================================================================= +// +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +// +// (c) - Software Engineering Group - ESRF +//============================================================================= + + +#include <tango.h> + +#include <TangoDevMapper.h> +#include <TangoDevMapperClass.h> + + +//+---------------------------------------------------------------------------- +/** + * Create TangoDevMapperClass singleton and return it in a C function for Python usage + */ +//+---------------------------------------------------------------------------- +extern "C" { +#ifdef WIN32 + +__declspec(dllexport) + +#endif + + Tango::DeviceClass *_create_TangoDevMapper_class(const char *name) { + return TangoDevMapper_ns::TangoDevMapperClass::init(name); + } +} + + +namespace TangoDevMapper_ns +{ + + +// +//---------------------------------------------------------------- +// Initialize pointer for singleton pattern +//---------------------------------------------------------------- +// +TangoDevMapperClass *TangoDevMapperClass::_instance = NULL; + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::TangoDevMapperClass(string &s) +// +// description : constructor for the TangoDevMapperClass +// +// in : - s : The class name +// +//----------------------------------------------------------------------------- +TangoDevMapperClass::TangoDevMapperClass(string &s):DeviceClass(s) +{ + + cout2 << "Entering TangoDevMapperClass constructor" << endl; + set_default_property(); + get_class_property(); + write_class_property(); + + cout2 << "Leaving TangoDevMapperClass constructor" << endl; + +} +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::~TangoDevMapperClass() +// +// description : destructor for the TangoDevMapperClass +// +//----------------------------------------------------------------------------- +TangoDevMapperClass::~TangoDevMapperClass() +{ + _instance = NULL; +} + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::instance +// +// description : Create the object if not already done. Otherwise, just +// return a pointer to the object +// +// in : - name : The class name +// +//----------------------------------------------------------------------------- +TangoDevMapperClass *TangoDevMapperClass::init(const char *name) +{ + if (_instance == NULL) + { + try + { + string s(name); + _instance = new TangoDevMapperClass(s); + } + catch (bad_alloc) + { + throw; + } + } + return _instance; +} + +TangoDevMapperClass *TangoDevMapperClass::instance() +{ + if (_instance == NULL) + { + cerr << "Class is not initialised !!" << endl; + exit(-1); + } + return _instance; +} + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::command_factory +// +// description : Create the command object(s) and store them in the +// command list +// +//----------------------------------------------------------------------------- +void TangoDevMapperClass::command_factory() +{ + + // add polling if any + for (unsigned int i=0 ; i<command_list.size(); i++) + { + } +} + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::get_class_property +// +// description : Get the class property for specified name. +// +// in : string name : The property name +// +//+---------------------------------------------------------------------------- +Tango::DbDatum TangoDevMapperClass::get_class_property(string &prop_name) +{ + for (unsigned int i=0 ; i<cl_prop.size() ; i++) + if (cl_prop[i].name == prop_name) + return cl_prop[i]; + // if not found, return an empty DbDatum + return Tango::DbDatum(prop_name); +} +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::get_default_device_property() +// +// description : Return the default value for device property. +// +//----------------------------------------------------------------------------- +Tango::DbDatum TangoDevMapperClass::get_default_device_property(string &prop_name) +{ + for (unsigned int i=0 ; i<dev_def_prop.size() ; i++) + if (dev_def_prop[i].name == prop_name) + return dev_def_prop[i]; + // if not found, return an empty DbDatum + return Tango::DbDatum(prop_name); +} + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::get_default_class_property() +// +// description : Return the default value for class property. +// +//----------------------------------------------------------------------------- +Tango::DbDatum TangoDevMapperClass::get_default_class_property(string &prop_name) +{ + for (unsigned int i=0 ; i<cl_def_prop.size() ; i++) + if (cl_def_prop[i].name == prop_name) + return cl_def_prop[i]; + // if not found, return an empty DbDatum + return Tango::DbDatum(prop_name); +} +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::device_factory +// +// description : Create the device object(s) and store them in the +// device list +// +// in : Tango::DevVarStringArray *devlist_ptr : The device name list +// +//----------------------------------------------------------------------------- +void TangoDevMapperClass::device_factory(const Tango::DevVarStringArray *devlist_ptr) +{ + + // Create all devices.(Automatic code generation) + //------------------------------------------------------------- + for (unsigned long i=0 ; i < devlist_ptr->length() ; i++) + { + cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl; + + // Create devices and add it into the device list + //---------------------------------------------------- + device_list.push_back(new TangoDevMapper(this, (*devlist_ptr)[i])); + + // Export device to the outside world + // Check before if database used. + //--------------------------------------------- + if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) + export_device(device_list.back()); + else + export_device(device_list.back(), (*devlist_ptr)[i]); + } + // End of Automatic code generation + //------------------------------------------------------------- + +} + + + + + + + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::get_class_property() +// +// description : Read the class properties from database. +// +//----------------------------------------------------------------------------- +void TangoDevMapperClass::get_class_property() +{ + // Initialize your default values here (if not done with POGO). + //------------------------------------------------------------------ + + // Read class properties from database.(Automatic code generation) + //------------------------------------------------------------------ + + // Call database and extract values + //-------------------------------------------- + if (Tango::Util::instance()->_UseDb==true) + get_db_class()->get_property(cl_prop); + Tango::DbDatum def_prop; + int i = -1; + + + // End of Automatic code generation + //------------------------------------------------------------------ + +} + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::set_default_property +// +// description: Set default property (class and device) for wizard. +// For each property, add to wizard property name and description +// If default value has been set, add it to wizard property and +// store it in a DbDatum. +// +//----------------------------------------------------------------------------- +void TangoDevMapperClass::set_default_property() +{ + string prop_name; + string prop_desc; + string prop_def; + + vector<string> vect_data; + // Set Default Class Properties + // Set Default Device Properties + prop_name = "Map"; + prop_desc = "Each line of the property describes how one attribute of the lower device\nserver has to be mapped into one or more attributes of the device mapper..\nAs to the way they are built, the attributes are all scalars.\nExamples:\n\nCurrentArray:current1,current2,current3\nSIP120_S2.10_PRES_RR:pressure\n\nIn the first case, the attribute CurrentArray is split into three scalar attributes.\nThe attribute CurrentArray must be long more than 3 elements.\nIf it is greater, the first 3 elements are taken.\nIf it is shorter, an error occurs.\nIn the second case, the attribute is mapped one to one, and hopefully\nthe SIP120_S2.10_PRES_RR is itself a scalar and, if spectrum, only its\nfirst element is mapped.\n"; + prop_def = ""; + vect_data.clear(); + if (prop_def.length()>0) + { + Tango::DbDatum data(prop_name); + data << vect_data ; + dev_def_prop.push_back(data); + add_wiz_dev_prop(prop_name, prop_desc, prop_def); + } + else + add_wiz_dev_prop(prop_name, prop_desc); + + prop_name = "TangoDevice"; + prop_desc = "The lower level tango device.\nThe lower level tango device will have its attributes mapped into the\nattributes of this device.\nThe device name must be in the usual form:\ndomain/family/member, e.g.:\ntest/device/1"; + prop_def = ""; + vect_data.clear(); + if (prop_def.length()>0) + { + Tango::DbDatum data(prop_name); + data << vect_data ; + dev_def_prop.push_back(data); + add_wiz_dev_prop(prop_name, prop_desc, prop_def); + } + else + add_wiz_dev_prop(prop_name, prop_desc); + +} +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapperClass::write_class_property +// +// description : Set class description as property in database +// +//----------------------------------------------------------------------------- +void TangoDevMapperClass::write_class_property() +{ + // First time, check if database used + //-------------------------------------------- + if (Tango::Util::_UseDb == false) + return; + + Tango::DbData data; + string classname = get_name(); + string header; + string::size_type start, end; + + // Put title + Tango::DbDatum title("ProjectTitle"); + string str_title("A mapper to map certain attributes into others"); + title << str_title; + data.push_back(title); + + // Put Description + Tango::DbDatum description("Description"); + vector<string> str_desc; + str_desc.push_back("This is a mapper that can run on top of a Tango Server exporting attributes."); + str_desc.push_back("Those attributes can be mapped into other attributes, with other names"); + str_desc.push_back("and other dimensions."); + str_desc.push_back("The configuration is made acting on the device properties."); + description << str_desc; + data.push_back(description); + + // put cvs or svn location + string filename(classname); + filename += "Class.cpp"; + + // Create a string with the class ID to + // get the string into the binary + string class_id(ClassId); + + // check for cvs information + string src_path(CvsPath); + start = src_path.find("/"); + if (start!=string::npos) + { + end = src_path.find(filename); + if (end>start) + { + string strloc = src_path.substr(start, end-start); + // Check if specific repository + start = strloc.find("/cvsroot/"); + if (start!=string::npos && start>0) + { + string repository = strloc.substr(0, start); + if (repository.find("/segfs/")!=string::npos) + strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); + } + Tango::DbDatum cvs_loc("cvs_location"); + cvs_loc << strloc; + data.push_back(cvs_loc); + } + } + // check for svn information + else + { + string src_path(SvnPath); + start = src_path.find("://"); + if (start!=string::npos) + { + end = src_path.find(filename); + if (end>start) + { + header = "$HeadURL: "; + start = header.length(); + string strloc = src_path.substr(start, (end-start)); + + Tango::DbDatum svn_loc("svn_location"); + svn_loc << strloc; + data.push_back(svn_loc); + } + } + } + + // Get CVS or SVN revision tag + + // CVS tag + string tagname(TagName); + header = "$Name: "; + start = header.length(); + string endstr(" $"); + + end = tagname.find(endstr); + if (end!=string::npos && end>start) + { + string strtag = tagname.substr(start, end-start); + Tango::DbDatum cvs_tag("cvs_tag"); + cvs_tag << strtag; + data.push_back(cvs_tag); + } + + // SVN tag + string svnpath(SvnPath); + header = "$HeadURL: "; + start = header.length(); + + end = svnpath.find(endstr); + if (end!=string::npos && end>start) + { + string strloc = svnpath.substr(start, end-start); + + string tagstr ("/tags/"); + start = strloc.find(tagstr); + if ( start!=string::npos ) + { + start = start + tagstr.length(); + end = strloc.find(filename); + string strtag = strloc.substr(start, end-start-1); + + Tango::DbDatum svn_tag("svn_tag"); + svn_tag << strtag; + data.push_back(svn_tag); + } + } + + // Get URL location + string httpServ(HttpServer); + if (httpServ.length()>0) + { + Tango::DbDatum db_doc_url("doc_url"); + db_doc_url << httpServ; + data.push_back(db_doc_url); + } + + // Put inheritance + Tango::DbDatum inher_datum("InheritedFrom"); + vector<string> inheritance; + inheritance.push_back("Device_4Impl"); + inher_datum << inheritance; + data.push_back(inher_datum); + + // Call database and and values + //-------------------------------------------- + get_db_class()->put_property(data); +} + +} // namespace diff --git a/src/TangoDevMapperClass.h b/src/TangoDevMapperClass.h new file mode 100644 index 0000000000000000000000000000000000000000..1902f483dc5d821a45631b6372ecc2391e8a9045 --- /dev/null +++ b/src/TangoDevMapperClass.h @@ -0,0 +1,98 @@ +//============================================================================= +// +// file : TangoDevMapperClass.h +// +// description : Include for the TangoDevMapperClass root class. +// This class is represents the singleton class for +// the TangoDevMapper device class. +// It contains all properties and methods which the +// TangoDevMapper requires only once e.g. the commands. +// +// project : TANGO Device Server +// +// $Author: claudio $ +// +// $Revision: 1.2 $ +// +// $Log: TangoDevMapperClass.h,v $ +// Revision 1.2 2012-05-07 10:33:52 claudio +// tango-7.2.6 +// meno printf +// +// Revision 1.1.1.1 2008/04/28 09:17:54 giacomo +// Prima release di TangoDevMapper. Aprile 2008 +// +// +// copyleft : European Synchrotron Radiation Facility +// BP 220, Grenoble 38043 +// FRANCE +// +//============================================================================= +// +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +// +// (c) - Software Engineering Group - ESRF +//============================================================================= + +#ifndef _TANGODEVMAPPERCLASS_H +#define _TANGODEVMAPPERCLASS_H + +#include <tango.h> +#include <TangoDevMapper.h> + + +namespace TangoDevMapper_ns +{//===================================== +// Define classes for attributes +//===================================== +//========================================= +// Define classes for commands +//========================================= +// +// The TangoDevMapperClass singleton definition +// + +class +#ifdef _TG_WINDOWS_ + __declspec(dllexport) +#endif + TangoDevMapperClass : public Tango::DeviceClass +{ +public: +// properties member data + +// add your own data members here +//------------------------------------ + +public: + Tango::DbData cl_prop; + Tango::DbData cl_def_prop; + Tango::DbData dev_def_prop; + +// Method prototypes + static TangoDevMapperClass *init(const char *); + static TangoDevMapperClass *instance(); + ~TangoDevMapperClass(); + Tango::DbDatum get_class_property(string &); + Tango::DbDatum get_default_device_property(string &); + Tango::DbDatum get_default_class_property(string &); + +protected: + TangoDevMapperClass(string &); + static TangoDevMapperClass *_instance; + void command_factory(); + void get_class_property(); + void write_class_property(); + void set_default_property(); + string get_cvstag(); + string get_cvsroot(); + +private: + void device_factory(const Tango::DevVarStringArray *); +}; + + +} // namespace TangoDevMapper_ns + +#endif // _TANGODEVMAPPERCLASS_H diff --git a/src/TangoDevMapperStateMachine.cpp b/src/TangoDevMapperStateMachine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0b15abb8a8aed8e3ed761ef1543950fce8350ee6 --- /dev/null +++ b/src/TangoDevMapperStateMachine.cpp @@ -0,0 +1,64 @@ +static const char *RcsId = "$Header: /home/cvsadm/cvsroot/elettra/server/tangodevmapper/src/TangoDevMapperStateMachine.cpp,v 1.2 2012-05-07 10:33:52 claudio Exp $"; +//+============================================================================= +// +// file : TangoDevMapperStateMachine.cpp +// +// description : C++ source for the TangoDevMapper and its alowed. +// method for commands and attributes +// +// project : TANGO Device Server +// +// $Author: claudio $ +// +// $Revision: 1.2 $ +// +// $Log: TangoDevMapperStateMachine.cpp,v $ +// Revision 1.2 2012-05-07 10:33:52 claudio +// tango-7.2.6 +// meno printf +// +// Revision 1.1.1.1 2008/04/28 09:17:54 giacomo +// Prima release di TangoDevMapper. Aprile 2008 +// +// +// copyleft : European Synchrotron Radiation Facility +// BP 220, Grenoble 38043 +// FRANCE +// +//-============================================================================= +// +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +// +// (c) - Software Engineering Group - ESRF +//============================================================================= + +#include <tango.h> +#include <TangoDevMapper.h> +#include <TangoDevMapperClass.h> + +/*==================================================================== + * This file contains the methods to allow commands and attributes + * read or write execution. + * + * If you wand to add your own code, add it between + * the "End/Re-Start of Generated Code" comments. + * + * If you want, you can also add your own methods. + *==================================================================== + */ + +namespace TangoDevMapper_ns +{ + +//================================================= +// Attributes Allowed Methods +//================================================= + + +//================================================= +// Commands Allowed Methods +//================================================= + + +} // namespace TangoDevMapper_ns diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..acee11b9b64b77ac3e6850c3ac82c8c32c91cf65 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,75 @@ +static const char *RcsId = "$Header: /home/cvsadm/cvsroot/elettra/server/tangodevmapper/src/main.cpp,v 1.2 2013-03-06 13:25:14 claudio Exp $"; +//+============================================================================= +// +// file : main.cpp +// +// description : C++ source for a TANGO device server main. +// The main rule is to initialise (and create) the Tango +// system and to create the DServerClass singleton. +// The main should be the same for every Tango device server. +// +// project : TANGO Device Server +// +// $Author: claudio $ +// +// $Revision: 1.2 $ $ +// +// $Log: main.cpp,v $ +// Revision 1.2 2013-03-06 13:25:14 claudio +// revision string +// +// Revision 1.1.1.1 2008/04/28 09:17:54 giacomo +// Prima release di TangoDevMapper. Aprile 2008 +// +// +// copyleft : European Synchrotron Radiation Facility +// BP 220, Grenoble 38043 +// FRANCE +// +//-============================================================================= +// +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +// +// (c) - Software Engineering Group - ESRF +//============================================================================= + +#include <tango.h> + +#define CVSVERSION "$Name: $" + +int main(int argc,char *argv[]) +{ + const char *cvs_version = CVSVERSION; + Tango::Util *tg; + try + { + // Initialise the device server + //---------------------------------------- + tg = Tango::Util::init(argc,argv); + + // Create the device server singleton + // which will create everything + //---------------------------------------- + tg->server_init(false); + + // Run the endless loop + //---------------------------------------- + cout << "Ready to accept request" << endl; + tg->server_run(); + } + catch (bad_alloc) + { + cout << "Can't allocate memory to store device object !!!" << endl; + cout << "Exiting" << endl; + } + catch (CORBA::Exception &e) + { + Tango::Except::print_exception(e); + + cout << "Received a CORBA_Exception" << endl; + cout << "Exiting" << endl; + } + tg->server_cleanup(); + return(0); +} diff --git a/src/read_dynamic_attribute.cpp b/src/read_dynamic_attribute.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17fbae9fd78845b861866f0ffb709570df5920d2 --- /dev/null +++ b/src/read_dynamic_attribute.cpp @@ -0,0 +1,639 @@ +#include "TangoDevMapper.h" +#include "MappedAttr.h" + +using namespace std; +using namespace Tango; + + +namespace TangoDevMapper_ns +{ + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapper::read_MappedAttr +// +// description : Extract real attribute values for MappedAttr acquisition result. +// +//----------------------------------------------------------------------------- +void TangoDevMapper::read_MappedAttr(Tango::Attribute &attr) +{ + DEBUG_STREAM << "TangoDevMapper::read_MappedAttr(Tango::Attribute &attr) entering... "<< endl; + + char errmsg[512]; + bool wrong_dtype = false; + long int dt; /* data type */ + int offset; /* used in SPECTRUM extraction, READ_WRITE */ + int size = 1; + int index; + Tango::AttrWriteType wt; /* write type (READ or READ_WRITE) */ + /* for extraction */ + DevUShort ush1; + DevUChar uch1, uchar1; + DevDouble d1; + DevLong l1; + DevFloat f1; + DevShort sho; + DevBoolean b1; + + /* to extract the READ_WRITE values or the SPECTRUMs */ + vector<DevDouble> d; + vector<DevFloat> f; + vector<DevLong> l; + vector<DevULong> ul; + vector<Tango::DevBoolean> b; + vector<DevUChar> uc; + vector<DevUShort> ush; + vector<DevShort> sh; + + /* the device attribute to read */ + DeviceAttribute da; + /* the pointer to the device proxy */ + DeviceProxy *dev; + /* name of the attribute the user wants to read (attr) */ + string mappedname = attr.get_name(); + std::map<string, MappedAttr*>::iterator iter = attributesMap.find(mappedname); + if(iter == attributesMap.end()) + { + Except::throw_exception("Error reading scalar attribute " + mappedname, + "Did not find the device attribute associated to the mapped attribute " +mappedname, + "TangoDevMapper::read_MappedAttr"); + return; + } + + MappedAttr* mattr = iter->second; + /* found an attribute with that name: good */ + /* now find the Tango device associated */ + string dname = mattr->deviceName(); + string attname = mattr->attributeName(); + std::map<string, DeviceProxy *>::iterator iter2 = namesDevsMap.find(dname); + if(iter2 == namesDevsMap.end()) + { + Except::throw_exception("Error reading scalar attribute " + attr.get_name(), + "Did not find the device associated to the attribute " + attname, + "TangoDevMapper::read_MappedAttr"); + return; + } + + dev = iter2->second; + /* read_attribute() on the associated attribute with name + * mattr->attributeName() */ + + if(dev == NULL) + { + Except::throw_exception("Error reading scalar attribute " + attr.get_name(), + "The device pointer is NULL", + "TangoDevMapper::read_MappedAttr"); + return; + } + try + { + da = dev->read_attribute(attname); + } + catch(DevFailed &e) + { +// printf("\r \r"); +// printf("\e[1;31m* \e[0mfailed reading %s from %s \e[1;34m-->\e[0m%s\n", +// attname.c_str(), dname.c_str(), attr.get_name().c_str()); + Except::re_throw_exception(e, "Error reading scalar attribute " + attr.get_name(), + "read_attribute on device " + dname + " failed", + "TangoDevMapper::read_MappedAttr"); + } + /* get the pointer to the MultiAttribute list */ + MultiAttribute *ma; + try + { + ma = get_device_attr(); + } + catch(DevFailed &e) + { +// printf("\r \r"); +// printf("\e[1;31m* \e[0mfailed getting MultiAttribute list %s\n", +// dname.c_str() ); + Except::re_throw_exception(e, "Error reading MultiAttribute list from " +dname, + "get_device_attr() on device " + dname + " failed", + "TangoDevMapper::read_MappedAttr"); + return; + } + + /* store data type */ + dt = mattr->dataType(); + /* store write type */ + wt = mattr->writeType(); + + /* must recognize the data type to extract it correctly */ + if(mattr->dataFormat() == Tango::SCALAR) + { + if(dt == Tango::DEV_DOUBLE) + { + if(wt == Tango::READ_WRITE) + { + da >> d; + if(d.size() == 2) + { + try + { + DevDouble *dd = new DevDouble; + ma->get_w_attr_by_name(attr.get_name().c_str()). + set_write_value(d[1]); + *dd = d[0]; + attr.set_value(dd, 1, 0, true); + } + catch(DevFailed &e) + { + Except::re_throw_exception(e, "Error getting WAttribute list for " +dname, + "get_w_attr_by_name() on device " + dname + " failed", + "TangoDevMapper::read_MappedAttr"); + } + } + else + wrong_dtype = true; + } + else if(wt == Tango::READ) + { + + DevDouble *dd = new DevDouble; + da >> d1; + *dd = d1; + attr.set_value(dd, 1, 0, true); + } + else + wrong_dtype = true; + } + else if(dt == Tango::DEV_FLOAT) + { + if(wt == Tango::READ_WRITE) + { + da >> f; + if(f.size() == 2) + { + try + { + DevFloat *df = new DevFloat; + ma->get_w_attr_by_name(attr.get_name().c_str()). + set_write_value(f[1]); + *df = f[0]; + attr.set_value(df, 1, 0, true); + } + catch(DevFailed &e) + { + Except::re_throw_exception(e, "Error getting WAttribute list for " +dname, + "get_w_attr_by_name() on device " + dname + " failed", + "TangoDevMapper::read_MappedAttr"); + } + } + else + wrong_dtype = true; + } + else if(wt == Tango::READ) + { + DevFloat *df = new DevFloat; + da >> f1; + *df = f1; + attr.set_value(df, 1, 0, true); + } + else + wrong_dtype = true; + } + + /* LONG */ + else if(dt == Tango::DEV_LONG) + { + DevLong *dl = new DevLong; + if(wt == Tango::READ_WRITE) + { + da >> l; + if(l.size() == 2) + { + try + { + ma->get_w_attr_by_name(attr.get_name().c_str()). + set_write_value(l[1]); + *dl = l[0]; + attr.set_value(dl); + } + catch(DevFailed &e) + { + Except::re_throw_exception(e, "Error getting WAttribute list for " +dname, + "get_w_attr_by_name() on device " + dname + " failed", + "TangoDevMapper::read_MappedAttr"); + } + } + else + wrong_dtype = true; + } + else if(wt == Tango::READ) + { + da >> l1; + *dl = l1; + attr.set_value(dl, 1, 0, true); + } + else + wrong_dtype = true; + } + + else if(dt == Tango::DEV_STRING) + { + // da >> outstr; + // str = new DevString; + // *str = CORBA::string_dup(outstr.c_str()); + // attr.set_value(str, 1, 0, true); + } + + else if(dt == Tango::DEV_BOOLEAN) + { + Tango::DevBoolean *db = new Tango::DevBoolean; + if(wt == Tango::READ_WRITE) + { + da >> b; + if(b.size() == 2) + { + try + { + Tango::DevShort bo_local; + bo_local = b[1]; + ma->get_w_attr_by_name(attr.get_name().c_str()). + set_write_value(bo_local); + + *db = b[0]; + attr.set_value(db); + } + catch(DevFailed &e) + { + Except::re_throw_exception(e, "Error getting WAttribute list for " +dname, + "get_w_attr_by_name() on device " + dname + " failed", + "TangoDevMapper::read_MappedAttr"); + } + } + else + wrong_dtype = true; + } + else if(wt == Tango::READ) + { + da >> b1; + *db = b1; +// printf("tango READ: boolean\n"); + attr.set_value(db); + } + else + wrong_dtype = true; + } + else if(dt == Tango::DEV_UCHAR) + { + DevUChar *duc = new DevUChar; + if(wt == + Tango::READ_WRITE) + { + da >> uc; + if(uc.size() == 2) + { + try + { + ma->get_w_attr_by_name(attr.get_name().c_str()). + set_write_value(uc[1]); + attr.set_value(&( uc[0])); + } + catch(DevFailed &e) + { + Except::re_throw_exception(e, "Error getting WAttribute list for " +dname, + "get_w_attr_by_name() on device " + dname + " failed", + "TangoDevMapper::read_MappedAttr"); + } + } + else + wrong_dtype = true; + } + else if(wt == Tango::READ) + { + da >> uchar1; + *duc = uchar1; +// printf("tango READ: %f\n", uchar1); + attr.set_value(duc, 1, 0, true); + } + else if(wt == Tango::WRITE) + { + da >> uch1; + *duc = uch1; +// printf("tango write: %f\n", uch1); + } + else + wrong_dtype = true; + } + + /* SHORT */ + else if(dt == Tango::DEV_SHORT) + { + if(wt == + Tango::READ_WRITE) + { + da >> sh; + if(sh.size() == 2) + { + try + { + ma->get_w_attr_by_name(attr.get_name().c_str()). + set_write_value(sh[1]); + attr.set_value(&( sh[0])); + } + catch(DevFailed &e) + { + Except::re_throw_exception(e, "Error getting WAttribute list for " +dname, + "get_w_attr_by_name() on device " + dname + " failed", + "TangoDevMapper::read_MappedAttr"); + } + } + else + wrong_dtype = true; + + } + else if(wt == Tango::READ) + { + DevShort *sh1 = new DevShort; + da >> sho; + *sh1 = sho; +// printf("\n++tango short scalar READ: %d\n", sho); + attr.set_value(sh1, 1, 0, true); + return; + } + else if(wt == Tango::WRITE) + { + // da >> sho; + // printf("tango write: %f\n", sh1); + } + else + wrong_dtype = true; + } + + else if(dt == Tango::DEV_USHORT) + { + if(wt == + Tango::READ_WRITE) + { + da >> ush; + if(ush.size() == 2) + { + try + { + ma->get_w_attr_by_name(attr.get_name().c_str()). + set_write_value(ush[1]); + attr.set_value(&( ush[0])); + } + catch(DevFailed &e) + { + Except::re_throw_exception(e, "Error getting WAttribute list for " +dname, + "get_w_attr_by_name() on device " + dname + " failed", + "TangoDevMapper::read_MappedAttr"); + } + } + else + wrong_dtype = true; + } + else if(wt == Tango::READ) + { + DevUShort *dush = new DevUShort; + da >> ush1; + *dush = ush1; + //printf("tango READ: %f\n", ush1); + attr.set_value(dush, 1, 0, true); + } + else if(wt == Tango::WRITE) + { + da >> ush1; + DEBUG_STREAM<<"tango write: "<< ush1<<endl; + } + else + wrong_dtype = true; + } + else + { + ERROR_STREAM<<"reading "<< attname.c_str()<<" from "<<dname.c_str() <<"-->"<< attr.get_name().c_str()<<endl; + Except::throw_exception("Error reading scalar attribute " + attr.get_name(), + "read_attribute on device " + dname + " failed: unsupported data Type", + "TangoDevMapper::read_MappedAttr"); + } + + } + else if(mattr->dataFormat() == Tango::SPECTRUM) + { + index = mattr->index(); + bool error = false; + + if(dt == Tango::DEV_DOUBLE) + { + da >> d; + if(wt == Tango::READ_WRITE && (size = d.size()/2) > index ) + { + DevDouble *dd = new DevDouble; + offset = d.size() / 2; + *dd = d[index]; + attr.set_value(dd, 1, 0, true); + ma->get_w_attr_by_name(mappedname.c_str()) + .set_write_value(d[offset + index]); + } + else if(wt == Tango::READ && (size = d.size()) > index) + { + DevDouble *dd = new DevDouble; + *dd = d[index]; + attr.set_value(dd, 1, 0, true); + } + else + wrong_dtype = true; + } + else if(dt == Tango::DEV_FLOAT) + { + da >> f; + if(wt == Tango::READ_WRITE && (size = f.size()/2) > index ) + { + DevFloat *ff = new DevFloat; + offset = f.size() / 2; + *ff = f[index]; + attr.set_value(ff, 1, 0, true); + ma->get_w_attr_by_name(mappedname.c_str()) + .set_write_value(f[offset + index]); + } + else if(wt == Tango::READ && (size = f.size()) > index) + { + DevFloat *ff = new DevFloat; + *ff = f[index]; + attr.set_value(ff, 1, 0, true); + } + else + wrong_dtype = true; + } + else if(dt == Tango::DEV_LONG) + { + da >> l; + if(wt == Tango::READ_WRITE && (size = l.size()/2) > index ) + { + DevLong *ll = new DevLong; + offset = l.size() / 2; + *ll = l[index]; + attr.set_value(ll, 1, 0, true); + ma->get_w_attr_by_name(mappedname.c_str()) + .set_write_value(l[offset + index]); + } + else if(wt == Tango::READ && (size = l.size()) > index) + { + DevLong *ll = new DevLong; + *ll = l[index]; + attr.set_value(ll, 1, 0, true); + } + else + wrong_dtype = true; + } + /* boolean */ + else if(dt == Tango::DEV_BOOLEAN) + { + da >> b; + if(wt == Tango::READ_WRITE && (size = b.size()/2) > index ) + { + DevBoolean *db = new DevBoolean; + offset = b.size() / 2; + *db = b[index]; + attr.set_value(db, 1, 0, true); + Tango::DevShort bval = b[offset + index]; + ma->get_w_attr_by_name(mappedname.c_str()) + .set_write_value(bval); + } + else if(wt == Tango::READ && (size = b.size()) > index) + { + DevBoolean *db = new DevBoolean; + *db= b[index]; + attr.set_value(db, 1, 0, true); + } + else + wrong_dtype = true; + } + else if(dt == Tango::DEV_UCHAR) + { + da >> uc; + if(wt == Tango::READ_WRITE && (size = uc.size()/2) > index ) + { + DevUChar *duc = new DevUChar; + offset = uc.size() / 2; + *duc = uc[index]; + attr.set_value(duc, 1, 0, true); + ma->get_w_attr_by_name(mappedname.c_str()) + .set_write_value(uc[offset + index]); + } + else if(wt == Tango::READ && (size = uc.size()) > index) + { + DevUChar *duc = new DevUChar; + *duc= uc[index]; + attr.set_value(duc, 1, 0, true); + } + else + wrong_dtype = true; + } + else if(dt == Tango::DEV_SHORT) + { + da >> sh; + if(wt == Tango::READ_WRITE && (size = sh.size()/2) > index ) + { + DevShort *dsh = new DevShort; + offset = sh.size() / 2; + *dsh = sh[index]; + attr.set_value(dsh, 1, 0, true); + ma->get_w_attr_by_name(mappedname.c_str()) + .set_write_value(sh[offset + index]); + } + else if(wt == Tango::READ &&(size = sh.size()) > index) + { + DevShort *dsh = new DevShort; + *dsh= sh[index]; + attr.set_value(dsh, 1, 0, true); + } + else + wrong_dtype = true; + } + else if(dt == Tango::DEV_USHORT) + { + da >> ush; + if(wt == Tango::READ_WRITE && (size = ush.size()/2) > index ) + { + DevUShort *dush = new DevUShort; + offset = ush.size() / 2; + *dush = ush[index]; + attr.set_value(dush, 1, 0, true); + ma->get_w_attr_by_name(mappedname.c_str()) + .set_write_value(ush[offset + index]); + } + else if(wt == Tango::READ && (size = ush.size()) > index) + { + DevUShort *dush = new DevUShort; + *dush= ush[index]; + attr.set_value(dush, 1, 0, true); + } + else + wrong_dtype = true; + } + else + { + ERROR_STREAM<<"reading "<< attname.c_str()<<" from "<<dname.c_str() <<"-->"<< attr.get_name().c_str()<<endl; + Except::throw_exception("Error reading scalar attribute " + attr.get_name(), + "read_attribute on device " + dname + " failed: unsupported data Type", + "TangoDevMapper::read_MappedAttr"); + + } + if(error) + { +// snprintf(errmsg, 512, "\e[1;31m* \e[0mfailed reading %s from %s \e[1;34m-->\e[0m%s\n" +// " \e[1;4;31merror\e[0m: mapped index [%d] exceeds target attribute dimensions [%d]\n" +// " \e[1;4;35mhint\e[0m: check the target attribute \"%s\" dimensions\n" +// " on the device \"%s\" and revise the map for the attribute\n" +// " \"%s\" in this device \e[1;4;37mdevice properties\e[0m so that the\n" +// " list of attributes does not exceed the size %d\n", +// attname.c_str(), dname.c_str(), attr.get_name().c_str(), +// index, size, attname.c_str(), dname.c_str(),attr.get_name().c_str() ); +// printf(errmsg); + Except::throw_exception("Error reading scalar attribute " + attr.get_name(), + string(errmsg), + "TangoDevMapper::read_MappedAttr"); + } + else + { +// printf("\r \r"); +// printf("\e[1;32m* \e[0mread %s[%d/%d] from %s \e[1;34m--> \e[0m%s", +// attname.c_str(), index, size, dname.c_str(), attr.get_name().c_str()); +// fflush(stdout); + + } + } + else + { + Except::throw_exception("Error decoding scalar attribute " + attr.get_name(), + "The attribute data format is not supported: supported " + "formats are SCALAR and SPECTRUM", + "TangoDevMapper::read_MappedAttr"); + return; + } + + if(wrong_dtype) + { +// snprintf(errmsg, 512, "\e[1;31m* \e[0mfailed reading %s from %s (index %d in size %d) \e[1;34m-->\e[0m%s\n" +// " \e[1;4;31merror\e[0m: wrong data type or error in extracting\n" +// " the read/set points.\n" +// " If the attribute is a spectrum, a mismatch in the extracted data sizes could have\n" +// " happened, although this is strange. Contact the author\n", +// attname.c_str(), dname.c_str(), index, size, attr.get_name().c_str()); +// printf(errmsg); + Except::throw_exception("Error reading scalar attribute - wrong_type " + attr.get_name(), + string(errmsg), + "TangoDevMapper::read_MappedAttr"); + } + +} + +} + + + + + + + + + + + + + diff --git a/src/write_dynamic_attribute.cpp b/src/write_dynamic_attribute.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e080244b5f56ecf26fa20431e94d84fdc90c73df --- /dev/null +++ b/src/write_dynamic_attribute.cpp @@ -0,0 +1,34 @@ +#include "TangoDevMapper.h" +#include "MappedAttr.h" + +using namespace std; +using namespace Tango; + +namespace TangoDevMapper_ns +{ + + +//+---------------------------------------------------------------------------- +// +// method : TangoDevMapper::write_MappedAttr +// +// description : Write MappedAttr attribute values to hardware. +// +//----------------------------------------------------------------------------- +void TangoDevMapper::write_MappedAttr(Tango::WAttribute &attr) +{ + printf("in write_mapped\n"); + DEBUG_STREAM << "TangoDevMapper::write_MappedAttr(Tango::WAttribute &attr) entering... "<< endl; + Except::throw_exception("It is not currently possible to write attributes in this device mapper", + "Since we cannot lock the devices, it is not safe to change an element\n" + "in a spectrum attribute. For this reason, this feature is not available", + "TangoDevMapper::write_MappedAttr"); +} + + + + +} /* namespace */ + + +