diff --git a/src/AlarmHandler.cpp b/src/AlarmHandler.cpp index 49fd770888ec063725e76acaa44b392fa2f74f4f..7bdad9dc88100f24774c9d506767c091d9061d0b 100644 --- a/src/AlarmHandler.cpp +++ b/src/AlarmHandler.cpp @@ -3512,7 +3512,7 @@ void AlarmHandler::add_event(alarm_t& a, vector<string> &evn) throw(string&) try { Tango::DeviceAttribute attr_value; attr_value = k->dp->read_attribute(k->attribute); - ecb.extract_values(&attr_value, k->value, k->type); + ecb.extract_values(&attr_value, k->value, k->type, k->read_size); k->valid = true; ostringstream msg; msg << "AlarmHandler::add_event(): initial values of " << k->name << " = "; @@ -3521,7 +3521,7 @@ void AlarmHandler::add_event(alarm_t& a, vector<string> &evn) throw(string&) msg << ", valid=" << k->valid << ends; DEBUG_STREAM << msg.str() << endl; //delete attr_value; - } catch(Tango::DevFailed& e) + } catch(Tango::DevFailed& e { TangoSys_MemStream out_stream; out_stream << "Failed to read initial value of " << k->name << " = " << e.errors[0].desc << ends; @@ -3715,6 +3715,7 @@ void AlarmHandler::do_alarm(bei_t& e) found->valid = true; found->ts = e.ts; found->type = e.type; + found->read_size = e.read_size; found->err_counter = 0; vector<string>::iterator j = found->m_alarm.begin(); while (j != found->m_alarm.end()) @@ -4769,38 +4770,115 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values DEBUG_STREAM << " node function: " << string(i->value.begin(), i->value.end()) << endl; if(i->children.size() != 1) { - err << "in node funcID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); - throw err.str(); - } + err << "in node funcID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); + throw err.str(); + } formula_res_t res; - res = eval_expression(i->children.begin(), attr_values); if (string(i->value.begin(), i->value.end()) == string("abs")) { + res = eval_expression(i->children.begin(), attr_values); res.value = fabs(res.value); return res; } else if (string(i->value.begin(), i->value.end()) == string("cos")) { + res = eval_expression(i->children.begin(), attr_values); res.value = cos(res.value); return res; } else if (string(i->value.begin(), i->value.end()) == string("sin")) { + res = eval_expression(i->children.begin(), attr_values); res.value = sin(res.value); return res; } else if (string(i->value.begin(), i->value.end()) == string("quality")) { + res = eval_expression(i->children.begin(), attr_values); res.value = res.quality; return res; } + else if ((string(i->value.begin(), i->value.end()) == string("AND") || string(i->value.begin(), i->value.end()) == string("OR")) && i->children.begin()->value.id() == formula_grammar::nameID) + { + vector<event>::iterator it = events->v_event.begin(); + string s(i->children.begin()->value.begin(), i->children.begin()->value.end()); + std::transform(s.begin(), s.end(), s.begin(), (int(*)(int))tolower); //transform to lowercase + DEBUG_STREAM << " -> " << string(i->value.begin(), i->value.end()) << "(" << s << ")" << endl; + while ((it != events->v_event.end()) && (it->name != s)) + it++; + if (it != events->v_event.end()) + { + if(!it->valid) + { + err << "in node funcID(" << string(i->value.begin(), i->value.end()) << "), (" << s << ") value not valid!" << ends; + if(it->ex_desc.length() > 0) + err << "attribute '" << string(i->value.begin(), i->value.end()) << "' exception: '" << it->ex_desc << "'"; + else + err << "attribute '" << string(i->value.begin(), i->value.end()) << "' value not valid!"; + throw err.str(); + } + else if(it->type != Tango::DEV_STRING && it->value.empty()) + { + if(it->ex_desc.length() > 0) + err << "attribute '" << string(i->value.begin(), i->value.end()) << "' exception: '" << it->ex_desc << "'"; + else + err << "attribute '" << string(i->value.begin(), i->value.end()) << "' value not initialized!!"; + throw err.str(); + } + + ostringstream temp_attr_val; + bool result; + if (string(i->value.begin(), i->value.end()) == string("AND")) + result = true; + else if (string(i->value.begin(), i->value.end()) == string("OR")) + result = false; + + temp_attr_val << "\"" << it->name << "\":"; + if(it->read_size > 1) + temp_attr_val << "["; + for(int att_ind = 0; att_ind < it->read_size && att_ind < it->value.size(); att_ind++) + { + temp_attr_val << it->value.at(att_ind); + if (string(i->value.begin(), i->value.end()) == string("AND")) + { + result = result && (bool)it->value.at(att_ind); + if(!result) //comment to have all array values in attr_values + break; //comment to have all array values in attr_values + } + else if (string(i->value.begin(), i->value.end()) == string("OR")) + { + result = result || (bool)it->value.at(att_ind); + if(result) //comment to have all array values in attr_values + break; //comment to have all array values in attr_values + } + if(att_ind < it->read_size-1 && att_ind < it->value.size()-1) + temp_attr_val << ","; + } + if(it->read_size > 1) + temp_attr_val << "]"; + temp_attr_val << ","; + attr_values += temp_attr_val.str(); + res.quality = it->quality; + res.ex_reason = it->ex_reason; + res.ex_desc = it->ex_desc; + res.ex_origin = it->ex_origin; + DEBUG_STREAM << " node name -> " << temp_attr_val.str() << " quality=" << res.quality << endl; + res.value = result; + return res; + } + else + { + err << "in function " << string(i->value.begin(), i->value.end()) << " event (" << s << ") not found in event table" << ends; + throw err.str(); + } + } else { err << "in node funcID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; throw err.str(); } - } + } else if (i->value.id() == formula_grammar::func_dualID) { DEBUG_STREAM << " node function dual: " << string(i->value.begin(), i->value.end()) << endl; diff --git a/src/event_table.cpp b/src/event_table.cpp index 1c7a602efc16a86ed37b52c00f33a45e3f085810..70f52bdc669d0b1ca3f704012b566fad044138fd 100644 --- a/src/event_table.cpp +++ b/src/event_table.cpp @@ -1134,7 +1134,7 @@ void EventCallBack::push_event(Tango::EventData* ev) e.ev_name = ev->attr_name; #endif e.ts = ev->attr_value->time; - extract_values(ev->attr_value, e.value, e.value_string, e.type); + extract_values(ev->attr_value, e.value, e.value_string, e.type, e.read_size); } else { #if 0//TANGO_VER >= 711 string ev_name_str(ev->attr_name); @@ -1195,7 +1195,7 @@ void EventCallBack::push_event(Tango::EventData* ev) static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->evlist.push_back(e); } /* push_event() */ -void EventCallBack::extract_values(Tango::DeviceAttribute *attr_value, vector<double> &val, string &val_string, int &type) +void EventCallBack::extract_values(Tango::DeviceAttribute *attr_value, vector<double> &val, string &val_string, int &type, int &read_size) { Tango::DevState stval; vector<Tango::DevState> v_st; @@ -1212,6 +1212,26 @@ void EventCallBack::extract_values(Tango::DeviceAttribute *attr_value, vector<do vector<string> v_string; val_string = string(""); + //Tango::AttributeDimension attr_w_dim; + Tango::AttributeDimension attr_r_dim; + + //attr_value->reset_exceptions(Tango::DeviceAttribute::isempty_flag); //disable is_empty exception //commented to throw exceptions if empty + if(!attr_value->is_empty()) + { + //attr_w_dim = data->attr_value->get_w_dimension(); + attr_r_dim = attr_value->get_r_dimension(); + } + else + { + attr_r_dim.dim_x = 0; + //attr_w_dim.dim_x = 0; + attr_r_dim.dim_y = 0; + //attr_w_dim.dim_y = 0; + } + read_size = attr_r_dim.dim_x; + if(attr_r_dim.dim_y > 1) + read_size *= attr_r_dim.dim_y; + if (attr_value->get_type() == Tango::DEV_UCHAR) { *(attr_value) >> v_uch; for(vector<Tango::DevUChar>::iterator it = v_uch.begin(); it != v_uch.end(); it++) diff --git a/src/event_table.h b/src/event_table.h index 576f2fe491ddff8c25857c1ab6c50b35d458aea8..8a8935b070393184bf0472a90091c81b667ac3de 100644 --- a/src/event_table.h +++ b/src/event_table.h @@ -57,6 +57,7 @@ class event { string ex_origin; Tango::TimeVal ts; /* event timestamp */ int type, /* attribute data type */ + read_size, /* attribute size of read part */ counter, /* molteplicita' */ err_counter; /* molteplicita' errore */ //map<string, string> m_alarm; @@ -109,6 +110,7 @@ typedef struct basic_event_info_s { string ex_desc; string ex_origin; int type; + int read_size; Tango::TimeVal ts; string msg; } bei_t; @@ -193,7 +195,7 @@ class EventCallBack : public Tango::CallBack, public Tango::LogAdapter ~EventCallBack(void); void push_event(Tango::EventData* ev); //void init(event_list* e); - void extract_values(Tango::DeviceAttribute *attr_value, vector<double> &val, string &val_string, int &type); + void extract_values(Tango::DeviceAttribute *attr_value, vector<double> &val, string &val_string, int &type, int &read_size); private: //event_list* e_ptr; Tango::DeviceImpl *mydev; diff --git a/src/formula_grammar.h b/src/formula_grammar.h index 2dc2940b02f0ffb4f77fe12f570c492223e91d61..f2a6badb557a5a86f1a591159ab3368a45909012 100644 --- a/src/formula_grammar.h +++ b/src/formula_grammar.h @@ -356,7 +356,9 @@ struct formula_grammar : public grammar<formula_grammar> = ( root_node_d[str_p("abs")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ? | root_node_d[str_p("cos")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ? | root_node_d[str_p("sin")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ? - | root_node_d[str_p("quality")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ? + | root_node_d[str_p("quality")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ? + | root_node_d[str_p("AND")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ? + | root_node_d[str_p("OR")] >> (discard_node_d[ch_p('(')] >> cond_expr >> discard_node_d[ch_p(')')]) //TODO: ? not expr_atom ? ) ; function_dual