Newer
Older
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
// Add your own code
alarms.vlock->readerIn();
alarm_container_t::iterator it = alarms.v_alarm.find(argin);
vector<string> info;
if(it == alarms.v_alarm.end())
{
alarms.vlock->readerOut();
ostringstream o;
o << "Alarm '" << argin << "' not found";
DEBUG_STREAM <<__func__ << ": " << o.str() << endl;
Tango::Except::throw_exception( \
(const char*)"NOT FOUND", \
(const char*)o.str().c_str(), \
(const char*)__func__, Tango::ERR);
}
info.push_back(KEY(NAME_KEY)+it->first);
Tango::MultiAttribute *m_attr = get_device_attr();
int attr_ind = m_attr->get_attr_ind_by_name(it->second.attr_name.c_str());
Tango::Attribute &attribute = m_attr->get_attr_by_ind(attr_ind);
ostringstream tmp_val;
vector<string> enum_labels = attribute.get_enum_labels();
if(*(it->second.attr_value) >= 0 && *(it->second.attr_value) < enum_labels.size())
tmp_val << enum_labels[*(it->second.attr_value)];
else
tmp_val << "UNKNOWN_ENUM(" << *(it->second.attr_value) << ")";
info.push_back(KEY(VALUE_KEY)+tmp_val.str());
info.push_back(KEY(FORMULA_KEY)+it->second.formula);
info.push_back(KEY(ATTR_VALUES_KEY)+it->second.attr_values);
ostringstream tmp_qual;
/*size_t siz = formula_grammar.attr_quality.size();
if((it->second.quality) >= 0 && (it->second.quality) < siz)
tmp_qual << formula_grammar.attr_quality[it->second.quality];
*/
tmp_qual << it->second.quality;
info.push_back(KEY(QUALITY_KEY)+tmp_qual.str());
ostringstream tmp_ex;
tmp_ex.str("");
if(it->second.ex_reason.length() > 0 || it->second.ex_desc.length() > 0 || it->second.ex_origin.length() > 0)
tmp_ex << "Reason: '" << it->second.ex_reason << "' Desc: '" << it->second.ex_desc << "' Origin: '" << it->second.ex_origin << "'";
info.push_back(KEY(EXCEPTION_KEY)+tmp_ex.str());
ostringstream tmp;
tmp.str("");
tmp << (it->second.enabled ? "true" : "false");
info.push_back(KEY(ENABLED_KEY)+tmp.str()); //TODO: redundant, information already in attr_value
tmp.str("");
tmp << (it->second.shelved ? "true" : "false");
info.push_back(KEY(SHELVED_KEY)+tmp.str()); //TODO: redundant, information already in attr_value
info.push_back(KEY(ACKNOWLEDGED_KEY)+it->second.ack); //TODO: redundant, information already in attr_value
tmp.str("");
tmp << (it->second.is_new ? "true" : "false");
info.push_back(KEY(AUDIBLE_KEY)+tmp.str());
tmp.str("");
tmp << (it->second.on_counter);
info.push_back(KEY(ON_COUNTER_KEY)+tmp.str());
tmp.str("");
tmp << (it->second.off_counter);
info.push_back(KEY(OFF_COUNTER_KEY)+tmp.str());
tmp.str("");
tmp << (it->second.freq_counter);
info.push_back(KEY(FREQ_COUNTER_KEY)+tmp.str());
tmp.str("");
tmp << (it->second.on_delay);
info.push_back(KEY(ONDELAY_KEY)+tmp.str());
tmp.str("");
tmp << (it->second.on_delay);
info.push_back(KEY(OFFDELAY_KEY)+tmp.str());
info.push_back(KEY(LEVEL_KEY)+it->second.lev);
tmp.str("");
tmp << (it->second.silent_time);
info.push_back(KEY(SILENT_TIME_KEY)+tmp.str());
tmp.str("");
tmp << (it->second.silenced);
info.push_back(KEY(SILENT_TIME_REMAINING_KEY)+tmp.str());
info.push_back(KEY(GROUP_KEY)+it->second.grp2str());
info.push_back(KEY(MESSAGE_KEY)+it->second.msg);
info.push_back(KEY(ON_COMMAND_KEY)+it->second.cmd_name_a);
info.push_back(KEY(OFF_COMMAND_KEY)+it->second.cmd_name_n);
alarms.vlock->readerOut();
argout = new Tango::DevVarStringArray();
argout->length(info.size());
for(size_t i=0; i<info.size(); i++)
(*argout)[i] = Tango::string_dup(info[i].c_str());
/*----- PROTECTED REGION END -----*/ // AlarmHandler::get_alarm_info
return argout;
}
//--------------------------------------------------------

