Code Snippets for coding a FESA3 class
Retrieving Parameters in a Server action
Scalar values
void ReadHistoryBlock::execute(fesa::RequestEvent* evt,Device* dev ,
HistoryBlock_DataType& data,
const HistoryBlock_FilterType& filter,
fesa::FesaLogger* log_)
{
//Default device
//std::cout << __FUNCTION__ << " " << __FILE__ << endl;
short block_start = filter.blockStart.get();
short block_end = filter.blockEnd.get();
...
}
ReadHistoryBlock = Name of the property as defined in design document
HistoryBlock_FilterType = Type of the filter as defined in design document
blockStart, blockEnd = Name of the filter parameters as defined in design document
Retrieve (array) values from RDA data container
void WholeHistoryAction::execute(fesa::RequestEvent* pEvt, Device* pDev,
WholeHistory_DataType& data,
const WholeHistory_FilterType& filter,
fesa::FesaLogger* pLog) {
WholeHistory_FilterType localFilterCopy = filter; // get rid of const key word
localFilterCopy.getRdaData()->print(); // print contents of RDA data container
char *container;
std::string filterItemTag = "ipadress"; // name of filter item
if(localFilterCopy.itemAvailable(filterItemTag.c_str())) {
std::cout << "Found Item: " << filterItemTag << " in Filter" << std::endl;
container = localFilterCopy.getRdaData()->extractString(filterItemTag.c_str());
std::cout << "Filter Value: " << container << std::endl;
}
}
Simple alternative:
void WholeHistoryAction::execute(fesa::RequestEvent* pEvt, Device* pDev,
WholeHistory_DataType& data,
const WholeHistory_FilterType& filter,
fesa::FesaLogger* pLog) {
WholeHistory_FilterType localFilterCopy = filter; // get rid of const key word
const char * i = localFilterCopy.ipadress.get();
}
Setting Strings in a String-Array
void ReadHistoryBlock::execute(fesa::RequestEvent* evt,Device* dev ,
HistoryBlock_DataType& data,
const HistoryBlock_FilterType& filter,
fesa::FesaLogger* log_)
{
//Default device
RequestValue rt("140.181.105.60", BIOREMPORT, block_start, block_end, -1);
vector< Value > history = rt.readHistory(block_start, block_end, -1); // Alle Werte in Bereich
vector< Value >::iterator it;
int index(0);
for( it=history.begin(); it!=history.end(); it++, index++ ) {
dev->historyBlock.setString( it->getInput().c_str(),
index,
evt->getMultiplexingContext() );
}
Setting Values for different Instances of a Device
void ReadHistoryBlock::execute(fesa::RequestEvent* evt,Device* dev ,
HistoryBlock_DataType& data,
const HistoryBlock_FilterType& filter,
fesa::FesaLogger* log_)
{
...
std::vector< Device* > v = *DeviceFactory::getInstance()->getDeviceCollection();
vector< Device* >::iterator devices;
for (unsigned int i=0; i < v.size(); i++){
Device * pDev = v[i];
//cout << "ReadHistoryBlock operates on device " << pDev->getName() << endl;
for(it=BRs.begin(); it!=BRs.end(); it++) {
if( (*it).getName() == pDev->getName() ) {
RequestValue rt((*it).getIP(), BIOREMPORT, block_start, block_end, -1);
vector< Value > history = rt.readHistory(block_start, block_end, -1); // Alle Werte in Bereich
vector< Value >::iterator it;
int index(0);
for( it=history.begin(); it!=history.end(); it++, index++ ) {
dev->historyBlock.setString( it->getInput().c_str(),
index,
evt->getMultiplexingContext() );
}
}
}
}
}
Usage of Application Parameters
fesa::ConfigData *cfgData = AbstractEquipment::getInstance()->getConfigData();
int argc = cfgData->getArgc();
char** argv = cfgData->getArgv();
for (int i = 0; i < argc; i++)
{
if (strcasecmp(argv[i],"-SCU") == 0)
{
return new fesaGSI::TimingEventSourceSCU();
}
}
Makefile.specific anpassen
Moechte man zusaetzliche, eigene C++-Bibliotheken in einer Fesaklasse verwenden, muss man die dafuer vorgesehenen Variablen noch selbst hinzufuegen:
LDFLAGS += -m32 $(SPECIFIC_LDFLAGS_SERVER)
CLASS_LIB += -m32 $(SPECIFIC_LDLIBSSERVER)
Die Option -m32 ermoeglicht das Kompillieren einer 32-Bit-Variante auf einem 64-Bit-System.
Logging in Fesa3
Diagnose-Output ist in Fesa3 z.B. so moeglich:
void WholeHistoryAction::execute(fesa::RequestEvent* pEvt, Device* pDev,
WholeHistory_DataType& data,
const WholeHistory_FilterType& filter,
fesa::FesaLogger* pLog) {
pLog->send("WholeHistoryAction::execute() start trace log", pLog->traceType);
pLog->send("WholeHistoryAction::execute() start error log", pLog->errorType);
}
Steht kein Logger zur Verfuegung kann man sich einen anlegen:
fesa::FesaLogger *pLog = fesa::FesaLogger::getDefaultLogger();
pLog->send("ServerDeviceClass::specificInit() start trace log", pLog->traceType);
Logfiles aller
FEC's und des Blade-Centers befinden sich hier: asl72x:/common/log01/logs
Standard-Konsolenausgaben sind immer moeglich, z.B. mit
std::cout << "Log-Output " << aValue << std::endl;
UdpLogging
Eine elegante Loesung zum Rechneruebergreifenden Logging gibt es von der Strahldiagnose. Urspruenglich vorgesehen fuer Fesa2.10 sind nur minimale Aenderungen fuer die Verwendung der C++-Klasse SDLog notwendig um sie im Common-Teil der eigenen Fesa-Klasse einzubinden. Die Quellen finden sich hier
http://sdlx014a.acc.gsi.de/FesaWeb/Fesa_SDLog.html oder in der Fesa3-Variante hier:
Fesa3Logging.
Lesen kann man die Log-Nachrichten mit Chainsaw, welches sich hier findet:
http://sdlx014a.acc.gsi.de/FesaWeb/Als Konfigurationsdatei kann man
file:/home/sdapp/web/config/ChainsawSD.xml angeben, in dem Receiver bereits vorkonfiguriert sind.
SDLog logger = SDLog::getInstance();
logger.connect("sdlx007.acc.gsi.de",1500);
logger.logInfo("ServerDeviceClass::specificInit()");
Available C++-Templates
Eclipse allows to define specific C++-Code Templates that may be used during editing source files. To insert them start typing the name of the template, Eclipse will suggest a list of matching possibilities.
Here is a list of the available C++-Templates specific for FESA:
C++-Code-Templates
How to set values to a GSI-multiplexing-context-field
// Here we loop through all devices ... in server action you as well can directly use the device-pointer.
for(std::vector<Device*>::iterator device = deviceCol_.begin();device!=deviceCol_.end();device++)
{
//stamp should be in Nanoseconds - UTC
long long stamp = 12345678;
//The GSI-multiplexing-context-field is named "acquisitionContext" in this example
(*device)->acquisitionContext.setacqStamp(stamp,pCtxt);
(*device)->acquisitionContext.setcycleName(const_cast<char*>(pCtxt->getCycleName().c_str()),pCtxt);
(*device)->acquisitionContext.setcycleStamp(pCtxt->getCycleStamp(),pCtxt);
}
How to Report an Error, using the GSI-error_collection-field
// Here we loop through all devices ... in server action you as well can directly use the device-pointer.
for(std::vector<Device*>::iterator device = deviceCol_.begin();device!=deviceCol_.end();device++)
{
std::string errorString= "Put in your error-text here";
long error_code= 4711;
(*device)->error_collection.addError(error_code,errorString,pCtxt,(*device),pLog);
}