Newer
Older
if(it == alarms.v_alarm.end())
{
alarms.vlock->readerOut();
ostringstream o;
o << "Alarm '" << string((*argin)[0]) << "' 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("");
ostringstream tmp;
tmp.str("");
tmp << "\"" << it->second.msg << "\"";

Graziano Scalamera
committed
{
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"));
info.insert(make_pair(MESSAGE_KEY,tmp.str()));
complete.push_back(KEY(MESSAGE_KEY)+tmp.str());
info.insert(make_pair(URL_KEY,it->second.url));
complete.push_back(KEY(URL_KEY)+it->second.url);

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(MESSAGE_KEY,tmp.str()));
complete.push_back(KEY(MESSAGE_KEY)+tmp.str());
info.insert(make_pair(URL_KEY,it->second.url));
complete.push_back(KEY(URL_KEY)+it->second.url);

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,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());

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());
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
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
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;
}
//--------------------------------------------------------
/**
* Command ReLoadAll related method
* Description: Re Load all alarms.
*
*/
//--------------------------------------------------------
void AlarmHandler::re_load_all()
{
DEBUG_STREAM << "AlarmHandler::ReLoadAll() - " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::re_load_all) ENABLED START -----*/
// Add your own code
vector<string> tmp_alm_vec;
alarms.get_alarm_list_db(tmp_alm_vec, saved_alarms, savedlock);//holds write locks savedlock
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
for(const auto &it_al : tmp_alm_vec)
{
bool modify_err=false;
try
{
modify((Tango::DevString)it_al.c_str());
}
catch(Tango::DevFailed &e)
{
INFO_STREAM << __func__ << ": error modifying '" << it_al << "' err='" << e.errors[0].desc << "'";
modify_err=true;
}
if(modify_err)
{
try
{
load((Tango::DevString)it_al.c_str());
}
catch(Tango::DevFailed &e)
{
INFO_STREAM << __func__ << ": error loading '" << it_al << "' err='" << e.errors[0].desc << "'";
}
}
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::re_load_all
}
//--------------------------------------------------------

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();
alm.ts_err_delay = gettime();
alm.ts_err_delay.tv_sec -= errorDelay;

Graziano Scalamera
committed
alm.formula.clear();
alm.msg.clear();

Graziano Scalamera
committed
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;
alm.attr_name = std::regex_replace(alm.attr_name, std::regex("/"), "_");

Graziano Scalamera
committed
//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
alm.msg = std::regex_replace(alm.msg, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";"
alm.url = std::regex_replace(alm.url, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";"

Graziano Scalamera
committed
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
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;
}
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
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 << " url = '" << alm.url << "'" << endl;

Graziano Scalamera
committed
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.msg.empty() == false) && \

Graziano Scalamera
committed
((alm.lev==LEV_LOG)||(alm.lev==LEV_WARNING)|| \
(alm.lev==LEV_FAULT)||(alm.lev==LEV_LOWEST)||(alm.lev==LEV_LOW)|| \
(alm.lev==LEV_MEDIUM)||(alm.lev==LEV_HIGH)||(alm.lev==LEV_HIGHEST)||(alm.lev.empty() == true))) {

Graziano Scalamera
committed
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->m_alarm.push(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)

Graziano Scalamera
committed
{
alarms.push_back(a); //take and release writer vlock
DEBUG_STREAM << "AlarmHandler::add_alarm(): added alarm '" \
<< a.name << "' starting=" << (int)starting << endl;
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
*/

Graziano Scalamera
committed
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())
{

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->read_size);

Graziano Scalamera
committed
k->valid = true;
ostringstream msg;
msg << "AlarmHandler::add_event(): initial values of " << k->name << " = ";

Graziano Scalamera
committed
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

Graziano Scalamera
committed
{
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->m_alarm.pop(a.name); //remove alarm/formula just added to event

Graziano Scalamera
committed
//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->m_alarm.pop(a.name); //remove alarm/formula just added to event

Graziano Scalamera
committed
//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(); ...
thread->signal(); //wake up subscibe thread if not waked by events->add
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;
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << e.ev_name << ": " << 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())
{

Graziano Scalamera
committed
found_ev->err_counter++;
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;
found_ev->quality = e.quality;
//LOOP ALARMS IN WHICH THIS EVENT IS USED
list<string> m_alarm=found_ev->m_alarm.show();
string found_ev_ex_reason = found_ev->ex_reason;
string found_ev_ex_desc = found_ev->ex_desc;
string found_ev_ex_origin = found_ev->ex_origin;
events->veclock.readerOut();
list<string>::iterator j = m_alarm.begin();
while (j != m_alarm.end())
{
alarms.vlock->readerIn();
alarm_container_t::iterator it = alarms.v_alarm.find(*j);
if(it != alarms.v_alarm.end())
{
if(it->second.ex_reason.empty() && it->second.ex_desc.empty() && it->second.ex_origin.empty())
it->second.ts_err_delay = gettime(); //first occurrance of this error, now begin to wait for err delay
it->second.ex_reason = found_ev_ex_reason;
it->second.ex_reason = found_ev_ex_reason;
it->second.ex_desc = found_ev_ex_desc;
it->second.ex_origin = found_ev_ex_origin;
if((ts.tv_sec - errorDelay) > it->second.ts_err_delay.tv_sec) //error is present and err delay has passed
{
if(!it->second.error)
it->second.ack = NOT_ACK;//if first error, reset ACK
}
it->second.ack = NOT_ACK;//if first error, reset ACK
}
alarm_t alm = it->second;
alarms.vlock->readerOut();
if(alm.error && alm.enabled && !(alm.shelved && alm.silenced > 0))

Graziano Scalamera
committed
try
{
Tango::DevErrorList errors(1);
errors.length(1);
errors[0].desc = CORBA::string_dup(alm.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(alm.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(alm.ex_origin.c_str());
Tango::DevFailed except(errors);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": PUSHING EXCEPTION FOR " << alm.attr_name << " " << alm.ex_desc << "-" << alm.ex_reason << "-" << alm.ex_origin << endl;
push_change_event(alm.attr_name, &except);
push_archive_event(alm.attr_name, &except);
}catch(Tango::DevFailed &ex)
{}
}
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
else
{
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(alm.attr_name);
if(!alm.enabled)
{
*attr_value = _OOSRV;
}
else if(alm.shelved && alm.silenced > 0)
{
*attr_value = _SHLVD;
}
if(setAlarmQuality)
{
timeval now;
gettimeofday(&now, NULL);
push_change_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,static_cast<Tango::AttrQuality>(alm.quality), 1/*size*/, 0, false);
push_archive_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,static_cast<Tango::AttrQuality>(alm.quality), 1/*size*/, 0, false);
}
else
{
push_change_event(alm.attr_name,(Tango::DevEnum *)attr_value);
push_archive_event(alm.attr_name,(Tango::DevEnum *)attr_value);
}
}
else
{
alarms.vlock->readerOut();
}
j++;
prepare_alarm_attr();//TODO: frequencyAlarm should be updated anyway
#ifdef _ZEROS_ALARM_EMPTY
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);
}
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_change_event("alarmDisabled",attr_alarmDisabled_read, alarmDisabled_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);
push_archive_event("alarmDisabled",attr_alarmDisabled_read, alarmDisabled_sz);