Graziano Scalamera
committed
/**
* Method : AlarmHandler::add_dynamic_commands()

Graziano Scalamera
committed
* Description : Create the dynamic commands if any
* for specified device.
*/
//--------------------------------------------------------
void AlarmHandler::add_dynamic_commands()

Graziano Scalamera
committed
{
/*----- PROTECTED REGION ID(AlarmHandler::add_dynamic_commands) ENABLED START -----*/

Graziano Scalamera
committed
// Add your own code to create and add dynamic commands if any
/*----- PROTECTED REGION END -----*/ // AlarmHandler::add_dynamic_commands

Graziano Scalamera
committed
}
/*----- PROTECTED REGION ID(AlarmHandler::namespace_ending) ENABLED START -----*/

Graziano Scalamera
committed
// Additional Methods
/*
* private methods
*/
void AlarmHandler::load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::load_alarm(): Creating Spirit Parser..." << endl;

Graziano Scalamera
committed
alarm_parse al_gr(alm); // Construct Spirit grammar
alm.name.clear();
alm.attr_name.clear();
alm.quality = Tango::ATTR_INVALID;
alm.ex_reason=string("NOT_SUBSCRIBED");
alm.ex_desc=string("One or more events not subscribed");
alm.ex_origin.clear();

Graziano Scalamera
committed
alm.formula.clear();
alm.msg.clear();
alm.lev.clear();
alm.grp=0;
alm.to_be_evaluated = false;
alm.on_delay = 0;
alm.off_delay = 0;

Graziano Scalamera
committed
alm.silent_time = -1;
alm.silenced = -1;
alm.cmd_name_a.clear();
alm.cmd_dp_a.clear();
alm.cmd_action_a.clear();
alm.send_arg_a = false;
alm.dp_a = NULL;
alm.cmd_name_n.clear();
alm.cmd_dp_n.clear();
alm.cmd_action_n.clear();
alm.send_arg_n = false;
alm.dp_n = NULL;

