Newer
Older
/*----- PROTECTED REGION END -----*/ // AlarmHandler::stop_new
}
//--------------------------------------------------------
/**
* Command GetAlarmInfo related method
* Description: Returns the complete attribute info as an array of key=value
*

Graziano Scalamera
committed
* @param argin Alarm name followed optionally by wanted key names
* @returns Complete attribute info as an array of key=value
*/
//--------------------------------------------------------

Graziano Scalamera
committed
Tango::DevVarStringArray *AlarmHandler::get_alarm_info(const Tango::DevVarStringArray *argin)
{
Tango::DevVarStringArray *argout;
DEBUG_STREAM << "AlarmHandler::GetAlarmInfo() - " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::get_alarm_info) ENABLED START -----*/

Graziano Scalamera
committed
if(argin->length() < 1)
{
Tango::Except::throw_exception( \
(const char*)"BAD PARAMETERS", \
(const char*)"At least alarm name expected", \
(const char*)__func__, Tango::ERR);
}
// Add your own code
alarms.vlock->readerIn();

Graziano Scalamera
committed
alarm_container_t::iterator it = alarms.v_alarm.find(string((*argin)[0]));
map<string,string> info;
vector<string> complete;
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);
}

Graziano Scalamera
committed
info.insert(make_pair(NAME_KEY,it->first));
complete.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) << ")";

Graziano Scalamera
committed
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 << "\"}";

Graziano Scalamera
committed
info.insert(make_pair(VALUE_KEY,string("ERROR")));
complete.push_back(KEY(VALUE_KEY)+string("ERROR"));

Graziano Scalamera
committed
info.insert(make_pair(FORMULA_KEY,it->second.formula));
complete.push_back(KEY(FORMULA_KEY)+it->second.formula);
info.insert(make_pair(ATTR_VALUES_KEY,tmp_ex.str()));
complete.push_back(KEY(ATTR_VALUES_KEY)+tmp_ex.str());

Graziano Scalamera
committed
}
else
{
info.insert(make_pair(VALUE_KEY,tmp_val.str()));
complete.push_back(KEY(VALUE_KEY)+tmp_val.str());
info.insert(make_pair(FORMULA_KEY,it->second.formula));
complete.push_back(KEY(FORMULA_KEY)+it->second.formula);
info.insert(make_pair(ATTR_VALUES_KEY,it->second.attr_values));
complete.push_back(KEY(ATTR_VALUES_KEY)+it->second.attr_values);
}
try
{
tmp_qual << quality_labels.at(it->second.quality);
} catch(std::out_of_range& ex)
{
tmp_qual << it->second.quality;
}
info.insert(make_pair(QUALITY_KEY,tmp_qual.str()));
complete.push_back(KEY(QUALITY_KEY)+tmp_qual.str());
//#if 0

Graziano Scalamera
committed
tmp << (it->second.enabled ? "1" : "0");
info.insert(make_pair(ENABLED_KEY,tmp.str())); //TODO: redundant, information already in attr_value
complete.push_back(KEY(ENABLED_KEY)+tmp.str()); //TODO: redundant, information already in attr_value

Graziano Scalamera
committed
tmp << (it->second.shelved ? "1" : "0");
info.insert(make_pair(SHELVED_KEY,tmp.str())); //TODO: redundant, information already in attr_value
complete.push_back(KEY(SHELVED_KEY)+tmp.str()); //TODO: redundant, information already in attr_value
tmp.str("");
tmp << ((it->second.ack == "ACK") ? "1" : "0");
info.insert(make_pair(ACKNOWLEDGED_KEY,tmp.str())); //TODO: redundant, information already in attr_value
complete.push_back(KEY(ACKNOWLEDGED_KEY)+tmp.str()); //TODO: redundant, information already in attr_value
//#endif

Graziano Scalamera
committed
tmp << (it->second.is_new ? "1" : "0");
info.insert(make_pair(AUDIBLE_KEY,tmp.str()));
complete.push_back(KEY(AUDIBLE_KEY)+tmp.str());

Graziano Scalamera
committed
if(it->second.stat == S_ALARM)
{
tmp << (it->second.on_counter);
}
else
{
tmp << (it->second.off_counter);
}
info.insert(make_pair(COUNTER_KEY,tmp.str()));
complete.push_back(KEY(COUNTER_KEY)+tmp.str());
tmp.str("");
tmp << (it->second.freq_counter);

Graziano Scalamera
committed
info.insert(make_pair(FREQ_COUNTER_KEY,tmp.str()));
complete.push_back(KEY(FREQ_COUNTER_KEY)+tmp.str());
tmp.str("");
tmp << (it->second.on_delay);

Graziano Scalamera
committed
info.insert(make_pair(ONDELAY_KEY,tmp.str()));
complete.push_back(KEY(ONDELAY_KEY)+tmp.str());
tmp.str("");
tmp << (it->second.on_delay);