Graziano Scalamera
committed
}
return;
}
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": arrived event=" << e.ev_name << endl;
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->read_size = e.read_size;

Graziano Scalamera
committed
found->err_counter = 0;
list<string> m_alarm=found->m_alarm.show();
Tango::TimeVal ts = found->ts;
events->veclock.readerOut(); //do not hold events->veclock in do_alarm_eval which push events
list<string>::iterator j = m_alarm.begin();
while (j != 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, ts);
if(changed)
num_changed++;
j++;
}
if(num_changed==0)
{
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++;
}
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
#ifdef _ZEROS_ALARM_EMPTY
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_change_event("alarmDisabled",attr_alarmDisabled_read, alarmDisabled_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);
push_archive_event("alarmDisabled",attr_alarmDisabled_read, alarmDisabled_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;
formula_res_t res;
//alarm_container_t::iterator it = alarms.v_alarm.find(j->first);
alarms.vlock->readerIn();
alarm_container_t::iterator it = alarms.v_alarm.find(alm_name);
if(it != alarms.v_alarm.end())
{
string attr_name = it->second.attr_name;
if(ev_name == "FORCED_EVAL" && !it->second.to_be_evaluated)
{
DEBUG_STREAM << __func__ << ": ev_name=" << ev_name << " -> FORCED_EVAL && !it->second.to_be_evaluated -> changed=false" << endl;
alarms.vlock->readerOut();
return false;
}
if(ev_name != "FORCED_EVAL")
it->second.freq_counter++;
string tmpname=it->first;
string ex_reason = it->second.ex_reason;
string ex_desc = it->second.ex_desc;
string ex_origin = it->second.ex_origin;
prev_error = it->second.error;
if(prev_error)
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": before evaluating exception {"<<ex_reason<<","<<ex_desc.length()<<","<<ex_origin<<"}"<<endl;
try {
res = eval_formula(it->second.formula_tree, it->second.attr_values);
it->second.to_be_evaluated = false;
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
changed = changed || prev_error;
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": changed=" << (int)changed << endl;
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(attr_name);

Graziano Scalamera
committed
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;
Tango::AttrQuality quality = (Tango::AttrQuality)it->second.quality;
ex_reason = it->second.ex_reason; //copying again because updated with formula result res.ex_reason in alarms.update
ex_desc = it->second.ex_desc;
ex_origin = it->second.ex_origin;
alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks
try
{ //DevFailed for push events
if(!it->second.error || !it->second.enabled || (it->second.shelved && it->second.silenced > 0))

Graziano Scalamera
committed
{
timeval now;
gettimeofday(&now, NULL);

Graziano Scalamera
committed
if(setAlarmQuality)
{
push_change_event(attr_name,(Tango::DevEnum *)attr_value,now,quality, 1/*size*/, 0, false);
push_archive_event(attr_name,(Tango::DevEnum *)attr_value,now,quality, 1/*size*/, 0, false);
}
else
{
push_change_event(attr_name,(Tango::DevEnum *)attr_value);
push_archive_event(attr_name,(Tango::DevEnum *)attr_value);
}

Graziano Scalamera
committed
}
else
{
Tango::DevErrorList errors(1);
errors.length(1);
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());