Graziano Scalamera
committed
evn.clear();
alm.formula_tree =
//boost::spirit::tree_parse_info< std::string::iterator, factory_t> tmp =
ast_parse<factory_t>(alarm_string.begin(), alarm_string.end(), al_gr, space_p); //parse string s with grammar al_gr, skipping white spaces
if (alm.formula_tree.full)
{
std::transform(alm.name.begin(), alm.name.end(), alm.name.begin(), (int(*)(int))tolower); //transform to lowercase
//replace / with __
if(!alm.name.empty())
{
alm.attr_name = alm.name;
size_t start_pos = 0;
string from("/");
string to("__");
while((start_pos = alm.attr_name.find(from, start_pos)) != std::string::npos)
{
alm.attr_name.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}

Graziano Scalamera
committed
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
//std::transform(alm.formula.begin(), alm.formula.end(), alm.formula.begin(), (int(*)(int))tolower); //transform to lowercase: incorrect, state has to be written uppercase
std::transform(alm.lev.begin(), alm.lev.end(), alm.lev.begin(), (int(*)(int))tolower); //transform to lowercase
if(alm.cmd_name_a.length() > 0)
{
const char *c = alm.cmd_name_a.c_str();
int j = 0;
while (*c) {
if (*c == '/')
j++;
if (j < 3)
alm.cmd_dp_a.push_back(*c);
else if (*c != '/')
alm.cmd_action_a.push_back(*c);
c++;
}
}
if(alm.cmd_name_n.length() > 0)
{
const char *c = alm.cmd_name_n.c_str();
int j = 0;
while (*c) {
if (*c == '/')
j++;
if (j < 3)
alm.cmd_dp_n.push_back(*c);
else if (*c != '/')
alm.cmd_action_n.push_back(*c);
c++;
}
}
alm.silenced = (alm.silent_time > 0) ? 0 : -1; //0: can be silenced, -1: cannot be silenced
DEBUG_STREAM << "Parsing succeeded! ->" << alm.name << endl;
find_event_formula(alm.formula_tree,evn); //populate event list found in this formula
ostringstream dbg_msg;
dbg_msg << "In " << alm.name << " Event =";
for (vector<string>::iterator i = evn.begin(); i != evn.end(); i++)
dbg_msg << *i << ", ";
dbg_msg << ends;
DEBUG_STREAM << dbg_msg.str() << endl;
}
else
{
ostringstream o;
o << "AlarmHandler::load_alarm(): Parsing Failed, '" << string(alarm_string.begin(), alm.formula_tree.stop) << "' parsed ok, BUT '" << string(alm.formula_tree.stop, alarm_string.end()) << "' not parsed" << ends; //TODO

Graziano Scalamera
committed
DEBUG_STREAM << o.str() << endl;
Tango::Except::throw_exception( \
(const char*)"Parsing Failed!", \
(const char*)o.str().c_str(), \
(const char*)"AlarmHandler::load_alarm()", Tango::ERR);

Graziano Scalamera
committed
}
alm.ts = gettime();
DEBUG_STREAM << "AlarmHandler::load_alarm(): name = '" << alm.name << "'" << endl;
DEBUG_STREAM << " attr_name = '" << alm.attr_name << "'" << endl;

Graziano Scalamera
committed
DEBUG_STREAM << " formula = '" << alm.formula << "'" << endl;
DEBUG_STREAM << " on_delay = '" << alm.on_delay << "'" << endl;
DEBUG_STREAM << " off_delay = '" << alm.off_delay << "'" << endl;

Graziano Scalamera
committed
DEBUG_STREAM << " msg = '" << alm.msg << "'" << endl;
DEBUG_STREAM << " grp = '" << showbase << hex << alm.grp << "'=" << alm.grp2str() << endl;
DEBUG_STREAM << " silent_time = '" << alm.silent_time << "'" << endl;
DEBUG_STREAM << " silenced = '" << alm.silenced << "'" << endl;
DEBUG_STREAM << " lev = '" << alm.lev << "'" << endl;
DEBUG_STREAM << " action_a = '" << alm.cmd_name_a << "'" << endl;
DEBUG_STREAM << " action_n = '" << alm.cmd_name_n << "'" << endl;
DEBUG_STREAM << " enabled = '" << (alm.enabled ? "1" : "0") << "'" << endl;

Graziano Scalamera
committed
if ((alm.name.empty() == false) && \
(alm.formula.empty() == false) && \
((alm.lev==LEV_LOG)||(alm.lev==LEV_WARNING)|| \
(alm.lev==LEV_FAULT)||(alm.lev.empty() == true))) {
alm.stat = S_NORMAL;
alm.ack = ACK;
alm.done = false;
// alm.grp = GR_DEFAULT;
// alm.lev = LEV_DEFAULT;
} else {
ostringstream o;
o << "AlarmHandler::load_alarm(): syntax error in '" << alarm_string << "'" << ends;

Graziano Scalamera
committed
WARN_STREAM << o.str() << endl;
Tango::Except::throw_exception( \
(const char*)o.str().c_str(), \
(const char*)"", \
(const char*)"AlarmHandler::load_alarm()", Tango::ERR);

Graziano Scalamera
committed
}
if (alarms.exist(alm.name)) {
ostringstream o;
o << "AlarmHandler::load_alarm(): alarm '" << alm.name << "' already exist" << ends;

Graziano Scalamera
committed
WARN_STREAM << o.str() << endl;
Tango::Except::throw_exception( \
(const char*)o.str().c_str(), \
(const char*)o.str().c_str(), \
(const char*)"AlarmHandler::load_alarm()", Tango::ERR);

Graziano Scalamera
committed
}
}
void AlarmHandler::init_alarms(map< string,vector<string> > &alarm_events)

Graziano Scalamera
committed
{
alarms.vlock->readerIn();
if (alarms.v_alarm.empty() == false)
{
for (alarm_container_t::iterator i = alarms.v_alarm.begin(); \
i != alarms.v_alarm.end(); i++)
{
map< string,vector<string> >::iterator f = //looking in map for alarm name as key
// find(alarm_events->begin(), alarm_events->end(), i->name);
alarm_events.find(i->second.name);
if(f == alarm_events.end())
continue; //ERROR: alarm not found in alarm_event map
DEBUG_STREAM << "AlarmHandler::init_alarms(): found Alarm= " << i->second.name << endl;

Graziano Scalamera
committed
for(vector<string>::iterator j = f->second.begin(); \
j != f->second.end(); j++)
{
vector<event>::iterator found = \
find(events->v_event.begin(), events->v_event.end(), (*j));
DEBUG_STREAM << "AlarmHandler::init_alarms(): looking in events table for Event= " << (*j) << endl;

Graziano Scalamera
committed
if (found != events->v_event.end())
{
i->second.insert(found->name);
found->push_alarm(i->second.name);
DEBUG_STREAM << "AlarmHandler::init_alarms(): found Event= " << found->name << " <- Alarm= " << i->second.name << endl;

Graziano Scalamera
committed
//break; ???
} /* if */
} /* for */
}
}
alarms.vlock->readerOut();
}
void AlarmHandler::init_events(vector<string> &evn)

