Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cs/ds/alarm-handler
  • francesco.tripaldi/alarm-handler
2 results
Show changes
Showing
with 8116 additions and 0 deletions
/*----- PROTECTED REGION ID(AlarmHandlerClass.cpp) ENABLED START -----*/
//=============================================================================
//
// file : AlarmHandlerClass.cpp
//
// description : C++ source for the AlarmHandlerClass.
// A singleton class derived from DeviceClass.
// It implements the command and attribute list
// and all properties and methods required
// by the AlarmHandler once per process.
//
// project : Elettra alarm handler device server
//
// This file is part of Tango device class.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Tango. If not, see <http://www.gnu.org/licenses/>.
//
//
//
//=============================================================================
// This file is generated by POGO
// (Program Obviously used to Generate tango Object)
//=============================================================================
#include <AlarmHandlerClass.h>
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass.cpp
//-------------------------------------------------------------------
/**
* Create AlarmHandlerClass singleton and
* return it in a C function for Python usage
*/
//-------------------------------------------------------------------
extern "C" {
#ifdef _TG_WINDOWS_
__declspec(dllexport)
#endif
Tango::DeviceClass *_create_AlarmHandler_class(const char *name) {
return AlarmHandler_ns::AlarmHandlerClass::init(name);
}
}
namespace AlarmHandler_ns
{
//===================================================================
// Initialize pointer for singleton pattern
//===================================================================
AlarmHandlerClass *AlarmHandlerClass::_instance = NULL;
//--------------------------------------------------------
/**
* method : AlarmHandlerClass::AlarmHandlerClass(string &s)
* description : constructor for the AlarmHandlerClass
*
* @param s The class name
*/
//--------------------------------------------------------
AlarmHandlerClass::AlarmHandlerClass(string &s):Tango::DeviceClass(s)
{
TANGO_LOG_INFO << "Entering AlarmHandlerClass constructor" << endl;
set_default_property();
get_class_property();
write_class_property();
/*----- PROTECTED REGION ID(AlarmHandlerClass::constructor) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::constructor
TANGO_LOG_INFO << "Leaving AlarmHandlerClass constructor" << endl;
}
//--------------------------------------------------------
/**
* method : AlarmHandlerClass::~AlarmHandlerClass()
* description : destructor for the AlarmHandlerClass
*/
//--------------------------------------------------------
AlarmHandlerClass::~AlarmHandlerClass()
{
/*----- PROTECTED REGION ID(AlarmHandlerClass::destructor) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::destructor
_instance = NULL;
}
//--------------------------------------------------------
/**
* method : AlarmHandlerClass::init
* description : Create the object if not already done.
* Otherwise, just return a pointer to the object
*
* @param name The class name
*/
//--------------------------------------------------------
AlarmHandlerClass *AlarmHandlerClass::init(const char *name)
{
if (_instance == NULL)
{
try
{
string s(name);
_instance = new AlarmHandlerClass(s);
}
catch (bad_alloc &)
{
throw;
}
}
return _instance;
}
//--------------------------------------------------------
/**
* method : AlarmHandlerClass::instance
* description : Check if object already created,
* and return a pointer to the object
*/
//--------------------------------------------------------
AlarmHandlerClass *AlarmHandlerClass::instance()
{
if (_instance == NULL)
{
cerr << "Class is not initialised !!" << endl;
exit(-1);
}
return _instance;
}
//===================================================================
// Command execution method calls
//===================================================================
//--------------------------------------------------------
/**
* method : AckClass::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 *AckClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
TANGO_LOG_INFO << "AckClass::execute(): arrived" << endl;
const Tango::DevVarStringArray *argin;
extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->ack(argin));
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : LoadClass::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 *LoadClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
TANGO_LOG_INFO << "LoadClass::execute(): arrived" << endl;
Tango::DevString argin;
extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->load(argin));
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : RemoveClass::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 *RemoveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
TANGO_LOG_INFO << "RemoveClass::execute(): arrived" << endl;
Tango::DevString argin;
extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->remove(argin));
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : SearchAlarmClass::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 *SearchAlarmClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
TANGO_LOG_INFO << "SearchAlarmClass::execute(): arrived" << endl;
Tango::DevString argin;
extract(in_any, argin);
return insert((static_cast<AlarmHandler *>(device))->search_alarm(argin));
}
//--------------------------------------------------------
/**
* method : StopAudibleClass::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 *StopAudibleClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{
TANGO_LOG_INFO << "StopAudibleClass::execute(): arrived" << endl;
((static_cast<AlarmHandler *>(device))->stop_audible());
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : SilenceClass::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 *SilenceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
TANGO_LOG_INFO << "SilenceClass::execute(): arrived" << endl;
const Tango::DevVarStringArray *argin;
extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->silence(argin));
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : ModifyClass::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 *ModifyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
TANGO_LOG_INFO << "ModifyClass::execute(): arrived" << endl;
Tango::DevString argin;
extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->modify(argin));
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : ShelveClass::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 *ShelveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
TANGO_LOG_INFO << "ShelveClass::execute(): arrived" << endl;
const Tango::DevVarStringArray *argin;
extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->shelve(argin));
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : EnableClass::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 *EnableClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
TANGO_LOG_INFO << "EnableClass::execute(): arrived" << endl;
Tango::DevString argin;
extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->enable(argin));
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : DisableClass::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 *DisableClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
TANGO_LOG_INFO << "DisableClass::execute(): arrived" << endl;
Tango::DevString argin;
extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->disable(argin));
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : ResetStatisticsClass::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 *ResetStatisticsClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{
TANGO_LOG_INFO << "ResetStatisticsClass::execute(): arrived" << endl;
((static_cast<AlarmHandler *>(device))->reset_statistics());
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : StopNewClass::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 *StopNewClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{
TANGO_LOG_INFO << "StopNewClass::execute(): arrived" << endl;
((static_cast<AlarmHandler *>(device))->stop_new());
return new CORBA::Any();
}
//--------------------------------------------------------
/**
* method : GetAlarmInfoClass::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 *GetAlarmInfoClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
TANGO_LOG_INFO << "GetAlarmInfoClass::execute(): arrived" << endl;
const Tango::DevVarStringArray *argin;
extract(in_any, argin);
return insert((static_cast<AlarmHandler *>(device))->get_alarm_info(argin));
}
//--------------------------------------------------------
/**
* method : ReLoadAllClass::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 *ReLoadAllClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{
TANGO_LOG_INFO << "ReLoadAllClass::execute(): arrived" << endl;
((static_cast<AlarmHandler *>(device))->re_load_all());
return new CORBA::Any();
}
//===================================================================
// Properties management
//===================================================================
//--------------------------------------------------------
/**
* Method : AlarmHandlerClass::get_class_property()
* Description : Get the class property for specified name.
*/
//--------------------------------------------------------
Tango::DbDatum AlarmHandlerClass::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, returns an empty DbDatum
return Tango::DbDatum(prop_name);
}
//--------------------------------------------------------
/**
* Method : AlarmHandlerClass::get_default_device_property()
* Description : Return the default value for device property.
*/
//--------------------------------------------------------
Tango::DbDatum AlarmHandlerClass::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 : AlarmHandlerClass::get_default_class_property()
* Description : Return the default value for class property.
*/
//--------------------------------------------------------
Tango::DbDatum AlarmHandlerClass::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 : AlarmHandlerClass::get_class_property()
* Description : Read database to initialize class property data members.
*/
//--------------------------------------------------------
void AlarmHandlerClass::get_class_property()
{
/*----- PROTECTED REGION ID(AlarmHandlerClass::get_class_property_before) ENABLED START -----*/
// Initialize class property data members
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::get_class_property_before
// Read class properties from database.
cl_prop.push_back(Tango::DbDatum("GroupNames"));
cl_prop.push_back(Tango::DbDatum("SubscribeRetryPeriod"));
cl_prop.push_back(Tango::DbDatum("StatisticsTimeWindow"));
cl_prop.push_back(Tango::DbDatum("ErrorDelay"));
cl_prop.push_back(Tango::DbDatum("SetAlarmQuality"));
// 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;
// Try to extract GroupNames value
if (cl_prop[++i].is_empty()==false) cl_prop[i] >> groupNames;
else
{
// Check default value for GroupNames
def_prop = get_default_class_property(cl_prop[i].name);
if (def_prop.is_empty()==false)
{
def_prop >> groupNames;
cl_prop[i] << groupNames;
}
}
// Try to extract SubscribeRetryPeriod value
if (cl_prop[++i].is_empty()==false) cl_prop[i] >> subscribeRetryPeriod;
else
{
// Check default value for SubscribeRetryPeriod
def_prop = get_default_class_property(cl_prop[i].name);
if (def_prop.is_empty()==false)
{
def_prop >> subscribeRetryPeriod;
cl_prop[i] << subscribeRetryPeriod;
}
}
// Try to extract StatisticsTimeWindow value
if (cl_prop[++i].is_empty()==false) cl_prop[i] >> statisticsTimeWindow;
else
{
// Check default value for StatisticsTimeWindow
def_prop = get_default_class_property(cl_prop[i].name);
if (def_prop.is_empty()==false)
{
def_prop >> statisticsTimeWindow;
cl_prop[i] << statisticsTimeWindow;
}
}
// Try to extract ErrorDelay value
if (cl_prop[++i].is_empty()==false) cl_prop[i] >> errorDelay;
else
{
// Check default value for ErrorDelay
def_prop = get_default_class_property(cl_prop[i].name);
if (def_prop.is_empty()==false)
{
def_prop >> errorDelay;
cl_prop[i] << errorDelay;
}
}
// Try to extract SetAlarmQuality value
if (cl_prop[++i].is_empty()==false) cl_prop[i] >> setAlarmQuality;
else
{
// Check default value for SetAlarmQuality
def_prop = get_default_class_property(cl_prop[i].name);
if (def_prop.is_empty()==false)
{
def_prop >> setAlarmQuality;
cl_prop[i] << setAlarmQuality;
}
}
/*----- PROTECTED REGION ID(AlarmHandlerClass::get_class_property_after) ENABLED START -----*/
// Check class property data members init
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::get_class_property_after
}
//--------------------------------------------------------
/**
* Method : AlarmHandlerClass::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 AlarmHandlerClass::set_default_property()
{
string prop_name;
string prop_desc;
string prop_def;
vector<string> vect_data;
// Set Default Class Properties
prop_name = "GroupNames";
prop_desc = "Labels for Group mask, first is for mask 0x00";
prop_def = "";
vect_data.clear();
if (prop_def.length()>0)
{
Tango::DbDatum data(prop_name);
data << vect_data ;
cl_def_prop.push_back(data);
add_wiz_class_prop(prop_name, prop_desc, prop_def);
}
else
add_wiz_class_prop(prop_name, prop_desc);
prop_name = "SubscribeRetryPeriod";
prop_desc = "Retry subscription period in seconds";
prop_def = "30";
vect_data.clear();
vect_data.push_back("30");
if (prop_def.length()>0)
{
Tango::DbDatum data(prop_name);
data << vect_data ;
cl_def_prop.push_back(data);
add_wiz_class_prop(prop_name, prop_desc, prop_def);
}
else
add_wiz_class_prop(prop_name, prop_desc);
prop_name = "StatisticsTimeWindow";
prop_desc = "Time window to compute statistics in seconds";
prop_def = "60";
vect_data.clear();
vect_data.push_back("60");
if (prop_def.length()>0)
{
Tango::DbDatum data(prop_name);
data << vect_data ;
cl_def_prop.push_back(data);
add_wiz_class_prop(prop_name, prop_desc, prop_def);
}
else
add_wiz_class_prop(prop_name, prop_desc);
prop_name = "ErrorDelay";
prop_desc = "Delay in seconds before changing to ERROR state after an exception is received.";
prop_def = "30";
vect_data.clear();
vect_data.push_back("30");
if (prop_def.length()>0)
{
Tango::DbDatum data(prop_name);
data << vect_data ;
cl_def_prop.push_back(data);
add_wiz_class_prop(prop_name, prop_desc, prop_def);
}
else
add_wiz_class_prop(prop_name, prop_desc);
prop_name = "SetAlarmQuality";
prop_desc = "Set alarm attribute quality as computed using quality of attributes in the formula";
prop_def = "false";
vect_data.clear();
vect_data.push_back("false");
if (prop_def.length()>0)
{
Tango::DbDatum data(prop_name);
data << vect_data ;
cl_def_prop.push_back(data);
add_wiz_class_prop(prop_name, prop_desc, prop_def);
}
else
add_wiz_class_prop(prop_name, prop_desc);
// Set Default device Properties
prop_name = "GroupNames";
prop_desc = "Labels for Group mask, first is for mask 0x00";
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 = "SubscribeRetryPeriod";
prop_desc = "Retry subscription period in seconds";
prop_def = "30";
vect_data.clear();
vect_data.push_back("30");
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 = "StatisticsTimeWindow";
prop_desc = "Time window to compute statistics in seconds";
prop_def = "60";
vect_data.clear();
vect_data.push_back("60");
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 = "ErrorDelay";
prop_desc = "Delay in seconds before changing to ERROR state after an exception is received.";
prop_def = "30";
vect_data.clear();
vect_data.push_back("30");
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 = "SetAlarmQuality";
prop_desc = "Set alarm attribute quality as computed using quality of attributes in the formula";
prop_def = "false";
vect_data.clear();
vect_data.push_back("false");
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 : AlarmHandlerClass::write_class_property()
* Description : Set class description fields as property in database
*/
//--------------------------------------------------------
void AlarmHandlerClass::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("Elettra alarm handler device server");
title << str_title;
data.push_back(title);
// Put Description
Tango::DbDatum description("Description");
vector<string> str_desc;
str_desc.push_back("Elettra alarm handler device server");
description << str_desc;
data.push_back(description);
// Put inheritance
Tango::DbDatum inher_datum("InheritedFrom");
vector<string> inheritance;
inheritance.push_back("TANGO_BASE_CLASS");
inher_datum << inheritance;
data.push_back(inher_datum);
// Call database and and values
get_db_class()->put_property(data);
}
//===================================================================
// Factory methods
//===================================================================
//--------------------------------------------------------
/**
* Method : AlarmHandlerClass::device_factory()
* Description : Create the device object(s)
* and store them in the device list
*/
//--------------------------------------------------------
void AlarmHandlerClass::device_factory(const Tango::DevVarStringArray *devlist_ptr)
{
/*----- PROTECTED REGION ID(AlarmHandlerClass::device_factory_before) ENABLED START -----*/
// Add your own code
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::device_factory_before
// Create devices and add it into the device list
for (unsigned long i=0 ; i<devlist_ptr->length() ; i++)
{
TANGO_LOG_DEBUG << "Device name : " << (*devlist_ptr)[i].in() << endl;
device_list.push_back(new AlarmHandler(this, (*devlist_ptr)[i]));
}
// Manage dynamic attributes if any
erase_dynamic_attributes(devlist_ptr, get_class_attr()->get_attr_list());
// Export devices to the outside world
for (unsigned long i=1 ; i<=devlist_ptr->length() ; i++)
{
// Add dynamic attributes if any
AlarmHandler *dev = static_cast<AlarmHandler *>(device_list[device_list.size()-i]);
dev->add_dynamic_attributes();
// Check before if database used.
if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false))
export_device(dev);
else
export_device(dev, dev->get_name().c_str());
}
/*----- PROTECTED REGION ID(AlarmHandlerClass::device_factory_after) ENABLED START -----*/
// Add your own code
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::device_factory_after
}
//--------------------------------------------------------
/**
* Method : AlarmHandlerClass::attribute_factory()
* Description : Create the attribute object(s)
* and store them in the attribute list
*/
//--------------------------------------------------------
void AlarmHandlerClass::attribute_factory(vector<Tango::Attr *> &att_list)
{
/*----- PROTECTED REGION ID(AlarmHandlerClass::attribute_factory_before) ENABLED START -----*/
// Add your own code
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::attribute_factory_before
// Attribute : alarmAudible
alarmAudibleAttrib *alarmaudible = new alarmAudibleAttrib();
Tango::UserDefaultAttrProp alarmaudible_prop;
alarmaudible_prop.set_description("True if there is at least one alarm that needs audible indication on the GUI");
// label not set for alarmAudible
// unit not set for alarmAudible
// standard_unit not set for alarmAudible
// display_unit not set for alarmAudible
// format not set for alarmAudible
// max_value not set for alarmAudible
// min_value not set for alarmAudible
// max_alarm not set for alarmAudible
// min_alarm not set for alarmAudible
// max_warning not set for alarmAudible
// min_warning not set for alarmAudible
// delta_t not set for alarmAudible
// delta_val not set for alarmAudible
alarmaudible->set_default_properties(alarmaudible_prop);
// Not Polled
alarmaudible->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmaudible->set_change_event(true, true);
alarmaudible->set_archive_event(true, true);
att_list.push_back(alarmaudible);
// Attribute : StatisticsResetTime
StatisticsResetTimeAttrib *statisticsresettime = new StatisticsResetTimeAttrib();
Tango::UserDefaultAttrProp statisticsresettime_prop;
statisticsresettime_prop.set_description("Time elapsed in seconds since last Resetstatistics");
// label not set for StatisticsResetTime
statisticsresettime_prop.set_unit("s");
statisticsresettime_prop.set_standard_unit("1");
statisticsresettime_prop.set_display_unit("s");
// format not set for StatisticsResetTime
// max_value not set for StatisticsResetTime
// min_value not set for StatisticsResetTime
// max_alarm not set for StatisticsResetTime
// min_alarm not set for StatisticsResetTime
// max_warning not set for StatisticsResetTime
// min_warning not set for StatisticsResetTime
// delta_t not set for StatisticsResetTime
// delta_val not set for StatisticsResetTime
statisticsresettime->set_default_properties(statisticsresettime_prop);
// Not Polled
statisticsresettime->set_disp_level(Tango::OPERATOR);
// Not Memorized
att_list.push_back(statisticsresettime);
// Attribute : alarm
alarmAttrib *alarm = new alarmAttrib();
Tango::UserDefaultAttrProp alarm_prop;
// description not set for alarm
// label not set for alarm
// unit not set for alarm
// standard_unit not set for alarm
// display_unit not set for alarm
// format not set for alarm
// max_value not set for alarm
// min_value not set for alarm
// max_alarm not set for alarm
// min_alarm not set for alarm
// max_warning not set for alarm
// min_warning not set for alarm
// delta_t not set for alarm
// delta_val not set for alarm
alarm->set_default_properties(alarm_prop);
// Not Polled
alarm->set_disp_level(Tango::OPERATOR);
// Not Memorized
att_list.push_back(alarm);
// Attribute : alarmNormal
alarmNormalAttrib *alarmnormal = new alarmNormalAttrib();
Tango::UserDefaultAttrProp alarmnormal_prop;
alarmnormal_prop.set_description("List of alarms in normal state");
// label not set for alarmNormal
// unit not set for alarmNormal
// standard_unit not set for alarmNormal
// display_unit not set for alarmNormal
// format not set for alarmNormal
// max_value not set for alarmNormal
// min_value not set for alarmNormal
// max_alarm not set for alarmNormal
// min_alarm not set for alarmNormal
// max_warning not set for alarmNormal
// min_warning not set for alarmNormal
// delta_t not set for alarmNormal
// delta_val not set for alarmNormal
alarmnormal->set_default_properties(alarmnormal_prop);
// Not Polled
alarmnormal->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmnormal->set_change_event(true, true);
alarmnormal->set_archive_event(true, true);
att_list.push_back(alarmnormal);
// Attribute : alarmUnacknowledged
alarmUnacknowledgedAttrib *alarmunacknowledged = new alarmUnacknowledgedAttrib();
Tango::UserDefaultAttrProp alarmunacknowledged_prop;
alarmunacknowledged_prop.set_description("List of alarms in unacknowledged state");
// label not set for alarmUnacknowledged
// unit not set for alarmUnacknowledged
// standard_unit not set for alarmUnacknowledged
// display_unit not set for alarmUnacknowledged
// format not set for alarmUnacknowledged
// max_value not set for alarmUnacknowledged
// min_value not set for alarmUnacknowledged
// max_alarm not set for alarmUnacknowledged
// min_alarm not set for alarmUnacknowledged
// max_warning not set for alarmUnacknowledged
// min_warning not set for alarmUnacknowledged
// delta_t not set for alarmUnacknowledged
// delta_val not set for alarmUnacknowledged
alarmunacknowledged->set_default_properties(alarmunacknowledged_prop);
// Not Polled
alarmunacknowledged->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmunacknowledged->set_change_event(true, true);
alarmunacknowledged->set_archive_event(true, true);
att_list.push_back(alarmunacknowledged);
// Attribute : alarmAcknowledged
alarmAcknowledgedAttrib *alarmacknowledged = new alarmAcknowledgedAttrib();
Tango::UserDefaultAttrProp alarmacknowledged_prop;
alarmacknowledged_prop.set_description("List of alarms in acknowledged state");
// label not set for alarmAcknowledged
// unit not set for alarmAcknowledged
// standard_unit not set for alarmAcknowledged
// display_unit not set for alarmAcknowledged
// format not set for alarmAcknowledged
// max_value not set for alarmAcknowledged
// min_value not set for alarmAcknowledged
// max_alarm not set for alarmAcknowledged
// min_alarm not set for alarmAcknowledged
// max_warning not set for alarmAcknowledged
// min_warning not set for alarmAcknowledged
// delta_t not set for alarmAcknowledged
// delta_val not set for alarmAcknowledged
alarmacknowledged->set_default_properties(alarmacknowledged_prop);
// Not Polled
alarmacknowledged->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmacknowledged->set_change_event(true, true);
alarmacknowledged->set_archive_event(true, true);
att_list.push_back(alarmacknowledged);
// Attribute : alarmUnacknowledgedNormal
alarmUnacknowledgedNormalAttrib *alarmunacknowledgednormal = new alarmUnacknowledgedNormalAttrib();
Tango::UserDefaultAttrProp alarmunacknowledgednormal_prop;
alarmunacknowledgednormal_prop.set_description("List of alarms in unacknowledged normal state");
// label not set for alarmUnacknowledgedNormal
// unit not set for alarmUnacknowledgedNormal
// standard_unit not set for alarmUnacknowledgedNormal
// display_unit not set for alarmUnacknowledgedNormal
// format not set for alarmUnacknowledgedNormal
// max_value not set for alarmUnacknowledgedNormal
// min_value not set for alarmUnacknowledgedNormal
// max_alarm not set for alarmUnacknowledgedNormal
// min_alarm not set for alarmUnacknowledgedNormal
// max_warning not set for alarmUnacknowledgedNormal
// min_warning not set for alarmUnacknowledgedNormal
// delta_t not set for alarmUnacknowledgedNormal
// delta_val not set for alarmUnacknowledgedNormal
alarmunacknowledgednormal->set_default_properties(alarmunacknowledgednormal_prop);
// Not Polled
alarmunacknowledgednormal->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmunacknowledgednormal->set_change_event(true, true);
alarmunacknowledgednormal->set_archive_event(true, true);
att_list.push_back(alarmunacknowledgednormal);
// Attribute : alarmShelved
alarmShelvedAttrib *alarmshelved = new alarmShelvedAttrib();
Tango::UserDefaultAttrProp alarmshelved_prop;
alarmshelved_prop.set_description("List of alarms in shelved state");
// label not set for alarmShelved
// unit not set for alarmShelved
// standard_unit not set for alarmShelved
// display_unit not set for alarmShelved
// format not set for alarmShelved
// max_value not set for alarmShelved
// min_value not set for alarmShelved
// max_alarm not set for alarmShelved
// min_alarm not set for alarmShelved
// max_warning not set for alarmShelved
// min_warning not set for alarmShelved
// delta_t not set for alarmShelved
// delta_val not set for alarmShelved
alarmshelved->set_default_properties(alarmshelved_prop);
// Not Polled
alarmshelved->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmshelved->set_change_event(true, true);
alarmshelved->set_archive_event(true, true);
att_list.push_back(alarmshelved);
// Attribute : alarmOutOfService
alarmOutOfServiceAttrib *alarmoutofservice = new alarmOutOfServiceAttrib();
Tango::UserDefaultAttrProp alarmoutofservice_prop;
alarmoutofservice_prop.set_description("List of alarms in out of service state");
// label not set for alarmOutOfService
// unit not set for alarmOutOfService
// standard_unit not set for alarmOutOfService
// display_unit not set for alarmOutOfService
// format not set for alarmOutOfService
// max_value not set for alarmOutOfService
// min_value not set for alarmOutOfService
// max_alarm not set for alarmOutOfService
// min_alarm not set for alarmOutOfService
// max_warning not set for alarmOutOfService
// min_warning not set for alarmOutOfService
// delta_t not set for alarmOutOfService
// delta_val not set for alarmOutOfService
alarmoutofservice->set_default_properties(alarmoutofservice_prop);
// Not Polled
alarmoutofservice->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmoutofservice->set_change_event(true, true);
alarmoutofservice->set_archive_event(true, true);
att_list.push_back(alarmoutofservice);
// Attribute : alarmSilenced
alarmSilencedAttrib *alarmsilenced = new alarmSilencedAttrib();
Tango::UserDefaultAttrProp alarmsilenced_prop;
alarmsilenced_prop.set_description("List of alarms in silenced state");
// label not set for alarmSilenced
// unit not set for alarmSilenced
// standard_unit not set for alarmSilenced
// display_unit not set for alarmSilenced
// format not set for alarmSilenced
// max_value not set for alarmSilenced
// min_value not set for alarmSilenced
// max_alarm not set for alarmSilenced
// min_alarm not set for alarmSilenced
// max_warning not set for alarmSilenced
// min_warning not set for alarmSilenced
// delta_t not set for alarmSilenced
// delta_val not set for alarmSilenced
alarmsilenced->set_default_properties(alarmsilenced_prop);
// Not Polled
alarmsilenced->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmsilenced->set_change_event(true, true);
alarmsilenced->set_archive_event(true, true);
att_list.push_back(alarmsilenced);
// Attribute : alarmList
alarmListAttrib *alarmlist = new alarmListAttrib();
Tango::UserDefaultAttrProp alarmlist_prop;
alarmlist_prop.set_description("List of all alarms");
// label not set for alarmList
// unit not set for alarmList
// standard_unit not set for alarmList
// display_unit not set for alarmList
// format not set for alarmList
// max_value not set for alarmList
// min_value not set for alarmList
// max_alarm not set for alarmList
// min_alarm not set for alarmList
// max_warning not set for alarmList
// min_warning not set for alarmList
// delta_t not set for alarmList
// delta_val not set for alarmList
alarmlist->set_default_properties(alarmlist_prop);
// Not Polled
alarmlist->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmlist->set_change_event(true, true);
alarmlist->set_archive_event(true, true);
att_list.push_back(alarmlist);
// Attribute : alarmFrequency
alarmFrequencyAttrib *alarmfrequency = new alarmFrequencyAttrib();
Tango::UserDefaultAttrProp alarmfrequency_prop;
alarmfrequency_prop.set_description("List of frequency of evaluation of all alarms");
// label not set for alarmFrequency
// unit not set for alarmFrequency
// standard_unit not set for alarmFrequency
// display_unit not set for alarmFrequency
// format not set for alarmFrequency
// max_value not set for alarmFrequency
// min_value not set for alarmFrequency
// max_alarm not set for alarmFrequency
// min_alarm not set for alarmFrequency
// max_warning not set for alarmFrequency
// min_warning not set for alarmFrequency
// delta_t not set for alarmFrequency
// delta_val not set for alarmFrequency
alarmfrequency->set_default_properties(alarmfrequency_prop);
// Not Polled
alarmfrequency->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmfrequency->set_change_event(true, true);
alarmfrequency->set_archive_event(true, true);
att_list.push_back(alarmfrequency);
// Attribute : alarmSummary
alarmSummaryAttrib *alarmsummary = new alarmSummaryAttrib();
Tango::UserDefaultAttrProp alarmsummary_prop;
// description not set for alarmSummary
// label not set for alarmSummary
// unit not set for alarmSummary
// standard_unit not set for alarmSummary
// display_unit not set for alarmSummary
// format not set for alarmSummary
// max_value not set for alarmSummary
// min_value not set for alarmSummary
// max_alarm not set for alarmSummary
// min_alarm not set for alarmSummary
// max_warning not set for alarmSummary
// min_warning not set for alarmSummary
// delta_t not set for alarmSummary
// delta_val not set for alarmSummary
alarmsummary->set_default_properties(alarmsummary_prop);
// Not Polled
alarmsummary->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmsummary->set_change_event(true, true);
alarmsummary->set_archive_event(true, true);
att_list.push_back(alarmsummary);
// Attribute : eventList
eventListAttrib *eventlist = new eventListAttrib();
Tango::UserDefaultAttrProp eventlist_prop;
eventlist_prop.set_description("List of all subscribed attributes");
// label not set for eventList
// unit not set for eventList
// standard_unit not set for eventList
// display_unit not set for eventList
// format not set for eventList
// max_value not set for eventList
// min_value not set for eventList
// max_alarm not set for eventList
// min_alarm not set for eventList
// max_warning not set for eventList
// min_warning not set for eventList
// delta_t not set for eventList
// delta_val not set for eventList
eventlist->set_default_properties(eventlist_prop);
// Not Polled
eventlist->set_disp_level(Tango::OPERATOR);
// Not Memorized
att_list.push_back(eventlist);
// Attribute : eventSummary
eventSummaryAttrib *eventsummary = new eventSummaryAttrib();
Tango::UserDefaultAttrProp eventsummary_prop;
// description not set for eventSummary
// label not set for eventSummary
// unit not set for eventSummary
// standard_unit not set for eventSummary
// display_unit not set for eventSummary
// format not set for eventSummary
// max_value not set for eventSummary
// min_value not set for eventSummary
// max_alarm not set for eventSummary
// min_alarm not set for eventSummary
// max_warning not set for eventSummary
// min_warning not set for eventSummary
// delta_t not set for eventSummary
// delta_val not set for eventSummary
eventsummary->set_default_properties(eventsummary_prop);
// Not Polled
eventsummary->set_disp_level(Tango::OPERATOR);
// Not Memorized
att_list.push_back(eventsummary);
// Attribute : alarmDisabled
alarmDisabledAttrib *alarmdisabled = new alarmDisabledAttrib();
Tango::UserDefaultAttrProp alarmdisabled_prop;
alarmdisabled_prop.set_description("List of alarms in out of service or shelved state");
// label not set for alarmDisabled
// unit not set for alarmDisabled
// standard_unit not set for alarmDisabled
// display_unit not set for alarmDisabled
// format not set for alarmDisabled
// max_value not set for alarmDisabled
// min_value not set for alarmDisabled
// max_alarm not set for alarmDisabled
// min_alarm not set for alarmDisabled
// max_warning not set for alarmDisabled
// min_warning not set for alarmDisabled
// delta_t not set for alarmDisabled
// delta_val not set for alarmDisabled
alarmdisabled->set_default_properties(alarmdisabled_prop);
// Not Polled
alarmdisabled->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmdisabled->set_change_event(true, true);
alarmdisabled->set_archive_event(true, true);
att_list.push_back(alarmdisabled);
// Create a list of static attributes
create_static_attribute_list(get_class_attr()->get_attr_list());
/*----- PROTECTED REGION ID(AlarmHandlerClass::attribute_factory_after) ENABLED START -----*/
// Add your own code
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::attribute_factory_after
}
//--------------------------------------------------------
/**
* Method : AlarmHandlerClass::pipe_factory()
* Description : Create the pipe object(s)
* and store them in the pipe list
*/
//--------------------------------------------------------
void AlarmHandlerClass::pipe_factory()
{
/*----- PROTECTED REGION ID(AlarmHandlerClass::pipe_factory_before) ENABLED START -----*/
// Add your own code
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::pipe_factory_before
/*----- PROTECTED REGION ID(AlarmHandlerClass::pipe_factory_after) ENABLED START -----*/
// Add your own code
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::pipe_factory_after
}
//--------------------------------------------------------
/**
* Method : AlarmHandlerClass::command_factory()
* Description : Create the command object(s)
* and store them in the command list
*/
//--------------------------------------------------------
void AlarmHandlerClass::command_factory()
{
/*----- PROTECTED REGION ID(AlarmHandlerClass::command_factory_before) ENABLED START -----*/
// Add your own code
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::command_factory_before
// Command Ack
AckClass *pAckCmd =
new AckClass("Ack",
Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
"String array containing the alarms to be acknowledged",
"",
Tango::OPERATOR);
command_list.push_back(pAckCmd);
// Command Load
LoadClass *pLoadCmd =
new LoadClass("Load",
Tango::DEV_STRING, Tango::DEV_VOID,
"Alarm entry",
"",
Tango::OPERATOR);
command_list.push_back(pLoadCmd);
// Command Remove
RemoveClass *pRemoveCmd =
new RemoveClass("Remove",
Tango::DEV_STRING, Tango::DEV_VOID,
"Alarm name",
"",
Tango::OPERATOR);
command_list.push_back(pRemoveCmd);
// Command SearchAlarm
SearchAlarmClass *pSearchAlarmCmd =
new SearchAlarmClass("SearchAlarm",
Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY,
"String containing a filter for output, if empty or * return all alarms",
"Configured alarms",
Tango::OPERATOR);
command_list.push_back(pSearchAlarmCmd);
// Command StopAudible
StopAudibleClass *pStopAudibleCmd =
new StopAudibleClass("StopAudible",
Tango::DEV_VOID, Tango::DEV_VOID,
"",
"",
Tango::OPERATOR);
command_list.push_back(pStopAudibleCmd);
// Command Silence
SilenceClass *pSilenceCmd =
new SilenceClass("Silence",
Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
"String array containing the alarms to be silenced",
"",
Tango::OPERATOR);
command_list.push_back(pSilenceCmd);
// Command Modify
ModifyClass *pModifyCmd =
new ModifyClass("Modify",
Tango::DEV_STRING, Tango::DEV_VOID,
"Alarm entry",
"",
Tango::OPERATOR);
command_list.push_back(pModifyCmd);
// Command Shelve
ShelveClass *pShelveCmd =
new ShelveClass("Shelve",
Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
"String array containing alarm to be shelved",
"",
Tango::OPERATOR);
command_list.push_back(pShelveCmd);
// Command Enable
EnableClass *pEnableCmd =
new EnableClass("Enable",
Tango::DEV_STRING, Tango::DEV_VOID,
"Alarm name",
"",
Tango::OPERATOR);
command_list.push_back(pEnableCmd);
// Command Disable
DisableClass *pDisableCmd =
new DisableClass("Disable",
Tango::DEV_STRING, Tango::DEV_VOID,
"Alarm name",
"",
Tango::OPERATOR);
command_list.push_back(pDisableCmd);
// Command ResetStatistics
ResetStatisticsClass *pResetStatisticsCmd =
new ResetStatisticsClass("ResetStatistics",
Tango::DEV_VOID, Tango::DEV_VOID,
"",
"",
Tango::OPERATOR);
command_list.push_back(pResetStatisticsCmd);
// Command StopNew
StopNewClass *pStopNewCmd =
new StopNewClass("StopNew",
Tango::DEV_VOID, Tango::DEV_VOID,
"",
"",
Tango::OPERATOR);
command_list.push_back(pStopNewCmd);
// Command GetAlarmInfo
GetAlarmInfoClass *pGetAlarmInfoCmd =
new GetAlarmInfoClass("GetAlarmInfo",
Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY,
"Alarm name followed optionally by wanted key names",
"Complete attribute info as an array of key=value",
Tango::OPERATOR);
command_list.push_back(pGetAlarmInfoCmd);
// Command ReLoadAll
ReLoadAllClass *pReLoadAllCmd =
new ReLoadAllClass("ReLoadAll",
Tango::DEV_VOID, Tango::DEV_VOID,
"",
"",
Tango::OPERATOR);
command_list.push_back(pReLoadAllCmd);
/*----- PROTECTED REGION ID(AlarmHandlerClass::command_factory_after) ENABLED START -----*/
// Add your own code
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::command_factory_after
}
//===================================================================
// Dynamic attributes related methods
//===================================================================
//--------------------------------------------------------
/**
* method : AlarmHandlerClass::create_static_attribute_list
* description : Create the a list of static attributes
*
* @param att_list the ceated attribute list
*/
//--------------------------------------------------------
void AlarmHandlerClass::create_static_attribute_list(vector<Tango::Attr *> &att_list)
{
for (unsigned long i=0 ; i<att_list.size() ; i++)
{
string att_name(att_list[i]->get_name());
transform(att_name.begin(), att_name.end(), att_name.begin(), ::tolower);
defaultAttList.push_back(att_name);
}
TANGO_LOG_INFO << defaultAttList.size() << " attributes in default list" << endl;
/*----- PROTECTED REGION ID(AlarmHandlerClass::create_static_att_list) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::create_static_att_list
}
//--------------------------------------------------------
/**
* method : AlarmHandlerClass::erase_dynamic_attributes
* description : delete the dynamic attributes if any.
*
* @param devlist_ptr the device list pointer
* @param list of all attributes
*/
//--------------------------------------------------------
void AlarmHandlerClass::erase_dynamic_attributes(const Tango::DevVarStringArray *devlist_ptr, vector<Tango::Attr *> &att_list)
{
Tango::Util *tg = Tango::Util::instance();
for (unsigned long i=0 ; i<devlist_ptr->length() ; i++)
{
Tango::DeviceImpl *dev_impl = tg->get_device_by_name(((string)(*devlist_ptr)[i]).c_str());
AlarmHandler *dev = static_cast<AlarmHandler *> (dev_impl);
vector<Tango::Attribute *> &dev_att_list = dev->get_device_attr()->get_attribute_list();
vector<Tango::Attribute *>::iterator ite_att;
for (ite_att=dev_att_list.begin() ; ite_att != dev_att_list.end() ; ++ite_att)
{
string att_name((*ite_att)->get_name_lower());
if ((att_name == "state") || (att_name == "status"))
continue;
vector<string>::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name);
if (ite_str == defaultAttList.end())
{
TANGO_LOG_INFO << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << endl;
Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str());
dev->remove_attribute(att_list[att.get_attr_idx()], true, false);
--ite_att;
}
}
}
/*----- PROTECTED REGION ID(AlarmHandlerClass::erase_dynamic_attributes) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::erase_dynamic_attributes
}
//--------------------------------------------------------
/**
* Method : AlarmHandlerClass::get_attr_object_by_name()
* Description : returns Tango::Attr * object found by name
*/
//--------------------------------------------------------
Tango::Attr *AlarmHandlerClass::get_attr_object_by_name(vector<Tango::Attr *> &att_list, string attname)
{
vector<Tango::Attr *>::iterator it;
for (it=att_list.begin() ; it<att_list.end() ; ++it)
if ((*it)->get_name()==attname)
return (*it);
// Attr does not exist
return NULL;
}
/*----- PROTECTED REGION ID(AlarmHandlerClass::Additional Methods) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::Additional Methods
} // namespace
/*----- PROTECTED REGION ID(AlarmHandlerClass.h) ENABLED START -----*/
//=============================================================================
//
// file : AlarmHandlerClass.h
//
// description : Include for the AlarmHandler root class.
// This class is the singleton class for
// the AlarmHandler device class.
// It contains all properties and methods which the
// AlarmHandler requires only once e.g. the commands.
//
// project : Elettra alarm handler device server
//
// This file is part of Tango device class.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Tango. If not, see <http://www.gnu.org/licenses/>.
//
//
//
//=============================================================================
// This file is generated by POGO
// (Program Obviously used to Generate tango Object)
//=============================================================================
#ifndef AlarmHandlerClass_H
#define AlarmHandlerClass_H
#include <tango/tango.h>
#include <AlarmHandler.h>
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass.h
namespace AlarmHandler_ns
{
/*----- PROTECTED REGION ID(AlarmHandlerClass::classes for dynamic creation) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::classes for dynamic creation
//=========================================
// Define classes for attributes
//=========================================
// Attribute alarmAudible class definition
class alarmAudibleAttrib: public Tango::Attr
{
public:
alarmAudibleAttrib():Attr("alarmAudible",
Tango::DEV_BOOLEAN, Tango::READ) {};
~alarmAudibleAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmAudible(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmAudible_allowed(ty);}
};
// Attribute StatisticsResetTime class definition
class StatisticsResetTimeAttrib: public Tango::Attr
{
public:
StatisticsResetTimeAttrib():Attr("StatisticsResetTime",
Tango::DEV_DOUBLE, Tango::READ) {};
~StatisticsResetTimeAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_StatisticsResetTime(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_StatisticsResetTime_allowed(ty);}
};
// Attribute alarm class definition
class alarmAttrib: public Tango::SpectrumAttr
{
public:
alarmAttrib():SpectrumAttr("alarm",
Tango::DEV_STRING, Tango::READ, 1024) {};
~alarmAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarm(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarm_allowed(ty);}
};
// Attribute alarmNormal class definition
class alarmNormalAttrib: public Tango::SpectrumAttr
{
public:
alarmNormalAttrib():SpectrumAttr("alarmNormal",
Tango::DEV_STRING, Tango::READ, 10000) {};
~alarmNormalAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmNormal(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmNormal_allowed(ty);}
};
// Attribute alarmUnacknowledged class definition
class alarmUnacknowledgedAttrib: public Tango::SpectrumAttr
{
public:
alarmUnacknowledgedAttrib():SpectrumAttr("alarmUnacknowledged",
Tango::DEV_STRING, Tango::READ, 10000) {};
~alarmUnacknowledgedAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmUnacknowledged(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmUnacknowledged_allowed(ty);}
};
// Attribute alarmAcknowledged class definition
class alarmAcknowledgedAttrib: public Tango::SpectrumAttr
{
public:
alarmAcknowledgedAttrib():SpectrumAttr("alarmAcknowledged",
Tango::DEV_STRING, Tango::READ, 10000) {};
~alarmAcknowledgedAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmAcknowledged(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmAcknowledged_allowed(ty);}
};
// Attribute alarmUnacknowledgedNormal class definition
class alarmUnacknowledgedNormalAttrib: public Tango::SpectrumAttr
{
public:
alarmUnacknowledgedNormalAttrib():SpectrumAttr("alarmUnacknowledgedNormal",
Tango::DEV_STRING, Tango::READ, 10000) {};
~alarmUnacknowledgedNormalAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmUnacknowledgedNormal(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmUnacknowledgedNormal_allowed(ty);}
};
// Attribute alarmShelved class definition
class alarmShelvedAttrib: public Tango::SpectrumAttr
{
public:
alarmShelvedAttrib():SpectrumAttr("alarmShelved",
Tango::DEV_STRING, Tango::READ, 10000) {};
~alarmShelvedAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmShelved(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmShelved_allowed(ty);}
};
// Attribute alarmOutOfService class definition
class alarmOutOfServiceAttrib: public Tango::SpectrumAttr
{
public:
alarmOutOfServiceAttrib():SpectrumAttr("alarmOutOfService",
Tango::DEV_STRING, Tango::READ, 10000) {};
~alarmOutOfServiceAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmOutOfService(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmOutOfService_allowed(ty);}
};
// Attribute alarmSilenced class definition
class alarmSilencedAttrib: public Tango::SpectrumAttr
{
public:
alarmSilencedAttrib():SpectrumAttr("alarmSilenced",
Tango::DEV_STRING, Tango::READ, 10000) {};
~alarmSilencedAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmSilenced(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmSilenced_allowed(ty);}
};
// Attribute alarmList class definition
class alarmListAttrib: public Tango::SpectrumAttr
{
public:
alarmListAttrib():SpectrumAttr("alarmList",
Tango::DEV_STRING, Tango::READ, 10000) {};
~alarmListAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmList(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmList_allowed(ty);}
};
// Attribute alarmFrequency class definition
class alarmFrequencyAttrib: public Tango::SpectrumAttr
{
public:
alarmFrequencyAttrib():SpectrumAttr("alarmFrequency",
Tango::DEV_DOUBLE, Tango::READ, 10000) {};
~alarmFrequencyAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmFrequency(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmFrequency_allowed(ty);}
};
// Attribute alarmSummary class definition
class alarmSummaryAttrib: public Tango::SpectrumAttr
{
public:
alarmSummaryAttrib():SpectrumAttr("alarmSummary",
Tango::DEV_STRING, Tango::READ, 10000) {};
~alarmSummaryAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmSummary(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmSummary_allowed(ty);}
};
// Attribute eventList class definition
class eventListAttrib: public Tango::SpectrumAttr
{
public:
eventListAttrib():SpectrumAttr("eventList",
Tango::DEV_STRING, Tango::READ, 10000) {};
~eventListAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_eventList(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_eventList_allowed(ty);}
};
// Attribute eventSummary class definition
class eventSummaryAttrib: public Tango::SpectrumAttr
{
public:
eventSummaryAttrib():SpectrumAttr("eventSummary",
Tango::DEV_STRING, Tango::READ, 10000) {};
~eventSummaryAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_eventSummary(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_eventSummary_allowed(ty);}
};
// Attribute alarmDisabled class definition
class alarmDisabledAttrib: public Tango::SpectrumAttr
{
public:
alarmDisabledAttrib():SpectrumAttr("alarmDisabled",
Tango::DEV_STRING, Tango::READ, 10000) {};
~alarmDisabledAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_alarmDisabled(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_alarmDisabled_allowed(ty);}
};
//=========================================
// Define classes for dynamic attributes
//=========================================
// Attribute AlarmState class definition
class AlarmStateAttrib: public Tango::Attr
{
public:
AlarmStateAttrib(const string &att_name):Attr(att_name.c_str(),
Tango::DEV_ENUM, Tango::READ) {};
~AlarmStateAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_AlarmState(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_AlarmState_allowed(ty);}
virtual bool same_type(const type_info &in_type) {return typeid(AlarmStateEnum) == in_type;}
virtual string get_enum_type() {return string("AlarmStateEnum");}
};
// Attribute AlarmFormula class definition
class AlarmFormulaAttrib: public Tango::Attr
{
public:
AlarmFormulaAttrib(const string &att_name):Attr(att_name.c_str(),
Tango::DEV_STRING, Tango::READ) {};
~AlarmFormulaAttrib() {};
virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
{(static_cast<AlarmHandler *>(dev))->read_AlarmFormula(att);}
virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
{return (static_cast<AlarmHandler *>(dev))->is_AlarmFormula_allowed(ty);}
};
//=========================================
// Define classes for commands
//=========================================
// Command Ack class definition
class AckClass : public Tango::Command
{
public:
AckClass(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) {};
AckClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~AckClass() {};
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<AlarmHandler *>(dev))->is_Ack_allowed(any);}
};
// Command Load class definition
class LoadClass : public Tango::Command
{
public:
LoadClass(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) {};
LoadClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~LoadClass() {};
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<AlarmHandler *>(dev))->is_Load_allowed(any);}
};
// Command Remove class definition
class RemoveClass : public Tango::Command
{
public:
RemoveClass(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) {};
RemoveClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~RemoveClass() {};
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<AlarmHandler *>(dev))->is_Remove_allowed(any);}
};
// Command SearchAlarm class definition
class SearchAlarmClass : public Tango::Command
{
public:
SearchAlarmClass(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) {};
SearchAlarmClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~SearchAlarmClass() {};
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<AlarmHandler *>(dev))->is_SearchAlarm_allowed(any);}
};
// Command StopAudible class definition
class StopAudibleClass : public Tango::Command
{
public:
StopAudibleClass(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) {};
StopAudibleClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~StopAudibleClass() {};
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<AlarmHandler *>(dev))->is_StopAudible_allowed(any);}
};
// Command Silence class definition
class SilenceClass : public Tango::Command
{
public:
SilenceClass(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) {};
SilenceClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~SilenceClass() {};
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<AlarmHandler *>(dev))->is_Silence_allowed(any);}
};
// Command Modify class definition
class ModifyClass : public Tango::Command
{
public:
ModifyClass(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) {};
ModifyClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~ModifyClass() {};
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<AlarmHandler *>(dev))->is_Modify_allowed(any);}
};
// Command Shelve class definition
class ShelveClass : public Tango::Command
{
public:
ShelveClass(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) {};
ShelveClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~ShelveClass() {};
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<AlarmHandler *>(dev))->is_Shelve_allowed(any);}
};
// Command Enable class definition
class EnableClass : public Tango::Command
{
public:
EnableClass(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) {};
EnableClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~EnableClass() {};
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<AlarmHandler *>(dev))->is_Enable_allowed(any);}
};
// Command Disable class definition
class DisableClass : public Tango::Command
{
public:
DisableClass(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) {};
DisableClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~DisableClass() {};
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<AlarmHandler *>(dev))->is_Disable_allowed(any);}
};
// Command ResetStatistics class definition
class ResetStatisticsClass : public Tango::Command
{
public:
ResetStatisticsClass(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) {};
ResetStatisticsClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~ResetStatisticsClass() {};
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<AlarmHandler *>(dev))->is_ResetStatistics_allowed(any);}
};
// Command StopNew class definition
class StopNewClass : public Tango::Command
{
public:
StopNewClass(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) {};
StopNewClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~StopNewClass() {};
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<AlarmHandler *>(dev))->is_StopNew_allowed(any);}
};
// Command GetAlarmInfo class definition
class GetAlarmInfoClass : public Tango::Command
{
public:
GetAlarmInfoClass(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) {};
GetAlarmInfoClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~GetAlarmInfoClass() {};
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<AlarmHandler *>(dev))->is_GetAlarmInfo_allowed(any);}
};
// Command ReLoadAll class definition
class ReLoadAllClass : public Tango::Command
{
public:
ReLoadAllClass(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) {};
ReLoadAllClass(const char *name,
Tango::CmdArgType in,
Tango::CmdArgType out)
:Command(name,in,out) {};
~ReLoadAllClass() {};
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<AlarmHandler *>(dev))->is_ReLoadAll_allowed(any);}
};
/**
* The AlarmHandlerClass singleton definition
*/
#ifdef _TG_WINDOWS_
class __declspec(dllexport) AlarmHandlerClass : public Tango::DeviceClass
#else
class AlarmHandlerClass : public Tango::DeviceClass
#endif
{
/*----- PROTECTED REGION ID(AlarmHandlerClass::Additionnal DServer data members) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::Additionnal DServer data members
// Class properties data members
public:
// GroupNames: Labels for Group mask, first is for mask 0x00
vector<string> groupNames;
// SubscribeRetryPeriod: Retry subscription period in seconds
Tango::DevLong subscribeRetryPeriod;
// StatisticsTimeWindow: Time window to compute statistics in seconds
vector<Tango::DevLong> statisticsTimeWindow;
// ErrorDelay: Delay in seconds before changing to ERROR state after an exception is received.
Tango::DevULong errorDelay;
// SetAlarmQuality: Set alarm attribute quality as computed using quality of attributes in the formula
Tango::DevBoolean setAlarmQuality;
public:
// write class properties data members
Tango::DbData cl_prop;
Tango::DbData cl_def_prop;
Tango::DbData dev_def_prop;
// Method prototypes
static AlarmHandlerClass *init(const char *);
static AlarmHandlerClass *instance();
~AlarmHandlerClass();
Tango::DbDatum get_class_property(string &);
Tango::DbDatum get_default_device_property(string &);
Tango::DbDatum get_default_class_property(string &);
protected:
AlarmHandlerClass(string &);
static AlarmHandlerClass *_instance;
void command_factory();
void attribute_factory(vector<Tango::Attr *> &);
void pipe_factory();
void write_class_property();
void set_default_property();
void get_class_property();
string get_cvstag();
string get_cvsroot();
private:
void device_factory(const Tango::DevVarStringArray *);
void create_static_attribute_list(vector<Tango::Attr *> &);
void erase_dynamic_attributes(const Tango::DevVarStringArray *,vector<Tango::Attr *> &);
vector<string> defaultAttList;
Tango::Attr *get_attr_object_by_name(vector<Tango::Attr *> &att_list, string attname);
};
} // End of namespace
#endif // AlarmHandler_H
/*----- PROTECTED REGION ID(AlarmHandler::DynAttrUtils.cpp) ENABLED START -----*/
//=============================================================================
//
// file : AlarmHandlerDynAttrUtils.cpp
//
// description : Dynamic attributes utilities file for the AlarmHandler class
//
// project : Elettra alarm handler device server
//
// This file is part of Tango device class.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Tango. If not, see <http://www.gnu.org/licenses/>.
//
//
//
//=============================================================================
// This file is generated by POGO
// (Program Obviously used to Generate tango Object)
//=============================================================================
#include <AlarmHandler.h>
#include <AlarmHandlerClass.h>
/*----- PROTECTED REGION END -----*/ // AlarmHandler::DynAttrUtils.cpp
//================================================================
// Attributes managed are:
//================================================================
// AlarmState | Tango::DevEnum Scalar
// AlarmFormula | Tango::DevString Scalar
//================================================================
// For compatibility reason, this file (AlarmHandlerDynAttrUtils)
// manage also the dynamic command utilities.
//================================================================
// The following table gives the correspondence
// between command and method names.
//
// Command name | Method name
//================================================================
//================================================================
namespace AlarmHandler_ns
{
//=============================================================
// Add/Remove dynamic attribute methods
//=============================================================
//--------------------------------------------------------
/**
* Add a AlarmState dynamic attribute.
*
* parameter attname: attribute name to be cretated and added.
*/
//--------------------------------------------------------
void AlarmHandler::add_AlarmState_dynamic_attribute(string attname)
{
// Attribute : AlarmState
AlarmStateAttrib *alarmstate = new AlarmStateAttrib(attname);
Tango::UserDefaultAttrProp alarmstate_prop;
// description not set for AlarmState
// label not set for AlarmState
// unit not set for AlarmState
// standard_unit not set for AlarmState
// display_unit not set for AlarmState
// format not set for AlarmState
// max_value not set for AlarmState
// min_value not set for AlarmState
// max_alarm not set for AlarmState
// min_alarm not set for AlarmState
// max_warning not set for AlarmState
// min_warning not set for AlarmState
// delta_t not set for AlarmState
// delta_val not set for AlarmState
/*----- PROTECTED REGION ID(AlarmHandler::att_AlarmState_dynamic_attribute) ENABLED START -----*/
DEBUG_STREAM << __func__<<": entering name="<<attname;
alarm_container_t::iterator i = alarms.v_alarm.find(attname);
if(i != alarms.v_alarm.end())
{
alarmstate_prop.set_description(i->second.formula.c_str());
}
else
{
INFO_STREAM << __func__<<": name="<<attname<<" NOT FOUND while looking for formula to add as attribute description";
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::att_AlarmState_dynamic_attribute
{
vector<string> labels;
labels.push_back("NORM");
labels.push_back("UNACK");
labels.push_back("ACKED");
labels.push_back("RTNUN");
labels.push_back("SHLVD");
labels.push_back("DSUPR");
labels.push_back("OOSRV");
labels.push_back("ERROR");
alarmstate_prop.set_enum_labels(labels);
}
alarmstate->set_default_properties(alarmstate_prop);
// Not Polled
alarmstate->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmstate->set_change_event(true, true);
alarmstate->set_archive_event(true, true);
AlarmState_data.insert(make_pair(attname, 0));
add_attribute(alarmstate);
}
//--------------------------------------------------------
/**
* remove a AlarmState dynamic attribute.
*
* parameter attname: attribute name to be removed.
*/
//--------------------------------------------------------
void AlarmHandler::remove_AlarmState_dynamic_attribute(string attname)
{
remove_attribute(attname, true, Tango::Util::instance()->_UseDb);
map<string,Tango::DevEnum>::iterator ite;
if ((ite=AlarmState_data.find(attname))!=AlarmState_data.end())
{
/*----- PROTECTED REGION ID(AlarmHandler::remove_AlarmState_dynamic_attribute) ENABLED START -----*/
DEBUG_STREAM << __func__<<": entering name="<<attname;
/*----- PROTECTED REGION END -----*/ // AlarmHandler::remove_AlarmState_dynamic_attribute
AlarmState_data.erase(ite);
}
}
//--------------------------------------------------------
/**
* Add a AlarmFormula dynamic attribute.
*
* parameter attname: attribute name to be cretated and added.
*/
//--------------------------------------------------------
void AlarmHandler::add_AlarmFormula_dynamic_attribute(string attname)
{
// Attribute : AlarmFormula
AlarmFormulaAttrib *alarmformula = new AlarmFormulaAttrib(attname);
Tango::UserDefaultAttrProp alarmformula_prop;
// description not set for AlarmFormula
// label not set for AlarmFormula
// unit not set for AlarmFormula
// standard_unit not set for AlarmFormula
// display_unit not set for AlarmFormula
// format not set for AlarmFormula
// max_value not set for AlarmFormula
// min_value not set for AlarmFormula
// max_alarm not set for AlarmFormula
// min_alarm not set for AlarmFormula
// max_warning not set for AlarmFormula
// min_warning not set for AlarmFormula
// delta_t not set for AlarmFormula
// delta_val not set for AlarmFormula
/*----- PROTECTED REGION ID(AlarmHandler::att_AlarmFormula_dynamic_attribute) ENABLED START -----*/
DEBUG_STREAM << __func__<<": entering name="<<attname;
/*----- PROTECTED REGION END -----*/ // AlarmHandler::att_AlarmFormula_dynamic_attribute
alarmformula->set_default_properties(alarmformula_prop);
// Not Polled
alarmformula->set_disp_level(Tango::OPERATOR);
// Not Memorized
alarmformula->set_change_event(true, true);
alarmformula->set_archive_event(true, true);
char array[1];
array[0] = '\0';
AlarmFormula_data.insert(make_pair(attname, array));
add_attribute(alarmformula);
}
//--------------------------------------------------------
/**
* remove a AlarmFormula dynamic attribute.
*
* parameter attname: attribute name to be removed.
*/
//--------------------------------------------------------
void AlarmHandler::remove_AlarmFormula_dynamic_attribute(string attname)
{
remove_attribute(attname, true, Tango::Util::instance()->_UseDb);
map<string,Tango::DevString>::iterator ite;
if ((ite=AlarmFormula_data.find(attname))!=AlarmFormula_data.end())
{
/*----- PROTECTED REGION ID(AlarmHandler::remove_AlarmFormula_dynamic_attribute) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::remove_AlarmFormula_dynamic_attribute
AlarmFormula_data.erase(ite);
}
}
//============================================================
// Tool methods to get pointer on attribute data buffer
//============================================================
//--------------------------------------------------------
/**
* Return a pointer on AlarmState data.
*
* parameter attname: the specified attribute name.
*/
//--------------------------------------------------------
Tango::DevEnum *AlarmHandler::get_AlarmState_data_ptr(string &name)
{
map<string,Tango::DevEnum>::iterator ite;
if ((ite=AlarmState_data.find(name))==AlarmState_data.end())
{
TangoSys_OMemStream tms;
tms << "Dynamic attribute " << name << " has not been created";
Tango::Except::throw_exception(
(const char *)"ATTRIBUTE_NOT_FOUND",
tms.str().c_str(),
(const char *)"AlarmHandler::get_AlarmState_data_ptr()");
}
return &(ite->second);
}
//--------------------------------------------------------
/**
* Return a pointer on AlarmFormula data.
*
* parameter attname: the specified attribute name.
*/
//--------------------------------------------------------
Tango::DevString *AlarmHandler::get_AlarmFormula_data_ptr(string &name)
{
map<string,Tango::DevString>::iterator ite;
if ((ite=AlarmFormula_data.find(name))==AlarmFormula_data.end())
{
TangoSys_OMemStream tms;
tms << "Dynamic attribute " << name << " has not been created";
Tango::Except::throw_exception(
(const char *)"ATTRIBUTE_NOT_FOUND",
tms.str().c_str(),
(const char *)"AlarmHandler::get_AlarmFormula_data_ptr()");
}
return &(ite->second);
}
//=============================================================
// Add/Remove dynamic command methods
//=============================================================
} // namespace
/*----- PROTECTED REGION ID(AlarmHandlerStateMachine.cpp) ENABLED START -----*/
//=============================================================================
//
// file : AlarmHandlerStateMachine.cpp
//
// description : State machine file for the AlarmHandler class
//
// project : Elettra alarm handler device server
//
// This file is part of Tango device class.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Tango. If not, see <http://www.gnu.org/licenses/>.
//
//
//
//=============================================================================
// This file is generated by POGO
// (Program Obviously used to Generate tango Object)
//=============================================================================
#include <AlarmHandler.h>
/*----- PROTECTED REGION END -----*/ // AlarmHandler::AlarmHandlerStateMachine.cpp
//================================================================
// States | Description
//================================================================
namespace AlarmHandler_ns
{
//=================================================
// Attributes Allowed Methods
//=================================================
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmAudible_allowed()
* Description : Execution allowed for alarmAudible attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmAudible_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmAudible attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmAudibleStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmAudibleStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_StatisticsResetTime_allowed()
* Description : Execution allowed for StatisticsResetTime attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_StatisticsResetTime_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for StatisticsResetTime attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::StatisticsResetTimeStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::StatisticsResetTimeStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarm_allowed()
* Description : Execution allowed for alarm attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarm_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarm attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmNormal_allowed()
* Description : Execution allowed for alarmNormal attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmNormal_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmNormal attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmNormalStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmNormalStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmUnacknowledged_allowed()
* Description : Execution allowed for alarmUnacknowledged attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmUnacknowledged_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmUnacknowledged attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmUnacknowledgedStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmUnacknowledgedStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmAcknowledged_allowed()
* Description : Execution allowed for alarmAcknowledged attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmAcknowledged_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmAcknowledged attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmAcknowledgedStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmAcknowledgedStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmUnacknowledgedNormal_allowed()
* Description : Execution allowed for alarmUnacknowledgedNormal attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmUnacknowledgedNormal_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmUnacknowledgedNormal attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmUnacknowledgedNormalStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmUnacknowledgedNormalStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmShelved_allowed()
* Description : Execution allowed for alarmShelved attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmShelved_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmShelved attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmShelvedStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmShelvedStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmOutOfService_allowed()
* Description : Execution allowed for alarmOutOfService attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmOutOfService_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmOutOfService attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmOutOfServiceStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmOutOfServiceStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmSilenced_allowed()
* Description : Execution allowed for alarmSilenced attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmSilenced_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmSilenced attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmSilencedStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmSilencedStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmList_allowed()
* Description : Execution allowed for alarmList attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmList_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmList attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmListStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmListStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmFrequency_allowed()
* Description : Execution allowed for alarmFrequency attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmFrequency_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmFrequency attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmFrequencyStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmFrequencyStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmSummary_allowed()
* Description : Execution allowed for alarmSummary attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmSummary_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmSummary attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmSummaryStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmSummaryStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_eventList_allowed()
* Description : Execution allowed for eventList attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_eventList_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for eventList attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::eventListStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::eventListStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_eventSummary_allowed()
* Description : Execution allowed for eventSummary attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_eventSummary_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for eventSummary attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::eventSummaryStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::eventSummaryStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_alarmDisabled_allowed()
* Description : Execution allowed for alarmDisabled attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_alarmDisabled_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for alarmDisabled attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::alarmDisabledStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::alarmDisabledStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_AlarmState_allowed()
* Description : Execution allowed for AlarmState attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_AlarmState_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for AlarmState attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::AlarmStateStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::AlarmStateStateAllowed_READ
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_AlarmFormula_allowed()
* Description : Execution allowed for AlarmFormula attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_AlarmFormula_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
// Not any excluded states for AlarmFormula attribute in read access.
/*----- PROTECTED REGION ID(AlarmHandler::AlarmFormulaStateAllowed_READ) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::AlarmFormulaStateAllowed_READ
return true;
}
//=================================================
// Commands Allowed Methods
//=================================================
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_Ack_allowed()
* Description : Execution allowed for Ack attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_Ack_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for Ack command.
/*----- PROTECTED REGION ID(AlarmHandler::AckStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::AckStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_Load_allowed()
* Description : Execution allowed for Load attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_Load_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for Load command.
/*----- PROTECTED REGION ID(AlarmHandler::LoadStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::LoadStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_Remove_allowed()
* Description : Execution allowed for Remove attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_Remove_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for Remove command.
/*----- PROTECTED REGION ID(AlarmHandler::RemoveStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::RemoveStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_SearchAlarm_allowed()
* Description : Execution allowed for SearchAlarm attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_SearchAlarm_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for SearchAlarm command.
/*----- PROTECTED REGION ID(AlarmHandler::SearchAlarmStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::SearchAlarmStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_StopAudible_allowed()
* Description : Execution allowed for StopAudible attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_StopAudible_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for StopAudible command.
/*----- PROTECTED REGION ID(AlarmHandler::StopAudibleStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::StopAudibleStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_Silence_allowed()
* Description : Execution allowed for Silence attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_Silence_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for Silence command.
/*----- PROTECTED REGION ID(AlarmHandler::SilenceStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::SilenceStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_Modify_allowed()
* Description : Execution allowed for Modify attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_Modify_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for Modify command.
/*----- PROTECTED REGION ID(AlarmHandler::ModifyStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::ModifyStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_Shelve_allowed()
* Description : Execution allowed for Shelve attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_Shelve_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for Shelve command.
/*----- PROTECTED REGION ID(AlarmHandler::ShelveStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::ShelveStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_Enable_allowed()
* Description : Execution allowed for Enable attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_Enable_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for Enable command.
/*----- PROTECTED REGION ID(AlarmHandler::EnableStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::EnableStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_Disable_allowed()
* Description : Execution allowed for Disable attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_Disable_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for Disable command.
/*----- PROTECTED REGION ID(AlarmHandler::DisableStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::DisableStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_ResetStatistics_allowed()
* Description : Execution allowed for ResetStatistics attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_ResetStatistics_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for ResetStatistics command.
/*----- PROTECTED REGION ID(AlarmHandler::ResetStatisticsStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::ResetStatisticsStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_StopNew_allowed()
* Description : Execution allowed for StopNew attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_StopNew_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for StopNew command.
/*----- PROTECTED REGION ID(AlarmHandler::StopNewStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::StopNewStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_GetAlarmInfo_allowed()
* Description : Execution allowed for GetAlarmInfo attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_GetAlarmInfo_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for GetAlarmInfo command.
/*----- PROTECTED REGION ID(AlarmHandler::GetAlarmInfoStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::GetAlarmInfoStateAllowed
return true;
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::is_ReLoadAll_allowed()
* Description : Execution allowed for ReLoadAll attribute
*/
//--------------------------------------------------------
bool AlarmHandler::is_ReLoadAll_allowed(TANGO_UNUSED(const CORBA::Any &any))
{
// Not any excluded states for ReLoadAll command.
/*----- PROTECTED REGION ID(AlarmHandler::ReLoadAllStateAllowed) ENABLED START -----*/
/*----- PROTECTED REGION END -----*/ // AlarmHandler::ReLoadAllStateAllowed
return true;
}
/*----- PROTECTED REGION ID(AlarmHandler::AlarmHandlerStateAllowed.AdditionalMethods) ENABLED START -----*/
// Additional Methods
/*----- PROTECTED REGION END -----*/ // AlarmHandler::AlarmHandlerStateAllowed.AdditionalMethods
} // End of namespace
cmake_minimum_required(VERSION 3.2)
# source files
set(SRC_FILES ${SRC_FILES}
${CMAKE_CURRENT_SOURCE_DIR}/AlarmHandler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/AlarmHandlerClass.cpp
${CMAKE_CURRENT_SOURCE_DIR}/AlarmHandlerDynAttrUtils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/AlarmHandlerStateMachine.cpp
${CMAKE_CURRENT_SOURCE_DIR}/alarm_table.cpp
${CMAKE_CURRENT_SOURCE_DIR}/alarm-thread.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ClassFactory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cmd_thread.cpp
${CMAKE_CURRENT_SOURCE_DIR}/event_table.cpp
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SubscribeThread.cpp
${CMAKE_CURRENT_SOURCE_DIR}/update-thread.cpp
PARENT_SCOPE)
/*----- PROTECTED REGION ID(AlarmHandler::ClassFactory.cpp) ENABLED START -----*/
//=============================================================================
//
// file : ClassFactory.cpp
//
// description : C++ source for the class_factory method of the DServer
// device class. This method is responsible for the creation of
// all class singleton for a device server. It is called
// at device server startup.
//
// project : Elettra alarm handler device server
//
// This file is part of Tango device class.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Tango. If not, see <http://www.gnu.org/licenses/>.
//
//
//
//=============================================================================
// This file is generated by POGO
// (Program Obviously used to Generate tango Object)
//=============================================================================
#include <tango/tango.h>
#include <AlarmHandlerClass.h>
// Add class header files if needed
/**
* Create AlarmHandler Class singleton and store it in DServer object.
*/
void Tango::DServer::class_factory()
{
// Add method class init if needed
add_class(AlarmHandler_ns::AlarmHandlerClass::init("AlarmHandler"));
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::ClassFactory.cpp
#include "AlarmHandler.h"
#include "event_table.h"
namespace AlarmHandler_ns
{
//=============================================================================
//=============================================================================
SubscribeThread::SubscribeThread(AlarmHandler *dev):Tango::LogAdapter(dev)
{
alarm_dev = dev;
period = 10; //TODO: configurable
shared = dev->events;
}
//=============================================================================
//=============================================================================
void SubscribeThread::updateProperty()
{
shared->put_signal_property();
}
//=============================================================================
//=============================================================================
void SubscribeThread::signal()
{
shared->signal();
}
//=============================================================================
//=============================================================================
void *SubscribeThread::run_undetached(void *ptr)
{
INFO_STREAM << "SubscribeThread id="<<omni_thread::self()->id()<<endl;
while(shared->get_if_stop()==false)
{
// Try to subscribe
usleep(500000); //TODO: try to delay a bit subscribe_events
if(shared->get_if_stop())
break;
DEBUG_STREAM << "SubscribeThread::"<<__func__<<": AWAKE"<<endl;
updateProperty();
alarm_dev->events->subscribe_events();
int nb_to_subscribe = shared->nb_sig_to_subscribe();
shared->check_signal_property(); //check if, while subscribing, new alarms to be saved in properties where added (update action)
// And wait a bit before next time or
// wait a long time if all signals subscribed
{
omni_mutex_lock sync(*shared);
//shared->lock();
int act=shared->action.load();
if (nb_to_subscribe==0 && act == NOTHING)
{
DEBUG_STREAM << "SubscribeThread::"<<__func__<<": going to wait nb_to_subscribe=0"<<endl;
//shared->condition.wait();
shared->wait();
//shared->wait(3*period*1000);
}
else if(shared->action == NOTHING)
{
DEBUG_STREAM << "SubscribeThread::"<<__func__<<": going to wait period="<<period<<" nb_to_subscribe="<<nb_to_subscribe<<endl;
//unsigned long s,n;
//omni_thread::get_time(&s,&n,period,0);
//shared->condition.timedwait(s,n);
shared->wait(period*1000);
}
//shared->unlock();
}
}
//shared->unsubscribe_events();
INFO_STREAM <<"SubscribeThread::"<< __func__<<": exiting..."<<endl;
return NULL;
}
//=============================================================================
//=============================================================================
} // namespace
#ifndef _SUBSCRIBE_THREAD_H
#define _SUBSCRIBE_THREAD_H
#include <tango/tango.h>
#include <stdint.h>
#include "event_table.h"
// constants definitions here.
//-----------------------------------------------
namespace AlarmHandler_ns
{
//class ArchiveCB;
class AlarmHandler;
class SubscribeThread;
//=========================================================
/**
* Create a thread retry to subscribe event.
*/
//=========================================================
class SubscribeThread: public omni_thread, public Tango::LogAdapter
{
private:
/**
* Shared data
*/
event_table *shared;
/**
* HdbDevice object
*/
AlarmHandler *alarm_dev;
public:
int period;
SubscribeThread(AlarmHandler *dev);
void updateProperty();
void signal();
/**
* Execute the thread loop.
* This thread is awaken when a command has been received
* and falled asleep when no command has been received from a long time.
*/
void *run_undetached(void *);
void start() {start_undetached();}
};
} // namespace_ns
#endif // _SUBSCRIBE_THREAD_H
/*
* alarm-thread.cpp
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#include "alarm-thread.h"
static const char __FILE__rev[] = __FILE__ " $Revision: 1.7 $";
/*
* alarm_thread::alarm_thread()
*/
alarm_thread::alarm_thread(AlarmHandler_ns::AlarmHandler *p) : p_Alarm(p)
{
//TANGO_LOG << __FILE__rev << endl;
}
/*
* alarm_thread::~alarm_thread()
*/
alarm_thread::~alarm_thread()
{
p_Alarm = NULL;
}
/*
* alarm_thread::run()
*/
void alarm_thread::run(void *)
{
size_t to_be_evaluated = 0;
//int period = 5; //seconds
int awaken = 0;
vector<string> alm_to_be_eval;
bool starting = true;
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
double last_eval = (now.tv_sec) + ((double)(now.tv_nsec))/1000000000;
while(starting)
{
starting = Tango::Util::instance()->is_svr_starting();
usleep(200000);
}
alm_to_be_eval = p_Alarm->alarms.to_be_evaluated_list();
to_be_evaluated = alm_to_be_eval.size();
while (true) {
/*
* pop_front() will wait() on condition variable
*/
try
{
if(to_be_evaluated > 0)
{
clock_gettime(CLOCK_MONOTONIC, &now);
double dnow = (now.tv_sec) + ((double)(now.tv_nsec))/1000000000;
if(dnow - last_eval > 10) //TODO: configurable
{
last_eval = dnow;
bool changed = true;
int num_changed = 0;
if(alm_to_be_eval.size() > 0)
{
for(vector<string>::iterator i = alm_to_be_eval.begin(); i != alm_to_be_eval.end(); i++)
{
changed = p_Alarm->do_alarm_eval(*i, "FORCED_EVAL", gettime());
if(changed)
num_changed++;
}
#if 0 //TODO
prepare_alarm_attr();
if(num_changed==0)
return;
if(ds_num == 0)
{
//attr.set_value_date_quality(ds,0/*gettime()*/,Tango::ATTR_WARNING, ds_num, 0, false);
struct timeval now;
gettimeofday(&now,NULL);
push_change_event("alarm",(char**)ds,now,Tango::ATTR_WARNING, ds_num, 0, false);
}
else
//attr.set_value(ds, ds_num, 0, false);
push_change_event("alarm",ds, ds_num, 0, false);
#endif
}
#if 1
alm_to_be_eval = p_Alarm->alarms.to_be_evaluated_list();
to_be_evaluated = alm_to_be_eval.size();
#else
to_be_evaluated = 0;
#endif
//usleep(200000); //TODO
}
}
bei_t e;
{
e = p_Alarm->evlist.pop_front();
//DEBUG_STREAM << "alarm_thread::run(): woken up!!!! " << e.name << endl;
if ((e.ev_name == ALARM_THREAD_EXIT) && \
(e.value[0] == ALARM_THREAD_EXIT_VALUE))
{
break;
}
else if ((e.ev_name == ALARM_THREAD_TO_BE_EVAL) && \
(e.value[0] == ALARM_THREAD_TO_BE_EVAL_VALUE))
{
alm_to_be_eval = p_Alarm->alarms.to_be_evaluated_list();
to_be_evaluated = alm_to_be_eval.size();
continue;
}
p_Alarm->do_alarm(e);
}
}
catch(omni_thread_fatal& ex)
{
ostringstream err;
err << "omni_thread_fatal exception running alarm thread, err=" << ex.error << ends;
//WARN_STREAM << "alarm_thread::run(): " << err.str() << endl;
printf("alarm_thread::run(): %s\n", err.str().c_str());
}
catch(Tango::DevFailed& ex)
{
ostringstream err;
err << "exception running alarm thread: '" << ex.errors[0].desc << "'" << ends;
//WARN_STREAM << "alarm_thread::run(): " << err.str() << endl;
printf("alarm_thread::run(): %s\n", err.str().c_str());
//Tango::Except::print_exception(ex);
}
catch(...)
{
//WARN_STREAM << "alarm_thread::run(): catched unknown exception!!" << endl;
printf("alarm_thread::run(): catched unknown exception!!\n");
}
}
//TANGO_LOG << "alarm_thread::run(): returning" << endl;
} /* alarm_thread::run() */
/*
* alarm-thread.h
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#ifndef ALARM_THREAD_H
#define ALARM_THREAD_H
#include <omnithread.h>
#include <tango/tango.h>
#include <AlarmHandler.h>
#define ALARM_THREAD_EXIT "alarm_thread_exit"
#define ALARM_THREAD_EXIT_VALUE -100
#define ALARM_THREAD_TO_BE_EVAL "to_be_evaluated"
#define ALARM_THREAD_TO_BE_EVAL_VALUE -200
class alarm_thread : public omni_thread {
public:
alarm_thread(AlarmHandler_ns::AlarmHandler *p);
~alarm_thread();
//int period;
protected:
void run(void *);
private:
AlarmHandler_ns::AlarmHandler *p_Alarm;
};
#endif /* ALARM_THREAD_H */
/* EOF */
/*
* alarm_grammar.h
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#ifndef ALARM_GRAMMAR_H_
#define ALARM_GRAMMAR_H_
//--------------------------NOTE!!---------------------------------
//----if a grammar is intended to be used in multithreaded code----
//----it is required to "#define BOOST_SPIRIT_THREADSAFE" and------
//----to link against Boost.Threads--------------------------------
//-----------------------------------------------------------------
#if BOOST_VERSION < 103600
#ifndef BOOST_SPIRIT_THREADSAFE
#define BOOST_SPIRIT_THREADSAFE
#endif
#ifndef PHOENIX_THREADSAFE
#define PHOENIX_THREADSAFE
#endif
#endif
#if BOOST_VERSION < 103600
#include <boost/spirit/core.hpp>
#include <boost/spirit/actor/assign_actor.hpp> //for assign_a
#include <boost/spirit/actor/push_back_actor.hpp> //for push_back_a
#include <boost/spirit/actor/insert_at_actor.hpp> //for insert_at_a
#include <boost/spirit/actor/clear_actor.hpp> //for clear_a
#include <boost/spirit/symbols/symbols.hpp> //for symbol table
#include <boost/spirit/utility/confix.hpp> //for confix
#include <boost/spirit/phoenix/primitives.hpp> //needed for "var" in group rule
#include <boost/spirit/phoenix/operators.hpp> //needed for "var" in group rule
#include <boost/spirit/phoenix/functions.hpp>
#else
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_assign_actor.hpp> //for assign_a
#include <boost/spirit/include/classic_push_back_actor.hpp> //for push_back_a
#include <boost/spirit/include/classic_insert_at_actor.hpp> //for insert_at_a
#include <boost/spirit/include/classic_clear_actor.hpp> //for clear_a
#include <boost/spirit/include/classic_symbols.hpp> //for symbol table
#include <boost/spirit/include/classic_confix.hpp> //for confix
#include <boost/spirit/include/phoenix1_primitives.hpp> //needed for "var" in group rule
#include <boost/spirit/include/phoenix1_operators.hpp> //needed for "var" in group rule
#include <boost/spirit/include/phoenix1_functions.hpp>
#endif
//#include <boost/spirit/attribute.hpp> //for closure
//#include <boost/spirit/tree/ast.hpp> //for ast parse trees (in tree_formula)
#include <iostream>
#include <string>
#include <map>
#include "event_table.h"
#include "formula_grammar.h"
#define NAME_KEY "tag"
#define FORMULA_KEY "formula"
#define ONDELAY_KEY "on_delay"
#define OFFDELAY_KEY "off_delay"
#define LEVEL_KEY "priority"
#define SILENT_TIME_KEY "shlvd_time"
#define GROUP_KEY "group"
#define MESSAGE_KEY "message"
#define URL_KEY "url"
#define ON_COMMAND_KEY "on_command"
#define OFF_COMMAND_KEY "off_command"
#define RECEIVERS_KEY "receivers"
#define ENABLED_KEY "enabled"
#define SILENT_TIME_REMAINING_KEY "shlvd_end"
#define SHELVED_KEY "shelved"
#define ACKNOWLEDGED_KEY "ack"
#define ATTR_VALUES_KEY "values"
#define VALUE_KEY "state"
#define ON_COUNTER_KEY "on_counter"
#define OFF_COUNTER_KEY "off_counter"
#define COUNTER_KEY "counter"
#define QUALITY_KEY "quality"
#define EXCEPTION_KEY "exception"
#define AUDIBLE_KEY "audible"
#define FREQ_COUNTER_KEY "freq_counter"
#define ALARM_TIME_KEY "time"
#define EVENT_KEY "event"
#define EVENT_TIME_KEY ALARM_TIME_KEY
#define KEY(S_VAL) S_VAL "="
#define SEP ";"
////////////////////////////////////////////////////////////////////////////
using namespace std;
#if BOOST_VERSION < 103600
using namespace boost::spirit;
#else
using namespace boost::spirit::classic;
#endif
using namespace phoenix; //needed for "var" in group rule
////////////////////////////////////////////////////////////////////////////
//
// Semantic actions for alarm gramamr
//
////////////////////////////////////////////////////////////////////////////
#if 0
struct push_back_impl
{
template <typename Container, typename Item>
struct result
{
typedef void type;
};
template <typename Container, typename Item>
void operator()(Container& c, Item const& item) const
{
c.push_back(item);
}
};
function<push_back_impl> const push_back = push_back_impl();
struct insert_map_impl
{
template <typename Container, typename Item1, typename Item2>
struct result
{
typedef void type;
};
template <typename Container, typename Item1, typename Item2>
void operator()(Container& c, Item1 const& item1, Item2 const& item2) const
{
c.insert(make_pair(item1, item2));
}
};
function<insert_map_impl> const insert_map = insert_map_impl();
#endif
////////////////////////////////////////////////////////////////////////////
//
// alarm grammar
//
////////////////////////////////////////////////////////////////////////////
struct alarm_parse : public grammar<alarm_parse>
{
alarm_t &m_alarm;
symbols<unsigned int> sym_grp;
alarm_parse(alarm_t &a) \
: m_alarm(a)
{
//init symbol table with group defined in alarm_t::grp_str
map<string,unsigned int>::iterator i = m_alarm.grp_str.begin();
while(i != m_alarm.grp_str.end())
{
sym_grp.add(i->first.c_str(), i->second);
i++;
}
}
template <typename ScannerT>
struct definition
{
definition(alarm_parse const& self)
{
//-------BOOST.SPIRIT GLOSSARY-------
// >> : sequence
// | : union (i.e. alternative)
// - : difference
// * : kleene star (matches 0 or more times)
// + : positive (matches 1 or more times)
// ! : optional (matches 0 or 1 time)
// str_p : matches string
// ch_p : matches char
// hex_p :
// alnum_p : matches alpha-numeric characters
// anychar_p : matches any single character (including the null terminator: '\0')
// lexemd_d : turns off white space skipping
// confix : recognize a sequence of: an opening, an expression and a closing
// assign_a :
// push_back_a :
//std::pair<string, vector<string> > temp;
expression
= no_node_d[str_p(KEY(NAME_KEY))] >>
no_node_d
[
name_alm
[
assign_a(self.m_alarm.name) //save name in alarm_t
]
] //discard_node_d
>>
no_node_d[separator]
>>
no_node_d[str_p(KEY(FORMULA_KEY))] >>
root_node_d
[
formula
[
assign_a(self.m_alarm.formula) //save formula in alarm_t
]
] //root_node_d
>> *(no_node_d[option])
;
option
= no_node_d[separator] >> no_node_d[on_delay] |
no_node_d[separator] >> no_node_d[off_delay] |
no_node_d[separator] >> no_node_d[level] |
no_node_d[separator] >> no_node_d[silent_time] |
no_node_d[separator] >> no_node_d[group] |
no_node_d[separator] >> no_node_d[msg] |
no_node_d[separator] >> no_node_d[url] |
no_node_d[separator] >> no_node_d[on_command] |
no_node_d[separator] >> no_node_d[off_command] |
no_node_d[separator] >> no_node_d[receivers] |
no_node_d[separator] >> no_node_d[enabled]
;
//------------------------------ALARM NAME--------------------------------------
symbol
= alnum_p | '.' | '_' | '-' | '+' //any alpha numeric char plus '.', '_', '-', '+'
;
symbol_attr_name
= alnum_p | '.' | '_' | '-' //any alpha numeric char plus '_'
;
name
= (+symbol) >> '/' >> (+symbol)
>> '/' >> (+symbol) >> '/' >> (+symbol_attr_name)
;
name_alm
= (+symbol_attr_name)
;
//------------------------------LEVEL--------------------------------------
level
= discard_node_d[str_p(KEY(LEVEL_KEY))] >>
//lexeme_d[(+alnum_p)] //match only possible levels?? (fault, log, ...)
//(+(alnum_p-'\t'))
(str_p("highest") | str_p("high") | str_p("medium") | str_p("lowest") | str_p("low") | str_p("fault") | str_p("warning") | str_p("log"))//TODO
[
assign_a(self.m_alarm.lev) //save level in alarm_t
]
;
//------------------------------GROUP--------------------------------------
group
= discard_node_d[str_p(KEY(GROUP_KEY))] >>
self.sym_grp //match only group defined in sym_grp symbol table
[
var(self.m_alarm.grp) |= arg1 //using phoenix::var
]
>> *(
ch_p('|')
>> self.sym_grp //match only group defined in sym_grp symbol table
[
var(self.m_alarm.grp) |= arg1 //using phoenix::var
]
)
;
//------------------------------MESSAGE--------------------------------------
escChar = (ch_p('\\') | ch_p(';')) >> ch_p(';'); //escaped semicolon: "\;" or ";;"
msg
= discard_node_d[str_p(KEY(MESSAGE_KEY))]
//>> ch_p('"')
>> (+(escChar | (anychar_p - ';'))) //one ore more char except ';'
[
assign_a(self.m_alarm.msg)
]
//>> '"'
;
//------------------------------URL--------------------------------------
url
= discard_node_d[str_p(KEY(URL_KEY))]
//>> ch_p('"')
>> (*(escChar | (anychar_p - ';'))) //zero ore more char except ';'
[
assign_a(self.m_alarm.url)
]
//>> '"'
;
//---------------------------ON DELAY----------------------------------------
on_delay
= discard_node_d[str_p(KEY(ONDELAY_KEY))] >>
(uint_p
[
assign_a(self.m_alarm.on_delay)
]
| epsilon_p)
;
//---------------------------OFF DELAY---------------------------------------
off_delay
= discard_node_d[str_p(KEY(OFFDELAY_KEY))] >>
(uint_p
[
assign_a(self.m_alarm.off_delay)
]
| epsilon_p)
;
//-----------------------------SILENT TIME------------------------------------
silent_time
= discard_node_d[str_p(KEY(SILENT_TIME_KEY))] >>
(int_p
[
assign_a(self.m_alarm.silent_time)
]
| epsilon_p)
;
//-----------------------------ON COMMAND------------------------------------
on_command
= discard_node_d[str_p(KEY(ON_COMMAND_KEY))] >>
(discard_node_d
[
name
[
assign_a(self.m_alarm.cmd_name_a) //save cmd_name_a in alarm_t
]
] //discard_node_d
| epsilon_p)
;
//-----------------------------OFF COMMAND------------------------------------
off_command
= discard_node_d[str_p(KEY(OFF_COMMAND_KEY))] >>
(discard_node_d
[
name
[
assign_a(self.m_alarm.cmd_name_n) //save cmd_name_a in alarm_t
]
] //discard_node_d
| epsilon_p)
;
//------------------------------RECEIVERS------------------------------------
receivers
= discard_node_d[str_p(KEY(RECEIVERS_KEY))]
//>> ch_p('"')
>> (*(escChar | (anychar_p - ';'))) //zero ore more char except ';'
[
assign_a(self.m_alarm.receivers)
]
//>> '"'
;
//------------------------------ENABLED----------------------------------------
enabled
= discard_node_d[str_p(KEY(ENABLED_KEY))] >>
//lexeme_d[(+alnum_p)] //match only possible levels?? (fault, log, ...)
//(+(alnum_p-'\t'))
//(ch_p('0') | ch_p('1'))
bin_p
[
assign_a(self.m_alarm.enabled) //save enabled in alarm_t
]
;
//------------------------------SEPARATOR--------------------------------------
separator = ch_p(SEP);
}
typedef rule<ScannerT> rule_t;
rule_t expression, event, option;
rule<typename lexeme_scanner<ScannerT>::type> symbol; //needed to use lexeme_d in rule name
rule<typename lexeme_scanner<ScannerT>::type> symbol_attr_name; //needed to use lexeme_d in rule name
rule_t name, name_alm, val, token, oper, msg, url, group, level, on_delay, off_delay, silent_time, on_command, off_command, receivers, enabled, separator,escChar;
formula_grammar formula;
rule_t const&
start() const { return expression; }
};
};
#endif /*ALARM_GRAMMAR_H_*/
/*
* alarm_table.cpp
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#include <sys/time.h>
#include <tango/tango.h>
#include "alarm_table.h"
#include "alarm_grammar.h"
#include "cmd_thread.h"
#include <regex>
static const char __FILE__rev[] = __FILE__ " $Revision: 1.5 $";
/*
* alarm_t class methods
*/
bool alarm_t::operator==(const alarm_t &that)
{
// return((stat == that.stat) && (ack == that.ack));
//verify if stat not equal but only contained because added *n in internal alarm
return((stat.find(that.stat) != std::string::npos) && (ack == that.ack));
}
bool alarm_t::operator==(const string &n)
{
return(name == n);
}
void alarm_t::str2alm(const string &s)
{
istringstream is(s);
ostringstream temp_msg;
string temp_grp;
unsigned int on_cnt;
is >> ts.tv_sec >> ts.tv_usec >> name >> stat >> ack >> on_cnt >> lev >> silent_time >> temp_grp >> msg; //stop at first white space in msg
#ifdef _CNT_ATOMIC
on_counter.store(on_cnt);
#else
on_counter = on_cnt;
#endif
temp_msg << is.rdbuf(); //read all remaining characters as msg
msg += temp_msg.str();
str2grp(temp_grp);
}
string alarm_t::alm2str(void)
{
ostringstream os;
os.clear();
#ifdef _CNT_ATOMIC
os << ts.tv_sec << "\t" << ts.tv_usec << "\t" << name << "\t" \
<< stat << "\t" << ack << "\t" << on_counter.load() << "\t" << lev << "\t" << silent_time << "\t" << grp2str() << "\t" << msg << ends;
#else
os << ts.tv_sec << "\t" << ts.tv_usec << "\t" << name << "\t" \
<< stat << "\t" << ack << "\t" << on_counter << "\t" << lev << "\t" << silent_time << "\t" << grp2str() << "\t" << msg << ends;
#endif
return(os.str());
}
map<string, unsigned int> alarm_t::grp_str; //needed here because static
void alarm_t::init_static_map(vector<string> &group_names)
{
//LOG_STREAM << "alarm_table::init_static_map(vector<string> &group_names): Entering..." << endl;
int j=0;
vector<string>::iterator i;
if(grp_str.size() > 0)
return;
if(group_names.empty())
{
//LOG_STREAM << "alarm_table::init_static_map(): inserting: default group " << GR_NONE_NAME << " = " << showbase << hex << GR_NONE << endl;
grp_str.insert(make_pair(string(GR_NONE_NAME), GR_NONE));
}
for (i = group_names.begin(); i != group_names.end(); i++)
{
if((*i) == string(GR_ALL_NAME))
continue;
if(i == group_names.begin())
{
//LOG_STREAM << "alarm_table::init_static_map(): inserting: group " << *i << " = " << showbase << hex << GR_NONE << endl;
grp_str.insert(make_pair(*i, GR_NONE));
}
else
{
//LOG_STREAM << "alarm_table::init_static_map(): inserting: group " << *i << " = " << showbase << hex << int(0x1 << j) << endl;
grp_str.insert(make_pair(*i, 0x1 << j));
j++;
}
}
//LOG_STREAM << "alarm_table::init_static_map(): inserting: group " << GR_ALL_NAME << " = " << showbase << hex << GR_ALL << endl;
grp_str.insert(make_pair(string(GR_ALL_NAME), GR_ALL));
}
string alarm_t::grp2str(void)
{
map<string, unsigned int>::iterator i = grp_str.begin();
bool first=true;
string argout;
if(grp == GR_ALL)
argout = string(GR_ALL_NAME);
else if(grp == GR_NONE)
{
if(i != grp_str.end())
argout = i->first;
else
argout = string(GR_NONE_NAME);
}
else
{
for (; i != grp_str.end(); i++)
{
if(i->first == string(GR_ALL_NAME))
continue;
if(grp & i->second)
{
if(first)
{
argout = i->first;
first = false;
}
else
argout += string("|") + i->first;
}
}
}
return argout;
}
void alarm_t::add_grp_from_str(string &s)
{
map<string, unsigned int>::iterator i = grp_str.find(s);
if(i != grp_str.end())
grp |= (*i).second;
}
void alarm_t::str2grp(string &s)
{
for(map<string, unsigned int>::iterator i=grp_str.begin(); i != grp_str.end(); i++)
if(s.find(i->first) != string::npos)
grp |= i->second;
}
void alarm_t::insert(const string& s)
{
s_event.insert(s);
}
void alarm_t::clear()
{
name.clear();
formula.clear();
msg.clear();
lev.clear();
grp=0;
s_event.clear();
to_be_evaluated = false;
stat.clear();
ack.clear();
done = false;
// ts = 0;
}
void alarm_t::confstr(string &s)
{
ostringstream conf;
conf <<
KEY(NAME_KEY)<<name << SEP <<
KEY(FORMULA_KEY)<<formula << SEP <<
KEY(ONDELAY_KEY)<<on_delay << SEP <<
KEY(OFFDELAY_KEY)<<off_delay << SEP <<
KEY(LEVEL_KEY)<< lev << SEP <<
KEY(SILENT_TIME_KEY)<<silent_time << SEP <<
KEY(GROUP_KEY)<< grp2str() << SEP <<
KEY(MESSAGE_KEY)<< msg << SEP <<
KEY(URL_KEY)<< url << SEP <<
KEY(ON_COMMAND_KEY)<< cmd_name_a << SEP <<
KEY(OFF_COMMAND_KEY)<< cmd_name_n << SEP <<
KEY(RECEIVERS_KEY)<< receivers << SEP <<
KEY(ENABLED_KEY)<< (enabled ? "1" : "0");
s = conf.str();
}
/*
* alarm_table class methods
*/
/* typedef std::string::iterator iterator_t;
typedef boost::spirit::node_val_data_factory<unsigned int> factory_t; /////TEMP!!!!!!!!!!!!!!!!!!!
typedef boost::spirit::tree_match<iterator_t, factory_t> parse_tree_match_t;
typedef boost::spirit::tree_parse_info<iterator_t, factory_t> tree_parse_info_t;
*/
/*
void alarm_table::init(vector<string>& avs, vector<string> &evn, map< string,vector<string> > &alarm_event)
{
//LOG_STREAM << "alarm_table::init(vector<string>& avs,map< string,vector<string> > &alarm_event): Entering..." << endl;
alarm_t tmp_alm;
LOG_STREAM << gettime().tv_sec << " " << __FILE__rev << endl;
LOG_STREAM << gettime().tv_sec << " alarm_table::init(): Creating Spirit Parser..." << endl;
alarm_parse al(tmp_alm); // Construct Spirit grammar
if (avs.empty() == false) {
for (vector<string>::iterator i = avs.begin(); \
i != avs.end(); i++) {
tmp_alm.name.clear();
tmp_alm.formula.clear();
tmp_alm.msg.clear();
tmp_alm.lev.clear();
tmp_alm.grp=0;
tree_parse_info_t info = ast_parse<factory_t>(i->begin(), i->end(), al, space_p);
if (info.full)
{
LOG_STREAM << gettime().tv_sec << " Parsing succeeded: " << tmp_alm.name << endl;
for (vector<string>::iterator i = evn.begin(); i != evn.end(); i++)
LOG_STREAM << gettime().tv_sec << " READ Event! ->" << *i << endl;
}
else
{
LOG_STREAM << gettime().tv_sec << " Parsing failed, stopped at: " << string(info.stop, i->end()) << ends; //TODO
}
if ((tmp_alm.name.empty() == false) && \
(tmp_alm.formula.empty() == false) && \
((tmp_alm.lev==LEV_LOG)||(tmp_alm.lev==LEV_WARNING)|| \
(tmp_alm.lev==LEV_FAULT)||(tmp_alm.lev.empty() == true)))
{
tmp_alm.stat = S_NORMAL;
tmp_alm.ack = ACK;
tmp_alm.done = false;
if(tmp_alm.grp == 0)
tmp_alm.grp = GR_DEFAULT;
if(tmp_alm.lev.empty() == true)
tmp_alm.lev = LEV_DEFAULT;
push_back(tmp_alm);
} else {
cerr << gettime().tv_sec << " alarm_table::init(): syntax error in '" << *i \
<< "', skipping!" << endl;
}
}
}
}*/
void alarm_table::push_back(alarm_t &a)
{
vlock->writerIn();
//v_alarm.push_back(a);
v_alarm.insert(make_pair(a.name,a));
vlock->writerOut();
}
void alarm_table::show(vector<string> &al_table_string)
{
vlock->readerIn();
ostringstream log_msg;
string log_str;
if (v_alarm.empty() == false) {
log_msg << "### alarms table: ###" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
alarm_container_t::iterator i = v_alarm.begin();
unsigned int j = 0;
while (i != v_alarm.end()) {
log_msg << j << " - name: '" << i->second.name << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " formula: '" << i->second.formula << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " stat: '" << i->second.stat << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " ack: '" << i->second.ack << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " msg: '" << i->second.msg << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " grp: '" << showbase << hex << i->second.grp << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " lev: '" << i->second.lev << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
i++;
j++;
}
}
vlock->readerOut();
}
unsigned int alarm_table::size(void)
{
return(v_alarm.size());
}
alarm_container_t& alarm_table::get(void)
{
return(v_alarm);
}
void alarm_table::stored(vector<alarm_t>& a)
{
vlock->readerIn();
if (a.empty() == false) {
for (vector<alarm_t>::iterator i = a.begin(); i != a.end(); i++)
{
alarm_container_t::iterator found = v_alarm.find(i->name);
if (found != v_alarm.end()) {
found->second.ts = i->ts;
found->second.stat = i->stat;
found->second.ack = i->ack;
found->second.done = i->done;
found->second.is_new = i->is_new;
} else {
/*
* shouldn't happen!!!
*/
LOG_STREAM << "alarm_table::stored(): " << i->name \
<< " NOT found in alarm table" << endl;
}
} /* for */
} /* if */
vlock->readerOut();
}
bool alarm_table::update(const string& alm_name, Tango::TimeVal ts, formula_res_t res, string &attr_values, string grp, string msg, string formula)
{
bool ret_changed=false;
Tango::TimeVal now = gettime();
TangoSys_MemStream out_stream;
vlock->readerIn();
alarm_container_t::iterator found = v_alarm.find(alm_name);
if (found != v_alarm.end())
{
if(found->second.silenced > 0)
{
Tango::TimeVal now = gettime();
double dnow = now.tv_sec + ((double)now.tv_usec) / 1000000;
double dsilent = found->second.ts_time_silenced.tv_sec + ((double)found->second.ts_time_silenced.tv_usec) / 1000000;
double dminutes = (dnow - dsilent)/60;
if(dminutes < found->second.silent_time)
{
found->second.silenced = found->second.silent_time - floor(dminutes);
}
else
{
found->second.silenced = 0;
found->second.shelved = false;
found->second.is_new = 0;
found->second.ack = ACK;
}
}
bool status_err_delay;
if(err_delay > 0)
status_err_delay = (!res.valid) && (found->second.err_counter >= 1) && ((now.tv_sec - err_delay) > found->second.ts_err_delay.tv_sec); //error is present and err delay has passed
else
status_err_delay = (!res.valid);
found->second.ex_reason = res.ex_reason;
found->second.ex_desc = res.ex_desc;
found->second.ex_origin = res.ex_origin;
if(!status_err_delay && !res.valid) //formula result not valid, waiting for err_delay
{
found->second.attr_values_delay = attr_values; //save last attr_values to be used in timer_update if this alarm pass over on or off delay
found->second.err_counter++;
if(found->second.err_counter == 1)
found->second.ts_err_delay = gettime(); //first occurrance of this error, now begin to wait for err delay
vlock->readerOut();
return ret_changed;
}
found->second.quality = res.quality;
bool status_on_delay;
if(found->second.on_delay > 0) //if enabled on delay
status_on_delay = ((bool)(!res.value.empty() && res.value[0] != 0)) && (found->second.on_counter >= 1) && ((ts.tv_sec - found->second.on_delay) > found->second.ts_on_delay.tv_sec); //formula gives true and on delay has passed
else
status_on_delay = (bool)(!res.value.empty() && res.value[0] != 0);
bool status_off_delay;
if(found->second.off_delay > 0) //if enabled off delay
status_off_delay = (!(bool)(!res.value.empty() && res.value[0] != 0)) && (found->second.off_counter >= 1) && ((ts.tv_sec - found->second.off_delay) > found->second.ts_off_delay.tv_sec); //formula gives false and off delay has passed
else
status_off_delay = !(bool)(!res.value.empty() && res.value[0] != 0);
//if status changed:
// - from S_NORMAL to S_ALARM considering also on delay
//or
// - from S_ALARM to S_NORMAL considering also off delay
if((status_on_delay && (found->second.stat == S_NORMAL)) || (status_off_delay && (found->second.stat == S_ALARM)))
{
ret_changed=true;
if((bool)(!res.value.empty() && res.value[0] != 0))
found->second.ack = NOT_ACK; //if changing from NORMAL to ALARM -> NACK
//a.grp = found->second.grp2str();
//a.msg = (int)(res.value[0]) ? found->second.msg : "";
found->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts only if status changed
if((bool)(!res.value.empty() && res.value[0] != 0))
{
found->second.is_new = 1; //here set this alarm as new, read attribute set it to 0 //12-06-08: StopNew command set it to 0
if(found->second.dp_a && ((ts.tv_sec - startup_complete.tv_sec) > 10)) //action from S_NORMAL to S_ALARM
{
/*try {
long call_id;
ostringstream tmp;
tmp << alm_name << ";" << attr_values;
Tango::DevString str = CORBA::string_dup(tmp.str().c_str());
Tango::DeviceData Din;
Din << str;
CORBA::string_free(str);
//found->second.dp_a->ping();
cmdloop->mutex_dp->lock();
//call_id = found->second.dp_a->command_inout_asynch(found->second.cmd_action_a, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer
call_id = found->second.dp_a->command_inout_asynch(found->second.cmd_action_a, Din); //true -> "fire and forget" mode: client do not care at all about the server answer
cmdloop->mutex_dp->unlock();
LOG_STREAM << "alarm_table::update() executed action: " << found->second.cmd_name_a << " !!!" << endl;
cmd_t arg;
arg.cmd_id = call_id;
arg.dp_add = (long)found->second.dp_a;
arg.arg_s = found->second.cmd_name_a;
cmdloop->list.push_back(arg);
} catch(Tango::DevFailed e)
{
string err(e.errors[0].desc);
if(err.find("is not yet arrived") == string::npos) //TODO: change this!!
out_stream << "Failed to execute action " << found->second.cmd_name_a << ", err=" << e.errors[0].desc << ends;
//LOG_STREAM << "alarm_table::update() ERROR: " << out_stream.str() << endl;
}*/
ostringstream tmp;
string tmp_attr_val = attr_values;
replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ',');
string tmp_msg = msg;
replace(tmp_msg.begin(), tmp_msg.end(), ';' , ',');
tm time_tm;
time_t time_sec= found->second.ts.tv_sec;
//gmtime_r(&time_sec,&time_tm); //-> UTC
localtime_r(&time_sec,&time_tm);
char time_buf[64];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &time_tm);
tmp << "name=" << alm_name << ";groups=" << grp << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<formula<<";time="<<time_buf << "." << found->second.ts.tv_usec<<";url="<<found->second.url;
cmd_t arg;
arg.cmd_id = CMD_COMMAND;
arg.dp_add = (long)found->second.dp_a;
arg.arg_s1 = tmp.str();
arg.arg_s2 = found->second.cmd_action_a;
arg.arg_s3 = found->second.cmd_name_a;
arg.arg_b = found->second.send_arg_a;
cmdloop->list.push_back(arg);
}
}
else
{
if(found->second.dp_n && ((ts.tv_sec - startup_complete.tv_sec) > 10)) //action from S_ALARM to S_NORMAL
{
/*try {
long call_id;
ostringstream tmp;
tmp << alm_name << ";" << attr_values;
Tango::DevString str = CORBA::string_dup(tmp.str().c_str());
Tango::DeviceData Din;
Din << str;
CORBA::string_free(str);
//found->second.dp_n->ping();
cmdloop->mutex_dp->lock();
//call_id = found->second.dp_n->command_inout_asynch(found->second.cmd_action_n, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer
call_id = found->second.dp_n->command_inout_asynch(found->second.cmd_action_n, Din); //true -> "fire and forget" mode: client do not care at all about the server answer
cmdloop->mutex_dp->unlock();
LOG_STREAM << "alarm_table::update() executed action: " << found->second.cmd_name_n << " !!!" << endl;
cmd_t arg;
arg.cmd_id = call_id;
arg.dp_add = (long)found->second.dp_n;
arg.arg_s = found->second.cmd_name_n;
cmdloop->list.push_back(arg);
} catch(Tango::DevFailed e)
{
string err(e.errors[0].desc);
if(err.find("is not yet arrived") == string::npos) //TODO: change this!!
out_stream << "Failed to execute action " << found->second.cmd_name_n << ", err=" << e.errors[0].desc << ends;
//LOG_STREAM << "alarm_table::update() ERROR: " << out_stream.str() << endl;
}*/
ostringstream tmp;
string tmp_attr_val = attr_values;
replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ',');
string tmp_msg = msg;
replace(tmp_msg.begin(), tmp_msg.end(), ';' , ',');
tm time_tm;
time_t time_sec= found->second.ts.tv_sec;
//gmtime_r(&time_sec,&time_tm); //-> UTC
localtime_r(&time_sec,&time_tm);
char time_buf[64];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &time_tm);
tmp << "name=" << alm_name << ";groups=" << grp << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<formula<<";time="<<time_buf << "." << found->second.ts.tv_usec;
cmd_t arg;
arg.cmd_id = CMD_COMMAND;
arg.dp_add = (long)found->second.dp_n;
arg.arg_s1 = tmp.str();
arg.arg_s2 = found->second.cmd_action_n;
arg.arg_s3 = found->second.cmd_name_n;
arg.arg_b = found->second.send_arg_n;
cmdloop->list.push_back(arg);
}
}
}
if (status_on_delay) {
found->second.stat = S_ALARM;
//found->second.ack = NOT_ACK;
}
else if (status_off_delay) {
found->second.stat = S_NORMAL;
}
//if error changed:
// - from false to true considering also err delay
//or
// - from true to false
if((status_err_delay && !found->second.error) || (!status_err_delay))
{
ret_changed=true;
}
if(status_err_delay)
{
if(!found->second.error)
{
found->second.is_new = 1;
found->second.ack = NOT_ACK;
}
found->second.error = true;
}
if((bool)(!res.value.empty() && res.value[0] != 0)) {
found->second.on_counter++;
found->second.off_counter = 0;
} else {
found->second.on_counter = 0;
found->second.off_counter++;
}
if(!res.valid)
{
found->second.err_counter++;
}
else
{
found->second.err_counter = 0;
found->second.error = false;
}
found->second.attr_values_delay = attr_values; //save last attr_values to be used in timer_update if this alarm pass over on or off delay
if(found->second.on_counter == 1)
found->second.ts_on_delay = gettime(); //first occurrance of this alarm, now begin to wait for on delay
if(found->second.off_counter == 1)
found->second.ts_off_delay = gettime(); //first occurrance of back to normal, now begin to wait for off delay
if(found->second.err_counter == 1)
found->second.ts_err_delay = gettime(); //first occurrance of this error, now begin to wait for err delay
//found->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts everytime
} else {
/*
* shouldn't happen!!!!
*/
out_stream << "couldn't find alarm '" << alm_name << "' in 'alarms' table" << ends;
LOG_STREAM << gettime().tv_sec << " alarm_table::update(): " << out_stream.str() << endl;
}
vlock->readerOut();
if(out_stream.str().length() > 0)
throw out_stream.str();
return ret_changed;
}
bool alarm_table::timer_update()
{
bool ret_changed=false;
Tango::TimeVal ts = gettime();
TangoSys_MemStream out_stream;
vlock->readerIn();
for(alarm_container_t::iterator i = v_alarm.begin(); i != v_alarm.end(); i++)
{
bool status_on_delay=false;
bool status_off_delay=false;
bool status_err_delay=false;
if(err_delay > 0) //if enabled err delay
status_err_delay = (i->second.err_counter >= 1) && ((ts.tv_sec - err_delay) > i->second.ts_err_delay.tv_sec); //waiting for err delay has passed
if(i->second.on_delay == 0 && i->second.off_delay == 0 && err_delay == 0 && !i->second.shelved && i->second.silenced <=0)
continue; //if not enabled on or off delay or not shelved, nothing to do in timer
if(i->second.on_delay > 0) //if enabled on delay
status_on_delay = (i->second.on_counter >= 1) && ((ts.tv_sec - i->second.on_delay) > i->second.ts_on_delay.tv_sec); //waiting for on delay has passed
if(i->second.off_delay > 0) //if enabled off delay
status_off_delay = (i->second.off_counter >= 1) && ((ts.tv_sec - i->second.off_delay) > i->second.ts_off_delay.tv_sec); //waiting for off delay has passed
//look here also if shelved time ended
bool old_shelved = i->second.shelved;
int old_silenced = i->second.silenced;
if(i->second.silenced > 0)
{
Tango::TimeVal now = gettime();
double dnow = now.tv_sec + ((double)now.tv_usec) / 1000000;
double dsilent = i->second.ts_time_silenced.tv_sec + ((double)i->second.ts_time_silenced.tv_usec) / 1000000;
double dminutes = (dnow - dsilent)/60;
if(dminutes < i->second.silent_time)
{
i->second.silenced = i->second.silent_time - floor(dminutes);
}
else
{
i->second.silenced = 0;
i->second.shelved = false;
i->second.is_new = 0;
i->second.ack = ACK;
}
}
//if just ended silence time, set ret_changed to true so to push events
//TODO: not interested in executing commands?
if(old_silenced>0 && i->second.silenced == 0)
{
ret_changed = true;
}
//if status changed:
// - from S_NORMAL to S_ALARM considering also on delay
//or
// - from S_ALARM to S_NORMAL considering also off delay
//or
// - from shelved to not shelved
if((status_on_delay && (i->second.stat == S_NORMAL)) || (status_off_delay && (i->second.stat == S_ALARM)) || (old_shelved && !i->second.shelved) || (status_err_delay && !i->second.error))
{
if(old_shelved && !i->second.shelved) //TODO: ok to execute on command and off command after shelving ends?
{
status_on_delay = i->second.stat == S_ALARM;
status_off_delay = i->second.stat == S_NORMAL;
}
ret_changed = true;
if(status_err_delay)
{
if(!i->second.error)
{
i->second.is_new = 1;
i->second.ack = NOT_ACK;
}
i->second.error = true;
}
if(status_on_delay)
i->second.ack = NOT_ACK; //if changing from NORMAL to ALARM but not ended shelved time -> NACK
i->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts only if status changed
if(status_on_delay)
{
i->second.is_new = 1; //here set this alarm as new, read attribute set it to 0 //12-06-08: StopNew command set it to 0
if(i->second.dp_a && ((ts.tv_sec - startup_complete.tv_sec) > 10))
{
/*try {
long call_id;
ostringstream tmp;
tmp << i->second.name << ";" << i->second.attr_values_on_delay;
Tango::DevString str = CORBA::string_dup(tmp.str().c_str());
Tango::DeviceData Din;
Din << str;
CORBA::string_free(str);
//i->second.dp_a->ping();
cmdloop->mutex_dp->lock();
//call_id = i->second.dp_a->command_inout_asynch(i->second.cmd_action_a, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer
call_id = i->second.dp_a->command_inout_asynch(i->second.cmd_action_a, Din);
cmdloop->mutex_dp->unlock();
LOG_STREAM << gettime().tv_sec << " alarm_table::timer_update() executed action: " << i->second.cmd_name_a << " !!!" << endl;
cmd_t arg;
arg.cmd_id = call_id;
arg.dp_add = (long)i->second.dp_a;
arg.arg_s = i->second.cmd_name_a;
cmdloop->list.push_back(arg);
} catch(Tango::DevFailed e)
{
string err(e.errors[0].desc);
if(err.find("is not yet arrived") == string::npos) //TODO: change this!!
out_stream << "Failed to execute action " << i->second.cmd_name_a << ", err=" << e.errors[0].desc << ends;
//LOG_STREAM << "alarm_table::timer_update() ERROR: " << out_stream.str() << endl;
}*/
ostringstream tmp;
string tmp_attr_val = i->second.attr_values_delay;
replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ',');
string tmp_msg = i->second.msg;
replace(tmp_msg.begin(), tmp_msg.end(), ';' , ',');
tm time_tm;
time_t time_sec= i->second.ts.tv_sec;
//gmtime_r(&time_sec,&time_tm); //-> UTC
localtime_r(&time_sec,&time_tm);
char time_buf[64];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &time_tm);
tmp << "name=" << i->second.name << ";groups=" << i->second.grp2str() << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<i->second.formula<<";time="<<time_buf << "." << i->second.ts.tv_usec<<";url="<<i->second.url;
cmd_t arg;
arg.cmd_id = CMD_COMMAND;
arg.dp_add = (long)i->second.dp_a;
arg.arg_s1 = tmp.str();
arg.arg_s2 = i->second.cmd_action_a;
arg.arg_s3 = i->second.cmd_name_a;
arg.arg_b = i->second.send_arg_a;
cmdloop->list.push_back(arg);
}
}
else if(status_off_delay && (i->second.stat == S_ALARM))
{
if(i->second.dp_n && ((ts.tv_sec - startup_complete.tv_sec) > 10))
{
/*try {
long call_id;
ostringstream tmp;
tmp << i->second.name << ";" << i->second.attr_values_off_delay;
Tango::DevString str = CORBA::string_dup(tmp.str().c_str());
Tango::DeviceData Din;
Din << str;
CORBA::string_free(str);
//i->second.dp_n->ping();
cmdloop->mutex_dp->lock();
//call_id = i->second.dp_n->command_inout_asynch(i->second.cmd_action_n, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer
call_id = i->second.dp_n->command_inout_asynch(i->second.cmd_action_n, Din);
cmdloop->mutex_dp->unlock();
LOG_STREAM << gettime().tv_sec << " alarm_table::timer_update() executed action: " << i->second.cmd_name_n << " !!!" << endl;
cmd_t arg;
arg.cmd_id = call_id;
arg.dp_add = (long)i->second.dp_n;
arg.arg_s = i->second.cmd_name_n;
cmdloop->list.push_back(arg);
} catch(Tango::DevFailed e)
{
string err(e.errors[0].desc);
if(err.find("is not yet arrived") == string::npos) //TODO: change this!!
out_stream << "Failed to execute action " << i->second.cmd_name_n << ", err=" << e.errors[0].desc << ends;
//LOG_STREAM << "alarm_table::timer_update() ERROR: " << out_stream.str() << endl;
}*/
ostringstream tmp;
string tmp_attr_val = i->second.attr_values_delay;
replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ',');
string tmp_msg = i->second.msg;
replace(tmp_msg.begin(), tmp_msg.end(), ';' , ',');
tm time_tm;
time_t time_sec= i->second.ts.tv_sec;
//gmtime_r(&time_sec,&time_tm); //-> UTC
localtime_r(&time_sec,&time_tm);
char time_buf[64];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &time_tm);
tmp << "name=" << i->second.name << ";groups=" << i->second.grp2str() << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<i->second.formula<<";time="<<time_buf << "." << i->second.ts.tv_usec<<";url="<<i->second.url;
cmd_t arg;
arg.cmd_id = CMD_COMMAND;
arg.dp_add = (long)i->second.dp_n;
arg.arg_s1 = tmp.str();
arg.arg_s2 = i->second.cmd_action_n;
arg.arg_s3 = i->second.cmd_name_n;
arg.arg_b = i->second.send_arg_n;
cmdloop->list.push_back(arg);
}
}
if((int)(status_on_delay)) {
i->second.off_counter = 0;
} else if(status_off_delay) {
i->second.on_counter = 0;
}
if(!i->second.enabled)
*(i->second.attr_value) = _OOSRV;
else if(i->second.shelved && i->second.silenced > 0)
*(i->second.attr_value) = _SHLVD;
else if((status_off_delay) && i->second.ack == ACK)
*(i->second.attr_value) = _NORM;
else if((status_on_delay) && i->second.ack == NOT_ACK)
*(i->second.attr_value) = _UNACK;
else if((status_on_delay) && i->second.ack == ACK)
*(i->second.attr_value) = _ACKED;
else if((status_off_delay) && i->second.ack == NOT_ACK)
*(i->second.attr_value) = _RTNUN;
try
{
if(!i->second.error || !i->second.enabled || (i->second.shelved && i->second.silenced > 0))
{
timeval now;
gettimeofday(&now, NULL);
if(setAlarmQuality)
{
mydev->push_change_event(i->second.attr_name,(Tango::DevEnum *)i->second.attr_value,now,(Tango::AttrQuality)i->second.quality, 1/*size*/, 0, false);
mydev->push_archive_event(i->second.attr_name,(Tango::DevEnum *)i->second.attr_value,now,(Tango::AttrQuality)i->second.quality, 1/*size*/, 0, false);
}
else
{
mydev->push_change_event(i->second.attr_name,(Tango::DevEnum *)i->second.attr_value);
mydev->push_archive_event(i->second.attr_name,(Tango::DevEnum *)i->second.attr_value);
}
}
else
{
Tango::DevErrorList errors(1);
errors.length(1);
errors[0].desc = CORBA::string_dup(i->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(i->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(i->second.ex_origin.c_str());
Tango::DevFailed except(errors);
mydev->push_change_event(i->second.attr_name, &except);
mydev->push_archive_event(i->second.attr_name, &except);
}
} catch(Tango::DevFailed &e)
{}
}
if (status_on_delay) {
i->second.stat = S_ALARM;
}
else if (status_off_delay) {
i->second.stat = S_NORMAL;
}
//found->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts everytime
}
vlock->readerOut();
if(out_stream.str().length() > 0)
throw out_stream.str();
return ret_changed;
}
void alarm_table::erase(alarm_container_t::iterator i)
{
vlock->writerIn();
v_alarm.erase(i);
vlock->writerOut();
}
bool alarm_table::exist(string& s)
{
alarm_container_t::iterator found = v_alarm.find(s);
if (found != v_alarm.end())
return true;
else
return false;
}
unsigned int alarm_table::to_be_evaluated_num()
{
unsigned int ret=0;
vlock->readerIn();
for(alarm_container_t::iterator i = v_alarm.begin(); i != v_alarm.end(); i++)
{
if(i->second.to_be_evaluated == true)
ret++;
}
vlock->readerOut();
return ret;
}
vector<string> alarm_table::to_be_evaluated_list()
{
vector<string> ret;
vlock->readerIn();
for(alarm_container_t::iterator i = v_alarm.begin(); i != v_alarm.end(); i++)
{
if(i->second.to_be_evaluated == true)
ret.push_back(i->first);
}
vlock->readerOut();
return ret;
}
void alarm_table::new_rwlock()
{
#ifndef _USE_BOOST_LOCK
vlock = new(ReadersWritersLock);
#else
vlock = new rwlock_t("VLOCK");
#endif
}
void alarm_table::del_rwlock()
{
delete vlock;
}
void alarm_table::init_cmdthread()
{
cmdloop = new cmd_thread();
cmdloop->start();
}
void alarm_table::stop_cmdthread()
{
cmd_t arg;
//arg.arg_s = CMD_THREAD_EXIT;
arg.cmd_id = CMD_THREAD_EXIT;
cmdloop->list.push_back(arg);
}
void alarm_table::save_alarm_conf_db(const string &att_name, const string &name, const string &status, const string &ack, bool enabled,
const string &formula, unsigned int on_delay, unsigned int off_delay, const string &grp, const string &lev, const string &msg, const string &url, const string &cmd_a, const string &cmd_n, const string &receivers, int silent_time)
{
// We want to put properties for attribute "att_name"
Tango::DbDatum dbd_att_name(att_name);
Tango::DbDatum dbd_name(NAME_KEY);
Tango::DbDatum dbd_formula(FORMULA_KEY);
Tango::DbDatum dbd_on_delay(ONDELAY_KEY);
Tango::DbDatum dbd_off_delay(OFFDELAY_KEY);
Tango::DbDatum dbd_level(LEVEL_KEY);
Tango::DbDatum dbd_silence_time(SILENT_TIME_KEY); //TODO: silent_time
Tango::DbDatum dbd_group(GROUP_KEY);
Tango::DbDatum dbd_message(MESSAGE_KEY);
Tango::DbDatum dbd_url(URL_KEY);
Tango::DbDatum dbd_oncommand(ON_COMMAND_KEY);
Tango::DbDatum dbd_offcommand(OFF_COMMAND_KEY);
Tango::DbDatum dbd_enabled(ENABLED_KEY);
Tango::DbDatum dbd_receivers(RECEIVERS_KEY);
Tango::DbData db_data;
dbd_att_name << (short int)13; // Thirteen properties for attribute "att_name"
dbd_name << name.c_str();
dbd_formula << formula.c_str();
dbd_on_delay << (Tango::DevLong)on_delay;
dbd_off_delay << (Tango::DevLong)off_delay;
dbd_level << lev.c_str();
dbd_silence_time << (Tango::DevLong)silent_time;
dbd_group << grp.c_str();
dbd_message << msg.c_str();
dbd_url << url.c_str();
dbd_oncommand << cmd_a.c_str();
dbd_offcommand << cmd_n.c_str();
dbd_receivers << receivers.c_str();
dbd_enabled << (enabled ? (short int)1 : (short int)0);
db_data.push_back(dbd_att_name);
db_data.push_back(dbd_name);
db_data.push_back(dbd_formula);
db_data.push_back(dbd_on_delay);
db_data.push_back(dbd_off_delay);
db_data.push_back(dbd_level);
db_data.push_back(dbd_silence_time);
db_data.push_back(dbd_group);
db_data.push_back(dbd_message);
db_data.push_back(dbd_url);
db_data.push_back(dbd_oncommand);
db_data.push_back(dbd_offcommand);
db_data.push_back(dbd_enabled);
db_data.push_back(dbd_receivers);
string dev_name(mydev->get_name());
try
{
Tango::DbDevice *db_dev = mydev->get_db_device();
db_dev->get_dbase()->put_device_attribute_property(dev_name,db_data);
//Tango::Util::instance()->get_database()->put_device_attribute_property(dev_name,db_data);
}
catch(Tango::DevFailed &e)
{
TANGO_LOG << __func__ << ": Exception saving configuration = " << e.errors[0].desc<<endl;
}
}
void alarm_table::delete_alarm_conf_db(string att_name)
{
// We want to put properties for attribute "att_name"
Tango::DbDatum dbd_att_name(att_name);
Tango::DbDatum dbd_name(NAME_KEY);
Tango::DbDatum dbd_formula(FORMULA_KEY);
Tango::DbDatum dbd_on_delay(ONDELAY_KEY);
Tango::DbDatum dbd_off_delay(OFFDELAY_KEY);
Tango::DbDatum dbd_level(LEVEL_KEY);
Tango::DbDatum dbd_silence_time(SILENT_TIME_KEY); //TODO: silent_time
Tango::DbDatum dbd_group(GROUP_KEY);
Tango::DbDatum dbd_message(MESSAGE_KEY);
Tango::DbDatum dbd_url(URL_KEY);
Tango::DbDatum dbd_oncommand(ON_COMMAND_KEY);
Tango::DbDatum dbd_offcommand(OFF_COMMAND_KEY);
Tango::DbDatum dbd_enabled(ENABLED_KEY);
Tango::DbDatum dbd_receivers(RECEIVERS_KEY);
Tango::DbData db_data;
db_data.push_back(dbd_att_name);
db_data.push_back(dbd_name);
db_data.push_back(dbd_formula);
db_data.push_back(dbd_on_delay);
db_data.push_back(dbd_off_delay);
db_data.push_back(dbd_level);
db_data.push_back(dbd_silence_time);
db_data.push_back(dbd_group);
db_data.push_back(dbd_message);
db_data.push_back(dbd_url);
db_data.push_back(dbd_oncommand);
db_data.push_back(dbd_offcommand);
db_data.push_back(dbd_enabled);
db_data.push_back(dbd_receivers);
string dev_name(mydev->get_name());
try
{
Tango::DbDevice *db_dev = mydev->get_db_device();
db_dev->get_dbase()->delete_device_attribute_property(dev_name,db_data);
}
catch(Tango::DevFailed &e)
{
TANGO_LOG << __func__ << ": Exception deleting " << att_name << " = " << e.errors[0].desc<<endl;
}
}
void alarm_table::get_alarm_list_db(vector<string> &al_list, map<string, string> &saved_alarms, ReadersWritersLock *savedlock)
{
string dev_name(mydev->get_name());
vector<string> att_list;
Tango::DbDevice *db_dev = mydev->get_db_device();
db_dev->get_dbase()->get_device_attribute_list(dev_name,att_list);
Tango::DbData db_data;
vector<string>::iterator it;
for(it = att_list.begin(); it!=att_list.end(); it++)
{
db_data.push_back(Tango::DbDatum(*it));
}
try
{
db_dev->get_attribute_property(db_data);
}
catch(Tango::DevFailed &e)
{
TANGO_LOG << __func__ << ": Exception reading configuration = " << e.errors[0].desc<<endl;
}
savedlock->writerIn();
saved_alarms.clear();
for (size_t i=0;i < db_data.size();/*i++*/)
{
Tango::DevLong64 nb_prop;
string &att_name = db_data[i].name;
db_data[i] >> nb_prop;
i++;
string alm_name;
string alm_formula;
string alm_on_delay("0");
string alm_off_delay("0");
string alm_level;
string alm_silence_time("-1");
string alm_group;
string alm_message;
string alm_url;
string alm_on_command("");
string alm_off_command("");
string alm_enabled("1");
string alm_receivers("");
for (long k=0;k < nb_prop;k++)
{
string &prop_name = db_data[i].name;
if (prop_name == NAME_KEY)
db_data[i] >> alm_name;
else if (prop_name == FORMULA_KEY)
db_data[i] >> alm_formula;
else if (prop_name == ONDELAY_KEY)
db_data[i] >> alm_on_delay;
else if (prop_name == OFFDELAY_KEY)
db_data[i] >> alm_off_delay;
else if (prop_name == LEVEL_KEY)
db_data[i] >> alm_level;
else if (prop_name == SILENT_TIME_KEY)
db_data[i] >> alm_silence_time;
else if (prop_name == GROUP_KEY)
db_data[i] >> alm_group;
else if (prop_name == MESSAGE_KEY)
db_data[i] >> alm_message;
else if (prop_name == URL_KEY)
db_data[i] >> alm_url;
else if (prop_name == ON_COMMAND_KEY)
db_data[i] >> alm_on_command;
else if (prop_name == OFF_COMMAND_KEY)
db_data[i] >> alm_off_command;
else if (prop_name == ENABLED_KEY)
db_data[i] >> alm_enabled;
else if (prop_name == RECEIVERS_KEY)
db_data[i] >> alm_receivers;
else
{
TANGO_LOG << "att_name="<<att_name<<" UNKWNOWN prop_name="<<prop_name<<endl;
i++;
continue;
}
i++;
}
alm_message = std::regex_replace(alm_message, std::regex(";"), "\\;");
alm_url = std::regex_replace(alm_url, std::regex(";"), "\\;");
alm_receivers = std::regex_replace(alm_receivers, std::regex(";"), "\\;");
stringstream alm;
alm << KEY(NAME_KEY)<<alm_name << SEP <<
KEY(FORMULA_KEY)<<alm_formula << SEP <<
KEY(ONDELAY_KEY)<<alm_on_delay << SEP <<
KEY(OFFDELAY_KEY)<<alm_off_delay << SEP <<
KEY(LEVEL_KEY)<< alm_level << SEP <<
KEY(SILENT_TIME_KEY)<<alm_silence_time << SEP <<
KEY(GROUP_KEY)<< alm_group << SEP <<
KEY(MESSAGE_KEY)<< alm_message << SEP <<
KEY(URL_KEY)<< alm_url << SEP <<
KEY(ON_COMMAND_KEY)<< alm_on_command << SEP <<
KEY(OFF_COMMAND_KEY)<< alm_off_command << SEP <<
KEY(RECEIVERS_KEY)<< alm_receivers << SEP <<
KEY(ENABLED_KEY)<< alm_enabled;
if(alm_name.empty() || alm_formula.empty() || alm_level.empty() || alm_group.empty() || alm_message.empty()) //TODO: decide if all mandatory
{
TANGO_LOG << __func__ << ": skipped '" << alm.str() << "'" << endl;
continue;
}
al_list.push_back(alm.str());
saved_alarms.insert(make_pair(alm_name,alm.str()));
}
savedlock->writerOut();
#if 0
db_dev->get_attribute_property(db_data);
//Tango::Util *tg = Tango::Util::instance();
//tg->get_database()->get_device_attribute_property("id11/motor/1", db_data);
Tango::Util::instance()->get_database()->get_device_attribute_property("id11/motor/1", db_data);
//mydev->get_device_attr();
#endif
}
/* EOF */
/*
* alarm_table.h
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#ifndef ALARM_TABLE_H
#define ALARM_TABLE_H
#define _RW_LOCK
#include <iostream>
#include <string>
#include <map>
#include <numeric> //for std::accumulate
#include <tango/tango.h>
//spirit defines have to be put befor first inclusion of spirit headers
#ifndef BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT
#define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 2 //tmp scanner_list
#endif
/*#ifndef BOOST_SPIRIT_THREADSAFE
#define BOOST_SPIRIT_THREADSAFE
#endif
#ifndef PHOENIX_THREADSAFE
#define PHOENIX_THREADSAFE
#endif
*/
//#include "spirit-parser.h"
//#include <boost/spirit/core.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION < 103600
#include <boost/spirit/tree/ast.hpp> //for ast parse trees (in tree_formula)
#else
#include <boost/spirit/include/classic_ast.hpp> //for ast parse trees (in tree_formula)
#endif
//#define _USE_BOOST_LOCK
#ifdef _USE_BOOST_LOCK
#include <boost/thread/shared_mutex.hpp>
#endif
//#include "log_thread.h"
#define MAX_ARRAY_PRINTED_CHARS 1000
#define LOG_STREAM TANGO_LOG
using namespace std;
typedef vector<Tango::DevDouble> value_t;
#if BOOST_VERSION < 103600
typedef std::string::iterator iterator_t;
typedef boost::spirit::node_val_data_factory<unsigned int> factory_t; //want a modified node to contain an unsigned int value
typedef boost::spirit::tree_match<iterator_t, factory_t> parse_tree_match_t;
typedef boost::spirit::tree_parse_info<iterator_t, factory_t> tree_parse_info_t;
#else
typedef std::string::iterator iterator_t;
typedef boost::spirit::classic::node_val_data_factory<unsigned int> factory_t; //want a modified node to contain an unsigned int value
typedef boost::spirit::classic::tree_match<iterator_t, factory_t> parse_tree_match_t;
typedef boost::spirit::classic::tree_parse_info<iterator_t, factory_t> tree_parse_info_t;
#endif
typedef parse_tree_match_t::tree_iterator iter_t;
#define S_NORMAL "NORMAL"
#define S_ALARM "ALARM"
#define S_ERROR "ERROR"
#define NOT_ACK "NACK"
#define ACK "ACK"
#define GR_ALL 0xffffffff
#define GR_NONE 0x00000000
#define GR_DEFAULT GR_NONE //or GR_ALL??
//#define MAX_GRP 32
#define GR_ALL_NAME "gr_all"
#define GR_NONE_NAME "gr_none"
#define LEV_LOG "log"
#define LEV_WARNING "warning"
#define LEV_FAULT "fault"
//#define LEV_DEFAULT LEV_FAULT
#define LEV_LOWEST "lowest"
#define LEV_LOW "low"
#define LEV_MEDIUM "medium"
#define LEV_HIGH "high"
#define LEV_HIGHEST "highest"
#define LEV_DEFAULT LEV_HIGH
class alarm_t;
class alarm_table;
class log_thread;
class cmd_thread;
#ifdef _USE_BOOST_LOCK
struct rwlock_t
{
string name;
rwlock_t(string n){name=n;};
rwlock_t(){name=string("RWLOCK");};
boost::shared_mutex mut;
void readerIn(){TANGO_LOG<<name<<": " << __func__<<endl;mut.lock_shared();}
void readerOut(){TANGO_LOG<<name<<": " << __func__<<endl;mut.unlock_shared();}
void writerIn(){TANGO_LOG<<name<<": " << __func__<<endl;mut.lock();}
void writerOut(){TANGO_LOG<<name<<": " << __func__<<endl;mut.unlock();}
};
#endif
template <typename T>
string print_vector(const std::vector<T>& v, const char * const separator = ",")
{
ostringstream out;
if(!v.empty())
{
std::copy(v.begin(),
--v.end(),
std::ostream_iterator<T>(out, separator));
out << v.back();
}
return out.str();
}
template <typename T>
string print_array(const std::vector<T>& v, long dim_x, long dim_y, const char * const separator = ",")
{
ostringstream out;
if(dim_y <1)
{
out <<"["<< print_vector(v);
out.seekp(0, ios::end);
stringstream::pos_type offset = out.tellp();
if(offset > MAX_ARRAY_PRINTED_CHARS)
{
out.seekp(MAX_ARRAY_PRINTED_CHARS, ios::beg);//limit size
out << "...]" << ends;
}
else
out << "]";
return out.str();
}
out << "[";
for(long i=0; i<dim_y; i++)
{
auto vstart = v.begin();//start iterator of a row in a vector containing a 2D array
auto vend = v.begin();//end iterator of a row in a vector containing a 2D array
advance(vstart,(int)(i * (dim_x)));
advance(vend,(int)((i+1) * dim_x));
value_t row = value_t(vstart,vend);
out <<"["<< print_vector(row);
out.seekp(0, ios::end);
stringstream::pos_type offset = out.tellp();
if(offset > MAX_ARRAY_PRINTED_CHARS)
{
out.seekp(MAX_ARRAY_PRINTED_CHARS, ios::beg);//limit size
out << "...]]" << ends;
break;
}
else
out << "]";
if(i < dim_y-1)
{
out << ",";
}
}
out << "]";
return out.str();
}
struct vectorUtils
{
static double fBitAnd(long a, long b){ return (double)(a & b);}
static double fBitOr(long a, long b){ return (double)(a | b);}
static double fBitXor(long a, long b){ return (double)(a ^ b);}
static double fBitShiftL(long a, long b){ return (double)(a << b);}
static double fBitShiftR(long a, long b){ return (double)(a >> b);}
static double fMin(double a, double b){ return (double)min(a, b);}
static double fMax(double a, double b){ return (double)max(a, b);}
static double fPow(double a, double b){ return (double)pow(a, b);}
static double fEqual(double a, double b){ return (double)(a == b);}
static double fDifferent(double a, double b){ return (double)(a != b);}
static double fGreaterEqual(double a, double b){ return (double)(a >= b);}
static double fGreater(double a, double b){ return (double)(a > b);}
static double fLessEqual(double a, double b){ return (double)(a <= b);}
static double fLess(double a, double b){ return (double)(a < b);}
static double fPlus(double a, double b){ return (double)(a + b);}
static double fMinus(double a, double b){ return (double)(a - b);}
static double fMult(double a, double b){ return (double)(a * b);}
static double fDiv(double a, double b){ return (double)(a / b);}
static double fAnd(double a, double b){ return (double)((bool)a && (bool)b);}
static double fOr(double a, double b){ return (double)((bool)a || (bool)b);}
template<class T >
static void applyVectorFunc(const vector<T> & v1, long v1_x, long v1_y, const vector<T> & v2, long v2_x, long v2_y, value_t &res, long &res_x, long &res_y, const string& origin, double (*func)(T, T))
{
if(v1.size() > 0 && v2.size() > 0 && (v1.size() == v2.size()))
{
res_x = v1_x;
res_y = v1_y;
if(v1_x != v2_x || (v1_y != v2_y && (v1_y > 1 || v2_y > 1)))//dim_y 0 and 1 are the same
{
ostringstream o;
o << "Array sizes do not match: " << (v1_y ? v1_y : 1) << "x" << v1_x << " != " << (v2_y ? v2_y : 1) << "x" << v2_x;
Tango::Except::throw_exception( //throw exception to have error not delayed
"FORMULA_ERROR",
o.str(),
origin);
}
res.resize(v1.size());
std::transform(v1.begin(), v1.end(), v2.begin(),res.begin(),
[func](T a, T b) { return func(a, b); });
}
else if(v2.size() == 1)
{
res_x = v1_x;
res_y = v1_y;
T b = v2[0];
res.resize(v1.size());
std::transform(v1.begin(), v1.end(), res.begin(),
[b,func](T a) { return func(a, b); });
}
else if(v1.size() == 1)
{
res_x = v2_x;
res_y = v2_y;
T a = v1[0];
res.resize(v2.size());
std::transform(v2.begin(), v2.end(), res.begin(),
[a,func](T b) { return func(a, b); });
}
else if(v1.size() > 0 && v2.size() > 0)
{
ostringstream o;
o << "Array sizes do not match: " << (v1_y ? v1_y : 1) << "x" << v1_x << " != " << (v2_y ? v2_y : 1) << "x" << v2_x;
Tango::Except::throw_exception( //throw exception to have error not delayed
"FORMULA_ERROR",
o.str(),
origin);
}
}
};
struct formula_res_t
{
formula_res_t(){valid=false;quality=Tango::ATTR_VALID;ex_reason=string("");ex_desc=string("");ex_origin=string("");dim_x=0;dim_y=0;}
value_t value;
long dim_x;
long dim_y;
int quality;
bool valid;
string error;
Tango::DevErrorList errors; //TODO: error stack
string ex_reason;
string ex_desc;
string ex_origin;
string attr_name; //last evaluated attr name
int combine_quality(int quality1, int quality2)
{
int res;
if(quality1 == Tango::ATTR_INVALID || quality2 == Tango::ATTR_INVALID)
res = Tango::ATTR_INVALID;
else if(quality1 == Tango::ATTR_ALARM || quality2 == Tango::ATTR_ALARM)
res = Tango::ATTR_ALARM;
else if(quality1 == Tango::ATTR_WARNING || quality2 == Tango::ATTR_WARNING)
res = Tango::ATTR_WARNING;
else if(quality1 == Tango::ATTR_CHANGING || quality2 == Tango::ATTR_CHANGING)
res = Tango::ATTR_CHANGING;
else
res = (quality1 > quality2) ? quality1 : quality2; //TODO: decide priority in enum AttrQuality { ATTR_VALID, ATTR_INVALID, ATTR_ALARM, ATTR_CHANGING, ATTR_WARNING /*, __max_AttrQuality=0xffffffff */ };
return res;
}
string combine_exception(string ex_1, string ex_2)
{
if(ex_1.length() > 0)
return ex_1;
else
return ex_2;
}
void extract_result()
{
if(!value.empty())
{
value = {(double)std::accumulate(value.begin(), value.end(), (bool)false, [](bool a, double b) { return (bool)(a || (bool)b); })};
dim_x=1;
dim_y=0;
}
}
formula_res_t operator==(const formula_res_t& e)
{
formula_res_t res;
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fEqual);
return res;
}
formula_res_t operator!=(const formula_res_t& e)
{
formula_res_t res;
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fDifferent);
return res;
}
formula_res_t operator<=(const formula_res_t& e)
{
formula_res_t res;
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fLessEqual);
return res;
}
formula_res_t operator>=(const formula_res_t& e)
{
formula_res_t res;
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fGreaterEqual);
return res;
}
formula_res_t operator<(const formula_res_t& e)
{
formula_res_t res;
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fLess);
return res;
}
formula_res_t operator>(const formula_res_t& e)
{
formula_res_t res;
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fGreater);
return res;
}
formula_res_t operator||(const formula_res_t& e)
{
formula_res_t res;
if(value.size() <= 1 && e.value.size() <= 1) //apply special logic ov validity only if comparing scalars. Being careful that if valid=false, then size could be 0
{
res.value = {(double)((valid && value[0]) || (e.valid && e.value[0]))}; //in OR one operand TRUE and valid is enough
res.valid = (valid && value[0]) || (e.valid && e.value[0]) || (valid && e.valid); //in OR one operand TRUE and valid is enough, otherwise both valid as usual
}
else
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
if(!(value.size() <= 1 && e.value.size() <= 1))
{
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fOr);
}
return res;
}
formula_res_t operator&&(const formula_res_t& e)
{
formula_res_t res;
if(value.size() <= 1 && e.value.size() <= 1) //apply special logic ov validity only if comparing scalars
{
res.value = {(double)(!((valid && !value[0]) || (e.valid && !e.value[0])) || (valid && value[0] && e.valid && e.value[0]))}; //if at least one operand is FALSE and valid, result is FALSE for sure (and valid)
res.valid = (valid && !value[0]) || (e.valid && !e.value[0]) || (valid && e.valid);
}
else
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
if(!(value.size() <= 1 && e.value.size() <= 1))
{
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fAnd);
}
return res;
}
formula_res_t operator+(const formula_res_t& e)
{
formula_res_t res;
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fPlus);
return res;
}
formula_res_t operator-(const formula_res_t& e)
{
formula_res_t res;
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fMinus);
return res;
}
formula_res_t operator*(const formula_res_t& e)
{
formula_res_t res;
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fMult);
return res;
}
formula_res_t operator/(const formula_res_t& e)
{
formula_res_t res;
res.valid = valid && e.valid;
res.quality = combine_quality(quality, e.quality);
if(!res.valid)
{
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
}
vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fDiv);
return res;
}
formula_res_t operator!()
{
formula_res_t res;
for(size_t ii=0; ii < value.size(); ii++)
{
res.value.push_back(!value[ii]);
}
return res;
}
formula_res_t operator-()
{
formula_res_t res;
for(size_t ii=0; ii < value.size(); ii++)
{
res.value.push_back(-value[ii]);
}
return res;
}
/*string operator<<(const formula_res_t& e)
{
stringstream res;
res << "value="<<e.value<<" quality="<<e.quality<<" EX reason="<<e.ex_reason<<" desc="<<e.ex_desc<<" origin="<<e.ex_origin;
return res.str();
}*/
};
/*
* store the alarm-name/alarm-formula pair
*/
class alarm_t {
public:
string name,
formula;
string attr_name;
string attr_name_formula;
Tango::DevEnum *attr_value;
Tango::DevString *attr_value_formula;
int quality;
string ex_reason;
string ex_desc;
string ex_origin;
Tango::TimeVal ts;
string stat{S_NORMAL},
ack{ACK};
bool error;
bool enabled{true};
bool shelved{false};
#ifdef _CNT_ATOMIC
atomic_uint on_counter= {0};
atomic_uint off_counter= {0};
atomic_uint err_counter= {0};
#else
unsigned int on_counter= {0};
unsigned int off_counter= {0};
unsigned int err_counter= {0};
#endif
unsigned int freq_counter{0};
tree_parse_info_t formula_tree;
static map<string, unsigned int> grp_str;
bool done;
bool to_be_evaluated;
string msg;
string url;
string receivers;
unsigned int grp{0};
string lev;
set<string> s_event;
int is_new;
Tango::TimeVal ts_on_delay; //says when it has gone in alarm status for the first time
unsigned int on_delay{0}; //TODO: seconds, is it enough precision?
Tango::TimeVal ts_off_delay; //says when it returned normal status
unsigned int off_delay{0}; //TODO: seconds, is it enough precision?
Tango::TimeVal ts_err_delay; //says when it has gone in error status for the first time
Tango::TimeVal ts_time_silenced; //says when it has been silenced
int silent_time{-1}; //minutes max to be silent
int silenced; //minutes still to be silent
string attr_values; //attr_values
string attr_values_delay; //attr_values of first occurrence of alarm waiting for on or off delay
string cmd_name_a{""}; //action to execute: when NORMAL -> ALARM, cmd_name = cmd_dp_a/cmd_action_a
string cmd_dp_a; //device proxy part of cmd_name_a
string cmd_action_a; //action part of cmd_name_a
bool send_arg_a; //send as string argument alarm name and attr values
Tango::DeviceProxy *dp_a;
string cmd_name_n{""}; //action to execute: when ALARM -> NORMAL, cmd_name_n = cmd_dp_n/cmd_action_n
string cmd_dp_n; //device proxy part of cmd_name_n
string cmd_action_n; //action part of cmd_name_n
bool send_arg_n; //send as string argument alarm name and attr values
Tango::DeviceProxy *dp_n;
/*
* methods
*/
alarm_t() noexcept {}; //constructor
#ifdef _CNT_ATOMIC
alarm_t& operator=(const alarm_t& rhs) { on_counter = rhs.on_counter.load(); off_counter = rhs.off_counter.load(); err_counter = rhs.err_counter.load(); return *this; }
alarm_t(const alarm_t& rhs) { on_counter = rhs.on_counter.load(); off_counter = rhs.off_counter.load(); err_counter = rhs.err_counter.load();}
#endif
void init_static_map(vector<string> &group_names);
bool operator==(const alarm_t& that);
bool operator==(const string& n);
void str2alm(const string &s);
string alm2str(void);
string grp2str(void);
void add_grp_from_str(string &s);
void str2grp(string &s);
void insert(const string& s);
void clear();
void confstr(string &s);
protected:
private:
};
typedef map<string,alarm_t> alarm_container_t;
class alarm_table {
public:
alarm_table() {}
~alarm_table() {del_rwlock();}
bool setAlarmQuality {false};
void set_dev(Tango::DeviceImpl* devImpl) {mydev=devImpl;}
void set_al_qual(bool set_al_qual) {setAlarmQuality=set_al_qual;}
//void init(vector<string>& avs);
//void init(vector<string>& avs, vector<string> &evn, map< string,vector<string> > &alarm_event);
void push_back(alarm_t& a);
void show(vector<string> &al_table_string);
unsigned int size(void);
alarm_container_t& get(void);
void stored(vector<alarm_t>& a);
bool update(const string& alm_name, Tango::TimeVal ts, formula_res_t res, string &attr_values, string grp, string msg, string formula);
bool timer_update();
void erase(alarm_container_t::iterator i);
bool exist(string& s);
unsigned int to_be_evaluated_num();
vector<string> to_be_evaluated_list();
//vector<alarm_t> v_alarm;
alarm_container_t v_alarm;
#ifndef _USE_BOOST_LOCK
ReadersWritersLock *vlock;
#else
rwlock_t *vlock;
#endif
void new_rwlock();
void del_rwlock();
void save_alarm_conf_db(const string &att_name, const string &name, const string &status, const string &ack, bool enabled,
const string &formula, unsigned int on_delay, unsigned int off_delay, const string &grp, const string &url, const string &lev, const string &msg, const string &cmd_a, const string &cmd_n, const string &receivers, int silent_time);
void delete_alarm_conf_db(string att_name);
void get_alarm_list_db(vector<string> &al_list, map<string, string> &saved_alarms, ReadersWritersLock *savedlock);
void init_cmdthread();
void stop_cmdthread();
Tango::TimeVal startup_complete; //to disable action execution at startup
void set_err_delay(unsigned int delay){err_delay=delay;};
protected:
private:
Tango::DeviceImpl* mydev;
log_thread *logloop;
cmd_thread *cmdloop;
unsigned int err_delay;
};
#endif /* ALARM_TABLE_H */
/*
* cmd_thread.cpp
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#include "cmd_thread.h"
static const char __FILE__rev[] = __FILE__ " $Revision: 1.3 $";
/*
* cmd_thread::cmd_thread()
*/
cmd_thread::cmd_thread()
{
TANGO_LOG << __FILE__rev << endl;
TANGO_LOG << gettime().tv_sec << " cmd_thread::cmd_thread(): constructor... !" << endl;
//mutex_dp = new omni_mutex::omni_mutex();
}
/*
* cmd_thread::~cmd_thread()
*/
cmd_thread::~cmd_thread()
{
TANGO_LOG << gettime().tv_sec << " cmd_thread::~cmd_thread(): delete device entering..." << endl;
//delete mutex_dp;
}
/*
* cmd_thread::run()
*/
void cmd_thread::run(void *)
{
long call_id;
while (true) {
/*
* pop_front() will wait() on condition variable
*/
try
{
cmd_t cmd = list.pop_front();
switch(cmd.cmd_id)
{
case CMD_THREAD_EXIT:
TANGO_LOG << gettime().tv_sec << " cmd_thread::run(): received command THREAD_EXIT -> exiting..." << endl;
return;
case CMD_COMMAND:
{
try {
TANGO_LOG << gettime().tv_sec << " cmd_thread::run(): COMMAND ... action=" << cmd.arg_s3 << endl;
dp = (Tango::DeviceProxy *)cmd.dp_add;
if(cmd.arg_b)
{
Tango::DevString str = CORBA::string_dup(cmd.arg_s1.c_str());
Tango::DeviceData Din;
Din << str;
CORBA::string_free(str);
//found->second.dp_a->ping();
//call_id = dp->command_inout_asynch(cmd.arg_s2, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer
call_id = dp->command_inout_asynch(cmd.arg_s2, Din); //true -> "fire and forget" mode: client do not care at all about the server answer
}
else
call_id = dp->command_inout_asynch(cmd.arg_s2);
TANGO_LOG << gettime().tv_sec << " cmd_thread::run() executed action: " << cmd.arg_s3 << " !!! call_id=" << call_id << endl;
/*cmd_t arg;
arg.cmd_id = CMD_RESPONSE;
arg.call_id = call_id;
arg.dp_add = cmd.dp_add;
arg.arg_s1 = cmd.arg_s1;
arg.arg_s2 = cmd.arg_s2;
arg.arg_s3 = cmd.arg_s3;
cmdloop->list.push_back(arg);*/
cmd.cmd_id = CMD_RESPONSE; //if no exception till now push in list request of response
cmd.call_id = call_id; //if no exception till now push in list request of response
list.push_back(cmd); //if no exception till now push in list request of response
} catch(Tango::DevFailed &e)
{
TangoSys_MemStream out_stream;
string err(e.errors[0].desc);
if(err.find("is not yet arrived") == string::npos) //TODO: change this!!
{
out_stream << "Failed to execute action " << cmd.arg_s3 << ", err=" << e.errors[0].desc << ends;
TANGO_LOG << gettime().tv_sec << " cmd_thread::run() ERROR: " << out_stream.str() << endl;
}
else
{
TANGO_LOG << gettime().tv_sec << " cmd_thread::run() exception 'is not yet arrived': pushing request of response, call_id=" << call_id << endl;
cmd.cmd_id = CMD_RESPONSE; //if no exception till now push in list request of response
cmd.call_id = call_id; //if no exception till now push in list request of response
list.push_back(cmd); //if no exception till now push in list request of response
}
}
}
break;
case CMD_RESPONSE:
{
//TANGO_LOG << gettime().tv_sec << " cmd_thread::run(): RESPONSE WAKE UP... action=" << cmd.arg_s3 << " call_id=" << cmd.call_id << endl;
Tango::DeviceData resp;
dp = (Tango::DeviceProxy *)cmd.dp_add;
try {
resp = dp->command_inout_reply(cmd.call_id);
TANGO_LOG << gettime().tv_sec << " cmd_thread::run() RECEIVED response to action " << cmd.arg_s3 << endl;
} catch(Tango::DevFailed &e)
{
TangoSys_MemStream out_stream;
out_stream << "EXCEPTION executing action " << cmd.arg_s3 << ", err=" << e.errors[0].desc << ends;
if(out_stream.str().find("is not yet arrived") != string::npos) //TODO: change this!!
{
list.push_back(cmd); //if exception "not yet arrived" push in list another request of response
omni_thread::sleep(0,300000000); //0.3 s
}
else
{
TANGO_LOG << gettime().tv_sec << " cmd_thread::run() " << out_stream.str() << endl;
Tango::Except::print_exception(e);
}
}
}
break;
}
/* if(cmd.arg_s == CMD_THREAD_EXIT)
{
TANGO_LOG << gettime().tv_sec << " cmd_thread::run(): received command THREAD_EXIT -> exiting..." << endl;
return;
}
else
{
TANGO_LOG << gettime().tv_sec << " cmd_thread::run(): WAKE UP... action=" << cmd.arg_s << endl;
Tango::DeviceData resp;
dp = (Tango::DeviceProxy *)cmd.dp_add;
try {
mutex_dp->lock();
resp = dp->command_inout_reply(cmd.cmd_id);
mutex_dp->unlock();
TANGO_LOG << gettime().tv_sec << " cmd_thread::run() received response to action " << cmd.arg_s << endl;
} catch(Tango::DevFailed &e)
{
TangoSys_MemStream out_stream;
out_stream << "EXCEPTION executing action " << cmd.arg_s << ", err=" << e.errors[0].desc << ends;
if(out_stream.str().find("is not yet arrived") != string::npos) //TODO: change this!!
{
list.push_back(cmd);
omni_thread::sleep(0,300000000); //0.2 s
}
else
TANGO_LOG << gettime().tv_sec << " cmd_thread::run() " << out_stream.str() << endl;
}
}*/
}
catch(omni_thread_fatal& ex)
{
ostringstream err;
err << "omni_thread_fatal exception running command thread, err=" << ex.error << ends;
//WARN_STREAM << "alarm_thread::run(): " << err.str() << endl;
printf("cmd_thread::run(): %s", err.str().c_str());
}
catch(Tango::DevFailed& ex)
{
ostringstream err;
err << "exception running command thread: '" << ex.errors[0].desc << "'" << ends;
//WARN_STREAM << "alarm_thread::run(): " << err.str() << endl;
printf("cmd_thread::run(): %s", err.str().c_str());
Tango::Except::print_exception(ex);
}
catch(...)
{
//WARN_STREAM << "alarm_thread::run(): catched unknown exception!!" << endl;
printf("cmd_thread::run(): catched unknown exception!!");
}
}
//TANGO_LOG << "alarm_thread::run(): returning" << endl;
} /* cmd_thread::run() */
/*
* cmd_list class methods
*/
void cmd_list::push_back(cmd_t& cmd)
{
this->lock();
//TANGO_LOG << "cmd_list::push_back: cmd_id=" << cmd.cmd_id << " call_id=" << cmd.call_id << endl;
try{
l_cmd.push_back(cmd);
empty.signal();
}
catch(omni_thread_fatal& ex)
{
ostringstream err;
err << "omni_thread_fatal exception signaling omni_condition, err=" << ex.error << ends;
//WARN_STREAM << "event_list::push_back(): " << err.str() << endl;
printf("cmd_list::push_back(): %s", err.str().c_str());
}
catch(Tango::DevFailed& ex)
{
ostringstream err;
err << "exception signaling omni_condition: '" << ex.errors[0].desc << "'" << ends;
//WARN_STREAM << "cmd_list::push_back(): " << err.str() << endl;
printf("cmd_list::push_back: %s", err.str().c_str());
Tango::Except::print_exception(ex);
}
catch(...)
{
printf("cmd_list::push_back(): catched unknown exception signaling omni_condition!!");
}
this->unlock();
}
const cmd_t cmd_list::pop_front(void)
{
this->lock();
//omni_mutex_lock l((omni_mutex)this); //call automatically unlock on destructor and on exception
try{
while (l_cmd.empty() == true)
empty.wait(); //wait release mutex while is waiting, then reacquire when signaled
}
catch(omni_thread_fatal& ex)
{
ostringstream err;
err << "omni_thread_fatal exception waiting on omni_condition, err=" << ex.error << ends;
printf("cmd_list::pop_front(): %s", err.str().c_str());
this->unlock();
sleep(1);
cmd_t c;
return c;
}
catch(Tango::DevFailed& ex)
{
ostringstream err;
err << "exception waiting on omni_condition: '" << ex.errors[0].desc << "'" << ends;
printf("cmd_list::pop_front: %s", err.str().c_str());
Tango::Except::print_exception(ex);
this->unlock();
sleep(1);
cmd_t c;
return c;
}
catch(...)
{
printf("cmd_list::pop_front(): catched unknown exception waiting on omni_condition!!");
this->unlock();
sleep(1);
cmd_t c;
return c;
}
/*const*/ cmd_t cmd;
cmd = *(l_cmd.begin());
//TANGO_LOG << "cmd_list::pop_front: " << e.name << " value=" << e.value[0] << endl;
l_cmd.pop_front();
this->unlock();
return cmd;
}
void cmd_list::clear(void)
{
//this->lock();
l_cmd.clear();
//this->unlock();
}
/*
* cmd_thread.h
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#ifndef CMD_THREAD_H
#define CMD_THREAD_H
#ifndef _LOGA
#define _LOGA 1
#endif // _LOGA
//#define CMD_THREAD_EXIT "EXIT"
#define CMD_COMMAND 1
#define CMD_RESPONSE 2
#define CMD_THREAD_EXIT 3
#include <omnithread.h>
#include <tango/tango.h>
#include "AlarmHandler.h"
struct cmd_t
{
short cmd_id;
long call_id;
string arg_s1;
string arg_s2;
string arg_s3;
bool arg_b;
long dp_add;
};
class cmd_list : public omni_mutex {
public:
cmd_list(void): empty(this) {}
~cmd_list(void) {}
void push_back(cmd_t& cmd);
const cmd_t pop_front(void);
void clear(void);
protected:
list<cmd_t> l_cmd;
private:
omni_condition empty;
};
class cmd_thread : public omni_thread{
public:
cmd_thread();
~cmd_thread();
cmd_list list;
//omni_mutex::omni_mutex *mutex_dp;
protected:
void run(void *);
private:
Tango::DeviceProxy *dp;
};
#endif /* CMD_THREAD_H */
/* EOF */
/*
* event_table.cpp
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#include <sys/time.h>
#include <tango/tango.h>
#include "event_table.h"
#include "AlarmHandler.h"
#include "alarm_grammar.h"
#include <regex>
static const char __FILE__rev[] = __FILE__ " $Revision: 1.5 $";
/*
* event_list class methods
*/
void event_list::push_back(bei_t& e)
{
this->lock();
try{
l_event.push_back(e);
empty.signal();
}
catch(omni_thread_fatal& ex)
{
ostringstream err;
err << "omni_thread_fatal exception signaling omni_condition, err=" << ex.error;
//WARN_STREAM << "event_list::push_back(): " << err.str() << endl;
printf("event_list::push_back(): %s", err.str().c_str());
}
catch(Tango::DevFailed& ex)
{
ostringstream err;
err << "exception signaling omni_condition: '" << ex.errors[0].desc << "'";
//WARN_STREAM << "event_list::push_back(): " << err.str() << endl;
//printf("event_list::push_back: %s", err.str().c_str());
//Tango::Except::print_exception(ex);
}
catch(...)
{
//WARN_STREAM << "event_list::push_back(): catched unknown exception!!" << endl;
printf("event_list::push_back(): catched unknown exception signaling omni_condition!!");
}
this->unlock();
}
const bei_t event_list::pop_front(void)
{
this->lock();
//omni_mutex_lock l((omni_mutex)this); //call automatically unlock on destructor and on exception
try{
while (l_event.empty() == true)
empty.wait(); //wait release mutex while is waiting, then reacquire when signaled
}
catch(omni_thread_fatal& ex)
{
ostringstream err;
err << "omni_thread_fatal exception waiting on omni_condition, err=" << ex.error;
//WARN_STREAM << "event_list::pop_front(): " << err.str() << endl;
printf("event_list::pop_front(): %s", err.str().c_str());
bei_t e;
this->unlock();
sleep(1);
return(e);
}
catch(Tango::DevFailed& ex)
{
ostringstream err;
err << "exception waiting on omni_condition: '" << ex.errors[0].desc << "'";
//WARN_STREAM << "event_list::pop_front(): " << err.str() << endl;
//printf("event_list::pop_front: %s", err.str().c_str());
//Tango::Except::print_exception(ex);
bei_t e;
this->unlock();
sleep(1);
return(e);
}
catch(...)
{
//WARN_STREAM << "event_list::pop_front(): catched unknown exception!!" << endl;
printf("event_list::pop_front(): catched unknown exception waiting on omni_condition!!");
bei_t e;
this->unlock();
sleep(1);
return(e);
}
/*const*/ bei_t e;
e = *(l_event.begin());
l_event.pop_front();
this->unlock();
return(e);
}
void event_list::clear(void)
{
//this->lock();
l_event.clear();
//this->unlock();
}
list<bei_t> event_list::show(void)
{
list<bei_t> el;
this->lock();
el = l_event;
this->unlock();
return(el);
}
size_t event_list::size(void)
{
size_t res;
this->lock();
res = l_event.size();
this->unlock();
return(res);
}
/*
* alarm_list class methods
*/
void alarm_list::push(string& a)
{
l.lock();
l_alarm.push_back(a);
l.unlock();
}
void alarm_list::pop(const string& a)
{
l.lock();
list<string>::iterator it = find(l_alarm.begin(), l_alarm.end(), a);
if(it != l_alarm.end())
l_alarm.erase(it);
else
TANGO_LOG << "alarm_list::"<<__func__<< ": ALARM '"<< a << "' NOT FOUND!"<< endl;
l.unlock();
return;
}
void alarm_list::clear(void)
{
l.lock();
l_alarm.clear();
l.unlock();
}
list<string> alarm_list::show(void)
{
list<string> al;
l.lock();
al = l_alarm;
l.unlock();
return(al);
}
bool alarm_list::empty(void)
{
bool res;
l.lock();
res = l_alarm.empty();
l.unlock();
return(res);
}
/*
* event class methods
*/
event::event(string& s, value_t& v, Tango::TimeVal& t) : \
name(s), value(v), ts(t)
{
const char *c = name.c_str();
int j = 0;
int num_slashes=3; //not FQDN
if(name.find("tango://") != string::npos) //FQDN!!
num_slashes = 6;
while (*c) {
if (*c == '/')
j++;
if (j < num_slashes)
devname.push_back(*c);
else if (*c != '/')
attname.push_back(*c);
c++;
}
type = -1;
event_id = SUB_ERR;
err_counter = 0;
valid = false;
dim_x=0;
dim_y=0;
}
event::event(string& s) : name(s)
{
const char *c = name.c_str();
int j = 0;
int num_slashes=3; //not FQDN
if(name.find("tango://") != string::npos) //FQDN!!
num_slashes = 6;
while (*c) {
if (*c == '/')
j++;
if (j < num_slashes)
devname.push_back(*c);
else if (*c != '/')
attname.push_back(*c);
c++;
}
type = -1;
event_id = SUB_ERR;
err_counter = 0;
valid = false;
dim_x=0;
dim_y=0;
}
bool event::operator==(const event& e)
{
return(name == e.name);
}
bool event::operator==(const string& s)
{
return(name == s);
}
/*
* event_table class methods
*/
/*void event_table::push_back(event e)
{
// v_event.push_back(e);//TODO: replaced with add
}*/
void event_table::show(list<string> &evl)
{
evl.clear();
ReaderLock lock(veclock);
if (v_event.empty() == false)
{
vector<event>::iterator i = v_event.begin();
while (i != v_event.end())
{
//DEBUG_STREAM << "\t" << i->name << endl;
evl.push_back(i->name);
i++;
}
}
}
void event_table::summary(list<string> &evs)
{
evs.clear();
ReaderLock lock(veclock);
if (v_event.empty() == false)
{
vector<event>::iterator i = v_event.begin();
while (i != v_event.end())
{
ostringstream ev_summary;
ev_summary << KEY(EVENT_KEY) << i->name << SEP;
tm time_tm;
time_t time_sec;
if(i->valid)
{
time_sec= i->ts.tv_sec;
}
else
{
timeval now;
gettimeofday(&now, NULL);
time_sec = now.tv_sec;
}
//gmtime_r(&time_sec,&time_tm); //-> UTC
localtime_r(&time_sec,&time_tm);
char time_buf[64];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &time_tm);
ev_summary << KEY(EVENT_TIME_KEY) << time_buf << SEP;
ostringstream tmp_val;
if(i->type != Tango::DEV_STRING)
tmp_val << print_array(i->value,i->dim_x,i->dim_y);
else
tmp_val << "[\""<<i->value_string<<"\"]";
ev_summary << KEY(ATTR_VALUES_KEY) << tmp_val.str() << SEP;
ostringstream tmp_ex;
//tmp_ex.str("");
if(!i->ex_reason.empty() || !i->ex_desc.empty() || !i->ex_origin.empty())
{
tmp_ex << "{\"Reason\":\"" << i->ex_reason << "\",\"Desc\":\"" << i->ex_desc << "\",\"Origin\":\"" << i->ex_origin << "\"}";
}
ev_summary << KEY(EXCEPTION_KEY) << tmp_ex.str() << SEP;
ev_summary << KEY(QUALITY_KEY);
try
{
ev_summary << quality_labels.at(i->quality) << SEP;
} catch(std::out_of_range& ex)
{
ev_summary << i->quality << SEP;
}
evs.push_back(ev_summary.str());
i++;
}
}
}
event_table::event_table(Tango::DeviceImpl *s):Tango::LogAdapter(s)
{
mydev = s;
stop_it = false;
action.store(NOTHING);
}
unsigned int event_table::size(void)
{
ReaderLock lock(veclock); //TODO: necessary?
return(v_event.size());
}
#if 0
void event_table::init_proxy(void) throw(vector<string> &)
{
vector<string> proxy_error;
if (v_event.empty() == false) {
for (vector<event>::iterator i = v_event.begin(); \
i != v_event.end(); i++)
{
try {
i->dp = new Tango::DeviceProxy(i->device);
} catch(Tango::DevFailed& e)
{
ostringstream o;
o << "new DeviceProxy() failed for " \
<< i->device;
ERROR_STREAM << o.str() << endl;
//throw o.str();
proxy_error.push_back(o.str());
}
}
}
if(!proxy_error.empty())
throw proxy_error;
}
void event_table::free_proxy(void)
{
if (v_event.empty() == false) {
for (vector<event>::iterator i = v_event.begin(); \
i != v_event.end(); i++) {
try{
delete i->dp;
DEBUG_STREAM << gettime().tv_sec << " event_table::free_proxy(): deleted proxy " << i->device << endl;
} catch(...)
{
ERROR_STREAM << "event_table::free_proxy: exception deleting proxy of event: " << i->name << endl;
}
}
}
}
void event_table::subscribe(EventCallBack& ecb)
{
vector<string> subscribe_error;
if (v_event.empty() == false) {
for (vector<event>::iterator i = v_event.begin(); \
i != v_event.end(); i++) {
try {
i->eid = i->dp->subscribe_event(i->attribute, \
Tango::CHANGE_EVENT, \
&ecb, i->filter);
} catch (...) {
ostringstream o;
o << "subscribe_event() failed for " \
<< i->name;
ERROR_STREAM << o.str() << endl;
//throw o.str();
subscribe_error.push_back(o.str());
}
}
}
if(!subscribe_error.empty())
throw subscribe_error;
}
void event_table::unsubscribe(void)
{
ostringstream o;
if (v_event.empty() == false) {
for (vector<event>::iterator i = v_event.begin(); \
i != v_event.end(); i++) {
try {
i->dp->unsubscribe_event(i->eid);
DEBUG_STREAM << gettime().tv_sec << " event_table::unsubscribe(): unsubscribed " << i->name << endl;
} catch (Tango::DevFailed& e) {
o << " unsubscribe_event() failed for " << i->name << " err=" << e.errors[0].desc;
ERROR_STREAM << gettime().tv_sec << " event_table::unsubscribe(): " << o.str() << endl;
//throw o.str();
} catch (...) {
o << " unsubscribe_event() failed for " \
<< i->name;
ERROR_STREAM << gettime().tv_sec << " event_table::unsubscribe(): " << o.str() << endl;
//throw o.str();
}
}
}
if(o.str().length() > 0)
throw o.str();
}
#endif
//=============================================================================
/**
* get signal by name.
*/
//=============================================================================
event *event_table::get_signal(string signame)
{
//omni_mutex_lock sync(*this);
for (unsigned int i=0 ; i<v_event.size() ; i++)
{
event *sig = &v_event[i];
if (sig->name==signame)
return sig;
}
for (unsigned int i=0 ; i<v_event.size() ; i++)
{
event *sig = &v_event[i];
if (static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->compare_without_domain(sig->name,signame))
return sig;
}
return NULL;
}
//=============================================================================
/**
* Stop saving on DB a signal.
*/
//=============================================================================
void event_table::stop(string &signame)
{
DEBUG_STREAM <<"event_table::"<< __func__<<": entering signame="<< signame << endl;
ReaderLock lock(veclock);
for (unsigned int i=0 ; i<v_event.size() ; i++)
{
if (v_event[i].name==signame)
{
v_event[i].siglock->writerIn();
if(!v_event[i].stopped)
{
v_event[i].stopped=true;
if(v_event[i].running)
{
try
{
remove(signame, true);
}
catch (Tango::DevFailed &e)
{
//Tango::Except::print_exception(e);
INFO_STREAM << "event_table::stop: error removing " << signame << endl;
}
}
if(v_event[i].paused)
{
try
{
remove(signame, true);
}
catch (Tango::DevFailed &e)
{
//Tango::Except::print_exception(e);
INFO_STREAM << "event_table::stop: error removing " << signame << endl;
}
}
v_event[i].running=false;
v_event[i].paused=false;
}
v_event[i].siglock->writerOut();
return;
}
}
for (unsigned int i=0 ; i<v_event.size() ; i++)
{
#ifndef _MULTI_TANGO_HOST
if (static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->compare_without_domain(v_event[i].name,signame))
#else
if (!static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->compare_tango_names(v_event[i].name,signame))
#endif
{
v_event[i].siglock->writerIn();
if(!v_event[i].stopped)
{
v_event[i].stopped=true;
if(v_event[i].running)
{
try
{
remove(signame, true);
}
catch (Tango::DevFailed &e)
{
//Tango::Except::print_exception(e);
INFO_STREAM << "event_table::stop: error removing " << signame << endl;
}
}
if(v_event[i].paused)
{
try
{
remove(signame, true);
}
catch (Tango::DevFailed &e)
{
//Tango::Except::print_exception(e);
INFO_STREAM << "event_table::stop: error removing " << signame << endl;
}
}
v_event[i].running=false;
v_event[i].paused=false;
}
v_event[i].siglock->writerOut();
return;
}
}
// if not found
Tango::Except::throw_exception(
(const char *)"BadSignalName",
"Signal " + signame + " NOT subscribed",
(const char *)"event_table::stop()");
}
//=============================================================================
/**
* Remove a signal in the list.
*/
//=============================================================================
void event_table::remove(string &signame, bool stop)
{
DEBUG_STREAM <<"event_table::"<< __func__<<": entering signame="<< signame << endl;
// Remove in signals list (vector)
{
if(!stop)
veclock.readerIn();
event *sig = get_signal(signame);
int event_id = sig->event_id;
Tango::AttributeProxy *attr = sig->attr;
if(!stop)
veclock.readerOut();
if(stop)
{
try
{
if(event_id != SUB_ERR && attr)
{
DEBUG_STREAM <<"event_table::"<< __func__<<": unsubscribing... "<< signame << endl;
//unlocking, locked in event_table::stop but possible deadlock if unsubscribing remote attribute with a faulty event connection
sig->siglock->writerOut();
attr->unsubscribe_event(event_id);
sig->siglock->writerIn();
DEBUG_STREAM <<"event_table::"<< __func__<<": unsubscribed... "<< signame << endl;
}
}
catch (Tango::DevFailed &e)
{
// Do nothing
// Unregister failed means Register has also failed
sig->siglock->writerIn();
INFO_STREAM <<"event_table::"<< __func__<<": Exception unsubscribing " << signame << " err=" << e.errors[0].desc << endl;
}
}
if(!stop)
veclock.writerIn();
vector<event>::iterator pos = v_event.begin();
bool found = false;
for (unsigned int i=0 ; i<v_event.size() && !found ; i++, pos++)
{
event *sig = &v_event[i];
if (sig->name==signame)
{
found = true;
if(stop)
{
DEBUG_STREAM <<"event_table::"<<__func__<< ": removing " << signame << endl;
//sig->siglock->writerIn(); //: removed, already locked in event_table::stop
try
{
if(sig->event_id != SUB_ERR)
{
delete sig->event_cb;
}
if(sig->attr)
delete sig->attr;
}
catch (Tango::DevFailed &e)
{
// Do nothing
// Unregister failed means Register has also failed
INFO_STREAM <<"event_table::"<< __func__<<": Exception deleting " << signame << " err=" << e.errors[0].desc << endl;
}
//sig->siglock->writerOut();
DEBUG_STREAM <<"event_table::"<< __func__<<": stopped " << signame << endl;
}
if(!stop)
{
static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->attr_AttributeNumber_read--;
delete sig->siglock;
v_event.erase(pos);
DEBUG_STREAM <<"event_table::"<< __func__<<": removed " << signame << endl;
}
break;
}
}
pos = v_event.begin();
if (!found)
{
for (unsigned int i=0 ; i<v_event.size() && !found ; i++, pos++)
{
event *sig = &v_event[i];
#ifndef _MULTI_TANGO_HOST
if (static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->compare_without_domain(sig->name,signame))
#else
if (!static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->compare_tango_names(sig->name,signame))
#endif
{
found = true;
DEBUG_STREAM <<"event_table::"<<__func__<< ": removing " << signame << endl;
if(stop)
{
sig->siglock->writerIn();
try
{
if(sig->event_id != SUB_ERR)
{
delete sig->event_cb;
}
if(sig->attr)
delete sig->attr;
}
catch (Tango::DevFailed &e)
{
// Do nothing
// Unregister failed means Register has also failed
INFO_STREAM <<"event_table::"<< __func__<<": Exception unsubscribing " << signame << " err=" << e.errors[0].desc << endl;
}
sig->siglock->writerOut();
DEBUG_STREAM <<"event_table::"<< __func__<<": stopped " << signame << endl;
}
if(!stop)
{
static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->attr_AttributeNumber_read--;
delete sig->siglock;
v_event.erase(pos);
DEBUG_STREAM <<"event_table::"<< __func__<<": removed " << signame << endl;
}
break;
}
}
}
if(!stop)
veclock.writerOut();
if (!found)
Tango::Except::throw_exception(
(const char *)"BadSignalName",
"Signal " + signame + " NOT subscribed",
(const char *)"event_table::remove()");
}
// then, update property
/* if(!stop)
{
DEBUG_STREAM <<"event_table::"<< __func__<<": going to increase action... action="<<action<<"++" << endl;
if(action <= UPDATE_PROP)
action++;
//put_signal_property(); //TODO: wakeup thread and let it do it? -> signal()
signal();
}*/
}
void event_table::update_property()
{
DEBUG_STREAM <<"event_table::"<< __func__<<": going to increase action... action="<<action.load()<<"++" << endl;
int expected=NOTHING;
action.compare_exchange_strong(expected, UPDATE_PROP); //if it is NOTHING, then change to UPDATE_PROP
signal();
}
//=============================================================================
/**
* Remove a signal in the list.
*/
//=============================================================================
void event_table::unsubscribe_events()
{
DEBUG_STREAM <<"event_table::"<<__func__<< " entering..."<< endl;
veclock.readerIn();
vector<event> local_signals(v_event);
veclock.readerOut();
for (unsigned int i=0 ; i<local_signals.size() ; i++)
{
event *sig = &local_signals[i];
if (local_signals[i].event_id != SUB_ERR && sig->attr)
{
DEBUG_STREAM <<"event_table::"<<__func__<< " unsubscribe " << sig->name << " id="<<omni_thread::self()->id()<< endl;
try
{
sig->attr->unsubscribe_event(sig->event_id);
DEBUG_STREAM <<"event_table::"<<__func__<< " unsubscribed " << sig->name << endl;
}
catch (Tango::DevFailed &e)
{
// Do nothing
// Unregister failed means Register has also failed
INFO_STREAM <<"event_table::"<<__func__<< " ERROR unsubscribing " << sig->name << " err="<<e.errors[0].desc<< endl;
}
}
}
veclock.writerIn();
for (unsigned int i=0 ; i<v_event.size() ; i++)
{
event *sig = &v_event[i];
sig->siglock->writerIn();
if (v_event[i].event_id != SUB_ERR && sig->attr)
{
delete sig->event_cb;
DEBUG_STREAM <<"event_table::"<<__func__<< " deleted cb " << sig->name << endl;
}
if(sig->attr)
{
delete sig->attr;
DEBUG_STREAM <<"event_table::"<<__func__<< " deleted proxy " << sig->name << endl;
}
sig->siglock->writerOut();
delete sig->siglock;
DEBUG_STREAM <<"event_table::"<<__func__<< " deleted lock " << sig->name << endl;
}
DEBUG_STREAM <<"event_table::"<<__func__<< " ended loop, deleting vector" << endl;
/*for (unsigned int j=0 ; j<signals.size() ; j++, pos++)
{
signals[j].event_id = SUB_ERR;
signals[j].event_conf_id = SUB_ERR;
signals[j].archive_cb = NULL;
signals[j].attr = NULL;
}*/
v_event.clear();
veclock.writerOut();
DEBUG_STREAM <<"event_table::"<< __func__<< ": exiting..."<<endl;
}
//=============================================================================
/**
* Add a new signal.
*/
//=============================================================================
void event_table::add(string &signame, vector<string> contexts)
{
DEBUG_STREAM << "event_table::"<<__func__<< " entering signame=" << signame << endl;
add(signame, contexts, NOTHING, false);
}
//=============================================================================
/**
* Add a new signal.
*/
//=============================================================================
void event_table::add(string &signame, vector<string> contexts, int to_do, bool start)
{
DEBUG_STREAM << "event_table::"<<__func__<<": Adding " << signame << " to_do="<<to_do<<" start="<<(start ? "Y" : "N")<< endl;
{
veclock.readerIn();
event *sig;
// Check if already subscribed
bool found = false;
for (unsigned int i=0 ; i<v_event.size() && !found ; i++)
{
sig = &v_event[i];
found = (sig->name==signame);
}
for (unsigned int i=0 ; i<v_event.size() && !found ; i++)
{
sig = &v_event[i];
found = static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->compare_without_domain(sig->name,signame);
}
veclock.readerOut();
//DEBUG_STREAM << "event_table::"<<__func__<<": signame="<<signame<<" found="<<(found ? "Y" : "N") << " start="<<(start ? "Y" : "N")<< endl;
if (found && !start)
Tango::Except::throw_exception(
(const char *)"BadSignalName",
"Signal " + signame + " already subscribed",
(const char *)"event_table::add()");
event *signal;
if (!found && !start)
{
// on name, split device name and attrib name
string::size_type idx = signame.find_last_of("/");
if (idx==string::npos)
{
Tango::Except::throw_exception(
(const char *)"SyntaxError",
"Syntax error in signal name " + signame,
(const char *)"event_table::add()");
}
signal = new event();
// Build Hdb Signal object
signal->name = signame;
signal->siglock = new(ReadersWritersLock);
signal->devname = signal->name.substr(0, idx);
signal->attname = signal->name.substr(idx+1);
signal->ex_reason = "NOT_connected";
signal->ex_desc = "Attribute not subscribed";
signal->ex_origin = "...";
signal->attr = NULL;
signal->running = false;
signal->stopped = true;
signal->paused = false;
signal->valid = false;
signal->dim_x=0;
signal->dim_y=0;
//DEBUG_STREAM << "event_table::"<<__func__<<": signame="<<signame<<" created signal"<< endl;
}
else if(found && start)
{
signal = sig;
#if 0
signal->siglock->writerIn();
signal->ex_reason = "NOT_connected";
signal->ex_desc = "Attribute not subscribed";
signal->ex_origin = "...";
signal->siglock->writerOut();
#endif
//DEBUG_STREAM << "created proxy to " << signame << endl;
// create Attribute proxy
signal->attr = new Tango::AttributeProxy(signal->name); //TODO: OK out of siglock? accessed only inside the same thread?
DEBUG_STREAM << "event_table::"<<__func__<<": signame="<<signame<<" created proxy"<< endl;
}
signal->event_id = SUB_ERR;
signal->evstate = Tango::ALARM;
signal->isZMQ = false;
signal->okev_counter = 0;
signal->okev_counter_freq = 0;
signal->nokev_counter = 0;
signal->nokev_counter_freq = 0;
signal->first = true;
signal->first_err = true;
clock_gettime(CLOCK_MONOTONIC, &signal->last_ev);
if(found && start)
{
}
//DEBUG_STREAM <<"event_table::"<< __func__<< " created proxy to " << signame << endl;
if (!found && !start)
{
veclock.writerIn();
// Add in vector
v_event.push_back(*signal);
delete signal;
static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->attr_AttributeNumber_read++;
//static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->attr_AttributeStoppedNumber_read++;
veclock.writerOut();
//DEBUG_STREAM << "event_table::"<<__func__<<": signame="<<signame<<" push_back signal"<< endl;
}
else if(found && start)
{
}
int act=action.load();
DEBUG_STREAM <<"event_table::"<< __func__<<": going to increase action... action="<<act<<" += " << to_do << endl;
int expected=NOTHING;
action.compare_exchange_strong(expected, UPDATE_PROP); //if it is NOTHING, then change to UPDATE_PROP
}
DEBUG_STREAM <<"event_table::"<< __func__<<": exiting... " << signame << endl;
signal();
//condition.signal();
}
//=============================================================================
/**
* Subscribe archive event for each signal
*/
//=============================================================================
void event_table::subscribe_events()
{
/*for (unsigned int ii=0 ; ii<v_event.size() ; ii++)
{
event *sig2 = &v_event[ii];
int ret = pthread_rwlock_trywrlock(&sig2->siglock);
DEBUG_STREAM << __func__<<": pthread_rwlock_trywrlock i="<<ii<<" name="<<sig2->name<<" just entered " << ret << endl;
if(ret == 0) pthread_rwlock_unlock(&sig2->siglock);
}*/
//omni_mutex_lock sync(*this);
list<string> l_events;
show(l_events);
DEBUG_STREAM << "event_table::" << __func__ << ": going to subscribe " << v_event.size() << " attributes" << endl;
for (auto it : l_events)
{
veclock.readerIn();
event *sig = get_signal(it);
sig->siglock->readerIn();
string sig_name(sig->name);
if (sig->event_id==SUB_ERR && !sig->stopped)
{
if(!sig->attr)
{
try
{
vector<string> contexts; //TODO!!!
add(sig->name, contexts, NOTHING, true);
}
catch (Tango::DevFailed &e)
{
string ex_reason(e.errors[0].reason);
ex_reason = std::regex_replace(ex_reason, std::regex(R"((\n)|(\r)|(\t)|(\0))"), " "); //match raw string "\n" or "\t" and replace with " "
string ex_desc(e.errors[0].desc);
ex_desc = std::regex_replace(ex_desc, std::regex(R"((\n)|(\r)|(\t)|(\0))"), " "); //match raw string "\n" or "\t" and replace with " "
string ex_origin(e.errors[0].origin);
ex_origin = std::regex_replace(ex_origin, std::regex(R"((\n)|(\r)|(\t)|(\0))"), " "); //match raw string "\n" or "\t" and replace with " "
bei_t ex;
ostringstream o;
o << "Error adding'" \
<< sig->name << "' error=" << ex_desc;
INFO_STREAM << "event_table::subscribe_events: " << o.str() << endl;
sig->ex_reason = ex.ex_reason = ex_reason;
sig->ex_desc = ex.ex_desc = ex_desc;
// sig->ex_desc.erase(std::remove(sig->ex_desc.begin(), sig->ex_desc.end(), '\n'), sig->ex_desc.end());
sig->ex_origin = ex.ex_origin = ex_origin;
sig->ts = ex.ts = gettime();
sig->quality = ex.quality = Tango::ATTR_INVALID;
ex.ev_name = sig->name;
sig->siglock->readerOut();
veclock.readerOut();
//TODO: since event callback not called for this attribute, need to manually trigger do_alarm to update internal structures ?
ex.type = TYPE_TANGO_ERR;
ex.msg=o.str();
try
{//DevFailed for push events
static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->do_alarm(ex);
} catch(Tango::DevFailed & ee)
{
WARN_STREAM << "event_table::"<<__func__<<": " << sig_name << " - EXCEPTION PUSHING EVENTS: " << ee.errors[0].desc << endl;
}
continue;
}
}
sig->event_cb = new EventCallBack(static_cast<AlarmHandler_ns::AlarmHandler *>(mydev));
sig->first = true;
sig->first_err = true;
DEBUG_STREAM << "event_table::"<<__func__<<":Subscribing for " << sig_name << " " << (sig->first ? "FIRST" : "NOT FIRST") << endl;
sig->siglock->readerOut();
int event_id = SUB_ERR;
bool isZMQ = true;
bool err = false;
try
{
event_id = sig->attr->subscribe_event(
Tango::CHANGE_EVENT,
sig->event_cb,
/*stateless=*/false);
/*sig->evstate = Tango::ON;
//sig->first = false; //first event already arrived at subscribe_event
sig->status.clear();
sig->status = "Subscribed";
DEBUG_STREAM << sig->name << " Subscribed" << endl;*/
// Check event source ZMQ/Notifd ?
/*Tango::ZmqEventConsumer *consumer =
Tango::ApiUtil::instance()->get_zmq_event_consumer();*/
isZMQ = true;//(consumer->get_event_system_for_event_id(event_id) == Tango::ZMQ);//TODO: remove
DEBUG_STREAM << sig_name << "(id="<< event_id <<"): Subscribed " << ((isZMQ)? "ZMQ Event" : "NOTIFD Event") << endl;
}
catch (Tango::DevFailed &e)
{
string ex_reason(e.errors[0].reason);
ex_reason = std::regex_replace(ex_reason, std::regex(R"((\n)|(\r)|(\t)|(\0))"), " "); //match raw string "\n" or "\t" and replace with " "
string ex_desc(e.errors[0].desc);
ex_desc = std::regex_replace(ex_desc, std::regex(R"((\n)|(\r)|(\t)|(\0))"), " "); //match raw string "\n" or "\t" and replace with " "
string ex_origin(e.errors[0].origin);
ex_origin = std::regex_replace(ex_origin, std::regex(R"((\n)|(\r)|(\t)|(\0))"), " "); //match raw string "\n" or "\t" and replace with " "
bei_t ex;
ostringstream o;
o << "Event exception for'" \
<< sig_name << "' error=" << ex_desc;
INFO_STREAM <<"event_table::"<<__func__<<": sig->attr->subscribe_event: " << o.str() << endl;
err = true;
//Tango::Except::print_exception(e);
//sig->siglock->writerIn(); //not yet subscribed, no one can modify
sig->ex_reason = ex.ex_reason = ex_reason;
sig->ex_desc = ex.ex_desc = ex_desc;
sig->ex_origin = ex.ex_origin = ex_origin;
sig->event_id = SUB_ERR;
delete sig->event_cb;
sig->ts = ex.ts = gettime();
sig->quality = ex.quality = Tango::ATTR_INVALID;
ex.ev_name = sig->name;
//sig->siglock->writerOut();//not yet subscribed, no one can modify
veclock.readerOut();
//since event callback not called for this attribute, need to manually trigger do_alarm to update interlan structures
ex.type = TYPE_TANGO_ERR;
ex.msg=o.str();
try
{//DevFailed for push events
static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->do_alarm(ex);
} catch(Tango::DevFailed & ee)
{
WARN_STREAM << "event_table::"<<__func__<<": " << ex.ev_name << " - EXCEPTION PUSHING EVENTS: " << ee.errors[0].desc << endl;
}
continue;
}
if(!err)
{
//sig->siglock->writerIn(); //nobody else write event_id and isZMQ
sig->event_id = event_id;
sig->isZMQ = isZMQ;
//sig->siglock->writerOut();//nobody else write event_id and isZMQ
}
}
else
{
sig->siglock->readerOut();
}
veclock.readerOut();
}
initialized = true;
}
void event_table::start(string &signame)
{
DEBUG_STREAM << "event_table::"<<__func__<< " entering signame=" << signame << endl;
ReaderLock lock(veclock);
vector<string> contexts;
for (unsigned int i=0 ; i<v_event.size() ; i++)
{
if (v_event[i].name==signame)
{
v_event[i].siglock->writerIn();
if(!v_event[i].running)
{
if(v_event[i].stopped)
{
try
{
add(signame, contexts, NOTHING, true);
}
catch (Tango::DevFailed &e)
{
//Tango::Except::print_exception(e);
INFO_STREAM << "event_table::start: error adding " << signame <<" err="<< e.errors[0].desc << endl;
v_event[i].ex_reason = e.errors[0].reason;
v_event[i].ex_desc = e.errors[0].desc;
v_event[i].ex_origin = e.errors[0].origin;
/*v_event[i].siglock->writerOut();
return;*/
}
}
v_event[i].running=true;
v_event[i].paused=false;
v_event[i].stopped=false;
}
v_event[i].siglock->writerOut();
return;
}
}
for (unsigned int i=0 ; i<v_event.size() ; i++)
{
#ifndef _MULTI_TANGO_HOST
if (static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->compare_without_domain(v_event[i].name,signame))
#else
if (!static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->compare_tango_names(v_event[i].name,signame))
#endif
{
v_event[i].siglock->writerIn();
if(!v_event[i].running)
{
if(v_event[i].stopped)
{
try
{
add(signame, contexts, NOTHING, true);
}
catch (Tango::DevFailed &e)
{
//Tango::Except::print_exception(e);
INFO_STREAM << "event_table::start: error adding " << signame << endl;
v_event[i].ex_reason = e.errors[0].reason;
v_event[i].ex_desc = e.errors[0].desc;
v_event[i].ex_origin = e.errors[0].origin;
/*signals[i].siglock->writerOut();
return;*/
}
}
v_event[i].running=true;
v_event[i].paused=false;
v_event[i].stopped=false;
}
v_event[i].siglock->writerOut();
return;
}
}
// if not found
Tango::Except::throw_exception(
(const char *)"BadSignalName",
"Signal " + signame + " NOT subscribed",
(const char *)"event_table::start()");
}
void event_table::start_all()
{
ReaderLock lock(veclock);
vector<string> contexts;
for (unsigned int i=0 ; i<v_event.size() ; i++)
{
v_event[i].siglock->writerIn();
if(!v_event[i].running)
{
if(v_event[i].stopped)
{
string signame = v_event[i].name;
try
{
add(signame, contexts, NOTHING, true);
}
catch (Tango::DevFailed &e)
{
//Tango::Except::print_exception(e);
INFO_STREAM << "event_table::start: error adding " << signame <<" err="<< e.errors[0].desc << endl;
v_event[i].ex_reason = e.errors[0].reason;
v_event[i].ex_desc = e.errors[0].desc;
v_event[i].ex_origin = e.errors[0].origin;
/*v_event[i].siglock->writerOut();
return;*/
}
}
v_event[i].running=true;
v_event[i].paused=false;
v_event[i].stopped=false;
}
v_event[i].siglock->writerOut();
}
}
//=============================================================================
//=============================================================================
bool event_table::get_if_stop()
{
//omni_mutex_lock sync(*this);
return stop_it;
}
//=============================================================================
//=============================================================================
void event_table::stop_thread()
{
//omni_mutex_lock sync(*this);
stop_it = true;
signal();
//condition.signal();
}
//=============================================================================
/**
* return number of signals to be subscribed
*/
//=============================================================================
int event_table::nb_sig_to_subscribe()
{
ReaderLock lock(veclock);
int nb = 0;
for (unsigned int i=0 ; i<v_event.size() ; i++)
{
v_event[i].siglock->readerIn();
if (v_event[i].event_id == SUB_ERR && !v_event[i].stopped)
{
nb++;
}
v_event[i].siglock->readerOut();
}
return nb;
}
//=============================================================================
/**
* build a list of signal to set HDB device property
*/
//=============================================================================
void event_table::put_signal_property()
{
int act=action.load();
DEBUG_STREAM << "event_table::"<<__func__<<": entering action=" << act << endl;
if (act>NOTHING)
{
static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->put_signal_property();
int expected=UPDATE_PROP;
action.compare_exchange_strong(expected, NOTHING); //if it is UPDATE_PROP, then change to NOTHING
}
DEBUG_STREAM << "event_table::"<<__func__<<": exiting action=" << action.load() << endl;
}
//=============================================================================
/**
* build a list of signal to set HDB device property
*/
//=============================================================================
void event_table::check_signal_property()
{
int act=action.load();
DEBUG_STREAM << "event_table::"<<__func__<<": entering action=" << act << endl;
if (act>NOTHING)
return;
if (static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->check_signal_property())
{
int expected=NOTHING;
action.compare_exchange_strong(expected, UPDATE_PROP); //if it is NOTHING, then change to UPDATE_PROP
}
DEBUG_STREAM << "event_table::"<<__func__<<": exiting action=" << action.load() << endl;
}
/*
* EventCallBack class methods
*/
EventCallBack::EventCallBack(Tango::DeviceImpl *s):Tango::LogAdapter(s)
{
//e_ptr = NULL;
mydev = s;
}
EventCallBack::~EventCallBack(void)
{
//e_ptr = NULL;
}
void EventCallBack::push_event(Tango::EventData* ev)
{
string temp_name;
bei_t e;
e.ex_reason = string("");
e.ex_desc = string("");
e.ex_origin = string("");
try {
//e.errors = ev->errors;
e.quality = Tango::ATTR_VALID;
//TANGO_LOG << "EVENT="<<ev->attr_name<<" quality="<<e.quality<<endl;
if (!ev->err) {
e.quality = (int)ev->attr_value->get_quality();
#if 0//TANGO_VER >= 711
string ev_name_str(ev->attr_name);
string::size_type pos = ev_name_str.find("tango://");
if (pos != string::npos)
{
pos = ev_name_str.find('/',8);
ev_name_str = ev_name_str.substr(pos + 1);
}
e.ev_name = ev_name_str.c_str();
#else
e.ev_name = ev->attr_name;
#endif
e.ts = ev->attr_value->time;
extract_values(ev->attr_value, e.value, e.value_string, e.type, e.read_size, e.dim_x, e.dim_y);
} else {
e.quality = Tango::ATTR_INVALID;
#if 0//TANGO_VER >= 711
string ev_name_str(ev->attr_name);
string::size_type pos = ev_name_str.find("tango://");
if (pos != string::npos)
{
pos = ev_name_str.find('/',8);
ev_name_str = ev_name_str.substr(pos + 1);
}
temp_name = ev_name_str.c_str() + string(".") + ev->event;
#else
temp_name = ev->attr_name + string(".") + ev->event; //TODO: BUG IN TANGO: part of attr_name after first dot continues in field event
#endif
size_t pos_change = temp_name.find(".change");
if(pos_change != string::npos)
{
temp_name = temp_name.substr(0,pos_change);
}
ostringstream o;
o << "Tango error for " << temp_name << ": " << ev->errors[0].desc.in();
e.ev_name = temp_name;
e.type = TYPE_TANGO_ERR;
//e.ev_name = INTERNAL_ERROR;
//e.type = -1;
e.msg = o.str();
e.msg = std::regex_replace(e.msg, std::regex(R"((\n)|(\r)|(\t)|(\0))"), " "); //match raw string "\n" or "\t" and replace with " "
}
}
catch (string &err) {
e.msg = err + " for event '" + ev->attr_name + "'";
e.ev_name = ev->attr_name;
e.type = TYPE_GENERIC_ERR;
//e.value.i = 0;
e.ts = gettime();
//cerr << o.str() << endl;
} catch(Tango::DevFailed& Terr)
{
ostringstream o;
o << "Event exception for'" \
<< ev->attr_name << "' error=" << Terr.errors[0].desc;
e.ev_name = ev->attr_name;
e.type = TYPE_GENERIC_ERR;
//e.value.i = 0;
e.ts = gettime();
e.msg = o.str();
e.msg = std::regex_replace(e.msg, std::regex(R"((\n)|(\r)|(\t)|(\0))"), " "); //match raw string "\n" or "\t" and replace with " "
}
catch (...) {
ostringstream o;
o << "Generic Event exception for'" \
<< ev->attr_name << "'";
e.ev_name = ev->attr_name;
e.type = TYPE_GENERIC_ERR;
//e.value.i = 0;
e.ts = gettime();
e.msg = o.str();
//cerr << o.str() << endl;
}
static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->evlist.push_back(e);
} /* push_event() */
void EventCallBack::extract_values(Tango::DeviceAttribute *attr_value, vector<double> &val, string &val_string, int &type, int &read_size, long &dim_x, long &dim_y)
{
Tango::DevState stval;
vector<Tango::DevState> v_st;
vector<Tango::DevULong> v_ulo;
vector<Tango::DevUChar> v_uch;
vector<Tango::DevShort> v_sh;
vector<Tango::DevUShort> v_ush;
vector<Tango::DevLong> v_lo;
vector<Tango::DevDouble> v_do;
vector<Tango::DevFloat> v_fl;
vector<Tango::DevBoolean> v_bo;
vector<Tango::DevLong64> v_lo64;
vector<Tango::DevULong64> v_ulo64;
vector<Tango::DevEnum> v_enum;
vector<string> v_string;
val_string = string("");
//Tango::AttributeDimension attr_w_dim;
Tango::AttributeDimension attr_r_dim;
//attr_value->reset_exceptions(Tango::DeviceAttribute::isempty_flag); //disable is_empty exception //commented to throw exceptions if empty
if(!attr_value->is_empty())
{
//attr_w_dim = data->attr_value->get_w_dimension();
attr_r_dim = attr_value->get_r_dimension();
}
else
{
attr_r_dim.dim_x = 0;
//attr_w_dim.dim_x = 0;
attr_r_dim.dim_y = 0;
//attr_w_dim.dim_y = 0;
}
dim_x = attr_r_dim.dim_x;
dim_y = attr_r_dim.dim_y;
read_size = attr_r_dim.dim_x;
if(attr_r_dim.dim_y > 1)
read_size *= attr_r_dim.dim_y;
if (attr_value->get_type() == Tango::DEV_UCHAR) {
attr_value->extract_read(v_uch);
for(vector<Tango::DevUChar>::iterator it = v_uch.begin(); it != v_uch.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_UCHAR;
} else if (attr_value->get_type() == Tango::DEV_SHORT) {
attr_value->extract_read(v_sh);
for(vector<Tango::DevShort>::iterator it = v_sh.begin(); it != v_sh.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_SHORT;
} else if (attr_value->get_type() == Tango::DEV_USHORT) {
attr_value->extract_read(v_ush);
for(vector<Tango::DevUShort>::iterator it = v_ush.begin(); it != v_ush.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_USHORT;
} else if (attr_value->get_type() == Tango::DEV_LONG) {
attr_value->extract_read(v_lo);
for(vector<Tango::DevLong>::iterator it = v_lo.begin(); it != v_lo.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_LONG;
} else if (attr_value->get_type() == Tango::DEV_STATE) {
//*(attr_value) >> v_st; //doesn't work in tango 5
*(attr_value) >> stval;
//v_st.push_back(stval);
//attr_value->extract_read(stval);
//for(vector<Tango::DevState>::iterator it = v_st.begin(); it != v_st.end(); it++)
val.push_back((double)(stval)); //convert all to double
type = Tango::DEV_STATE;
#if 1//TANGO_VER >= 600
} else if (attr_value->get_type() == Tango::DEV_ULONG) {
attr_value->extract_read(v_ulo);
for(vector<Tango::DevULong>::iterator it = v_ulo.begin(); it != v_ulo.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_ULONG;
#endif //TANGO_VER >= 600
} else if (attr_value->get_type() == Tango::DEV_DOUBLE) {
attr_value->extract_read(v_do);
for(vector<Tango::DevDouble>::iterator it = v_do.begin(); it != v_do.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_DOUBLE;
} else if (attr_value->get_type() == Tango::DEV_FLOAT) {
attr_value->extract_read(v_fl);
for(vector<Tango::DevFloat>::iterator it = v_fl.begin(); it != v_fl.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_FLOAT;
} else if (attr_value->get_type() == Tango::DEV_BOOLEAN) {
attr_value->extract_read(v_bo);
for(vector<Tango::DevBoolean>::iterator it = v_bo.begin(); it != v_bo.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_BOOLEAN;
} else if (attr_value->get_type() == Tango::DEV_LONG64) {
attr_value->extract_read(v_lo64);
for(vector<Tango::DevLong64>::iterator it = v_lo64.begin(); it != v_lo64.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_LONG64;
} else if (attr_value->get_type() == Tango::DEV_ULONG64) {
attr_value->extract_read(v_ulo64);
for(vector<Tango::DevULong64>::iterator it = v_ulo64.begin(); it != v_ulo64.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_ULONG64;
} else if (attr_value->get_type() == Tango::DEV_ENUM) {
attr_value->extract_read(v_enum);
for(vector<Tango::DevEnum>::iterator it = v_enum.begin(); it != v_enum.end(); it++)
val.push_back((double)(*it)); //convert all to double
type = Tango::DEV_ENUM;
} else if (attr_value->get_type() == Tango::DEV_STRING) {
attr_value->extract_read(v_string);
val_string = *(v_string.begin()); //TODO: support string spectrum attrbutes
type = Tango::DEV_STRING;
}
else {
ostringstream o;
o << "unknown type";
throw o.str();
}
}
/*void EventCallBack::init(event_list* e)
{
//e_ptr = e;
}*/
Tango::TimeVal gettime(void)
{
struct timeval tv;
struct timezone tz;
Tango::TimeVal t;
gettimeofday(&tv, &tz);
t.tv_sec = tv.tv_sec;
t.tv_usec = tv.tv_usec;
t.tv_nsec = 0;
return t;
}
/* EOF */
/*
* event_table.h
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#ifndef EVENT_TABLE_H
#define EVENT_TABLE_H
#include <iostream>
#include <string>
#include <map>
#include <atomic>
#include <tango/tango.h>
using namespace std;
#define INTERNAL_ERROR "internal_error"
#define TYPE_TANGO_ERR -2
#define TYPE_GENERIC_ERR -3
#define SUB_ERR -1
constexpr int NOTHING = 0;
constexpr int UPDATE_PROP = 1;
class alarm_list {
public:
alarm_list(void) {}
alarm_list(const alarm_list& la) {l_alarm = la.l_alarm;}
~alarm_list(void) {}
void push(string& a);
void pop(const string &a);
void clear(void);
list<string> show(void);
bool empty();
alarm_list& operator=(const alarm_list& other) {if (this != &other) {l_alarm = other.l_alarm;} return *this;}
protected:
list<string> l_alarm;
omni_mutex l;
};
class event;
class event_list;
class event_table;
class EventCallBack;
typedef vector<Tango::DevDouble> value_t;
/*
* basic event type
*/
class event {
public:
string name; /* event name */
string devname;
string attname;
value_t value; /* event value */
string value_string; //added for DevString attributes
int quality{Tango::ATTR_INVALID};
string ex_reason;
string ex_desc;
string ex_origin;
Tango::TimeVal ts; /* event timestamp */
int type, /* attribute data type */
read_size, /* attribute size of read part */
counter, /* molteplicita' */
err_counter; /* molteplicita' errore */
long dim_x, dim_y;
alarm_list m_alarm;
bool valid; //TODO: old
bool first;//TODO: new
bool first_err;//TODO: new
Tango::AttributeProxy *attr;
Tango::DevState evstate;
unsigned int event_id;
bool isZMQ;
EventCallBack *event_cb;
bool running;
bool paused;
bool stopped;
uint32_t okev_counter;
uint32_t okev_counter_freq;
timeval last_okev;
uint32_t nokev_counter;
uint32_t nokev_counter_freq;
timeval last_nokev;
timespec last_ev;
vector<string> filter;
/*
* methods
*/
event(string& s, value_t& v, Tango::TimeVal& t);
event(string& s);
event() {}
~event() {}
//void push_alarm(string& n);
//void pop_alarm(string& n);
// bool event::operator==(const event& e); //TODO: gcc 4 problem??
bool operator==(const event& e);
// bool event::operator==(const string& s); //TODO: gcc 4 problem??
bool operator==(const string& s);
ReadersWritersLock *siglock;
protected:
private:
};
typedef struct basic_event_info_s {
string ev_name;
value_t value;
string value_string;
int quality;
//Tango::DevErrorList errors;
string ex_reason;
string ex_desc;
string ex_origin;
int type;
int read_size;
long dim_x;
long dim_y;
Tango::TimeVal ts;
string msg;
} bei_t;
/*
* here the event callback handler will store the relevant
* events info coming from subscribed events for the
* processing thread
*/
class event_list : public omni_mutex {
public:
event_list(void): empty(this) {}
~event_list(void) {}
void push_back(bei_t& e);
const bei_t pop_front(void);
void clear(void);
list<bei_t> show(void);
size_t size();
protected:
list<bei_t> l_event;
private:
omni_condition empty;
};
/*
* store all the events
*/
class event_table : public Tango::TangoMonitor, public Tango::LogAdapter {
public:
event_table(Tango::DeviceImpl *s);//:Tango::LogAdapter(s) {mydev = s;}
~event_table(void) {stop_thread();}
//void push_back(event e);
void show(list<string> &evl);
void summary(list<string> &evs);
unsigned int size(void);
#if 0
void init_proxy(void) throw(vector<string> &);
void free_proxy(void);
void subscribe(EventCallBack& ecb);
void unsubscribe(void);
#endif
/**
* Add a new signal.
*/
void add(string &signame, vector<string> contexts);
void add(string &signame, vector<string> contexts, int to_do, bool start);
event *get_signal(string signame);
void stop(string &signame);
void remove(string &signame, bool stop);
void subscribe_events();
void unsubscribe_events();
void start(string &signame);
void start_all();
void update_property();
/**
* return number of signals to be subscribed
*/
int nb_sig_to_subscribe();
/**
* build a list of signal to set HDB device property
*/
void put_signal_property();
void check_signal_property();
bool is_initialized();
bool get_if_stop();
void stop_thread();
vector<event> v_event;
ReadersWritersLock veclock;
bool stop_it;
bool initialized;
atomic_int action;
private:
Tango::DeviceImpl *mydev;
}; /* class event_table */
/*
* event callback
*/
class EventCallBack : public Tango::CallBack, public Tango::LogAdapter
{
public:
EventCallBack(Tango::DeviceImpl *s);
~EventCallBack(void);
void push_event(Tango::EventData* ev);
//void init(event_list* e);
void extract_values(Tango::DeviceAttribute *attr_value, vector<double> &val, string &val_string, int &type, int &read_size, long &dim_x, long &dim_y);
private:
//event_list* e_ptr;
Tango::DeviceImpl *mydev;
};
/*
* utility function
*/
Tango::TimeVal gettime(void);
#endif /* EVENT_TABLE_H */
/*
* formula_grammar.h
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#ifndef FORMULA_GRAMMAR_H_
#define FORMULA_GRAMMAR_H_
#include <boost/version.hpp>
//#define BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING //test trying to have node also if formula of type (ev/ev/ev/ev) 27/02/2008
#if BOOST_VERSION < 103600
#ifndef BOOST_SPIRIT_THREADSAFE
#define BOOST_SPIRIT_THREADSAFE
#endif
#endif
#if BOOST_VERSION < 103600
#include <boost/spirit/core.hpp>
#include <boost/spirit/tree/ast.hpp>
//for ast parse trees (in tree_formula)
#include <boost/spirit/symbols/symbols.hpp> //for symbol table
using namespace boost::spirit;
#else
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_ast.hpp>
//for ast parse trees (in tree_formula)
#include <boost/spirit/include/classic_symbols.hpp> //for symbol table
using namespace boost::spirit::classic;
#endif
using namespace std;
/*typedef char const* iterator_t;
typedef node_val_data_factory<unsigned int> factory_t;
typedef tree_match<iterator_t, factory_t> parse_tree_match_t;
typedef tree_parse_info<iterator_t, factory_t> tree_parse_t;
typedef parse_tree_match_t::tree_iterator iter_t;*/
typedef node_val_data<iterator_t, unsigned int> node_t;
typedef tree_node<node_t> tree_node_t;
/*static unsigned int stat_tmp;
static void Save_Stat (unsigned int val)
{
stat_tmp = val;
}
static void Assign_Stat (tree_node_t & node, const iterator_t & begin, const iterator_t & end)
{
node.value.value(stat_tmp);
}*/
static unsigned int stat_tmp;
struct Save_Stat
{
void operator () (unsigned int val) const
{
stat_tmp = val;
}
};
struct Assign_Stat
{
void operator () (tree_node_t & node, const iterator_t & begin, const iterator_t & end) const
{
node.value.value(stat_tmp);
}
};
//TODO: duplicated from alarm.h
enum _AlarmStateEnum {
_NORM,
_UNACK,
_ACKED,
_RTNUN,
_SHLVD,
_DSUPR,
_OOSRV,
_ERROR
} ;
static vector<string> quality_labels = {"ATTR_VALID","ATTR_INVALID","ATTR_ALARM","ATTR_CHANGING","ATTR_WARNING"};
struct formula_grammar : public grammar<formula_grammar>
{
/*formula_t &m_formula;
symbols<unsigned int> sym_grp;
formula_grammar(formula_t &f) \
: m_formula(f)
{
}*/
static const int val_rID = 1;
static const int val_hID = 2;
static const int val_stID = 3;
static const int event_ID = 4;
static const int nameID = 5;
static const int indexID = 6;
static const int funcID = 7;
static const int logical_exprID = 8;
static const int bitwise_exprID = 9;
static const int equality_exprID = 10;
static const int compare_exprID = 11;
static const int add_exprID = 12;
static const int mult_exprID = 13;
static const int expr_atomID = 14;
static const int shift_exprID = 15;
static const int unary_exprID = 16;
static const int val_stringID = 17; //TODO: OK ?
static const int func_dualID = 18;
static const int logical_expr_parenID = 19;
static const int cond_exprID = 20;
static const int exprID = 21;
static const int nonempty_exprID = 22;
static const int val_qualityID = 23;
static const int val_alarm_enum_stID = 24;
static const int propertyID = 25;
static const int index_rangeID = 26;
static const int index_listID = 27;
symbols<unsigned int> tango_states;
symbols<unsigned int> attr_quality;
symbols<unsigned int> alarm_enum_states;
formula_grammar()
{
tango_states.add("ON", (unsigned int)Tango::ON);
tango_states.add("OFF", (unsigned int)Tango::OFF);
tango_states.add("CLOSE", (unsigned int)Tango::CLOSE);
tango_states.add("OPEN", (unsigned int)Tango::OPEN);
tango_states.add("INSERT", (unsigned int)Tango::INSERT);
tango_states.add("EXTRACT", (unsigned int)Tango::EXTRACT);
tango_states.add("MOVING", (unsigned int)Tango::MOVING);
tango_states.add("STANDBY", (unsigned int)Tango::STANDBY);
tango_states.add("FAULT", (unsigned int)Tango::FAULT);
tango_states.add("INIT", (unsigned int)Tango::INIT);
tango_states.add("RUNNING", (unsigned int)Tango::RUNNING);
tango_states.add("ALARM", (unsigned int)Tango::ALARM);
tango_states.add("DISABLE", (unsigned int)Tango::DISABLE);
tango_states.add("UNKNOWN", (unsigned int)Tango::UNKNOWN);
attr_quality.add("ATTR_VALID", (unsigned int)Tango::ATTR_VALID);
attr_quality.add("ATTR_INVALID", (unsigned int)Tango::ATTR_INVALID);
attr_quality.add("ATTR_ALARM", (unsigned int)Tango::ATTR_ALARM);
attr_quality.add("ATTR_CHANGING", (unsigned int)Tango::ATTR_CHANGING);
attr_quality.add("ATTR_WARNING", (unsigned int)Tango::ATTR_WARNING);
alarm_enum_states.add("NORM", (unsigned int)_NORM);
alarm_enum_states.add("UNACK", (unsigned int)_UNACK);
alarm_enum_states.add("ACKED", (unsigned int)_ACKED);
alarm_enum_states.add("RTNUN", (unsigned int)_RTNUN);
alarm_enum_states.add("SHLVD", (unsigned int)_SHLVD);
alarm_enum_states.add("DSUPR", (unsigned int)_DSUPR);
alarm_enum_states.add("OOSRV", (unsigned int)_OOSRV);
alarm_enum_states.add("ERROR", (unsigned int)_ERROR);
}
template <typename ScannerT>
struct definition
{
/* typedef
scanner<
typename ScannerT::iterator_t,
scanner_policies<
typename ScannerT::iteration_policy_t,
ast_match_policy<
typename ScannerT::match_policy_t::iterator_t,
typename ScannerT::match_policy_t::factory_t
>,
typename ScannerT::action_policy_t
>
> ast_scanner;*/
//typedef scanner_list< ScannerT, phrase_scanner_t > scanners; //try using multiple scanners
definition(formula_grammar const& self)
{
symbol
= (alnum_p | '.' | '_' | '-' | '+') //any alpha numeric char plus '.', '_', '-'
;
symbol_attr
= (alnum_p | '_' | '.') - str_p(".normal") - str_p(".alarm") - str_p(".quality") //any alpha numeric char plus '_', '.' for attribute names
;
//------------------------------ALARM NAME--------------------------------------
name
#if BOOST_VERSION < 103600
= token_node_d[
#else
= reduced_node_d[
#endif
lexeme_d[ //needed to ignore "space_p" (skip white spaces) evaluating name
!("tango://" >> (+symbol) >> ':' >> uint_p >> "/") //eventually match FQDN
>> (+symbol) >> '/' >> (+symbol)
>> '/' >> (+symbol) >> '/' >> (+symbol_attr)
]
]
// = repeat_p(3)[(+symbol) >> ch_p('/')] >> (+symbol)
;
index_range
=
( uint_p >> !(discard_node_d[ch_p('-')] >> uint_p)) // n or n-m
;
index_list
= (index_range >> *(discard_node_d[ch_p(',')] >> index_range)) // n-m,k,s-t,..
;
index
= discard_node_d[ch_p('[')] >>
(str_p("-1") | index_list) >>
discard_node_d[ch_p(']')]
;
property
= str_p(".quality")
| str_p(".alarm")
| str_p(".normal")
;
//------------------------------FORMULA--------------------------------------
val_r
#if BOOST_VERSION < 103600
= leaf_node_d[real_p]
#else
= reduced_node_d[real_p]
#endif
;
val_h
#if BOOST_VERSION < 103600
= token_node_d[(str_p("0x") >> hex_p)] //token_node_d here to create only one node with all chars
#else
= reduced_node_d[(str_p("0x") >> hex_p)] //token_node_d here to create only one node with all chars
#endif
;
val_st
=
//access_node_d[self.tango_states[&Save_Stat]][&Assign_Stat] //save Tango::state value in node
access_node_d[self.tango_states[Save_Stat()]][Assign_Stat()] //save Tango::state value in node
;
val_quality
=
//access_node_d[self.attr_quality[&Save_Stat]][&Assign_Stat] //save Tango::state value in node
access_node_d[self.attr_quality[Save_Stat()]][Assign_Stat()] //save Tango::state value in node
;
val_alarm_enum_st
=
//access_node_d[self.alarm_enum_states[&Save_Stat]][&Assign_Stat] //save Tango::state value in node
access_node_d[self.alarm_enum_states[Save_Stat()]][Assign_Stat()] //save Tango::state value in node
;
val_string
#if BOOST_VERSION < 103600
= token_node_d[
#else
= reduced_node_d[
#endif
lexeme_d[ //to conserve white spaces
ch_p('\'')
>> (+(anychar_p - '\'')) //one ore more char except '"'
>> '\''
]
]
// = repeat_p(3)[(+symbol) >> ch_p('/')] >> (+symbol)
;
event_
= name
>> ( *(index)//0 or more indexex
>> !(property) //followed by 0 or 1 property
)
;
/*top = ternary_if;
ternary_if
= logical_expr_paren
>> !(root_node_d[str_p("?")] >> logical_expr_paren >> discard_node_d[ch_p(':')] >> logical_expr_paren)
;*/
cond_expr = logical_expr >> *(root_node_d[ch_p('?')] >> cond_expr >> discard_node_d[ch_p(':')] >> cond_expr);
/*top = logical_expr
;*/
logical_expr
= bitwise_expr
>> *( (root_node_d[str_p("&&")] >> bitwise_expr)
| (root_node_d[str_p("||")] >> bitwise_expr)
)
;
bitwise_expr
= equality_expr
>> *( (root_node_d[ch_p('&')] >> equality_expr)
| (root_node_d[ch_p('|')] >> equality_expr)
| (root_node_d[ch_p('^')] >> equality_expr)
)
;
equality_expr
= compare_expr
>> *( (root_node_d[str_p("==")] >> compare_expr)
| (root_node_d[str_p("!=")] >> compare_expr)
)
;
compare_expr
= shift_expr
>> *( (root_node_d[str_p("<=")] >> add_expr)
| (root_node_d[str_p(">=")] >> add_expr)
| (root_node_d[ch_p('<')] >> add_expr)
| (root_node_d[ch_p('>')] >> add_expr)
)
;
shift_expr
= add_expr
>> *( (root_node_d[str_p("<<")] >> add_expr)
| (root_node_d[str_p(">>")] >> add_expr)
)
;
add_expr
= mult_expr
>> *( (root_node_d[ch_p('+')] >> mult_expr)
| (root_node_d[ch_p('-')] >> mult_expr)
)
;
mult_expr
= unary_expr
>> *( (root_node_d[ch_p('*')] >> unary_expr)
| (root_node_d[ch_p('/')] >> unary_expr)
)
;
unary_expr
= ( expr_atom
| function
| function_dual
| (root_node_d[ch_p('+')] >> expr_atom)
| (root_node_d[ch_p('-')] >> expr_atom)
| (root_node_d[ch_p('!')] >> expr_atom)
// | (root_node_d[ch_p('~')] >> expr_atom) //TODO
)
;
function
= ( root_node_d[str_p("abs")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ?
| root_node_d[str_p("cos")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ?
| root_node_d[str_p("sin")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ?
| root_node_d[str_p("quality")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ?
| root_node_d[str_p("AND")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ?
| root_node_d[str_p("OR")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ?
)
;
function_dual
= ( (root_node_d[str_p("max")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(',')] >> cond_expr >> discard_node_d[ch_p(')')]))
//| (root_node_d[str_p("max")] >> (inner_node_d[ch_p('(') >> discard_node_d[ch_p('(')] >> logical_expr >> discard_node_d[ch_p(')')] >> discard_node_d[ch_p(',')] >> discard_node_d[ch_p('(')] >> logical_expr >> discard_node_d[ch_p(')')] >> ')']))
| (root_node_d[str_p("min")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(',')] >> cond_expr >> discard_node_d[ch_p(')')]))
//| (root_node_d[str_p("min")] >> (inner_node_d[ch_p('(') >> discard_node_d[ch_p('(')] >> logical_expr >> discard_node_d[ch_p(')')] >> discard_node_d[ch_p(',')] >> discard_node_d[ch_p('(')] >> logical_expr >> discard_node_d[ch_p(')')] >> ')']))
| (root_node_d[str_p("pow")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(',')] >> cond_expr >> discard_node_d[ch_p(')')]))
)
//= *( (root_node_d[str_p("max")] >> (inner_node_d[ch_p('(') >> logical_expr_paren >> discard_node_d[ch_p(',')] >> logical_expr_paren >> ')']))
// | (root_node_d[str_p("min")] >> (inner_node_d[ch_p('(') >> logical_expr_paren >> discard_node_d[ch_p(',')] >> logical_expr_paren >> ')']))
//| (root_node_d[str_p("min")] >> (discard_node_d[ch_p('(')] >> logical_expr_paren >> discard_node_d[ch_p(',')] >> logical_expr_paren >> discard_node_d[ch_p(',')]))
//| (root_node_d[str_p("min")] >> (ch_p('(') >> expr_atom >> ch_p(',') >> expr_atom >> ch_p(',')))
//)
;
non_empty_expression = cond_expr;
top = non_empty_expression | epsilon_p;
// top = non_empty_expression;
expr_atom
= //val_h | val_r
event_
| val_h | val_r | val_st | val_quality | val_alarm_enum_st | val_string
//| (inner_node_d[ch_p('(') >> non_empty_expression >> ')'])
| (discard_node_d[ch_p('(')] >> non_empty_expression >> discard_node_d[ch_p(')')])
;
/*logical_expr_paren
= (discard_node_d[ch_p('(')] >> logical_expr >> discard_node_d[ch_p(')')])
| logical_expr
;*/
}
rule<ScannerT> top;
//rule<ScannerT> symbol;
rule<typename lexeme_scanner<ScannerT>::type> symbol; //needed to use lexeme_d in rule name
rule<typename lexeme_scanner<ScannerT>::type> symbol_attr; //needed to use lexeme_d in rule name
rule<ScannerT, parser_context<>, parser_tag<val_rID> > val_r;
rule<ScannerT, parser_context<>, parser_tag<val_hID> > val_h;
rule<ScannerT, parser_context<>, parser_tag<val_stID> > val_st;
rule<ScannerT, parser_context<>, parser_tag<event_ID> > event_;
rule<ScannerT, parser_context<>, parser_tag<logical_exprID> > logical_expr;
rule<ScannerT, parser_context<>, parser_tag<bitwise_exprID> > bitwise_expr;
rule<ScannerT, parser_context<>, parser_tag<shift_exprID> > shift_expr;
rule<ScannerT, parser_context<>, parser_tag<equality_exprID> > equality_expr;
rule<ScannerT, parser_context<>, parser_tag<compare_exprID> > compare_expr;
rule<ScannerT, parser_context<>, parser_tag<add_exprID> > add_expr;
rule<ScannerT, parser_context<>, parser_tag<mult_exprID> > mult_expr;
rule<ScannerT, parser_context<>, parser_tag<unary_exprID> > unary_expr;
rule<ScannerT, parser_context<>, parser_tag<expr_atomID> > expr_atom;
rule<ScannerT, parser_context<>, parser_tag<funcID> > function;
rule<ScannerT, parser_context<>, parser_tag<nameID> > name;
rule<ScannerT, parser_context<>, parser_tag<index_rangeID> > index_range;
rule<ScannerT, parser_context<>, parser_tag<index_listID> > index_list;
rule<ScannerT, parser_context<>, parser_tag<indexID> > index;
rule<ScannerT, parser_context<>, parser_tag<val_stringID> > val_string;
rule<ScannerT, parser_context<>, parser_tag<func_dualID> > function_dual;
rule<ScannerT, parser_context<>, parser_tag<logical_expr_parenID> > logical_expr_paren;
rule<ScannerT, parser_context<>, parser_tag<cond_exprID> > cond_expr;
rule<ScannerT, parser_context<>, parser_tag<nonempty_exprID> > non_empty_expression;
rule<ScannerT, parser_context<>, parser_tag<exprID> > expression;
rule<ScannerT, parser_context<>, parser_tag<val_qualityID> > val_quality;
rule<ScannerT, parser_context<>, parser_tag<val_alarm_enum_stID> > val_alarm_enum_st;
rule<ScannerT, parser_context<>, parser_tag<propertyID> > property;
rule<ScannerT> const&
start() const { return top; }
};
};
#endif /*FORMULA_GRAMMAR_H_*/
/*----- PROTECTED REGION ID(AlarmHandler::main.cpp) ENABLED START -----*/
//=============================================================================
//
// file : main.cpp
//
// description : C++ source for the AlarmHandler 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 : Elettra alarm handler device server
//
// This file is part of Tango device class.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Tango. If not, see <http://www.gnu.org/licenses/>.
//
//
//
//=============================================================================
// This file is generated by POGO
// (Program Obviously used to Generate tango Object)
//=============================================================================
#include <tango/tango.h>
// Check if crash reporting is used.
#if defined(ENABLE_CRASH_REPORT)
# include <crashreporting/crash_report.h>
#else
# define DECLARE_CRASH_HANDLER
# define INSTALL_CRASH_HANDLER
#endif
DECLARE_CRASH_HANDLER;
#ifndef TANGO_LOG
#define TANGO_LOG cout
#endif
int main(int argc,char *argv[])
{
using std::endl;
using std::bad_alloc;
INSTALL_CRASH_HANDLER
try
{
// Initialise the device server
//----------------------------------------
Tango::Util *tg = Tango::Util::init(argc,argv);
// Create the device server singleton
// which will create everything
//----------------------------------------
tg->server_init(false);
// Run the endless loop
//----------------------------------------
TANGO_LOG << "Ready to accept request" << endl;
tg->server_run();
}
catch (bad_alloc &)
{
TANGO_LOG << "Can't allocate memory to store device object !!!" << endl;
TANGO_LOG << "Exiting" << endl;
}
catch (CORBA::Exception &e)
{
Tango::Except::print_exception(e);
TANGO_LOG << "Received a CORBA_Exception" << endl;
TANGO_LOG << "Exiting" << endl;
}
Tango::Util::instance()->server_cleanup();
return(0);
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::main.cpp
/*
* update-thread.cpp
*/
#include "update-thread.h"
static const char __FILE__rev[] = __FILE__ " $Revision: 1.2 $";
/*
* alarm_thread::alarm_thread()
*/
update_thread::update_thread(AlarmHandler_ns::AlarmHandler *p) : p_Alarm(p),Tango::LogAdapter(p)
{
//TANGO_LOG << __FILE__rev << endl;
}
/*
* alarm_thread::~alarm_thread()
*/
update_thread::~update_thread()
{
DEBUG_STREAM << __func__ << "update_thread::~update_thread(): entering!" << endl;
p_Alarm = NULL;
}
/*
* alarm_thread::run()
*/
void update_thread::run(void *)
{
DEBUG_STREAM << __func__ << "update_thread::run(): entering!" << endl;
//printf("update_thread::run(): running...\n");
unsigned int pausasec, pausanano;
pausasec=1;
pausanano = 100000000; //0.1 sec
omni_thread::sleep(pausasec,pausanano);
while (!p_Alarm->abortflag) {
try
{
//omni_thread::sleep(pausasec,pausanano);
abort_sleep(pausasec+(double)pausanano/1000000000);
if(!p_Alarm->abortflag)
p_Alarm->timer_update();
//printf("update_thread::run(): TIMER!!\n");
}
catch(...)
{
INFO_STREAM << "update_thread::run(): catched unknown exception!!";
}
}
DEBUG_STREAM << "update_thread::run(): exiting!" << endl;
} /* update_thread::run() */
void update_thread::abort_sleep(double time)
{
omni_mutex_lock sync(*this);
long time_millis = (long)(time*1000);
int res = wait(time_millis);
}