Commit d1ad43e4 authored by Nicolas Tappret's avatar Nicolas Tappret

add cache for all attributes, And add diffrence attribute linked to a live...

add cache for all attributes, And add diffrence attribute linked to a live attribute and reference attribute
parent 8046bf9a
......@@ -2,3 +2,4 @@
cmake-build-debug/
bin/
obj/
nbproject
This diff is collapsed.
......@@ -45,6 +45,9 @@
#define MAXERROR 5 // Maximum number of error per device
#define MAXVALUELENGTH 100000 // Maximum length of a spectrum attribute
#define SAFE_FREE(x) if(x) {free(x);x=nullptr;}
#define MY_SAFE_DELETE(x) if(x) {delete(x);x=nullptr;}
typedef struct {
vector<string> errList;
} ERRITEM;
......@@ -73,7 +76,7 @@ class AttributeCombiner : public TANGO_BASE_CLASS
/*----- PROTECTED REGION ID(AttributeCombiner::Data Members) ENABLED START -----*/
// Add your own data members
public:
public:
AttributeMap attMap;
Tango::Group *deviceGroup;
vector<ERRITEM> errorStack;
......@@ -126,6 +129,9 @@ public:
// Alarm: Set alarm if value are not all equal (true or false) for grouped attribute
vector<string> attributeList;
// AttributeRefList: List of reference attribute
// name Ref attribute;Live attribute Name For Difference;name of difference attribute
// or only
// name Ref attribute
vector<string> attributeRefList;
// DeviceList: List of devices
vector<string> deviceList;
......@@ -133,6 +139,8 @@ public:
vector<string> commandList;
// Timeout: Timeout value of grouped call
Tango::DevLong timeout;
// refreshTime: minimum time beetween 2 read.
Tango::DevLong64 refreshTime;
// Attribute data members
public:
......@@ -294,6 +302,14 @@ public:
*/
virtual void enable_all();
virtual bool is_EnableAll_allowed(const CORBA::Any &any);
/**
* Command saveAttribute related method
* Description: save attribute in reference attribute. Pass only the name of the attribute you want saved
*
* @param argin name of the attribute than you wand saved
*/
virtual void save_attribute(Tango::DevString argin);
virtual bool is_saveAttribute_allowed(const CORBA::Any &any);
//--------------------------------------------------------
......@@ -307,7 +323,20 @@ public:
/*----- PROTECTED REGION ID(AttributeCombiner::Additional Method prototypes) ENABLED START -----*/
// Additional Method prototypes
static time_t timeMS();
// Return the cacheData variable cast to DevDouble
template <typename inType>
void convertTypePtrToDoublePtr(inType * cacheData,Tango::DevDouble * cacheConverted, int nbToCopy);
void setValueGoodCacheType(Tango::Attribute &attr, ATTITEM *item);
void writeAttributeProperty(const string& attrName,const string& propertyName, const string& contents);
string readAttributeProperty(const string& attrName,const string& propertyName);
template <typename T>
void saveAttribute(ATTITEM * attrToSave);
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::Additional Method prototypes
};
......
<?xml version="1.0" encoding="ASCII"?>
<pogoDsl:PogoSystem xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pogoDsl="http://www.esrf.fr/tango/pogo/PogoDsl">
<classes name="AttributeCombiner" pogoRevision="9.6">
<description description="A class to combine attributes coming from several devices" title="AttributeCombiner" sourcePath="/mntdirect/_segfs/tango/cppserver/calculcation/AttributeCombiner" language="Cpp" filestogenerate="XMI file,Code files,Protected Regions" license="GPL" copyright="Copyright (C): 2018&#xA; European Synchrotron Radiation Facility&#xA; BP 220, Grenoble 38043&#xA; France" hasMandatoryProperty="false" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false">
<description description="A class to combine attributes coming from several devices" title="AttributeCombiner" sourcePath="/mntdirect/_segfs/tango/cppserver/calculation/AttributeCombiner.working" language="Cpp" filestogenerate="XMI file,Code files,Protected Regions" license="GPL" copyright="Copyright (C): 2018&#xA; European Synchrotron Radiation Facility&#xA; BP 220, Grenoble 38043&#xA; France" hasMandatoryProperty="false" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false">
<inheritances classname="Device_Impl" sourcePath=""/>
<identification contact="at esrf.fr - pons" author="pons" emailDomain="esrf.fr" classFamily="Calculation" siteSpecific="" platform="All Platforms" bus="Not Applicable" manufacturer="none" reference=""/>
</description>
......@@ -9,7 +9,7 @@
<type xsi:type="pogoDsl:StringVectorType"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</deviceProperties>
<deviceProperties name="AttributeRefList" description="List of reference attribute">
<deviceProperties name="AttributeRefList" description="List of reference attribute&#xA;name Ref attribute;Live attribute Name For Difference;name of difference attribute&#xA;or only&#xA;name Ref attribute">
<type xsi:type="pogoDsl:StringVectorType"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</deviceProperties>
......@@ -26,6 +26,11 @@
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
<DefaultPropValue>1500</DefaultPropValue>
</deviceProperties>
<deviceProperties name="refreshTime" description="minimum time beetween 2 read.">
<type xsi:type="pogoDsl:LongType"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
<DefaultPropValue>1000</DefaultPropValue>
</deviceProperties>
<commands name="State" description="This command gets the device state (stored in its device_state data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0">
<argin description="none">
<type xsi:type="pogoDsl:VoidType"/>
......@@ -116,6 +121,15 @@
</argout>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</commands>
<commands name="saveAttribute" description="save attribute in reference attribute. Pass only the name of the attribute you want saved" execMethod="save_attribute" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false">
<argin description="name of the attribute than you wand saved">
<type xsi:type="pogoDsl:StringType"/>
</argin>
<argout description="">
<type xsi:type="pogoDsl:VoidType"/>
</argout>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</commands>
<attributes name="Errors" attType="Spectrum" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="2048" maxY="" allocReadMember="false" isDynamic="false">
<dataType xsi:type="pogoDsl:StringType"/>
<changeEvent fire="false" libCheckCriteria="false"/>
......
......@@ -302,6 +302,26 @@ CORBA::Any *EnableAllClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(cons
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : saveAttributeClass::execute()
* description : method to trigger the execution of the command.
*
* @param device The device on which the command must be executed
* @param in_any The command input data
*
* returns The command output data (packed in the Any object)
*/
//--------------------------------------------------------
CORBA::Any *saveAttributeClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
cout2 << "saveAttributeClass::execute(): arrived" << endl;
Tango::DevString argin;
extract(in_any, argin);
((static_cast<AttributeCombiner *>(device))->save_attribute(argin));
return new CORBA::Any();
}
//===================================================================
// Properties management
......@@ -385,7 +405,7 @@ void AttributeCombinerClass::set_default_property()
else
add_wiz_dev_prop(prop_name, prop_desc);
prop_name = "AttributeRefList";
prop_desc = "List of reference attribute";
prop_desc = "List of reference attribute\nname Ref attribute;Live attribute Name For Difference;name of difference attribute\nor only\nname Ref attribute";
prop_def = "";
vect_data.clear();
if (prop_def.length()>0)
......@@ -437,6 +457,20 @@ void AttributeCombinerClass::set_default_property()
}
else
add_wiz_dev_prop(prop_name, prop_desc);
prop_name = "refreshTime";
prop_desc = "minimum time beetween 2 read.";
prop_def = "1000";
vect_data.clear();
vect_data.push_back("1000");
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);
}
//--------------------------------------------------------
......@@ -708,6 +742,15 @@ void AttributeCombinerClass::command_factory()
Tango::OPERATOR);
command_list.push_back(pEnableAllCmd);
// Command saveAttribute
saveAttributeClass *psaveAttributeCmd =
new saveAttributeClass("saveAttribute",
Tango::DEV_STRING, Tango::DEV_VOID,
"name of the attribute than you wand saved",
"",
Tango::OPERATOR);
command_list.push_back(psaveAttributeCmd);
/*----- PROTECTED REGION ID(AttributeCombinerClass::command_factory_after) ENABLED START -----*/
// Add your own code
......
......@@ -383,6 +383,29 @@ public:
{return (static_cast<AttributeCombiner *>(dev))->is_EnableAll_allowed(any);}
};
// Command saveAttribute class definition
class saveAttributeClass : public Tango::Command
{
public:
saveAttributeClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out,
const char *in_desc,
const char *out_desc,
Tango::DispLevel level)
:Command(name,in,out,in_desc,out_desc, level) {};
saveAttributeClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~saveAttributeClass() {};
virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
{return (static_cast<AttributeCombiner *>(dev))->is_saveAttribute_allowed(any);}
};
/**
* The AttributeCombinerClass singleton definition
......
......@@ -205,6 +205,21 @@ bool AttributeCombiner::is_EnableAll_allowed(TANGO_UNUSED(const CORBA::Any &any)
return true;
}
//--------------------------------------------------------
/**
* Method : AttributeCombiner::is_saveAttribute_allowed()
* Description : Execution allowed for saveAttribute attribute
*/
//--------------------------------------------------------
bool AttributeCombiner::is_saveAttribute_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for saveAttribute command.
/*----- PROTECTED REGION ID(AttributeCombiner::saveAttributeStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AttributeCombiner::saveAttributeStateAllowed
return true;
}
/*----- PROTECTED REGION ID(AttributeCombiner::AttributeCombinerStateAllowed.AdditionalMethods) ENABLED START -----*/
......
......@@ -27,142 +27,209 @@
//
//=============================================================================
namespace AttributeCombiner_ns
{
class AttributeMap;
namespace AttributeCombiner_ns {
class AttributeMap;
}
#include <AttributeCombiner.h>
using namespace std;
namespace AttributeCombiner_ns
{
namespace AttributeCombiner_ns {
// Construct an empty attribute map
AttributeMap::AttributeMap() {
}
// Construct an empty attribute map
// Destruct attribute map
AttributeMap::~AttributeMap() {
clear();
}
AttributeMap::AttributeMap() {
}
// Free allocated resource
void AttributeMap::clear() {
map.clear();
}
// Destruct attribute map
// Add a ref attribute
void AttributeMap::addRef(string attName) {
ATTITEM newItem;
newItem.attName = attName;
newItem.grouped = false;
newItem.attNames.clear();
newItem.type = Tango::DEV_DOUBLE;
newItem.rwType = Tango::READ_WRITE;
newItem.setInit = false;
newItem.isSpectrum = true;
newItem.lengthAttName = "";
newItem.isRef = true;
newItem.refData = NULL;
// Look for insertion position
bool found = false;
int i=0;
while(!found && i<(int)map.size()) {
found = map[i].attName.compare(attName) > 0;
if(!found) i++;
}
// Insert
if(found) {
map.insert(map.begin()+i,newItem);
} else {
map.push_back(newItem);
}
AttributeMap::~AttributeMap() {
clear();
}
}
// Free allocated resource
void AttributeMap::clear() {
for (unsigned int i = 0; i < map.size(); i++) {
SAFE_FREE(map[i]->refData);
if (map[i]->cacheData != nullptr && map[i]->cacheSize > 0) {
SAFE_FREE(map[i]->cacheData);
}
MY_SAFE_DELETE(map[i]);
}
map.clear();
}
// Add a ref attribute
void AttributeMap::addRef(string attName) {
ATTITEM * newItem = new ATTITEM();
newItem->attName = attName;
newItem->grouped = false;
newItem->attNames.clear();
newItem->type = Tango::DEV_DOUBLE;
newItem->rwType = Tango::READ_WRITE;
newItem->setInit = false;
newItem->isSpectrum = true;
newItem->lengthAttName = "";
newItem->isRef = true;
newItem->isDiff = false;
newItem->refData = nullptr;
newItem->cacheData = nullptr;
newItem->cacheSize = 0;
newItem->refSize = 0;
newItem->refItem = nullptr;
newItem->liveItem = nullptr;
newItem->lastUpdate = AttributeCombiner::timeMS();
// Look for insertion position
bool found = false;
int i = 0;
while (!found && i < (int) map.size()) {
found = map[i]->attName.compare(attName) > 0;
if (!found) i++;
}
// Insert
if (found) {
map.insert(map.begin() + i, newItem);
} else {
map.push_back(newItem);
}
// Add an attribute
void AttributeMap::add(string attName,vector<std::string> attNames,bool grouped,int type,int rwType,bool isSpectrum,string lgthAttName,bool manageAlarm) {
ATTITEM newItem;
newItem.attName = attName;
newItem.grouped = grouped;
newItem.attNames = attNames;
newItem.type = type;
newItem.rwType = rwType;
newItem.setInit = false;
newItem.isSpectrum = isSpectrum;
newItem.lengthAttName = lgthAttName;
newItem.isRef = false;
newItem.refData = NULL;
newItem.manageAlarm = manageAlarm;
// Look for insertion position
bool found = false;
int i=0;
while(!found && i<(int)map.size()) {
found = map[i].attName.compare(attName) > 0;
if(!found) i++;
}
// Insert
if(found) {
map.insert(map.begin()+i,newItem);
} else {
map.push_back(newItem);
}
}
// Get item according to attribute name
ATTITEM *AttributeMap::get(string attName) {
bool found = false;
int min=0;
int max=map.size()-1;
int mid,comp;
while(!found && min<=max) {
mid = (min+max)/2;
comp = map[mid].attName.compare(attName);
if(comp>0) {
max = mid-1;
} else if(comp<0) {
min = mid+1;
} else {
found = true;
}
}
// Add a difference ref attribute
void AttributeMap::addDifferenceRef(string attName,ATTITEM * refItem,ATTITEM * liveItem) {
ATTITEM * newItem = new ATTITEM();
newItem->attName = attName;
newItem->grouped = false;
newItem->attNames.clear();
newItem->type = Tango::DEV_DOUBLE;
newItem->rwType = Tango::READ;
newItem->setInit = false;
newItem->isSpectrum = true;
newItem->lengthAttName = "";
newItem->isRef = false;
newItem->isDiff = true;
newItem->refData = nullptr;
newItem->cacheData = nullptr;
newItem->cacheSize = 0;
newItem->refSize = 0;
newItem->refItem = refItem;
newItem->liveItem = liveItem;
newItem->lastUpdate = AttributeCombiner::timeMS();
// Look for insertion position
bool found = false;
int i = 0;
while (!found && i < (int) map.size()) {
found = map[i]->attName.compare(attName) > 0;
if (!found) i++;
}
// Insert
if (found) {
map.insert(map.begin() + i, newItem);
} else {
map.push_back(newItem);
}
if(found) {
}
return &map[mid];
// Add an attribute
void AttributeMap::add(string attName, vector<std::string> attNames, bool grouped, int type, int rwType, bool isSpectrum, string lgthAttName, bool manageAlarm) {
ATTITEM * newItem = new ATTITEM();
newItem->attName = attName;
newItem->grouped = grouped;
newItem->attNames = attNames;
newItem->type = type;
newItem->rwType = rwType;
newItem->setInit = false;
newItem->isSpectrum = isSpectrum;
newItem->lengthAttName = lgthAttName;
newItem->isRef = false;
newItem->isDiff = false;
newItem->refData = nullptr;
newItem->cacheData = nullptr;
newItem->cacheSize = 0;
newItem->refSize = 0;
newItem->manageAlarm = manageAlarm;
newItem->refItem = nullptr;
newItem->liveItem = nullptr;
newItem->lastUpdate = AttributeCombiner::timeMS();
// Look for insertion position
bool found = false;
int i = 0;
while (!found && i < (int) map.size()) {
found = map[i]->attName.compare(attName) > 0;
if (!found) i++;
}
// Insert
if (found) {
map.insert(map.begin() + i, newItem);
} else {
map.push_back(newItem);
}
} else {
}
return NULL;
// Get item according to attribute name
}
ATTITEM *AttributeMap::get(string attName) {
}
bool found = false;
int min = 0;
int max = map.size() - 1;
int mid, comp;
ATTITEM *AttributeMap::get(int idx) {
while (!found && min <= max) {
return &map[idx];
mid = (min + max) / 2;
comp = map[mid]->attName.compare(attName);
if (comp > 0) {
max = mid - 1;
} else if (comp < 0) {
min = mid + 1;
} else {
found = true;
}
}
}
unsigned int AttributeMap::size() {
if (found) {
return map.size();
return map[mid];
}
} else {
return NULL;
}
}
ATTITEM *AttributeMap::get(int idx) {
return map[idx];
}
unsigned int AttributeMap::size() {
return map.size();
}
} // namespace AttributeCombiner_ns
......@@ -35,7 +35,9 @@
namespace AttributeCombiner_ns
{
typedef struct _ATTITEM {
typedef struct ATTITEM ATTITEM;
struct ATTITEM {
std::string attName; // Attribute name (seen in the all)
std::vector<std::string> attNames; // Attribute name list
......@@ -46,6 +48,8 @@ typedef struct _ATTITEM {
std::string lengthAttName; // Name of the length attribute for multiple spectrum
bool isSpectrum; // Is a multiple spectrum attribute
bool manageAlarm; // true if the attribute should switch ot alarm when values are not equal
ATTITEM * refItem; // Attribute name of the reference attribute (for difference Attribute)
ATTITEM * liveItem; // Attribute name of the live attribute (for difference Attribute)
// Attribute value
Tango::DevBoolean bVal;
......@@ -57,19 +61,25 @@ typedef struct _ATTITEM {
Tango::DevULong64 ulVal64;
Tango::DevDouble dVal;
Tango::DevEnum eVal;
time_t lastUpdate;
// Reference data
bool isRef;
bool isDiff;
int refSize;
Tango::DevDouble *refData;
int cacheSize;
void *cacheData;
} ATTITEM;
};
class AttributeMap {
private:
std::vector<ATTITEM> map;
std::vector<ATTITEM*> map;
public:
......@@ -87,16 +97,19 @@ public:
// Add an attribute
void addRef(std::string attName);
// Add a difference ref attribute
void addDifferenceRef(std::string attName,ATTITEM * refItem,ATTITEM * liveItem);
// Get item according to attribute name
ATTITEM *get(std::string attName);
// Get item at pos idx
ATTITEM *get(int idx);
// Return size of map
unsigned int size();
};
} // namespace AttributeCombiner_ns
......
......@@ -29,7 +29,15 @@ Losses;SaA,SaB,SaC,SaD;DevLong;false;false;false;None;false;false<br/>
InjLosses;AvgSum;DevLong;false;true;false;4;false;false<br/>
Adc;AdcA,AdcB,AdcC,AdcD;DevShort;false;true;false;AdcLength;false;false<br/>
**AttributeRefList** List of attribute that are just R/W memory (May be use for reference attribute)
**AttributeRefList** List of attribute that are just R/W memory (May be use for reference attribute) (3 or 1 fields per line if needed)
*AttributeRefName*: Attribute Name Reference<br/>
*AttributeLiveName*: Attribute LiveAttributeName for the next calcul difference<br/>
*AttributeDiffName*: Attribute difference = LiveAttributeName - AttributeRefName<br/>