Graziano Scalamera
committed
{
if (evn.empty() == false) {
sort(evn.begin(), evn.end());
vector<string>::iterator new_end = \
unique(evn.begin(), evn.end());
while (evn.end() != new_end) {
evn.pop_back();
}
vector<string>::iterator j = evn.begin();
while (j != evn.end()) {
//TODOevents->push_back(event(*j));

Graziano Scalamera
committed
j++;
}
} /* if */
}
void AlarmHandler::add_alarm(alarm_t& a, bool starting) throw(string&)

Graziano Scalamera
committed
{
alarms.push_back(a);
DEBUG_STREAM << "AlarmHandler::add_alarm(): added alarm '" \

Graziano Scalamera
committed
<< a.name << "'" << endl;
if(!starting)
{
alarm_container_t::iterator italm = alarms.v_alarm.find(a.name);
add_AlarmState_dynamic_attribute(italm->second.attr_name);
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(italm->second.attr_name);
italm->second.attr_value = attr_value;
italm->second.attr_name_formula = italm->second.attr_name + string("Formula");
#if _FORMULA_ATTR
add_AlarmFormula_dynamic_attribute(italm->second.attr_name_formula);
Tango::DevString *attr_value_formula = get_AlarmFormula_data_ptr(italm->second.attr_name_formula);
*attr_value_formula = Tango::string_dup(italm->second.formula.c_str());
italm->second.attr_value_formula = attr_value_formula;
#endif
}

Graziano Scalamera
committed
}
void AlarmHandler::add_event(alarm_t& a, vector<string> &evn) throw(string&)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::add_event(): formula '" << a.formula << "' found " << evn.size() << " events" << endl;

Graziano Scalamera
committed
/*
* get the list of all the events in the formula
*/
for(vector<string>::iterator j = evn.begin(); j != evn.end(); j++)
{
vector<event>::iterator k = \
find(events->v_event.begin(), events->v_event.end(), *j);
if (k == events->v_event.end()) //if not already present
{
string name=*j;
vector<string> context;//TODO
events->add(name, context, UPDATE_PROP, false);//throws exception if already present
}
}

Graziano Scalamera
committed
for (vector<string>::iterator j = evn.begin(); j != evn.end(); j++) {
vector<event>::iterator k = \
find(events->v_event.begin(), events->v_event.end(), *j);
if (k != events->v_event.end()) {
/*
* the event already exist; push alarm name
* into the per-event alarm list
*/
k->push_alarm(a.name);
a.to_be_evaluated = true;
DEBUG_STREAM << "AlarmHandler::add_event(): '" << *j << "' found, added " \

Graziano Scalamera
committed
<< " alarm '" << a.name << "' to list, valid=" << k->valid << endl;
alarms.vlock->readerIn();
alarm_container_t::iterator l = alarms.v_alarm.find(a.name);
if (l != alarms.v_alarm.end())
{
l->second.insert(*j); //insert event name in set<string> (s_event) in alarm_t
}
else
{
WARN_STREAM << "AlarmHandler::add_event(): error inserting event '" << *j << "' in set of alarm '"

Graziano Scalamera
committed
<< a.name << "'" << endl;
}
alarms.vlock->readerOut();
}
else
{
/*
* new event; add to event table
*/
//event e(*j);
//events->push_back(e);

Graziano Scalamera
committed
/*
* update per-alarm event list
*/
DEBUG_STREAM << "AlarmHandler::add_event(): adding '" << *j \

Graziano Scalamera
committed
<< "' to event list of alarm '" << a.name << "'" << endl;
alarms.vlock->readerIn();
alarm_container_t::iterator l = alarms.v_alarm.find(a.name);
if (l != alarms.v_alarm.end())
{
l->second.insert(*j); //insert event name in set<string> in alarm_t
}
else
{
WARN_STREAM << "AlarmHandler::add_event(): error inserting event '" << *j << "' in set of alarm '"

Graziano Scalamera
committed
<< a.name << "'" << endl;
}
alarms.vlock->readerOut();
/*
* now, for the just-added event

Graziano Scalamera
committed
*/
k = find(events->v_event.begin(), events->v_event.end(), *j);
if (k != events->v_event.end())
{
k->push_alarm(a.name);

Graziano Scalamera
committed
//now initialize value of this attribute
try {
Tango::DeviceAttribute attr_value;
attr_value = k->dp->read_attribute(k->attribute);
ecb.extract_values(&attr_value, k->value, k->type);
k->valid = true;
ostringstream msg;
msg << "AlarmHandler::add_event(): initial values of " << k->name << " = ";

Graziano Scalamera
committed
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
for(vector<double>::iterator dd=k->value.begin(); dd!=k->value.end(); dd++)
msg << (*dd) << " ";
msg << ", valid=" << k->valid << ends;
DEBUG_STREAM << msg.str() << endl;
//delete attr_value;
} catch(Tango::DevFailed& e)
{
TangoSys_MemStream out_stream;
out_stream << "Failed to read initial value of " << k->name << " = " << e.errors[0].desc << ends;
k->valid = false;
#if TANGO_VER < 611 //if using subscribe stateless, alarm is not removed if it fails the subscription
k->pop_alarm(a.name); //remove alarm/formula just added to event
//events->v_event.pop_back();
events->v_event.erase(k); //remove event just added to event_table
//delete attr_value;
#endif
throw out_stream.str();
} catch(string & e)
{
TangoSys_MemStream out_stream;
out_stream << "Error reading initial value of " << k->name << " = " << e << ends;
k->pop_alarm(a.name); //remove alarm/formula just added to event
//events->v_event.pop_back();
events->v_event.erase(k); //remove event just added to event_table
//delete attr_value;
throw out_stream.str();
}

Graziano Scalamera
committed
}
}
} //for (vector<string>::iterator j = evn.begin(); ...
for(vector<string>::iterator j = evn.begin(); j != evn.end(); j++)
{

Graziano Scalamera
committed
vector<event>::iterator k = \
find(events->v_event.begin(), events->v_event.end(), *j);
if (k != events->v_event.end()) //if already present

Graziano Scalamera
committed
{
string name=*j;
events->start(name);//throws exception if not found
}
}