Graziano Scalamera
committed
info.insert(make_pair(OFFDELAY_KEY,tmp.str()));
complete.push_back(KEY(OFFDELAY_KEY)+tmp.str());
info.insert(make_pair(LEVEL_KEY,it->second.lev));
complete.push_back(KEY(LEVEL_KEY)+it->second.lev);
tmp.str("");
tmp << (it->second.silent_time);

Graziano Scalamera
committed
info.insert(make_pair(SILENT_TIME_KEY,tmp.str()));
complete.push_back(KEY(SILENT_TIME_KEY)+tmp.str());
tmp.str("");
tmp << (it->second.silenced);

Graziano Scalamera
committed
info.insert(make_pair(SILENT_TIME_REMAINING_KEY,tmp.str()));
complete.push_back(KEY(SILENT_TIME_REMAINING_KEY)+tmp.str());
info.insert(make_pair(GROUP_KEY,it->second.grp2str()));
complete.push_back(KEY(GROUP_KEY)+it->second.grp2str());
tmp.str("");
tmp << "\"" << it->second.msg << "\"";
info.insert(make_pair(MESSAGE_KEY,tmp.str()));
complete.push_back(KEY(MESSAGE_KEY)+tmp.str());
info.insert(make_pair(ON_COMMAND_KEY,it->second.cmd_name_a));
complete.push_back(KEY(ON_COMMAND_KEY)+it->second.cmd_name_a);
info.insert(make_pair(OFF_COMMAND_KEY,it->second.cmd_name_n));
complete.push_back(KEY(OFF_COMMAND_KEY)+it->second.cmd_name_n);
alarms.vlock->readerOut();
argout = new Tango::DevVarStringArray();

Graziano Scalamera
committed
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
if(argin->length() == 1)
{
argout->length(complete.size());
for(size_t i=0; i<complete.size(); i++)
(*argout)[i] = Tango::string_dup(complete[i].c_str());
}
else
{
vector<string> out;
//out.push_back(NAME_KEY + string("=") + it->first);
for(size_t arg_i=0; arg_i < argin->length()-1; arg_i++)
{
map<string,string>::iterator it2 = info.find(string((*argin)[arg_i+1]));
if(it2 != info.end())
{
out.push_back(it2->first + string("=") + it2->second);
}
}
argout->length(out.size()/*+1*/);
vector<string>::iterator it3;
size_t i=0;
for(it3=out.begin(); it3!=out.end(); it3++)
{
(*argout)[i] = Tango::string_dup(it3->c_str());
i++;
}
}
/*----- 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... ->" << alarm_string << 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
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
//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 << ", ";

Graziano Scalamera
committed
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"; //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 << "'";

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";

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
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
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!";
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++;
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
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!";
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++;
}
if(num_changed==0)
{
prepare_alm_mtx->lock();
alarms.vlock->readerIn();
alarm_container_t::iterator ai;
size_t freq_ind = 0;
for (ai = alarms.v_alarm.begin(); ai != alarms.v_alarm.end(); ai++)
{
attr_alarmFrequency_read[freq_ind] = ai->second.freq_counter;
freq_ind++;
}
alarms.vlock->readerOut();
prepare_alm_mtx->unlock();
push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
return;
prepare_alarm_attr();//TODO: frequencyAlarm should be updated anyway
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("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_change_event("alarmAudible",attr_alarmAudible_read);
push_change_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz);
push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_archive_event("alarmAudible",attr_alarmAudible_read);
push_archive_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz);
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())
{
if(ev_name == "FORCED_EVAL" && !it->second.to_be_evaluated)
{
alarms.vlock->readerOut();
return false;
}
if(ev_name != "FORCED_EVAL")
it->second.freq_counter++;
string tmpname=it->first;
try {
res = eval_formula(it->second.formula_tree, it->second.attr_values);
it->second.attr_values.erase(it->second.attr_values.size()-1);
it->second.attr_values += string("}");
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!";
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;
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";
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
#if 0 //TODO: attribute not existing -> cannot notify error pushing exception
try
{ //DevFailed for push events
Tango::DevErrorList errors(1);
errors.length(1);
string ex_reason = string("NOT_FOUND");
string ex_desc = ev_name + ": " + o.str();
string ex_origin = ev_name;
errors[0].desc = CORBA::string_dup(ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(ex_reason.c_str());
errors[0].origin = CORBA::string_dup(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
}

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;
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
}
if(!changed)

Graziano Scalamera
committed
return;
prepare_alarm_attr();//TODO: frequencyAlarm should be updated anyway

Graziano Scalamera
committed
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("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_change_event("alarmAudible",attr_alarmAudible_read);
push_change_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz);
push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);