diff --git a/src/Alarm.cpp b/src/Alarm.cpp index 6823e919eae748f949041e999708a70c857ab824..5d4a9acc3a70ccb9236506d412c94c9802f0302b 100644 --- a/src/Alarm.cpp +++ b/src/Alarm.cpp @@ -1476,10 +1476,10 @@ void Alarm::load(Tango::DevString argin) #endif string cmd_name_full = alm.cmd_name_a + string(";") + alm.cmd_name_n; alarms.log_alarm_db(TYPE_LOG_DESC_ADD, ts, alm.name, "", "", //add new alarm on log before subscribe event - alm.formula, alm.time_threshold, alm.grp2str(), alm.lev, alm.msg, cmd_name_full, alm.silent_time); //but if it fails remove it from table + alm.formula, alm.on_delay, alm.grp2str(), alm.lev, alm.msg, cmd_name_full, alm.silent_time); //but if it fails remove it from table alarms.save_alarm_conf_db(alm.attr_name, ts, alm.name, "", "", //add new alarm on log before subscribe event - alm.formula, alm.time_threshold, alm.grp2str(), alm.lev, alm.msg, alm.cmd_name_a, alm.cmd_name_n, alm.silent_time); //but if it fails remove it from table + alm.formula, alm.on_delay, alm.off_delay, alm.grp2str(), alm.lev, alm.msg, alm.cmd_name_a, alm.cmd_name_n, alm.silent_time); //but if it fails remove it from table @@ -1762,7 +1762,7 @@ Tango::DevVarStringArray *Alarm::configured(Tango::DevString argin) { ostringstream os; os.clear(); - os << ai->second.ts.tv_sec << "\t" << ai->second.name << "\t" /*TODO<< KEY(FORMULA_KEY)*/ << ai->second.formula << "\t" << KEY(DELAY_KEY) << ai->second.time_threshold << + os << ai->second.ts.tv_sec << "\t" << ai->second.name << "\t" /*TODO<< KEY(FORMULA_KEY)*/ << ai->second.formula << "\t" << KEY(ONDELAY_KEY) << ai->second.on_delay << "\t" << KEY(OFFDELAY_KEY) << ai->second.off_delay << "\t" << KEY(LEVEL_KEY) << ai->second.lev << "\t" << KEY(SILENT_TIME_KEY) << ai->second.silent_time << "\t" << KEY(GROUP_KEY) << ai->second.grp2str() << "\t" << KEY(MESSAGE_KEY) << ai->second.msg << "\t" << KEY(ON_COMMAND_KEY) << ai->second.cmd_name_a << "\t" << KEY(OFF_COMMAND_KEY) << ai->second.cmd_name_n << ends; alarm_filtered.push_back(os.str()); @@ -1996,7 +1996,8 @@ void Alarm::modify(Tango::DevString argin) alm.lev.clear(); alm.grp=0; alm.to_be_evaluated = false; - alm.time_threshold = 0; + alm.on_delay = 0; + alm.off_delay = 0; alm.silent_time = -1; alm.silenced = -1; alm.cmd_name_a.clear(); @@ -2090,7 +2091,8 @@ void Alarm::modify(Tango::DevString argin) i->second.lev = alm.lev; i->second.grp = alm.grp; //i->second.to_be_evaluated = alm.to_be_evaluated; - i->second.time_threshold = alm.time_threshold; + i->second.on_delay = alm.on_delay; + i->second.off_delay = alm.off_delay; i->second.silent_time = alm.silent_time; i->second.silenced = alm.silenced; i->second.cmd_name_a = alm.cmd_name_a; @@ -2119,7 +2121,7 @@ void Alarm::modify(Tango::DevString argin) alarms.log_alarm_db(TYPE_LOG_DESC_UPDATE, ts, alm.name, "", "", - alm.formula, alm.time_threshold, alm.grp2str(), alm.lev, alm.msg, cmd_name_full, alm.silent_time); + alm.formula, alm.on_delay, alm.grp2str(), alm.lev, alm.msg, cmd_name_full, alm.silent_time); //delete proxy for actions if(i->second.dp_a) @@ -2285,7 +2287,8 @@ void Alarm::load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn) alm.lev.clear(); alm.grp=0; alm.to_be_evaluated = false; - alm.time_threshold = 0; + alm.on_delay = 0; + alm.off_delay = 0; alm.silent_time = -1; alm.silenced = -1; alm.cmd_name_a.clear(); @@ -2376,9 +2379,10 @@ void Alarm::load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn) } alm.ts = gettime(); DEBUG_STREAM << "Alarm::load_alarm(): name = '" << alm.name << "'" << endl; - DEBUG_STREAM << " attr_name = '" << alm.attr_name << "'" << endl; + DEBUG_STREAM << " attr_name = '" << alm.attr_name << "'" << endl; DEBUG_STREAM << " formula = '" << alm.formula << "'" << endl; - DEBUG_STREAM << " time_threshold = '" << alm.time_threshold << "'" << endl; + DEBUG_STREAM << " on_delay = '" << alm.on_delay << "'" << endl; + DEBUG_STREAM << " off_delay = '" << alm.off_delay << "'" << endl; DEBUG_STREAM << " msg = '" << alm.msg << "'" << endl; DEBUG_STREAM << " grp = '" << showbase << hex << alm.grp << "'=" << alm.grp2str() << endl; DEBUG_STREAM << " silent_time = '" << alm.silent_time << "'" << endl; @@ -3196,8 +3200,8 @@ void Alarm::set_internal_alarm(string name, Tango::TimeVal t, string msg, unsign if(it->msg.find(name) != string::npos) { existing=true; - if(it->counter < count) - it->counter = count; + if(it->on_counter < count) + it->on_counter = count; break; } } @@ -3220,7 +3224,7 @@ void Alarm::set_internal_alarm(string name, Tango::TimeVal t, string msg, unsign } else it->stat += "*2";*/ - it->counter++; + it->on_counter++; it->msg = msg; //update with the last message } else @@ -3233,7 +3237,7 @@ void Alarm::set_internal_alarm(string name, Tango::TimeVal t, string msg, unsign stat << S_ALARM; else stat << S_ALARM << "*" << count;*/ - alm.counter = count; + alm.on_counter = count; //alm.stat = stat.str(); alm.stat = S_ALARM; alm.ack = NOT_ACK; @@ -3914,7 +3918,8 @@ void Alarm::prepare_alarm_attr() aid->lev = ai->second.lev; aid->is_new = ai->second.is_new; //copy is_new state //ai->second.is_new = 0; //and set state as not more new //12-06-08: StopNew command set it to 0 - aid->counter = ai->second.counter; + aid->on_counter = ai->second.on_counter; + aid->off_counter = ai->second.off_counter; aid->ack = ai->second.ack; //if already acknowledged but has arrived new alarm ack is reset aid->silenced = ai->second.silenced; //update silenced from alarm table (maybe not necessary) aid->silent_time = ai->second.silent_time; //if already alarmed and not saved correctly in properties needed to update @@ -3949,7 +3954,8 @@ void Alarm::prepare_alarm_attr() aid->msg =ai->second.msg; aid->grp = ai->second.grp; aid->lev = ai->second.lev; - aid->counter = ai->second.counter; + aid->on_counter = ai->second.on_counter; + aid->off_counter = ai->second.off_counter; aid->ack = ai->second.ack; //if already acknowledged but has arrived new alarm ack is reset aid->is_new = ai->second.is_new; //copy is_new state aid->silenced = ai->second.silenced; //update silenced from alarm table (maybe not necessary) @@ -4010,7 +4016,7 @@ void Alarm::prepare_alarm_attr() is_new = (aid->is_new && aid->silenced <= 0) ? "NEW" : " "; os << aid->ts.tv_sec << "\t" << aid->ts.tv_usec << "\t" \ << aid->name << "\t" << aid->stat << "\t" << aid->ack \ - << "\t" << aid->counter << "\t" << aid->lev << "\t" << aid->silenced << "\t" << aid->grp2str() << "\t" << aid->msg << "\t" << is_new << ends; + << "\t" << aid->on_counter << "\t" << aid->lev << "\t" << aid->silenced << "\t" << aid->grp2str() << "\t" << aid->msg << "\t" << is_new << ends; tmp_alarm_table.push_back(os.str()); } } @@ -4037,7 +4043,7 @@ void Alarm::prepare_alarm_attr() os.clear(); os << aid->ts.tv_sec << "\t" << aid->ts.tv_usec << "\t" \ << aid->name << "\t" << aid->stat << "\t" << aid->ack \ - << "\t" << aid->counter << "\t" << aid->lev << "\t"<< -1/*silenced*/ <<"\t" << aid->grp2str() << "\t" << aid->msg << "\t "<< ends; //TODO: silenced for internal errors? + << "\t" << aid->on_counter << "\t" << aid->lev << "\t"<< -1/*silenced*/ <<"\t" << aid->grp2str() << "\t" << aid->msg << "\t "<< ends; //TODO: silenced for internal errors? tmp_alarm_table.push_back(os.str()); } } diff --git a/src/alarm_grammar.h b/src/alarm_grammar.h index fd9806c72919465a0ff70187e4b44dfa1cb64759..32810b18f5904f73ee020a9c1f90b2b33131438f 100644 --- a/src/alarm_grammar.h +++ b/src/alarm_grammar.h @@ -69,7 +69,8 @@ #define NAME_KEY "name" #define FORMULA_KEY "formula" -#define DELAY_KEY "time_threshold" +#define ONDELAY_KEY "on_delay" +#define OFFDELAY_KEY "off_delay" #define LEVEL_KEY "level" #define SILENT_TIME_KEY "silent_time" #define GROUP_KEY "group" @@ -194,7 +195,8 @@ struct alarm_parse : public grammar<alarm_parse> ; option - = discard_node_d[time_threshold] | + = discard_node_d[on_delay] | + discard_node_d[off_delay] | discard_node_d[level] | discard_node_d[silent_time] | discard_node_d[group] | @@ -252,12 +254,21 @@ struct alarm_parse : public grammar<alarm_parse> ] >> '"' ; - //---------------------------TIME THRESHOLD---------------------------------- - time_threshold - = discard_node_d[str_p(KEY(DELAY_KEY))] >> + //---------------------------ON DELAY---------------------------------------- + on_delay + = discard_node_d[str_p(KEY(ONDELAY_KEY))] >> (uint_p [ - assign_a(self.m_alarm.time_threshold) + assign_a(self.m_alarm.on_delay) + ] + | epsilon_p) + ; + //---------------------------OFF DELAY--------------------------------------- + off_delay + = discard_node_d[str_p(KEY(OFFDELAY_KEY))] >> + (uint_p + [ + assign_a(self.m_alarm.off_delay) ] | epsilon_p) ; @@ -300,7 +311,7 @@ struct alarm_parse : public grammar<alarm_parse> rule_t expression, event, option; rule<typename lexeme_scanner<ScannerT>::type> symbol; //needed to use lexeme_d in rule name rule<typename lexeme_scanner<ScannerT>::type> symbol_attr_name; //needed to use lexeme_d in rule name - rule_t name, name_alm, val, token, oper, msg, group, level, time_threshold, silent_time, on_command, off_command; + rule_t name, name_alm, val, token, oper, msg, group, level, on_delay, off_delay, silent_time, on_command, off_command; formula_grammar formula; rule_t const& diff --git a/src/alarm_table.cpp b/src/alarm_table.cpp index 57986308bd62db64e56c7c15289ba7ab113a4bb0..dd8ddf5113d1b348dcfa1ffca82d58504cea417e 100644 --- a/src/alarm_table.cpp +++ b/src/alarm_table.cpp @@ -23,16 +23,29 @@ static const char __FILE__rev[] = __FILE__ " $Revision: 1.5 $"; +//TODO: duplicated from alarm.h +enum _AlarmStateEnum { + _NORM, + _UNACK, + _ACKED, + _RTNUN, + _SHLVD, + _DSUPR, + _OOSRV, +} ; + /* * alarm_t class methods */ alarm_t::alarm_t() { grp=0; - counter=0; + on_counter=0; + off_counter=0; stat = S_NORMAL; ack = ACK; - time_threshold = 0; + on_delay = 0; + off_delay = 0; silent_time = -1; cmd_name_a=string(""); cmd_name_n=string(""); @@ -55,7 +68,7 @@ void alarm_t::str2alm(const string &s) istringstream is(s); ostringstream temp_msg; string temp_grp; - is >> ts.tv_sec >> ts.tv_usec >> name >> stat >> ack >> counter >> lev >> silent_time >> temp_grp >> msg; //stop at first white space in msg + is >> ts.tv_sec >> ts.tv_usec >> name >> stat >> ack >> on_counter >> lev >> silent_time >> temp_grp >> msg; //stop at first white space in msg temp_msg << is.rdbuf(); //read all remaining characters as msg msg += temp_msg.str(); str2grp(temp_grp); @@ -66,7 +79,7 @@ string alarm_t::alm2str(void) ostringstream os; os.clear(); os << ts.tv_sec << "\t" << ts.tv_usec << "\t" << name << "\t" \ - << stat << "\t" << ack << "\t" << counter << "\t" << lev << "\t" << silent_time << "\t" << grp2str() << "\t" << msg << ends; + << stat << "\t" << ack << "\t" << on_counter << "\t" << lev << "\t" << silent_time << "\t" << grp2str() << "\t" << msg << ends; return(os.str()); } @@ -367,16 +380,22 @@ bool alarm_table::update(const string& alm_name, Tango::TimeVal ts, formula_res_ found->second.ex_reason = res.ex_reason; found->second.ex_desc = res.ex_desc; found->second.ex_origin = res.ex_origin; - bool status_time_threshold; - if(found->second.time_threshold > 0) //if enabled time threshold - status_time_threshold = ((int)(res.value)) && (found->second.counter >= 1) && ((ts.tv_sec - found->second.time_threshold) > found->second.ts_time_threshold.tv_sec); //formula gives true and time threshold is passed + bool status_on_delay; + if(found->second.on_delay > 0) //if enabled on delay + status_on_delay = ((int)(res.value)) && (found->second.on_counter >= 1) && ((ts.tv_sec - found->second.on_delay) > found->second.ts_on_delay.tv_sec); //formula gives true and on delay has passed + else + status_on_delay = (int)(res.value); + bool status_off_delay; + if(found->second.off_delay > 0) //if enabled off delay + status_off_delay = (!(int)(res.value)) && (found->second.off_counter >= 1) && ((ts.tv_sec - found->second.off_delay) > found->second.ts_off_delay.tv_sec); //formula gives false and off delay has passed else - status_time_threshold = (int)(res.value); + status_off_delay = !(int)(res.value); + //if status changed: - // - from S_NORMAL to S_ALARM considering also time threshold + // - from S_NORMAL to S_ALARM considering also on delay //or - // - from S_ALARM to S_NORMAL - if((status_time_threshold && (found->second.stat == S_NORMAL)) || (!(int)(res.value) && (found->second.stat == S_ALARM))) + // - from S_ALARM to S_NORMAL considering also off delay + if((status_on_delay && (found->second.stat == S_NORMAL)) || (status_off_delay && (found->second.stat == S_ALARM))) { ret_changed=true; a.type_log = TYPE_LOG_STATUS; @@ -487,20 +506,28 @@ bool alarm_table::update(const string& alm_name, Tango::TimeVal ts, formula_res_ } } } - if (status_time_threshold) { + if (status_on_delay) { found->second.stat = S_ALARM; //found->second.ack = NOT_ACK; } + else if (status_off_delay) { + found->second.stat = S_NORMAL; + } + if((int)(res.value)) { - found->second.counter++; + found->second.on_counter++; + found->second.off_counter = 0; } else { - found->second.stat = S_NORMAL; - found->second.counter = 0; + found->second.on_counter = 0; + found->second.off_counter++; } - if(found->second.counter == 1) - found->second.ts_time_threshold = gettime(); //first occurrance of this alarm, now begin to wait for time threshold - if(found->second.counter >= 1) - found->second.attr_values_time_threshold = attr_values; //save last attr_values to be used in timer_update if this alarm pass over time threshold + + found->second.attr_values_delay = attr_values; //save last attr_values to be used in timer_update if this alarm pass over on or off delay + + if(found->second.on_counter == 1) + found->second.ts_on_delay = gettime(); //first occurrance of this alarm, now begin to wait for on delay + if(found->second.off_counter == 1) + found->second.ts_off_delay = gettime(); //first occurrance of back to normal, now begin to wait for off delay //found->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts everytime } else { @@ -533,14 +560,20 @@ bool alarm_table::timer_update() #endif for(alarm_container_t::iterator i = v_alarm.begin(); i != v_alarm.end(); i++) { - bool status_time_threshold; - if(i->second.time_threshold > 0) //if enabled time threshold - status_time_threshold = (i->second.counter >= 1) && ((ts.tv_sec - i->second.time_threshold) > i->second.ts_time_threshold.tv_sec); //waiting for threshold and time threshold is passed - else - continue; //if not enabled time threshold, nothing to do in timer + bool status_on_delay; + bool status_off_delay; + if(i->second.on_delay == 0 && i->second.off_delay == 0) + continue; //if not enabled on or off delay, nothing to do in timer + if(i->second.on_delay > 0) //if enabled on delay + status_on_delay = (i->second.on_counter >= 1) && ((ts.tv_sec - i->second.on_delay) > i->second.ts_on_delay.tv_sec); //waiting for on delay has passed + if(i->second.off_delay > 0) //if enabled off delay + status_off_delay = (i->second.off_counter >= 1) && ((ts.tv_sec - i->second.off_delay) > i->second.ts_off_delay.tv_sec); //waiting for off delay has passed - //if status changed from S_NORMAL to S_ALARM considering also time threshold - if(status_time_threshold && (i->second.stat == S_NORMAL)) + //if status changed: + // - from S_NORMAL to S_ALARM considering also on delay + //or + // - from S_ALARM to S_NORMAL considering also off delay + if(status_on_delay && (i->second.stat == S_NORMAL) || (status_off_delay && (i->second.stat == S_ALARM))) { ret_changed = true; if(i->second.silenced > 0) @@ -559,59 +592,117 @@ bool alarm_table::timer_update() a.name = i->second.name; a.time_s = ts.tv_sec; a.time_us = ts.tv_usec; - a.status = S_ALARM; + a.status = (status_on_delay) ? S_ALARM : S_NORMAL; //a.level = found->second.lev; - i->second.ack = NOT_ACK; //if changing from NORMAL to ALARM -> NACK + if(status_on_delay) + i->second.ack = NOT_ACK; //if changing from NORMAL to ALARM -> NACK a.ack = i->second.ack; - a.values = i->second.attr_values_time_threshold; + a.values = i->second.attr_values_delay; logloop->log_alarm_db(a); i->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts only if status changed - - i->second.is_new = 1; //here set this alarm as new, read attribute set it to 0 //12-06-08: StopNew command set it to 0 - if(i->second.dp_a && ((ts.tv_sec - startup_complete.tv_sec) > 10)) + if(status_on_delay) { - /*try { - long call_id; + i->second.is_new = 1; //here set this alarm as new, read attribute set it to 0 //12-06-08: StopNew command set it to 0 + if(i->second.dp_a && ((ts.tv_sec - startup_complete.tv_sec) > 10)) + { + /*try { + long call_id; + ostringstream tmp; + tmp << i->second.name << ";" << i->second.attr_values_on_delay; + Tango::DevString str = CORBA::string_dup(tmp.str().c_str()); + Tango::DeviceData Din; + Din << str; + CORBA::string_free(str); + //i->second.dp_a->ping(); + cmdloop->mutex_dp->lock(); + //call_id = i->second.dp_a->command_inout_asynch(i->second.cmd_action_a, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer + call_id = i->second.dp_a->command_inout_asynch(i->second.cmd_action_a, Din); + cmdloop->mutex_dp->unlock(); + LOG_STREAM << gettime().tv_sec << " alarm_table::timer_update() executed action: " << i->second.cmd_name_a << " !!!" << endl; + cmd_t arg; + arg.cmd_id = call_id; + arg.dp_add = (long)i->second.dp_a; + arg.arg_s = i->second.cmd_name_a; + cmdloop->list.push_back(arg); + } catch(Tango::DevFailed e) + { + string err(e.errors[0].desc); + if(err.find("is not yet arrived") == string::npos) //TODO: change this!! + out_stream << "Failed to execute action " << i->second.cmd_name_a << ", err=" << e.errors[0].desc << ends; + //LOG_STREAM << "alarm_table::timer_update() ERROR: " << out_stream.str() << endl; + }*/ ostringstream tmp; - tmp << i->second.name << ";" << i->second.attr_values_time_threshold; - Tango::DevString str = CORBA::string_dup(tmp.str().c_str()); - Tango::DeviceData Din; - Din << str; - CORBA::string_free(str); - //i->second.dp_a->ping(); - cmdloop->mutex_dp->lock(); - //call_id = i->second.dp_a->command_inout_asynch(i->second.cmd_action_a, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer - call_id = i->second.dp_a->command_inout_asynch(i->second.cmd_action_a, Din); - cmdloop->mutex_dp->unlock(); - LOG_STREAM << gettime().tv_sec << " alarm_table::timer_update() executed action: " << i->second.cmd_name_a << " !!!" << endl; + string tmp_attr_val = i->second.attr_values_delay; + replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ','); + string tmp_msg = i->second.msg; + replace(tmp_msg.begin(), tmp_msg.end(), ';' , ','); + tmp << "name=" << i->second.name << ";groups=" << i->second.grp2str() << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<i->second.formula; cmd_t arg; - arg.cmd_id = call_id; + arg.cmd_id = CMD_COMMAND; arg.dp_add = (long)i->second.dp_a; - arg.arg_s = i->second.cmd_name_a; - cmdloop->list.push_back(arg); - } catch(Tango::DevFailed e) + arg.arg_s1 = tmp.str(); + arg.arg_s2 = i->second.cmd_action_a; + arg.arg_s3 = i->second.cmd_name_a; + arg.arg_b = i->second.send_arg_a; + cmdloop->list.push_back(arg); + } + } + else if(status_off_delay) + { + if(i->second.dp_a && ((ts.tv_sec - startup_complete.tv_sec) > 10)) { - string err(e.errors[0].desc); - if(err.find("is not yet arrived") == string::npos) //TODO: change this!! - out_stream << "Failed to execute action " << i->second.cmd_name_a << ", err=" << e.errors[0].desc << ends; - //LOG_STREAM << "alarm_table::timer_update() ERROR: " << out_stream.str() << endl; - }*/ - ostringstream tmp; - string tmp_attr_val = i->second.attr_values_time_threshold; - replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ','); - string tmp_msg = i->second.msg; - replace(tmp_msg.begin(), tmp_msg.end(), ';' , ','); - tmp << "name=" << i->second.name << ";groups=" << i->second.grp2str() << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<i->second.formula; - cmd_t arg; - arg.cmd_id = CMD_COMMAND; - arg.dp_add = (long)i->second.dp_a; - arg.arg_s1 = tmp.str(); - arg.arg_s2 = i->second.cmd_action_a; - arg.arg_s3 = i->second.cmd_name_a; - arg.arg_b = i->second.send_arg_a; - cmdloop->list.push_back(arg); + /*try { + long call_id; + ostringstream tmp; + tmp << i->second.name << ";" << i->second.attr_values_off_delay; + Tango::DevString str = CORBA::string_dup(tmp.str().c_str()); + Tango::DeviceData Din; + Din << str; + CORBA::string_free(str); + //i->second.dp_n->ping(); + cmdloop->mutex_dp->lock(); + //call_id = i->second.dp_n->command_inout_asynch(i->second.cmd_action_n, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer + call_id = i->second.dp_n->command_inout_asynch(i->second.cmd_action_n, Din); + cmdloop->mutex_dp->unlock(); + LOG_STREAM << gettime().tv_sec << " alarm_table::timer_update() executed action: " << i->second.cmd_name_n << " !!!" << endl; + cmd_t arg; + arg.cmd_id = call_id; + arg.dp_add = (long)i->second.dp_n; + arg.arg_s = i->second.cmd_name_n; + cmdloop->list.push_back(arg); + } catch(Tango::DevFailed e) + { + string err(e.errors[0].desc); + if(err.find("is not yet arrived") == string::npos) //TODO: change this!! + out_stream << "Failed to execute action " << i->second.cmd_name_n << ", err=" << e.errors[0].desc << ends; + //LOG_STREAM << "alarm_table::timer_update() ERROR: " << out_stream.str() << endl; + }*/ + ostringstream tmp; + string tmp_attr_val = i->second.attr_values_delay; + replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ','); + string tmp_msg = i->second.msg; + replace(tmp_msg.begin(), tmp_msg.end(), ';' , ','); + tmp << "name=" << i->second.name << ";groups=" << i->second.grp2str() << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<i->second.formula; + cmd_t arg; + arg.cmd_id = CMD_COMMAND; + arg.dp_add = (long)i->second.dp_n; + arg.arg_s1 = tmp.str(); + arg.arg_s2 = i->second.cmd_action_n; + arg.arg_s3 = i->second.cmd_name_n; + arg.arg_b = i->second.send_arg_n; + cmdloop->list.push_back(arg); + } } - *(i->second.attr_value) = true; + + //TODO: if not _SHLVD, _DSUPR, _OOSRV + if((status_off_delay) && i->second.ack == ACK) + *(i->second.attr_value) = _NORM; + else if((status_on_delay) && i->second.ack == NOT_ACK) + *(i->second.attr_value) = _UNACK; + else if((status_on_delay) && i->second.ack == ACK) + *(i->second.attr_value) = _ACKED; + else if((status_off_delay) && i->second.ack == NOT_ACK) + *(i->second.attr_value) = _RTNUN; try { if(i->second.ex_reason.length() == 0) @@ -636,9 +727,12 @@ bool alarm_table::timer_update() } catch(Tango::DevFailed &e) {} } - if (status_time_threshold) { + + if (status_on_delay) { i->second.stat = S_ALARM; - //found->second.ack = NOT_ACK; + } + else if (status_off_delay) { + i->second.stat = S_NORMAL; } //found->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts everytime } @@ -783,13 +877,14 @@ void alarm_table::log_alarm_db(unsigned int type, Tango::TimeVal ts, string name } void alarm_table::save_alarm_conf_db(string att_name, Tango::TimeVal ts, string name, string status, string ack, - string formula, unsigned int time_threshold, string grp, string lev, string msg, string cmd_a, string cmd_n, int silent_time, vector<string> alm_list) + string formula, unsigned int on_delay, unsigned int off_delay, string grp, string lev, string msg, string cmd_a, string cmd_n, int silent_time, vector<string> alm_list) { // We want to put properties for attribute "att_name" Tango::DbDatum dbd_att_name(att_name); Tango::DbDatum dbd_name(NAME_KEY); Tango::DbDatum dbd_formula(FORMULA_KEY); - Tango::DbDatum dbd_time_threshold(DELAY_KEY); + Tango::DbDatum dbd_on_delay(ONDELAY_KEY); + Tango::DbDatum dbd_off_delay(OFFDELAY_KEY); Tango::DbDatum dbd_level(LEVEL_KEY); Tango::DbDatum dbd_silence_time(SILENT_TIME_KEY); //TODO: silent_time Tango::DbDatum dbd_group(GROUP_KEY); @@ -801,7 +896,8 @@ void alarm_table::save_alarm_conf_db(string att_name, Tango::TimeVal ts, string dbd_att_name << 9; // Eigth properties for attribute "att_name" dbd_name << name; dbd_formula << formula; - dbd_time_threshold << time_threshold; + dbd_on_delay << on_delay; + dbd_off_delay << off_delay; dbd_level << lev; dbd_silence_time << silent_time; dbd_group << grp; @@ -812,7 +908,8 @@ void alarm_table::save_alarm_conf_db(string att_name, Tango::TimeVal ts, string db_data.push_back(dbd_att_name); db_data.push_back(dbd_name); db_data.push_back(dbd_formula); - db_data.push_back(dbd_time_threshold); + db_data.push_back(dbd_on_delay); + db_data.push_back(dbd_off_delay); db_data.push_back(dbd_level); db_data.push_back(dbd_silence_time); db_data.push_back(dbd_group); @@ -860,7 +957,8 @@ void alarm_table::get_alarm_list_db(vector<string> &al_list) i++; string alm_name; string alm_formula; - string alm_time_threshold("0"); + string alm_on_delay("0"); + string alm_off_delay("0"); string alm_level; string alm_silence_time("-1"); string alm_group; @@ -875,8 +973,10 @@ void alarm_table::get_alarm_list_db(vector<string> &al_list) db_data[i] >> alm_name; else if (prop_name == FORMULA_KEY) db_data[i] >> alm_formula; - else if (prop_name == DELAY_KEY) - db_data[i] >> alm_time_threshold; + else if (prop_name == ONDELAY_KEY) + db_data[i] >> alm_on_delay; + else if (prop_name == OFFDELAY_KEY) + db_data[i] >> alm_off_delay; else if (prop_name == LEVEL_KEY) db_data[i] >> alm_level; else if (prop_name == SILENT_TIME_KEY) @@ -900,7 +1000,8 @@ void alarm_table::get_alarm_list_db(vector<string> &al_list) stringstream alm; alm << alm_name << "\t" << /*TODO: KEY(FORMULA_KEY)<<*/alm_formula << "\t" << - KEY(DELAY_KEY)<<alm_time_threshold << "\t" << + KEY(ONDELAY_KEY)<<alm_on_delay << "\t" << + KEY(OFFDELAY_KEY)<<alm_off_delay << "\t" << KEY(LEVEL_KEY)<< alm_level << "\t" << KEY(SILENT_TIME_KEY)<<alm_silence_time << "\t" << KEY(GROUP_KEY)<< alm_group << "\t" << diff --git a/src/alarm_table.h b/src/alarm_table.h index 062648dea5184712c19029fb9db7d1fd17946a76..3383184a94bd15fd1bad4da56b875f16e0443f55 100644 --- a/src/alarm_table.h +++ b/src/alarm_table.h @@ -268,7 +268,8 @@ class alarm_t { Tango::TimeVal ts; string stat, ack; - unsigned int counter; + unsigned int on_counter; + unsigned int off_counter; tree_parse_info_t formula_tree; @@ -281,13 +282,15 @@ class alarm_t { string lev; set<string> s_event; int is_new; - Tango::TimeVal ts_time_threshold; //says when it has gone in alarm status for the first time - unsigned int time_threshold; //TODO: seconds, is it enough precision? + Tango::TimeVal ts_on_delay; //says when it has gone in alarm status for the first time + unsigned int on_delay; //TODO: seconds, is it enough precision? + Tango::TimeVal ts_off_delay; //says when it returned normal status + unsigned int off_delay; //TODO: seconds, is it enough precision? Tango::TimeVal ts_time_silenced; //says when it has been silenced int silent_time; //minutes max to be silent int silenced; //minutes still to be silent - string attr_values_time_threshold; //attr_values of first occurrence of alarm waiting for time threshold + string attr_values_delay; //attr_values of first occurrence of alarm waiting for on or off delay string cmd_name_a; //action to execute: when NORMAL -> ALARM, cmd_name = cmd_dp_a/cmd_action_a string cmd_dp_a; //device proxy part of cmd_name_a string cmd_action_a; //action part of cmd_name_a @@ -356,7 +359,7 @@ class alarm_table { void log_alarm_db(unsigned int type, Tango::TimeVal ts, string name, string status, string ack, string formula, unsigned int time_threshold, string grp, string lev, string msg, string action, int silent_time, vector<string> alm_list=vector<string>()); void save_alarm_conf_db(string att_name, Tango::TimeVal ts, string name, string status, string ack, - string formula, unsigned int time_threshold, string grp, string lev, string msg, string cmd_a, string cmd_n, int silent_time, vector<string> alm_list=vector<string>()); + string formula, unsigned int on_delay, unsigned int off_delay, string grp, string lev, string msg, string cmd_a, string cmd_n, int silent_time, vector<string> alm_list=vector<string>()); void get_alarm_list_db(vector<string> &al_list); void init_cmdthread(); void stop_cmdthread();