Graziano Scalamera
committed
}

Graziano Scalamera
committed
/*
* because called asynchronously by alarm evaluating thread
* will use an alarm to report errors
*/
void AlarmHandler::do_alarm(bei_t& e)

Graziano Scalamera
committed
{
bool changed=true;
int num_changed=0;

Graziano Scalamera
committed
//if (e.name == INTERNAL_ERROR) {
if(e.type == TYPE_TANGO_ERR || e.type == TYPE_GENERIC_ERR)
{

Graziano Scalamera
committed
ostringstream o;
o << e.msg << endl;
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;

Graziano Scalamera
committed
vector<event>::iterator found_ev = \
find(events->v_event.begin(), events->v_event.end(), e.ev_name);
if (found_ev == events->v_event.end())
{
//try to remove network domain and FQDN
string ev_name_str(e.ev_name);
string::size_type pos_slash = ev_name_str.find("tango://");
if (pos_slash != string::npos) //FQDN!!
{
//first remove network domain if any
string::size_type pos_dot = ev_name_str.find(".",8); //look for first . after tango://
string::size_type pos_colon = ev_name_str.find(":",8); //look for first : after tango://
pos_slash = ev_name_str.find('/',8); //look for first / after tango://
if(pos_dot < pos_slash && pos_dot != string::npos && pos_colon != string::npos && pos_slash != string::npos) //dot is in the TANGO_HOST part
{
string ev_name_str_no_domain = ev_name_str.substr(0,pos_dot) + ev_name_str.substr(pos_colon);
//DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event "<< e.ev_name << " not found, trying without domain: " << ev_name_str_no_domain;

Graziano Scalamera
committed
found_ev = \
find(events->v_event.begin(), events->v_event.end(), ev_name_str_no_domain);
}
if (found_ev == events->v_event.end() && pos_slash != string::npos)
{
ev_name_str = ev_name_str.substr(pos_slash + 1);//remove FQDN
//DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event "<< e.ev_name << " not found, trying without fqdn: " << ev_name_str;

Graziano Scalamera
committed
found_ev = \
find(events->v_event.begin(), events->v_event.end(), ev_name_str);
}
}
if (found_ev == events->v_event.end())
{
/*
* shouldn't happen!!!
*/
ostringstream o;
o << "TANGO Error but event '" \
<< e.ev_name << "' not found in event table!" << ends;
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(e.ev_name, gettime(), o.str());
}
}
if(found_ev != events->v_event.end())
{
found_ev->err_counter++;
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
if(e.type == TYPE_TANGO_ERR)
found_ev->ex_reason = string("Event_ERROR");
else
found_ev->ex_reason = string("Alarm_ERROR");
found_ev->ex_desc = o.str();
found_ev->ex_origin = e.ev_name;
//LOOP ALARMS IN WHICH THIS EVENT IS USED
vector<string>::iterator j = found_ev->m_alarm.begin();
while (j != found_ev->m_alarm.end())
{
alarms.vlock->readerIn();
alarm_container_t::iterator it = alarms.v_alarm.find(*j);
if(it != alarms.v_alarm.end())
{
try
{
if(e.type == TYPE_TANGO_ERR)
it->second.ex_reason = found_ev->ex_reason;
else
it->second.ex_reason = found_ev->ex_reason;
it->second.ex_desc = found_ev->ex_desc;
it->second.ex_origin = found_ev->ex_origin;
Tango::DevErrorList errors(1);
errors.length(1);
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str());
Tango::DevFailed except(errors);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": PUSHING EXCEPTION FOR " << it->second.attr_name << " " << it->second.ex_desc << "-" << it->second.ex_reason << "-" << it->second.ex_origin << endl;
push_change_event(it->second.attr_name, &except);
push_archive_event(it->second.attr_name, &except);
}catch(Tango::DevFailed &ex)
{}
}
alarms.vlock->readerOut();
j++;
}

Graziano Scalamera
committed
}
return;
}
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": arrived event=" << e.ev_name << endl;

Graziano Scalamera
committed
formula_res_t res;

Graziano Scalamera
committed
vector<event>::iterator found = \
find(events->v_event.begin(), events->v_event.end(), e.ev_name);
if (found == events->v_event.end())
{
//try to remove network domain and FQDN
string ev_name_str(e.ev_name);
string::size_type pos_slash = ev_name_str.find("tango://");
if (pos_slash != string::npos) //FQDN!!
{
//first remove network domain if any
string::size_type pos_dot = ev_name_str.find(".",8); //look for first . after tango://
string::size_type pos_colon = ev_name_str.find(":",8); //look for first : after tango://
pos_slash = ev_name_str.find('/',8); //look for first / after tango://
if(pos_dot < pos_slash && pos_dot != string::npos && pos_colon != string::npos && pos_slash != string::npos) //dot is in the TANGO_HOST part
{
string ev_name_str_no_domain = ev_name_str.substr(0,pos_dot) + ev_name_str.substr(pos_colon);
//DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event "<< e.ev_name << " not found, trying without domain: " << ev_name_str_no_domain;

Graziano Scalamera
committed
found = \
find(events->v_event.begin(), events->v_event.end(), ev_name_str_no_domain);
}
if (found == events->v_event.end() && pos_slash != string::npos)
{
ev_name_str = ev_name_str.substr(pos_slash + 1);//remove FQDN
//DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event "<< e.ev_name << " not found, trying without fqdn: " << ev_name_str;

Graziano Scalamera
committed
found = \
find(events->v_event.begin(), events->v_event.end(), ev_name_str);
}
}
if (found == events->v_event.end())
{
/*
* shouldn't happen!!!
*/
ostringstream o;
o << "event '" \
<< e.ev_name << "' not found in event table!" << ends;
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
}
}
if (found != events->v_event.end())
{
found->value = e.value;
found->value_string = e.value_string;
found->quality = e.quality;
//found->errors = e.errors;
found->ex_reason = e.ex_reason;
found->ex_desc = e.ex_desc;
found->ex_origin = e.ex_origin;

Graziano Scalamera
committed
found->valid = true;
found->ts = e.ts;
found->type = e.type;
found->err_counter = 0;
vector<string>::iterator j = found->m_alarm.begin();
while (j != found->m_alarm.end())
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": before do_alarm_eval name=" << *j << " ev=" << e.ev_name << endl;
changed = do_alarm_eval(*j, e.ev_name, found->ts);
if(changed)
num_changed++;
j++;
}
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

Graziano Scalamera
committed
{
//attr.set_value(ds, ds_num, 0, false);
push_change_event("alarm",ds, ds_num, 0, false);

Graziano Scalamera
committed
}
push_change_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_change_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_change_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_change_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_change_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_change_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_change_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_change_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_change_event("audibleAlarm",attr_audibleAlarm_read);
push_change_event("alarmSummary",attr_alarmSummary_read);

Graziano Scalamera
committed
push_archive_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_archive_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_archive_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_archive_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_archive_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_archive_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_archive_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_archive_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_archive_event("audibleAlarm",attr_audibleAlarm_read);
push_archive_event("alarmSummary",attr_alarmSummary_read);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event=" << e.ev_name << "NOT FOUND IN EVENT TABLE" << endl;
} /* do_alarm() */
bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ts)
{
bool changed = true;
bool eval_err = false;
formula_res_t res;
//alarm_container_t::iterator it = alarms.v_alarm.find(j->first);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": before lock name=" << alm_name<< " ev=" << ev_name << endl;
alarms.vlock->readerIn();
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": after lock name=" << alm_name<< " ev=" << ev_name << endl;
alarm_container_t::iterator it = alarms.v_alarm.find(alm_name);
if(it != alarms.v_alarm.end())
{

Graziano Scalamera
committed
it->second.freq_counter++;
string tmpname=it->first;
try {
it->second.attr_values = string("");
res = eval_formula(it->second.formula_tree, it->second.attr_values);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": Evaluation of " << it->second.formula << "; result=" << res.value << " quality=" << res.quality << endl;
changed = alarms.update(tmpname, ts, res, it->second.attr_values, it->second.grp2str(), it->second.msg, it->second.formula); //update internal structure and log to db

Graziano Scalamera
committed
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(it->second.attr_name);
if(!it->second.enabled)
*attr_value = _OOSRV;
else if(it->second.shelved && it->second.silenced > 0)
*attr_value = _SHLVD;
else if((it->second.stat == S_NORMAL) && it->second.ack == ACK)
*attr_value = _NORM;
else if((it->second.stat == S_ALARM) && it->second.ack == NOT_ACK)
*attr_value = _UNACK;
else if((it->second.stat == S_ALARM) && it->second.ack == ACK)
*attr_value = _ACKED;
else if((it->second.stat == S_NORMAL) && it->second.ack == NOT_ACK)
*attr_value = _RTNUN;
try
{ //DevFailed for push events
if(it->second.ex_reason.length() == 0)

Graziano Scalamera
committed
{
timeval now;
gettimeofday(&now, NULL);
push_change_event(it->second.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)it->second.quality, 1/*size*/, 0, false);
push_archive_event(it->second.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)it->second.quality, 1/*size*/, 0, false);

Graziano Scalamera
committed
}
else
{
Tango::DevErrorList errors(1);
errors.length(1);
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str());
Tango::DevFailed except(errors);
push_change_event(it->second.attr_name, &except);
push_archive_event(it->second.attr_name, &except);
}
} catch(Tango::DevFailed & ex)
{
WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;
}
} catch(std::out_of_range& ex)
{
eval_err = true;
ostringstream o;
o << tmpname << ": in formula array index out of range!" << ends;
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
try
{ //DevFailed for push events
Tango::DevErrorList errors(1);
errors.length(1);
it->second.ex_reason = string("OUT_OF_RANGE");
it->second.ex_desc = ev_name + ": " + o.str();
it->second.ex_origin = ev_name;
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str());
Tango::DevFailed except(errors);
push_change_event(it->second.attr_name, &except);
push_archive_event(it->second.attr_name, &except);
} catch(Tango::DevFailed & ex)
{
WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;
}
} catch(string & ex)
{
eval_err = true;
ostringstream o;
o << tmpname << ": in formula err=" << ex << ends;
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
try
{ //DevFailed for push events
Tango::DevErrorList errors(1);
errors.length(1);
it->second.ex_reason = string("FORMULA_ERROR");
it->second.ex_desc = ev_name + ": " + o.str();
it->second.ex_origin = ev_name;
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str());
Tango::DevFailed except(errors);
push_change_event(it->second.attr_name, &except);
push_archive_event(it->second.attr_name, &except);
} catch(Tango::DevFailed & ex)
{
WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;

Graziano Scalamera
committed
}
}
if(!eval_err)
it->second.to_be_evaluated = false;
}
else
{
ostringstream o;
//o << j->first << ": not found formula in alarm table" << ends;
o << (alm_name) << ": not found formula in alarm table" << ends;
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
try
{ //DevFailed for push events
Tango::DevErrorList errors(1);
errors.length(1);
it->second.ex_reason = string("NOT_FOUND");
it->second.ex_desc = ev_name + ": " + o.str();
it->second.ex_origin = ev_name;
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str());
Tango::DevFailed except(errors);
push_change_event(it->second.attr_name, &except);
push_archive_event(it->second.attr_name, &except);
} catch(Tango::DevFailed & ex)

Graziano Scalamera
committed
{
WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;

Graziano Scalamera
committed
}
}
alarms.vlock->readerOut();
return changed;
}

Graziano Scalamera
committed
void AlarmHandler::timer_update()

Graziano Scalamera
committed
{
bool changed=true;
//DEBUG_STREAM << "AlarmHandler::timer_update(): entering..." << endl;

Graziano Scalamera
committed
try {
changed=alarms.timer_update();
} catch(string & e)
{
ostringstream o;
o << "Error checking time thresholds and updating alarm status=" << e << ends;
WARN_STREAM << "AlarmHandler::timer_update(): " << o.str() << endl;
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
/* Tango::DevErrorList errors(1);
errors.length(1);
it->second.ex_reason = string("INTERNAL_ERROR");
it->second.ex_desc = o.str();
it->second.ex_origin = string("AlarmHandler::timer_update");
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str());
Tango::DevFailed except(errors);
push_change_event(it->second.attr_name, &except);
push_archive_event(it->second.attr_name, &except);*/

Graziano Scalamera
committed
}
prepare_alarm_attr();
if(!changed)
return;
try
{
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

Graziano Scalamera
committed
{

Graziano Scalamera
committed
//attr.set_value(ds, ds_num, 0, false);
push_change_event("alarm",ds, ds_num, 0, false);

Graziano Scalamera
committed
}
push_change_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_change_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_change_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_change_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_change_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_change_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_change_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_change_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_change_event("audibleAlarm",attr_audibleAlarm_read);
push_change_event("alarmSummary",attr_alarmSummary_read);

Graziano Scalamera
committed
push_archive_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_archive_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_archive_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_archive_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_archive_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_archive_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_archive_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_archive_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_archive_event("audibleAlarm",attr_audibleAlarm_read);
push_archive_event("alarmSummary",attr_alarmSummary_read);

Graziano Scalamera
committed
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << "error pushing alarm change event err=" << e.errors[0].desc;
INFO_STREAM << __func__<<": " << err.str() << endl;
}
}
bool AlarmHandler::remove_alarm(string& s) throw(string&)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": entering alm name=" << s << endl;

Graziano Scalamera
committed
alarms.vlock->writerIn();
alarm_container_t::iterator i = alarms.v_alarm.find(s);
if (i != alarms.v_alarm.end()) {
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": found in table alm name=" << s << endl;

Graziano Scalamera
committed
for (set<string>::iterator j = i->second.s_event.begin(); \
j != i->second.s_event.end(); j++) {
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": looping event =" << *j << endl;

Graziano Scalamera
committed
/*
* for each event into the per-alarm event list find
* the event table entry and remove this alarm from
* per-event alarm list
*/
vector<event>::iterator k = \
find(events->v_event.begin(), events->v_event.end(), *j);
if (k != events->v_event.end()) {
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": found event =" << *j << " in vector events, removing from its alarm list name=" << i->second.name << endl;

Graziano Scalamera
committed
/*
* remove alarm
*/
k->pop_alarm(i->second.name);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": after pop_alarm" << endl;

Graziano Scalamera
committed
if (k->m_alarm.empty()) {
/*
* no more alarms associated to this event, unsubscribe
* and remove from event table
*/
DEBUG_STREAM << "AlarmHandler::remove_alarm(): removing event '" \

Graziano Scalamera
committed
<< k->name << "' from event table" << endl;
try {
events->stop(k->name);
events->remove(k->name, false);

Graziano Scalamera
committed
} catch (...) {
ostringstream o;
o << "unsubscribe_event() failed for " \
<< k->name << ends;
WARN_STREAM << "AlarmHandler::remove_alarm(): " << o.str() << endl;

Graziano Scalamera
committed
alarms.vlock->writerOut();
throw o.str();
//return false;
}

Graziano Scalamera
committed
}
} else {
/*
* shouldn't happen!!!
*/
ostringstream o;
o << "event '" << *j \
<< "' not found in event table" << ends;
WARN_STREAM << "AlarmHandler::remove_alarm(): " << o.str() << endl;

Graziano Scalamera
committed
alarms.vlock->writerOut();
throw o.str();
//return false;
}
} /* for */

Graziano Scalamera
committed
//delete proxy for actions
if(i->second.dp_a)
delete i->second.dp_a;
i->second.dp_a = NULL;
if(i->second.dp_n)
delete i->second.dp_n;
i->second.dp_n = NULL;
try
{
remove_AlarmState_dynamic_attribute(i->second.attr_name);
}
catch(Tango::DevFailed &e)
{
ostringstream o;
o << "AlarmHandler::" << __func__<<": attname '" << i->second.attr_name << "' exception removing attribute err="<<e.errors[0].desc ;
INFO_STREAM << o.str() << endl;
}
#if _FORMULA_ATTR
CORBA::string_free(*(i->second.attr_value_formula));
try
{
remove_AlarmFormula_dynamic_attribute(i->second.attr_name_formula);
}
catch(Tango::DevFailed &e)
{
ostringstream o;
o << "AlarmHandler::" << __func__<<": attname '" << i->second.attr_name_formula << "' exception removing attribute err="<<e.errors[0].desc ;
INFO_STREAM << o.str() << endl;
}

Graziano Scalamera
committed
/*
* remove this alarm from alarm table
*/
alarms.erase(i);

Graziano Scalamera
committed
alarms.vlock->writerOut();
return true;
}
WARN_STREAM << "AlarmHandler::"<<__func__<<": NOT found in table alm name=" << s << endl;

Graziano Scalamera
committed
alarms.vlock->writerOut();
ostringstream o;
o << "alarm '" \
<< s << "' not found in alarm table" << ends;
WARN_STREAM << "AlarmHandler::remove_alarm(): " << o.str() << endl;

Graziano Scalamera
committed
throw o.str();
//return false;
} /* remove_alarm() */