/*----- PROTECTED REGION ID(AlarmHandler.cpp) ENABLED START -----*/ //============================================================================= // // file : AlarmHandler.cpp // // description : C++ source for the AlarmHandler class and its commands. // The class is derived from Device. It represents the // CORBA servant object which will be accessed from the // network. All commands which can be executed on the // AlarmHandler are implemented in this file. // // project : Elettra alarm handler device server // // This file is part of Tango device class. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Tango. If not, see <http://www.gnu.org/licenses/>. // // // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include <AlarmHandler.h> #include <AlarmHandlerClass.h> #include <ctype.h> //for tolower #include "alarm-thread.h" #include "alarm_grammar.h" #include "update-thread.h" //#define _DUMP_TREE_XML #ifdef _DUMP_TREE_XML #if BOOST_VERSION < 103600 #include <boost/spirit/iterator/fixed_size_queue.hpp> #include <boost/spirit/core.hpp> #include <boost/spirit/tree/ast.hpp> #include <boost/spirit/tree/tree_to_xml.hpp> using namespace boost::spirit; #else #include <boost/spirit/include/classic_fixed_size_queue.hpp> #include <boost/spirit/include/classic_core.hpp> #include <boost/spirit/include/classic_ast.hpp> #include <boost/spirit/include/classic_tree_to_xml.hpp> using namespace boost::spirit::classic; #endif #include <iostream> #include <stack> #include <functional> #include <string> #include <cassert> #endif //_DUMP_TREE_XML #include <sstream> #include <regex> std::map<parser_id, std::string> rule_names; //only for log messages int AlarmHandler_ns::AlarmHandler::instanceCounter = 0; #ifndef ALARM_BUILDTIME #define ALARM_BUILDTIME __DATE__ " " __TIME__ " boost=" BOOST_LIB_VERSION #endif const char version_string[] = "$Build: @buildID@ " ALARM_BUILDTIME " $"; static const char __FILE__rev[] = __FILE__ " $Revision: 1.29 $"; /*----- PROTECTED REGION END -----*/ // AlarmHandler.cpp /** * AlarmHandler class description: * Elettra alarm handler device server */ //================================================================ // The following table gives the correspondence // between command and method names. // // Command name | Method name //================================================================ // State | Inherited (no method) // Status | Inherited (no method) // Ack | ack // Load | load // Remove | remove // SearchAlarm | search_alarm // StopAudible | stop_audible // Silence | silence // Modify | modify // Shelve | shelve // Enable | enable // Disable | disable // ResetStatistics | reset_statistics // StopNew | stop_new // GetAlarmInfo | get_alarm_info // ReLoadAll | re_load_all //================================================================ //================================================================ // Attributes managed are: //================================================================ // alarmAudible | Tango::DevBoolean Scalar // StatisticsResetTime | Tango::DevDouble Scalar // alarm | Tango::DevString Spectrum ( max = 1024) // alarmNormal | Tango::DevString Spectrum ( max = 10000) // alarmUnacknowledged | Tango::DevString Spectrum ( max = 10000) // alarmAcknowledged | Tango::DevString Spectrum ( max = 10000) // alarmUnacknowledgedNormal | Tango::DevString Spectrum ( max = 10000) // alarmShelved | Tango::DevString Spectrum ( max = 10000) // alarmOutOfService | Tango::DevString Spectrum ( max = 10000) // alarmSilenced | Tango::DevString Spectrum ( max = 10000) // alarmList | Tango::DevString Spectrum ( max = 10000) // alarmFrequency | Tango::DevDouble Spectrum ( max = 10000) // alarmSummary | Tango::DevString Spectrum ( max = 10000) // eventList | Tango::DevString Spectrum ( max = 10000) // eventSummary | Tango::DevString Spectrum ( max = 10000) //================================================================ namespace AlarmHandler_ns { /*----- PROTECTED REGION ID(AlarmHandler::namespace_starting) ENABLED START -----*/ // static initializations /*----- PROTECTED REGION END -----*/ // AlarmHandler::namespace_starting //-------------------------------------------------------- /** * Method : AlarmHandler::AlarmHandler() * Description : Constructors for a Tango device * implementing the classAlarmHandler */ //-------------------------------------------------------- AlarmHandler::AlarmHandler(Tango::DeviceClass *cl, string &s) : TANGO_BASE_CLASS(cl, s.c_str()) { /*----- PROTECTED REGION ID(AlarmHandler::constructor_1) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // AlarmHandler::constructor_1 } //-------------------------------------------------------- AlarmHandler::AlarmHandler(Tango::DeviceClass *cl, const char *s) : TANGO_BASE_CLASS(cl, s) { /*----- PROTECTED REGION ID(AlarmHandler::constructor_2) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // AlarmHandler::constructor_2 } //-------------------------------------------------------- AlarmHandler::AlarmHandler(Tango::DeviceClass *cl, const char *s, const char *d) : TANGO_BASE_CLASS(cl, s, d) { /*----- PROTECTED REGION ID(AlarmHandler::constructor_3) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // AlarmHandler::constructor_3 } //-------------------------------------------------------- /** * Method : AlarmHandler::delete_device() * Description : will be called at device destruction or at init command */ //-------------------------------------------------------- void AlarmHandler::delete_device() { DEBUG_STREAM << "AlarmHandler::delete_device() " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::delete_device) ENABLED START -----*/ // Delete device allocated objects /* * unsubscribe events and release memory */ bool starting = Tango::Util::instance()->is_svr_starting(); bool shutting_down = Tango::Util::instance()->is_svr_shutting_down(); bool restarting = Tango::Util::instance()->is_device_restarting(device_name); DEBUG_STREAM << __func__ << " starting="<<(int)starting << " shutting_down="<<(int)shutting_down<<" restarting="<<(int)restarting; abortflag = true; updateloop->signal(); DEBUG_STREAM << "AlarmHandler::delete_device(): after abortflag=true..." << endl; try { events->unsubscribe_events(); } catch (string& err) { ERROR_STREAM << err << endl; } DEBUG_STREAM << "AlarmHandler::delete_device(): events unsubscribed!" << endl; /* * kill alarm thread */ bei_t e; e.ev_name = ALARM_THREAD_EXIT; e.value.push_back(ALARM_THREAD_EXIT_VALUE); e.value.push_back(ALARM_THREAD_EXIT_VALUE); evlist.push_back(e); if(!shutting_down && !restarting) alarms.del_rwlock(); //otherwise moved in alarm_table destructor alarms.stop_cmdthread(); events->stop_thread(); usleep(50000); DEBUG_STREAM << "AlarmHandler::delete_device(): stopped alarm and log threads!" << endl; delete events; thread->join(nullptr); sleep(1); //wait for alarm_thread, update_thread and log_thread to exit //delete almloop; DEBUG_STREAM << "AlarmHandler::delete_device(): deleted events" << endl; //delete proxy for actions for(alarm_container_t::iterator i = alarms.v_alarm.begin(); i!=alarms.v_alarm.end(); i++) { if(i->second.dp_a) delete i->second.dp_a; i->second.dp_a = NULL; if(i->second.dp_n) delete i->second.dp_n; i->second.dp_n = NULL; } if(0/*shutting_down*/) //TODO: no need to remove attributes when shutting down ? { for(alarm_container_t::iterator it = alarms.v_alarm.begin(); it != alarms.v_alarm.end(); it++) { try { remove_AlarmState_dynamic_attribute_no_clean_db(it->second.attr_name); } catch(Tango::DevFailed &e) { INFO_STREAM << __func__<<": exception removing " << it->second.attr_name << ": " << e.errors[0].desc; } #if _FORMULA_ATTR CORBA::string_free(*(it->second.attr_value_formula)); try { remove_AlarmFormula_dynamic_attribute(it->second.attr_name_formula); } catch(Tango::DevFailed &e) { INFO_STREAM << __func__<<": exception removing " << it->second.attr_name_formula << ": " << e.errors[0].desc; } #endif } } /* * clear all data structures */ alarms.v_alarm.clear(); evlist.clear(); /* for (int i = ds_num - 1; i >= 0; i--) { CORBA::string_free(ds[i]); }*/ ds_num = 0; /* * store current "alarmed" table status */ vector<string> vs; for (vector<alarm_t>::iterator i = alarmed.begin(); \ i != alarmed.end(); i++) { vs.push_back(i->alm2str()); } Tango::DbDatum as("AlarmStatus"); Tango::DbData data_del; data_del.push_back(as); //get_db_device()->delete_property(data_del); as << vs; Tango::DbData data_put; data_put.push_back(as); Tango::Database *db=NULL; try { #ifndef _USE_ELETTRA_DB_RW db = new Tango::Database(); #else //salvataggio proprietà usando host_rw e port_rw per connettersi al database if(host_rw != "") db = new Tango::Database(host_rw,port_rw); else db = new Tango::Database(); #endif } catch(Tango::DevFailed &e) { stringstream o; o << " Error connecting to Tango DataBase='" << e.errors[0].desc << "'"; WARN_STREAM << __FUNCTION__<< o.str(); } if(db) { try { db->put_device_property(get_name(), data_put); DEBUG_STREAM << "AlarmHandler::delete_device(): saved AlarmStatus in properties!!" << endl; } catch(Tango::DevFailed &e) { ERROR_STREAM << __FUNCTION__<< " error saving properties='" << e.errors[0].desc << "'"; } delete db; } /* * clear storage */ alarmed.clear(); delete alarmedlock; delete savedlock; delete internallock; delete dslock; instanceCounter--; //Tango::leavefunc(); delete prepare_alm_mtx; /*----- PROTECTED REGION END -----*/ // AlarmHandler::delete_device delete[] attr_alarmAudible_read; delete[] attr_StatisticsResetTime_read; delete[] attr_alarmNormal_read; delete[] attr_alarmUnacknowledged_read; delete[] attr_alarmAcknowledged_read; delete[] attr_alarmUnacknowledgedNormal_read; delete[] attr_alarmShelved_read; delete[] attr_alarmOutOfService_read; delete[] attr_alarmSilenced_read; delete[] attr_alarmList_read; delete[] attr_alarmFrequency_read; delete[] attr_alarmSummary_read; delete[] attr_eventList_read; delete[] attr_eventSummary_read; } //-------------------------------------------------------- /** * Method : AlarmHandler::init_device() * Description : will be called at device initialization. */ //-------------------------------------------------------- void AlarmHandler::init_device() { DEBUG_STREAM << "AlarmHandler::init_device() create device " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::init_device_before) ENABLED START -----*/ bool starting = Tango::Util::instance()->is_svr_starting(); bool shutting_down = Tango::Util::instance()->is_svr_shutting_down(); bool restarting = Tango::Util::instance()->is_device_restarting(device_name); DEBUG_STREAM << __func__ << " starting="<<(int)starting << " shutting_down="<<(int)shutting_down<<" restarting="<<(int)restarting; // Initialization before get_device_property() call int dbPortint=0; abortflag = false; instanceCounter++; prepare_alm_mtx = new omni_mutex(); events = new event_table(this); thread = new SubscribeThread(this); //because of static map<string, unsigned int> grp_str and of exception while subscribing //more than one time the same event in the same executable, control the number of instances if(instanceCounter > 1) { ERROR_STREAM << "More than one instance in the same executable of Alarm Server is not allowed!!" << endl; cout << "ERROR: second instance of Alarm Server, exiting..." << endl; exit(-1); } //------------------------------------------- alarmedlock = new(ReadersWritersLock); internallock = new(ReadersWritersLock); dslock = new(ReadersWritersLock); savedlock = new(ReadersWritersLock); alarms.set_dev(this); /*----- PROTECTED REGION END -----*/ // AlarmHandler::init_device_before // Get the device properties from database get_device_property(); attr_alarmAudible_read = new Tango::DevBoolean[1]; attr_StatisticsResetTime_read = new Tango::DevDouble[1]; attr_alarmNormal_read = new Tango::DevString[10000]; attr_alarmUnacknowledged_read = new Tango::DevString[10000]; attr_alarmAcknowledged_read = new Tango::DevString[10000]; attr_alarmUnacknowledgedNormal_read = new Tango::DevString[10000]; attr_alarmShelved_read = new Tango::DevString[10000]; attr_alarmOutOfService_read = new Tango::DevString[10000]; attr_alarmSilenced_read = new Tango::DevString[10000]; attr_alarmList_read = new Tango::DevString[10000]; attr_alarmFrequency_read = new Tango::DevDouble[10000]; attr_alarmSummary_read = new Tango::DevString[10000]; attr_eventList_read = new Tango::DevString[10000]; attr_eventSummary_read = new Tango::DevString[10000]; /*----- PROTECTED REGION ID(AlarmHandler::init_device) ENABLED START -----*/ /* for(size_t i=0; i<MAX_ALARMS; i++) { normalAlarms_read[i].resize(MAX_ATTR_NAME); unacknowledgedAlarms_read[i].resize(MAX_ATTR_NAME); acknowledgedAlarms_read[i].resize(MAX_ATTR_NAME); unacknowledgedNormalAlarms_read[i].resize(MAX_ATTR_NAME); shelvedAlarms_read[i].resize(MAX_ATTR_NAME); outOfServiceAlarms_read[i].resize(MAX_ATTR_NAME); silencedAlarms_read[i].resize(MAX_ATTR_NAME); alarmSummary_read[i].resize(MAX_ATTR_SUMMARY); }*/ // Initialize device alarms.set_err_delay(errorDelay); thread->period = subscribeRetryPeriod; #ifdef _USE_ELETTRA_DB_RW host_rw = ""; Tango::Database *db=NULL; try { db = new Tango::Database(); }catch(Tango::DevFailed &e) { ERROR_STREAM << __FUNCTION__ << " Error connecting to Tango DataBase='" << e.errors[0].desc << "'"; } if(db) { try { Tango::DbData db_data; db_data.push_back((Tango::DbDatum("Host"))); db_data.push_back((Tango::DbDatum("Port"))); db->get_property("Database",db_data); db_data[0] >> host_rw; db_data[1] >> port_rw; }catch(Tango::DevFailed &e) { ERROR_STREAM << __FUNCTION__ << " Error reading Database property='" << e.errors[0].desc << "'"; } delete db; } #endif ds_num = 0; //initialize number of lines returned by read_alarm internal_counter = 0; /*Tango::DbData db_data; db_data.push_back(Tango::DbDatum("alarm")); get_db_device()->get_attribute_property(db_data);*/ /* * connect to log database */ alarms.new_rwlock(); try { alarms.init_cmdthread(); } catch(...) { WARN_STREAM << "AlarmHandler::init_device(): error creating cmd thread" << endl; } rule_names[formula_grammar::val_rID] = "ValReal"; rule_names[formula_grammar::val_hID] = "ValHex"; rule_names[formula_grammar::val_stID] = "ValStatus"; rule_names[formula_grammar::event_ID] = "EventFather"; rule_names[formula_grammar::nameID] = "EventName"; rule_names[formula_grammar::indexID] = "EventIndex"; rule_names[formula_grammar::funcID] = "Function"; rule_names[formula_grammar::logical_exprID] = "LogicalE"; rule_names[formula_grammar::bitwise_exprID] = "BitwiseE"; rule_names[formula_grammar::equality_exprID] = "EqualityE"; rule_names[formula_grammar::compare_exprID] = "CompareE"; rule_names[formula_grammar::add_exprID] = "AddE"; rule_names[formula_grammar::mult_exprID] = "MultE"; rule_names[formula_grammar::expr_atomID] = "AtomicE"; rule_names[formula_grammar::shift_exprID] = "ShiftE"; rule_names[formula_grammar::unary_exprID] = "UnaryE"; rule_names[formula_grammar::val_stringID] = "ValString"; rule_names[formula_grammar::func_dualID] = "FuncDualE"; rule_names[formula_grammar::logical_expr_parenID] = "LogicalParenE"; rule_names[formula_grammar::cond_exprID] = "ConditionalE"; rule_names[formula_grammar::nonempty_exprID] = "NonEmptyE"; rule_names[formula_grammar::exprID] = "Expression"; rule_names[formula_grammar::val_qualityID] = "ValQuality"; rule_names[formula_grammar::val_alarm_enum_stID] = "ValAlarmEnumStatus"; rule_names[formula_grammar::propertyID] = "EventProperty"; /* * get device attribute properties and initialize internal * data structures */ // short n_prop; string expr; string pr_name; vector<string> tmp_alm_vec; /* db_data[0] >> n_prop; INFO_STREAM << "Number alarm to load = " << n_prop << endl; for (int i = 1; i <= n_prop; i++) { pr_name = db_data[i].name; db_data[i] >> expr; DEBUG_STREAM << " -> attr property: " << pr_name << " = " << expr << endl; size_t pos = pr_name.find('_'); int count_ = 1; while(pos != string::npos) //TODO: better this control { pos = pr_name.find('_', pos+1); count_++; if((count_ == 3) && (pos != string::npos)) //if at least 3 _ in the attr property name, expr is OK //TODO: better this control { tmp_alm_vec.push_back(expr); break; } } }*/ try { alarms.get_alarm_list_db(tmp_alm_vec, saved_alarms, savedlock);//holds write locks savedlock } catch(string & e) { ERROR_STREAM << "AlarmHandler::init_device(): " << e << endl; cout << "Error: " << e << ". Exiting..." << endl; exit(-4); } /* * store the alarms into alarm table vector */ map< string,vector<string> > alarm_event; //map alarm->vector event popolated by parser vector<string> evn; //vector with all event (possibly duplicated) popolated by parser vector<string> temp_evn; vector<string> tmp_alm_name_lst; //alarms.init(tmp_alm_vec, evn, alarm_event); alarm_t tmp_alm; evn.clear(); for(vector<string>::iterator it_al = tmp_alm_vec.begin(); it_al!= tmp_alm_vec.end(); it_al++) { tmp_alm.clear(); temp_evn.clear(); try { load_alarm(*it_al, tmp_alm, temp_evn); add_alarm(tmp_alm,/*starting*/true); tmp_alm_name_lst.push_back(tmp_alm.name); } catch(Tango::DevFailed& e) { ostringstream err; err << "error loading alarm=" << tmp_alm.name << " , " << e.errors[0].desc; WARN_STREAM << "AlarmHandler::init_device(): " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); continue; } catch (string& err) { ostringstream err_out; err_out << "error loading alarm=" << tmp_alm.name << " , " << err; WARN_STREAM << "AlarmHandler::init_device(): " << err_out.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err_out.str()); continue; } //eliminate duplicated event if (temp_evn.empty() == false) { sort(temp_evn.begin(), temp_evn.end()); vector<string>::iterator new_end = \ unique(temp_evn.begin(), temp_evn.end()); while (temp_evn.end() != new_end) temp_evn.pop_back(); } alarm_event.insert(make_pair(tmp_alm.name,temp_evn)); evn.insert(evn.end(),temp_evn.begin(),temp_evn.end()); /* alarms.log_alarm_db(TYPE_LOG_DESC_SYNC, gettime(), tmp_alm.name, "", "", //remove if alarm with the same name exist but is changed tmp_alm.formula, tmp_alm.grp2str(), tmp_alm.lev, tmp_alm.msg); alarms.log_alarm_db(TYPE_LOG_DESC_ADD, gettime(), tmp_alm.name, "", "", //add new alarm if there is not already one active with the same name tmp_alm.formula, tmp_alm.grp2str(), tmp_alm.lev, tmp_alm.msg);*/ } /* alarms.log_alarm_db(TYPE_LOG_DESC_UPD_OLD, gettime(), "", "", "", //set as not active all alarms not present in this list "", "", "", "", tmp_alm_name_lst);*/ DEBUG_STREAM << "alarms table size = " << alarms.size() << endl; vector<string> al_table_string; alarms.show(al_table_string); for(vector<string>::iterator str_it=al_table_string.begin(); str_it!=al_table_string.end(); str_it++) DEBUG_STREAM << (*str_it) << endl; /* * check 'stored' alarms against current alarm table for consistency */ vector<string> to_remove_from_stored; if (stored.empty() == false) { for (vector<alarm_t>::iterator i = stored.begin(); \ i != stored.end(); i++) { alarm_container_t::iterator found = alarms.v_alarm.find(i->name); if (found == alarms.v_alarm.end()) { to_remove_from_stored.push_back(i->name); //stored.erase(i); } } } for(vector<string>::iterator k=to_remove_from_stored.begin(); k != to_remove_from_stored.end(); k++) { vector<alarm_t>::iterator rmv = find(stored.begin(),stored.end(),*k); if(rmv != stored.end()) { ERROR_STREAM << "init_device(): alarm '" << *k \ << "' NOT found in alarm table! " \ << "Removing from 'stored' alarms" << endl; stored.erase(rmv); } else WARN_STREAM << "init_device(): alarm " << *k << " not found while removing from stored !!!" << endl; } /* * update "alarm" table with "stored" alarms */ alarms.stored(stored); /* * update "alarmed" table with "stored" alarms */ if (stored.empty() == false) { alarmedlock->writerIn(); for (vector<alarm_t>::iterator i = stored.begin(); \ i != stored.end(); i++) { alarmed.push_back(*i); } alarmedlock->writerOut(); } for(alarm_container_t::iterator i = alarms.v_alarm.begin(); \ i!=alarms.v_alarm.end(); i++) { if(i->second.cmd_name_a.length() > 0) { try { i->second.dp_a = new Tango::DeviceProxy(i->second.cmd_dp_a); i->second.dp_a->ping(); Tango::CommandInfo info = i->second.dp_a->command_query(i->second.cmd_action_a); if((info.in_type != Tango::DEV_STRING) && (info.in_type != Tango::DEV_VOID)) { ostringstream err; err << i->second.name << ": error, command " << i->second.cmd_name_a << " does not accept a Tango::DevString or a Tango::DevVoid as input value"; ERROR_STREAM << "AlarmHandler::init_device(): " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } else { if(info.in_type == Tango::DEV_STRING) i->second.send_arg_a = true; else i->second.send_arg_a = false; DEBUG_STREAM << "AlarmHandler::init_device(): " << i->second.name << ": successfully connected to proxy=" << i->second.cmd_dp_a << " for action=" << i->second.cmd_action_a << endl; } } catch(Tango::DevFailed& e) { ostringstream err; err << i->second.name << ": error connecting to device proxy=" << i->second.cmd_dp_a << ", err=" << e.errors[0].desc; WARN_STREAM << "AlarmHandler::init_device(): " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); i->second.dp_a = NULL; } } if(i->second.cmd_name_n.length() > 0) { try { i->second.dp_n = new Tango::DeviceProxy(i->second.cmd_dp_n); i->second.dp_n->ping(); Tango::CommandInfo info = i->second.dp_n->command_query(i->second.cmd_action_n); if((info.in_type != Tango::DEV_STRING) && (info.in_type != Tango::DEV_VOID)) { ostringstream err; err << i->second.name << ": error, command " << i->second.cmd_name_n << " does not accept a Tango::DevString or a Tango::DevVoid as input value"; ERROR_STREAM << "AlarmHandler::init_device(): " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } else { if(info.in_type == Tango::DEV_STRING) i->second.send_arg_n = true; else i->second.send_arg_n = false; DEBUG_STREAM << "AlarmHandler::init_device(): " << i->second.name << ": successfully connected to proxy=" << i->second.cmd_dp_n << " for action=" << i->second.cmd_action_n << endl; } } catch(Tango::DevFailed& e) { ostringstream err; err << i->second.name << ": error connecting to device proxy=" << i->second.cmd_dp_n << ", err=" << e.errors[0].desc; WARN_STREAM << "AlarmHandler::init_device(): " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); i->second.dp_n = NULL; } } } thread->start(); //TODO:ecb.init(&evlist); for(map<string, vector<string> >::iterator al_ev_it=alarm_event.begin(); \ al_ev_it!=alarm_event.end(); al_ev_it++) { alarm_container_t::iterator i = alarms.v_alarm.find(al_ev_it->first); if(i != alarms.v_alarm.end()) { #if 1 try { add_event(i->second, al_ev_it->second);//moved after events->add /*if(i->second.to_be_evaluated) //moved after thread->start(); (subscribe thread started) { bei_t e; e.ev_name = ALARM_THREAD_TO_BE_EVAL; e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE); e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE); evlist.push_back(e); }*/ } catch (string& err) { WARN_STREAM << "AlarmHandler::init_device(): " << err << endl; for(vector<string>::iterator j=al_ev_it->second.begin(); j!=al_ev_it->second.end(); j++) { DEBUG_STREAM << "AlarmHandler::init_device(): Removing alarm=" << i->second.name << " from event=" << *j << endl; vector<event>::iterator k = \ find(events->v_event.begin(), events->v_event.end(), *j); if (k != events->v_event.end()) { k->m_alarm.pop(i->second.name); //remove alarm/formula just added to event DEBUG_STREAM << "AlarmHandler::init_device(): Removed!!!! alarm=" << i->second.name << " from event=" << *j << endl; if(k->m_alarm.empty()) { events->v_event.erase(k); //remove event just added to event_table DEBUG_STREAM << "AlarmHandler::init_device(): event=" << *j << " no more used, REMOVED!!!" << endl; } } } set_internal_alarm(INTERNAL_ERROR, gettime(), err); } #else try { add_event(i->second, al_ev_it->second); } catch (string& err) { WARN_STREAM << "AlarmHandler::init_device(): " << err << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err); } try { subscribe_event(i->second, ecb, al_ev_it->second); } catch (string& err) { WARN_STREAM << "AlarmHandler::init_device(): " << err << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err); } #endif } } set_change_event("alarm",true,false); /* * create alarm processing thread */ //almloop = new alarm_thread::alarm_thread(/*this*/); almloop = new alarm_thread(this); almloop->start(); updateloop = new update_thread(this); updateloop->start(); //thread->start(); events->start_all(); for(map<string, vector<string> >::iterator al_ev_it=alarm_event.begin(); \ al_ev_it!=alarm_event.end(); al_ev_it++) { alarm_container_t::iterator i = alarms.v_alarm.find(al_ev_it->first); if(i != alarms.v_alarm.end()) { if(i->second.to_be_evaluated) //moved after thread->start(); (subscribe thread started) { bei_t e; e.ev_name = ALARM_THREAD_TO_BE_EVAL; e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE); e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE); evlist.push_back(e); } } } set_state(Tango::RUNNING); set_status("Alarm server is running"); alarms.startup_complete = gettime(); //enable actions execution in 10 seconds // // for (int i=0; i< MAX_ALARMS ; i++) ds[i]=0; // ds_num = 0; for (int i=0; i< MAX_ALARMS ; i++) ds[i]=(char *) (dss[i]); timespec now; clock_gettime(CLOCK_MONOTONIC, &now); double dnow = (now.tv_sec) + ((double)(now.tv_nsec))/1000000000; last_statistics_reset_time = dnow; INFO_STREAM << __func__ << ": exiting!"; /*----- PROTECTED REGION END -----*/ // AlarmHandler::init_device } //-------------------------------------------------------- /** * Method : AlarmHandler::get_device_property() * Description : Read database to initialize property data members. */ //-------------------------------------------------------- void AlarmHandler::get_device_property() { /*----- PROTECTED REGION ID(AlarmHandler::get_device_property_before) ENABLED START -----*/ // Initialize property data members /*----- PROTECTED REGION END -----*/ // AlarmHandler::get_device_property_before // Read device properties from database. Tango::DbData dev_prop; dev_prop.push_back(Tango::DbDatum("GroupNames")); dev_prop.push_back(Tango::DbDatum("SubscribeRetryPeriod")); dev_prop.push_back(Tango::DbDatum("StatisticsTimeWindow")); dev_prop.push_back(Tango::DbDatum("ErrorDelay")); // is there at least one property to be read ? if (dev_prop.size()>0) { // Call database and extract values if (Tango::Util::instance()->_UseDb==true) get_db_device()->get_property(dev_prop); // get instance on AlarmHandlerClass to get class property Tango::DbDatum def_prop, cl_prop; AlarmHandlerClass *ds_class = (static_cast<AlarmHandlerClass *>(get_device_class())); int i = -1; // Try to initialize GroupNames from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> groupNames; else { // Try to initialize GroupNames from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> groupNames; } // And try to extract GroupNames value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> groupNames; // Try to initialize SubscribeRetryPeriod from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> subscribeRetryPeriod; else { // Try to initialize SubscribeRetryPeriod from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> subscribeRetryPeriod; } // And try to extract SubscribeRetryPeriod value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> subscribeRetryPeriod; // Try to initialize StatisticsTimeWindow from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> statisticsTimeWindow; else { // Try to initialize StatisticsTimeWindow from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> statisticsTimeWindow; } // And try to extract StatisticsTimeWindow value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> statisticsTimeWindow; // Try to initialize ErrorDelay from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> errorDelay; else { // Try to initialize ErrorDelay from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> errorDelay; } // And try to extract ErrorDelay value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> errorDelay; } /*----- PROTECTED REGION ID(AlarmHandler::get_device_property_after) ENABLED START -----*/ // Check device property data members init /* * initialize groups */ alarm_t tmp_alm; tmp_alm.init_static_map(groupNames); /*----- PROTECTED REGION END -----*/ // AlarmHandler::get_device_property_after } //-------------------------------------------------------- /** * Method : AlarmHandler::always_executed_hook() * Description : method always executed before any command is executed */ //-------------------------------------------------------- void AlarmHandler::always_executed_hook() { //DEBUG_STREAM << "AlarmHandler::always_executed_hook() " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::always_executed_hook) ENABLED START -----*/ // code always executed before all requests /*----- PROTECTED REGION END -----*/ // AlarmHandler::always_executed_hook } //-------------------------------------------------------- /** * Method : AlarmHandler::read_attr_hardware() * Description : Hardware acquisition for attributes */ //-------------------------------------------------------- void AlarmHandler::read_attr_hardware(TANGO_UNUSED(vector<long> &attr_list)) { //DEBUG_STREAM << "AlarmHandler::read_attr_hardware(vector<long> &attr_list) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_attr_hardware) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_attr_hardware } //-------------------------------------------------------- /** * Read attribute alarmAudible related method * Description: True if there is at least one alarm that needs audible indication on the GUI * * Data type: Tango::DevBoolean * Attr type: Scalar */ //-------------------------------------------------------- void AlarmHandler::read_alarmAudible(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmAudible(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmAudible) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmAudible_read); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmAudible } //-------------------------------------------------------- /** * Read attribute StatisticsResetTime related method * Description: Time elapsed in seconds since last Resetstatistics * * Data type: Tango::DevDouble * Attr type: Scalar */ //-------------------------------------------------------- void AlarmHandler::read_StatisticsResetTime(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_StatisticsResetTime(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_StatisticsResetTime) ENABLED START -----*/ timespec now; clock_gettime(CLOCK_MONOTONIC, &now); double dnow = (now.tv_sec) + ((double)(now.tv_nsec))/1000000000; *attr_StatisticsResetTime_read = dnow - last_statistics_reset_time; // Set the attribute value attr.set_value(attr_StatisticsResetTime_read); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_StatisticsResetTime } //-------------------------------------------------------- /** * Read attribute alarm related method * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 1024 */ //-------------------------------------------------------- void AlarmHandler::read_alarm(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarm(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarm) ENABLED START -----*/ // Add your own code here if(ds_num == 0) { attr.set_value_date_quality(ds,0/*gettime()*/,Tango::ATTR_WARNING, ds_num, 0, false); } else attr.set_value(ds, ds_num, 0, false); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarm } //-------------------------------------------------------- /** * Read attribute alarmNormal related method * Description: List of alarms in normal state * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_alarmNormal(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmNormal(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmNormal) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmNormal_read, normalAlarms_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmNormal } //-------------------------------------------------------- /** * Read attribute alarmUnacknowledged related method * Description: List of alarms in unacknowledged state * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_alarmUnacknowledged(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmUnacknowledged(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmUnacknowledged) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmUnacknowledged_read, unacknowledgedAlarms_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmUnacknowledged } //-------------------------------------------------------- /** * Read attribute alarmAcknowledged related method * Description: List of alarms in acknowledged state * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_alarmAcknowledged(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmAcknowledged(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmAcknowledged) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmAcknowledged_read, acknowledgedAlarms_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmAcknowledged } //-------------------------------------------------------- /** * Read attribute alarmUnacknowledgedNormal related method * Description: List of alarms in unacknowledged normal state * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_alarmUnacknowledgedNormal(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmUnacknowledgedNormal(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmUnacknowledgedNormal) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmUnacknowledgedNormal_read, unacknowledgedNormalAlarms_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmUnacknowledgedNormal } //-------------------------------------------------------- /** * Read attribute alarmShelved related method * Description: List of alarms in shelved state * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_alarmShelved(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmShelved(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmShelved) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmShelved_read, shelvedAlarms_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmShelved } //-------------------------------------------------------- /** * Read attribute alarmOutOfService related method * Description: List of alarms in out of service state * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_alarmOutOfService(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmOutOfService(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmOutOfService) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmOutOfService_read, outOfServiceAlarms_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmOutOfService } //-------------------------------------------------------- /** * Read attribute alarmSilenced related method * Description: List of alarms in silenced state * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_alarmSilenced(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmSilenced(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmSilenced) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmSilenced_read, silencedAlarms_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmSilenced } //-------------------------------------------------------- /** * Read attribute alarmList related method * Description: List of all alarms * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_alarmList(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmList(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmList) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmList_read, listAlarms_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmList } //-------------------------------------------------------- /** * Read attribute alarmFrequency related method * Description: List of frequency of evaluation of all alarms * * Data type: Tango::DevDouble * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_alarmFrequency(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmFrequency(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmFrequency) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmFrequency_read, listAlarms_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmFrequency } //-------------------------------------------------------- /** * Read attribute alarmSummary related method * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_alarmSummary(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_alarmSummary(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_alarmSummary) ENABLED START -----*/ // Set the attribute value attr.set_value(attr_alarmSummary_read, alarmSummary_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarmSummary } //-------------------------------------------------------- /** * Read attribute eventList related method * Description: List of all subscribed attributes * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_eventList(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_eventList(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_eventList) ENABLED START -----*/ prepare_event_list(); // Set the attribute value attr.set_value(attr_eventList_read, eventList_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_eventList } //-------------------------------------------------------- /** * Read attribute eventSummary related method * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 10000 */ //-------------------------------------------------------- void AlarmHandler::read_eventSummary(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_eventSummary(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(AlarmHandler::read_eventSummary) ENABLED START -----*/ prepare_event_summary(); // Set the attribute value attr.set_value(attr_eventSummary_read, eventSummary_sz); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_eventSummary } //-------------------------------------------------------- /** * Read attribute AlarmState related method * Description: * * Data type: Tango::DevEnum (AlarmStateEnum) * Attr type: Scalar */ //-------------------------------------------------------- void AlarmHandler::read_AlarmState(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_AlarmState(Tango::Attribute &attr) entering... " << endl; Tango::DevEnum *att_value = get_AlarmState_data_ptr(attr.get_name()); /*----- PROTECTED REGION ID(AlarmHandler::read_AlarmState) ENABLED START -----*/ string reason(""); string desc(""); string origin(""); int quality = Tango::ATTR_VALID; alarms.vlock->readerIn(); alarm_container_t::iterator it; for(it = alarms.v_alarm.begin(); it != alarms.v_alarm.end(); it++) { if(it->second.attr_name == attr.get_name()) { break; } } bool error; if(it != alarms.v_alarm.end()) { reason = it->second.ex_reason; desc = it->second.ex_desc; origin = it->second.ex_origin; quality = it->second.quality; error = it->second.error; } DEBUG_STREAM << "AlarmHandler::read_AlarmState: " << attr.get_name() << " desc=" << desc << endl; alarms.vlock->readerOut(); if(error) //TODO: if needs to be considered err_delay also in single alarm attributes, error must be used //if(desc.length() > 0) { Tango::Except::throw_exception( reason, desc, origin, Tango::ERR); } // Set the attribute value if(quality != Tango::ATTR_VALID) { timeval now; gettimeofday(&now, NULL); attr.set_value_date_quality(att_value, now/*TODO timestamp*/, (Tango::AttrQuality)quality); } else { attr.set_value(att_value); } /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_AlarmState } //-------------------------------------------------------- /** * Read attribute AlarmFormula related method * Description: * * Data type: Tango::DevString * Attr type: Scalar */ //-------------------------------------------------------- void AlarmHandler::read_AlarmFormula(Tango::Attribute &attr) { //DEBUG_STREAM << "AlarmHandler::read_AlarmFormula(Tango::Attribute &attr) entering... " << endl; Tango::DevString *att_value = get_AlarmFormula_data_ptr(attr.get_name()); /*----- PROTECTED REGION ID(AlarmHandler::read_AlarmFormula) ENABLED START -----*/ // Set the attribute value attr.set_value(att_value); /*----- PROTECTED REGION END -----*/ // AlarmHandler::read_AlarmFormula } //-------------------------------------------------------- /** * Method : AlarmHandler::add_dynamic_attributes() * Description : Create the dynamic attributes if any * for specified device. */ //-------------------------------------------------------- void AlarmHandler::add_dynamic_attributes() { // Example to add dynamic attribute: // Copy inside the following protected area to create instance(s) at startup. // add_AlarmState_dynamic_attribute("MyAlarmStateAttribute"); // add_AlarmFormula_dynamic_attribute("MyAlarmFormulaAttribute"); /*----- PROTECTED REGION ID(AlarmHandler::add_dynamic_attributes) ENABLED START -----*/ // Add your own code to create and add dynamic attributes if any 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++) { add_AlarmState_dynamic_attribute(i->second.attr_name); Tango::DevEnum *attr_value = get_AlarmState_data_ptr(i->second.attr_name); i->second.attr_value = attr_value; i->second.attr_name_formula = i->second.attr_name + string("Formula"); #if _FORMULA_ATTR add_AlarmFormula_dynamic_attribute(i->second.attr_name_formula); Tango::DevString *attr_value_formula = get_AlarmFormula_data_ptr(i->second.attr_name_formula); *attr_value_formula = Tango::string_dup(i->second.formula.c_str()); i->second.attr_value_formula = attr_value_formula; #endif } } alarms.vlock->readerOut(); /*----- PROTECTED REGION END -----*/ // AlarmHandler::add_dynamic_attributes } //-------------------------------------------------------- /** * Command Ack related method * Description: Alarm acknowledge * * @param argin String array containing the alarms to be acknowledged */ //-------------------------------------------------------- void AlarmHandler::ack(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "AlarmHandler::Ack() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::ack) ENABLED START -----*/ // Add your own code vector<string> str; str << (*argin); vector<string>::iterator si; alarm_t localalarmed, localv_alarm; for (si = str.begin(); si != str.end(); si++) { alarms.vlock->readerIn(); alarmedlock->readerIn(); vector<alarm_t>::iterator found = \ find(alarmed.begin(), alarmed.end(), *si); if (found != alarmed.end()) { alarm_container_t::iterator i = alarms.v_alarm.find(*si); if(i == alarms.v_alarm.end()) { INFO_STREAM << __func__ << ": alarm '" << *si << "' not found"; alarmedlock->readerOut(); alarms.vlock->readerOut(); continue; } if(!i->second.enabled || i->second.shelved) { DEBUG_STREAM << __func__ << ": alarm '" << *si << "' not enabled"; alarmedlock->readerOut(); alarms.vlock->readerOut(); continue; } //update alarm ack in alarm table i->second.ack = ACK; //update alarm status from alarm table found->stat = i->second.stat; localalarmed = *found; //NOTE: copy before updating ack localv_alarm = i->second; found->ack = ACK; alarmedlock->readerOut(); alarms.vlock->readerOut(); if(localalarmed.ack == NOT_ACK) { Tango::DevEnum *attr_value = get_AlarmState_data_ptr(localv_alarm.attr_name); if(!localv_alarm.enabled) *attr_value = _OOSRV; else if(localv_alarm.shelved && localv_alarm.silenced > 0) *attr_value = _SHLVD; else if((localv_alarm.stat == S_NORMAL) && localv_alarm.ack == ACK) *attr_value = _NORM; else if((localv_alarm.stat == S_ALARM) && localv_alarm.ack == NOT_ACK) *attr_value = _UNACK; else if((localv_alarm.stat == S_ALARM) && localv_alarm.ack == ACK) *attr_value = _ACKED; else if((localv_alarm.stat == S_NORMAL) && localv_alarm.ack == NOT_ACK) *attr_value = _RTNUN; try { //DevFailed for push events if(localv_alarm.ex_reason.empty()) { timeval now; gettimeofday(&now, NULL); push_change_event(localv_alarm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)localv_alarm.quality, 1/*size*/, 0, false); push_archive_event(localv_alarm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)localv_alarm.quality, 1/*size*/, 0, false); } else { Tango::DevErrorList errors(1); errors.length(1); errors[0].desc = CORBA::string_dup(localv_alarm.ex_desc.c_str()); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup(localv_alarm.ex_reason.c_str()); errors[0].origin = CORBA::string_dup(localv_alarm.ex_origin.c_str()); Tango::DevFailed except(errors); push_change_event(localv_alarm.attr_name, &except); push_archive_event(localv_alarm.attr_name, &except); } } catch(Tango::DevFailed & ex) { WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } } } else //not found in alarmed { alarmedlock->readerOut(); alarms.vlock->readerOut(); } } /* * remove S_NORMAL status ACKnowledged alarms */ alarm_t to_be_removed; to_be_removed.name = ""; to_be_removed.formula = ""; to_be_removed.stat = S_NORMAL; to_be_removed.ack = ACK; bool go = true; while (go) { alarmedlock->writerIn(); vector<alarm_t>::iterator found = \ find(alarmed.begin(), alarmed.end(), to_be_removed); if (found != alarmed.end()) { DEBUG_STREAM << "AlarmHandler::ack(): " << found->name \ << " S_NORMAL and ACK, removing" << endl; alarmed.erase(found); } else { go = false; } alarmedlock->writerOut(); } prepare_alarm_attr(); 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 { //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); 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); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } /*----- PROTECTED REGION END -----*/ // AlarmHandler::ack } //-------------------------------------------------------- /** * Command Load related method * Description: Load a new alarm. * * @param argin Alarm entry */ //-------------------------------------------------------- void AlarmHandler::load(Tango::DevString argin) { DEBUG_STREAM << "AlarmHandler::Load() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::load) ENABLED START -----*/ // Add your own code DEBUG_STREAM << "AlarmHandler::LOAD ENTERING alm=" << argin << endl; string s; alarm_t alm; vector<string> evn; s = argin; //std::transform(s.begin(), s.end(), s.begin(), (int(*)(int))tolower); //transform to lowercase Tango::TimeVal ts = gettime(); try { load_alarm(s, alm, evn);//doesn't hold locks } catch(Tango::DevFailed& e) { ostringstream err; err << "error loading alarm=" << alm.name << " , " << e.errors[0].desc; WARN_STREAM << "AlarmHandler::load(): " << err.str() << endl; Tango::Except::throw_exception( \ (const char*)"AlarmHandler::load()", \ err.str(), \ (const char*)"AlarmHandler::load()", Tango::ERR); } try { add_alarm(alm);//holds alarm writer lock + reader lock } catch (string& err) { //TODO: not throwing string exception WARN_STREAM << "AlarmHandler::load(): " << err << endl; Tango::Except::throw_exception( \ (const char*)"AlarmHandler::load()", \ (const char*)err.c_str(), \ (const char*)"AlarmHandler::load()", Tango::ERR); } #if 0 try { Tango::Attribute attr = this->get_device_attr()->get_attr_by_name(alm.attr_name.c_str()); push_att_conf_event(&attr); } catch(Tango::DevFailed &e) { ostringstream o; o << "AlarmHandler::" << __func__<<": alarm '" << alm.name << "' cannot push att_conf event, err="<<e.errors[0].desc ; INFO_STREAM << o.str() << endl; } #endif #if 0 try { add_event(alm, evn); } catch (string& err) { WARN_STREAM << "AlarmHandler::load(): " << err << endl; alarms.vlock->writerIn(); alarm_container_t::iterator i = alarms.v_alarm.find(alm.name); //look for alarm just added if (i != alarms.v_alarm.end()) alarms.erase(i); //and remove from alarm_table alarms.vlock->writerOut(); Tango::Except::throw_exception( \ (const char*)"AlarmHandler::load()", \ (const char*)err.c_str(), \ (const char*)"AlarmHandler::load()", Tango::ERR); } #endif #if 0//already saved attribute property by subscribe thread alarms.save_alarm_conf_db(alm.attr_name, alm.name, "", "", alm.enabled, //add new alarm on log before subscribe event alm.formula, alm.on_delay, alm.off_delay, alm.grp2str(), alm.lev, alm.msg, alm.url, alm.cmd_name_a, alm.cmd_name_n, alm.silent_time); //but if it fails remove it from table DEBUG_STREAM << "AlarmHandler::LOAD save_alarm_conf_db-" << alm.attr_name << endl; string conf_str; alm.confstr(conf_str); savedlock->writerIn(); saved_alarms.insert(make_pair(alm.attr_name,conf_str)); savedlock->writerOut(); #endif alarms.vlock->readerIn(); alarm_container_t::iterator i = alarms.v_alarm.find(alm.name); if(i != alarms.v_alarm.end()) { try { add_event(i->second, evn);//moved after events->add //holds alarm reader lock } catch (string& err) { WARN_STREAM << "AlarmHandler::"<<__func__<<": string exception=" << err << endl; //TODO: handle error #if 0 for(vector<string>::iterator j = evn.begin(); j != evn.end(); j++) { DEBUG_STREAM << "AlarmHandler::"<<__func__<<": Removing alarm=" << i->second.name << " from event=" << *j << endl; vector<event>::iterator k = \ find(events->v_event.begin(), events->v_event.end(), *j); if (k != events->v_event.end()) { k->m_alarm.pop(i->second.name); //remove alarm/formula just added to event DEBUG_STREAM << "AlarmHandler::"<<__func__<<": Removed!!!! alarm=" << i->second.name << " from event=" << *j << endl; if(k->m_alarm.empty()) { events->v_event.erase(k); //remove event just added to event_table DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event=" << *j << " no more used, REMOVED!!!" << endl; } } } set_internal_alarm(INTERNAL_ERROR, gettime(), err); #endif } catch (Tango::DevFailed &e) { WARN_STREAM << "AlarmHandler::"<<__func__<<": Tango exception=" << e.errors[0].desc << endl; } if(i->second.cmd_name_a.length() > 0) { try { i->second.dp_a = new Tango::DeviceProxy(i->second.cmd_dp_a); i->second.dp_a->ping(); Tango::CommandInfo info = i->second.dp_a->command_query(i->second.cmd_action_a); if(info.in_type != Tango::DEV_STRING) { ostringstream err; err << "Error: command " << i->second.cmd_name_a << " does not accept a Tango::DevString as input value"; ERROR_STREAM << "AlarmHandler::load(): " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } else { if(info.in_type == Tango::DEV_STRING) i->second.send_arg_a = true; else i->second.send_arg_a = false; DEBUG_STREAM << "AlarmHandler::load(): successfully connected to proxy=" << i->second.cmd_dp_a << " for action=" << i->second.cmd_action_a << endl; } } catch(Tango::DevFailed& e) { ostringstream err; err << alm.name << ": error connecting to device proxy=" << i->second.cmd_dp_a << ", err=" << e.errors[0].desc; WARN_STREAM << "AlarmHandler::load(): " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } } if(i->second.cmd_name_n.length() > 0) { try { i->second.dp_n = new Tango::DeviceProxy(i->second.cmd_dp_n); i->second.dp_n->ping(); Tango::CommandInfo info = i->second.dp_n->command_query(i->second.cmd_action_n); if(info.in_type != Tango::DEV_STRING) { ostringstream err; err << "Error: command " << i->second.cmd_name_n << " does not accept a Tango::DevString as input value"; ERROR_STREAM << "AlarmHandler::load(): " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } else { if(info.in_type == Tango::DEV_STRING) i->second.send_arg_n = true; else i->second.send_arg_n = false; DEBUG_STREAM << "AlarmHandler::load(): successfully connected to proxy=" << i->second.cmd_dp_n << " for action=" << i->second.cmd_action_n << endl; } } catch(Tango::DevFailed& e) { ostringstream err; err << alm.name << ": error connecting to device proxy=" << i->second.cmd_dp_n << ", err=" << e.errors[0].desc; WARN_STREAM << "AlarmHandler::load(): " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } } DEBUG_STREAM << "AlarmHandler::"<<__func__<<": created command proxy, to_be_evaluated=" << (int)alm.to_be_evaluated << endl; //TODO: to be moved in subscribe thread after subscription //if at least one event was already existing, evaluate formula of just added alarm if(i->second.to_be_evaluated) //TODO: remove this evaluation of the formula that is not necessary { DEBUG_STREAM << "AlarmHandler::"<<__func__<<": to_be_evaluated!!" << endl; bei_t e; e.ev_name = ALARM_THREAD_TO_BE_EVAL; e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE); e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE); evlist.push_back(e); } } alarms.vlock->readerOut(); #if 0//TODO prepare_alarm_attr(); 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 //attr.set_value(ds, ds_num, 0, false); push_change_event("alarm",ds, ds_num, 0, false); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } #endif DEBUG_STREAM << "AlarmHandler::LOAD EXITING alm=" << argin << endl; /*----- PROTECTED REGION END -----*/ // AlarmHandler::load } //-------------------------------------------------------- /** * Command Remove related method * Description: Remove alarm. * * @param argin Alarm name */ //-------------------------------------------------------- void AlarmHandler::remove(Tango::DevString argin) { DEBUG_STREAM << "AlarmHandler::Remove() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::remove) ENABLED START -----*/ // Add your own code string s, log_alm_name; s = argin; log_alm_name = argin; bool ret = false; alarmedlock->readerIn(); vector<alarm_t>::iterator found = find(alarmed.begin(), alarmed.end(), s); if (found != alarmed.end()) { ostringstream err; err << s << " is in ALARM status! Acknowledge it before removing."; if((found->stat == S_ALARM) && (found->ack == NOT_ACK)) { alarmedlock->readerOut(); Tango::Except::throw_exception( \ (const char*)"Error removing alarm", \ (const char*)err.str().c_str(), \ (const char*)"AlarmHandler::remove", Tango::ERR); } } alarmedlock->readerOut(); try { ret = remove_alarm(s); } catch (string& err) { Tango::Except::throw_exception( \ (const char*)"Error removing alarm", \ (const char*)err.c_str(), \ (const char*)"AlarmHandler::remove", Tango::ERR); } if (ret) { DEBUG_STREAM << "AlarmHandler::remove(): removing alarm '" \ << s << "'" << endl; while (true) { string::size_type i = s.find_first_of("/."); if (i == string::npos) break; s.replace(i, 1, "_"); } } /* end if */ alarmedlock->writerIn(); found = find(alarmed.begin(), alarmed.end(), s); //look again because in the meanwhile lock was not acquired if (found != alarmed.end()) { alarmed.erase(found); //remove from alarmed table } alarmedlock->writerOut(); prepare_alarm_attr(); 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 { //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); 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); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } /*----- PROTECTED REGION END -----*/ // AlarmHandler::remove } //-------------------------------------------------------- /** * Command SearchAlarm related method * Description: Return list of configured alarms matching the filter string * * @param argin String containing a filter for output, if empty or * return all alarms * @returns Configured alarms */ //-------------------------------------------------------- Tango::DevVarStringArray *AlarmHandler::search_alarm(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "AlarmHandler::SearchAlarm() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::search_alarm) ENABLED START -----*/ // Add your own code // POGO has generated a method core with argout allocation. // If you would like to use a static reference without copying, // See "TANGO Device Server Programmer's Manual" // (chapter : Writing a TANGO DS / Exchanging data) //------------------------------------------------------------ argout = new Tango::DevVarStringArray(); //argout->length(1); //(*argout)[0] = CORBA::string_dup("dummy"); DEBUG_STREAM << "AlarmHandler::configured(): entering... !" << endl; // Add your own code to control device here string filter(argin); string filter_begin(filter); string filter_end(""); size_t start_pos = 0; /* string from("*"); string to(""); while((start_pos = filter.find(from, start_pos)) != std::string::npos) { filter.replace(start_pos, from.length(), to); start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' }*/ start_pos = filter.find("*", start_pos); if(start_pos != std::string::npos && start_pos == filter.size()-1) //* is the only character or at the end of the filter { filter.replace(start_pos, 1, ""); filter_begin = filter; DEBUG_STREAM << __func__ << ": updated filter to: " << filter_begin; } /*else if(start_pos != std::string::npos) //* is in the middle of the filter { string filter_begin=filter.substr(0,start_pos); string filter_end=filter.substr(start_pos+1); DEBUG_STREAM << __func__ << ": splitted filter to: " << filter_begin << " - " << filter_end; }*/ size_t found; vector<string> alarm_filtered; ostringstream os1; os1.clear(); /*os1 << headerConfig << "\t" << alarms.v_alarm.size() << ends; alarm_filtered.push_back(os1.str());*/ alarm_container_t::iterator ai; alarms.vlock->readerIn(); for (ai = alarms.v_alarm.begin(); ai != alarms.v_alarm.end(); ai++) { found = 0; if(filter_begin.length() != 0) { found = ai->first.find(filter_begin); } if((filter_begin.length() == 0) || (found != string::npos)) { ostringstream os; os.clear(); os << ai->second.ts.tv_sec << SEP << KEY(NAME_KEY) << ai->second.name << SEP << KEY(FORMULA_KEY) << ai->second.formula << SEP << KEY(ONDELAY_KEY) << ai->second.on_delay << SEP << KEY(OFFDELAY_KEY) << ai->second.off_delay << SEP << KEY(LEVEL_KEY) << ai->second.lev << SEP << KEY(SILENT_TIME_KEY) << ai->second.silent_time << SEP << KEY(GROUP_KEY) << ai->second.grp2str() << SEP << KEY(MESSAGE_KEY) << ai->second.msg << SEP << KEY(URL_KEY) << ai->second.url << SEP << KEY(ON_COMMAND_KEY) << ai->second.cmd_name_a << SEP << KEY(OFF_COMMAND_KEY) << ai->second.cmd_name_n << SEP << KEY(ENABLED_KEY) << (ai->second.enabled ? "1" : "0"); alarm_filtered.push_back(os.str()); } } /* for */ alarms.vlock->readerOut(); argout->length(alarm_filtered.size()); int i = 0; for (vector<string>::iterator it= alarm_filtered.begin(); it != alarm_filtered.end(); it++) { (*argout)[i] = CORBA::string_dup(it->c_str()); i++; } /*----- PROTECTED REGION END -----*/ // AlarmHandler::search_alarm return argout; } //-------------------------------------------------------- /** * Command StopAudible related method * Description: Stop audible indications on the GUI * */ //-------------------------------------------------------- void AlarmHandler::stop_audible() { DEBUG_STREAM << "AlarmHandler::StopAudible() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::stop_audible) ENABLED START -----*/ // Add your own code //12-06-08: StopNew command set is_new to 0 // Add your own code to control device here alarm_container_t::iterator ai; alarms.vlock->readerIn(); for (ai = alarms.v_alarm.begin(); ai != alarms.v_alarm.end(); ai++) { ai->second.is_new = 0; //set all alarm as no more new } alarms.vlock->readerOut(); prepare_alarm_attr(); 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 { //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); 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); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } /*----- PROTECTED REGION END -----*/ // AlarmHandler::stop_audible } //-------------------------------------------------------- /** * Command Silence related method * Description: Alarm temporarily silence * * @param argin String array containing the alarms to be silenced */ //-------------------------------------------------------- void AlarmHandler::silence(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "AlarmHandler::Silence() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::silence) ENABLED START -----*/ // Add your own code vector<string> str; str << (*argin); vector<string>::iterator si; for (si = str.begin(); si != str.end(); si++) { alarms.vlock->readerIn(); alarm_container_t::iterator i = alarms.v_alarm.find(*si); if(i != alarms.v_alarm.end()) { if(i->second.silenced > 0) { Tango::TimeVal now = gettime(); double dnow = now.tv_sec + ((double)now.tv_usec) / 1000000; double dsilent = i->second.ts_time_silenced.tv_sec + ((double)i->second.ts_time_silenced.tv_usec) / 1000000; double dminutes = (dnow - dsilent)/60; //silenced already calculated in alarm_table::update, but here updated for panel also if state not changed: //to see minutes countdown if(dminutes < i->second.silent_time) { i->second.silenced = i->second.silent_time - floor(dminutes); } else { i->second.silenced = 0; i->second.shelved = false; } } if(i->second.silenced > 0) { ostringstream err; err << "Alarm " << *si << " already silenced for " << i->second.silenced << " more minutes"; alarms.vlock->readerOut(); Tango::Except::throw_exception( \ (const char*)"Alarm already silenced", \ err.str(), \ (const char*)"AlarmHandler::silence()", Tango::ERR); } if(i->second.silent_time <= 0) { ostringstream err; err << "Alarm " << *si << " cannot be silenced"; alarms.vlock->readerOut(); Tango::Except::throw_exception( \ (const char*)"Alarm cannot be silenced", \ err.str(), \ (const char*)"AlarmHandler::silence()", Tango::ERR); } //load silent time i->second.ts_time_silenced = gettime(); i->second.silenced = i->second.silent_time; //search also in alarmed alarmedlock->readerIn(); vector<alarm_t>::iterator found = \ find(alarmed.begin(), alarmed.end(), *si); if (found != alarmed.end()) { //load silent time from alarm table found->silenced = i->second.silent_time; found->ts_time_silenced = i->second.ts_time_silenced; } alarmedlock->readerOut(); } //alarms.unlock(); if(i == alarms.v_alarm.end()) { alarms.vlock->readerOut(); ostringstream err; err << "Alarm " << *si << " not found"; Tango::Except::throw_exception( \ (const char*)"Alarm not found!!", \ err.str(), \ (const char*)"AlarmHandler::silence()", Tango::ERR); } alarms.vlock->readerOut(); } prepare_alarm_attr(); 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 { //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); 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); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } /*----- PROTECTED REGION END -----*/ // AlarmHandler::silence } //-------------------------------------------------------- /** * Command Modify related method * Description: Modify an existing alarm. * * @param argin Alarm entry */ //-------------------------------------------------------- void AlarmHandler::modify(Tango::DevString argin) { DEBUG_STREAM << "AlarmHandler::Modify() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::modify) ENABLED START -----*/ // Add your own code DEBUG_STREAM << "AlarmHandler::Modify: " << argin << endl; // Add your own code //------------------------------ //1: parse to get alarm name //------------------------------ string alarm_string(argin); alarm_t alm; parse_alarm(alarm_string, alm); DEBUG_STREAM << "AlarmHandler::Modify: parsing ended: alm name=" << alm.name << endl; //------------------------------ //2: if alarm already exist and // formula is not changed //------------------------------ alarms.vlock->writerIn(); //TODO: use readerIn instead? alarm_container_t::iterator i = alarms.v_alarm.find(alm.name); if (i != alarms.v_alarm.end()) { if(i->second.formula == alm.formula) { Tango::TimeVal ts = gettime(); string cmd_name_full = alm.cmd_name_a + string(";") + alm.cmd_name_n; i->second.stat = S_NORMAL; i->second.ack = ACK; i->second.done = false; i->second.msg = alm.msg; i->second.url = alm.url; i->second.lev = alm.lev; i->second.grp = alm.grp; //i->second.to_be_evaluated = alm.to_be_evaluated; i->second.on_delay = alm.on_delay; i->second.off_delay = alm.off_delay; i->second.silent_time = alm.silent_time; i->second.silenced = (i->second.silent_time > 0) ? 0 : -1; //0: can be silenced, -1: cannot be silencedd; i->second.cmd_name_a = alm.cmd_name_a; i->second.cmd_dp_a = alm.cmd_dp_a; i->second.cmd_action_a = alm.cmd_action_a; //i->second.send_arg_a = alm.send_arg_a; i->second.cmd_name_n = alm.cmd_name_n; i->second.cmd_dp_n = alm.cmd_dp_n; i->second.cmd_action_n = alm.cmd_action_n; //i->second.send_arg_n = alm.send_arg_n; i->second.enabled = alm.enabled; //update attribute properties events->update_property(); //delete proxy for actions if(i->second.dp_a) delete i->second.dp_a; i->second.dp_a = NULL; if(i->second.dp_n) delete i->second.dp_n; i->second.dp_n = NULL; if(alm.cmd_name_a.length() > 0) { try { i->second.dp_a = new Tango::DeviceProxy(i->second.cmd_dp_a); i->second.dp_a->ping(); Tango::CommandInfo info = i->second.dp_a->command_query(i->second.cmd_action_a); if(info.in_type != Tango::DEV_STRING) { ostringstream err; err << "Error: command " << i->second.cmd_name_a << " does not accept a Tango::DevString as input value"; ERROR_STREAM << __func__<<": " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } else { if(info.in_type == Tango::DEV_STRING) i->second.send_arg_a = true; else i->second.send_arg_a = false; DEBUG_STREAM << __func__<<": successfully connected to proxy=" << i->second.cmd_dp_a << " for action=" << i->second.cmd_action_a << endl; } } catch(Tango::DevFailed& e) { ostringstream err; err << alm.name << ": error connecting to device proxy=" << i->second.cmd_dp_a << ", err=" << e.errors[0].desc; WARN_STREAM << __func__<<": " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } } if(alm.cmd_name_n.length() > 0) { try { i->second.dp_n = new Tango::DeviceProxy(i->second.cmd_dp_n); i->second.dp_n->ping(); Tango::CommandInfo info = i->second.dp_n->command_query(i->second.cmd_action_a); if(info.in_type != Tango::DEV_STRING) { ostringstream err; err << "Error: command " << i->second.cmd_name_n << " does not accept a Tango::DevString as input value"; ERROR_STREAM << __func__<<": " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } else { if(info.in_type == Tango::DEV_STRING) i->second.send_arg_n = true; else i->second.send_arg_n = false; DEBUG_STREAM << __func__<<": successfully connected to proxy=" << i->second.cmd_dp_n << " for action=" << i->second.cmd_action_n << endl; } } catch(Tango::DevFailed& e) { ostringstream err; err << alm.name << ": error connecting to device proxy=" << i->second.cmd_dp_n << ", err=" << e.errors[0].desc; WARN_STREAM << __func__<<": " << err.str() << endl; set_internal_alarm(INTERNAL_ERROR, gettime(), err.str()); } } alarms.vlock->writerOut(); return; } } else { alarms.vlock->writerOut(); ostringstream o; o << "Alarm '"<<alm.name<<"' not found"; DEBUG_STREAM << o.str() << endl; Tango::Except::throw_exception( \ (const char*)"Not found", \ (const char*)o.str().c_str(), \ (const char*)__func__, Tango::ERR); } alarms.vlock->writerOut(); //------------------------------ //3: remove (set active=0 on db) //------------------------------ remove((Tango::DevString)alm.name.c_str()); DEBUG_STREAM << "AlarmHandler::Modify: removed alm name=" << alm.name << endl; //------------------------------ //4: load modified alarm //------------------------------ load(argin); prepare_alarm_attr(); 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 { //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); 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); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } /*----- PROTECTED REGION END -----*/ // AlarmHandler::modify } //-------------------------------------------------------- /** * Command Shelve related method * Description: Shelve an alarm: no state transition recorded, no audible nor visual indication * * @param argin String array containing alarm to be shelved */ //-------------------------------------------------------- void AlarmHandler::shelve(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "AlarmHandler::Shelve() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::shelve) ENABLED START -----*/ // Add your own code vector<string> str; str << (*argin); vector<string>::iterator si; for (si = str.begin(); si != str.end(); si++) { alarms.vlock->readerIn(); alarm_container_t::iterator i = alarms.v_alarm.find(*si); if(i == alarms.v_alarm.end()) { ostringstream err; err << *si << " not found in configured alarms"; alarms.vlock->readerOut(); Tango::Except::throw_exception( \ (const char*)"NOT_FOUND", \ (const char*)err.str().c_str(), \ (const char*)__func__, Tango::ERR); } if(!i->second.enabled) { ostringstream err; err << *si << " is not enabled"; alarms.vlock->readerOut(); Tango::Except::throw_exception( \ (const char*)"NOT_ENABLED", \ (const char*)err.str().c_str(), \ (const char*)__func__, Tango::ERR); } if(i->second.silenced > 0) { Tango::TimeVal now = gettime(); double dnow = now.tv_sec + ((double)now.tv_usec) / 1000000; double dsilent = i->second.ts_time_silenced.tv_sec + ((double)i->second.ts_time_silenced.tv_usec) / 1000000; double dminutes = (dnow - dsilent)/60; //silenced already calculated in alarm_table::update, but here updated for panel also if state not changed: //to see minutes countdown if(dminutes < i->second.silent_time)//TODO: shelve_time ? { i->second.silenced = i->second.silent_time - floor(dminutes);//TODO: shelve_time ? } else { i->second.silenced = 0; i->second.shelved = false; } } if(i->second.shelved) { ostringstream err; err << *si << " is already shelved"; alarms.vlock->readerOut(); Tango::Except::throw_exception( \ (const char*)"ALREADY_SHELVED", \ (const char*)err.str().c_str(), \ (const char*)__func__, Tango::ERR); } if(i->second.silent_time <= 0) { ostringstream err; err << "Alarm " << *si << " cannot be shelved"; alarms.vlock->readerOut(); Tango::Except::throw_exception( \ (const char*)"NOT_ALLOWED", \ err.str(), \ (const char*)__func__, Tango::ERR); } alarms.vlock->readerOut(); } for (si = str.begin(); si != str.end(); si++) { alarms.vlock->readerIn(); alarm_container_t::iterator i = alarms.v_alarm.find(*si); if(i == alarms.v_alarm.end()) { alarms.vlock->readerOut(); continue; } i->second.shelved = true; //load silent time i->second.ts_time_silenced = gettime(); i->second.silenced = i->second.silent_time; //TODO: shelve_time ? //search also in alarmed alarmedlock->writerIn(); vector<alarm_t>::iterator found = \ find(alarmed.begin(), alarmed.end(), *si); if (found != alarmed.end()) { alarmed.erase(found); } alarmedlock->writerOut(); alarm_t alm = i->second; alarms.vlock->readerOut(); Tango::DevEnum *attr_value = get_AlarmState_data_ptr(alm.attr_name); *attr_value = _SHLVD; try { //DevFailed for push events if(alm.ex_reason.empty()) { timeval now; gettimeofday(&now, NULL); push_change_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false); push_archive_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false); } else { 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); push_change_event(alm.attr_name, &except); push_archive_event(alm.attr_name, &except); } } catch(Tango::DevFailed & ex) { WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } } prepare_alarm_attr(); 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 { //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("alarmSummary",attr_alarmSummary_read); 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("alarmSummary",attr_alarmSummary_read); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } /*----- PROTECTED REGION END -----*/ // AlarmHandler::shelve } //-------------------------------------------------------- /** * Command Enable related method * Description: Enable an alarm from Out of service state * * @param argin Alarm name */ //-------------------------------------------------------- void AlarmHandler::enable(Tango::DevString argin) { DEBUG_STREAM << "AlarmHandler::Enable() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::enable) ENABLED START -----*/ // Add your own code string arginname(argin); alarms.vlock->readerIn(); alarm_container_t::iterator i = alarms.v_alarm.find(arginname); if(i == alarms.v_alarm.end()) { ostringstream err; err << arginname << " not found in configured alarms"; alarms.vlock->readerOut(); Tango::Except::throw_exception( \ (const char*)"NOT_FOUND", \ (const char*)err.str().c_str(), \ (const char*)__func__, Tango::ERR); } i->second.enabled = true; i->second.silenced = (i->second.silent_time > 0) ? 0 : -1; //0: can be silenced, -1: cannot be silenced i->second.shelved = false; alarm_t alm = i->second; alarms.vlock->readerOut(); Tango::DevEnum *attr_value = get_AlarmState_data_ptr(alm.attr_name); if((alm.stat == S_NORMAL) && alm.ack == ACK) *attr_value = _NORM; else if((alm.stat == S_ALARM) && alm.ack == NOT_ACK) *attr_value = _UNACK; else if((alm.stat == S_ALARM) && alm.ack == ACK) *attr_value = _ACKED; else if((alm.stat == S_NORMAL) && alm.ack == NOT_ACK) *attr_value = _RTNUN; try { //DevFailed for push events if(alm.ex_reason.empty()) { timeval now; gettimeofday(&now, NULL); push_change_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false); push_archive_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false); } else { 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); push_change_event(alm.attr_name, &except); push_archive_event(alm.attr_name, &except); } } catch(Tango::DevFailed & ex) { WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } prepare_alarm_attr(); 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 { //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("alarmSummary",attr_alarmSummary_read); 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("alarmSummary",attr_alarmSummary_read); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } //update attribute properties events->update_property(); /*----- PROTECTED REGION END -----*/ // AlarmHandler::enable } //-------------------------------------------------------- /** * Command Disable related method * Description: Put an alarm in Out of service state * * @param argin Alarm name */ //-------------------------------------------------------- void AlarmHandler::disable(Tango::DevString argin) { DEBUG_STREAM << "AlarmHandler::Disable() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::disable) ENABLED START -----*/ // Add your own code string arginname(argin); alarms.vlock->readerIn(); alarm_container_t::iterator i = alarms.v_alarm.find(arginname); if(i == alarms.v_alarm.end()) { ostringstream err; err << arginname << " not found in configured alarms"; alarms.vlock->readerOut(); Tango::Except::throw_exception( \ (const char*)"NOT_FOUND", \ (const char*)err.str().c_str(), \ (const char*)__func__, Tango::ERR); } i->second.enabled = false; i->second.silenced = (i->second.silent_time > 0) ? 0 : -1; //0: can be silenced, -1: cannot be silenced i->second.shelved = false; alarm_t alm = i->second; alarms.vlock->readerOut(); Tango::DevEnum *attr_value = get_AlarmState_data_ptr(alm.attr_name); *attr_value = _OOSRV; try { //DevFailed for push events if(alm.ex_reason.empty()) { timeval now; gettimeofday(&now, NULL); push_change_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false); push_archive_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false); } else { 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); push_change_event(alm.attr_name, &except); push_archive_event(alm.attr_name, &except); } } catch(Tango::DevFailed & ex) { WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } /* * remove from alarmed */ bool go = true; while (go) { alarmedlock->writerIn(); vector<alarm_t>::iterator found = \ find(alarmed.begin(), alarmed.end(), arginname); if (found != alarmed.end()) { DEBUG_STREAM << "AlarmHandler::"<<__func__<<": " << found->name \ << " removing" << endl; alarmed.erase(found); } else { go = false; } alarmedlock->writerOut(); } prepare_alarm_attr(); 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 { //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); 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); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } //update attribute properties events->update_property(); /*----- PROTECTED REGION END -----*/ // AlarmHandler::disable } //-------------------------------------------------------- /** * Command ResetStatistics related method * Description: Reset statistics * */ //-------------------------------------------------------- void AlarmHandler::reset_statistics() { DEBUG_STREAM << "AlarmHandler::ResetStatistics() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::reset_statistics) ENABLED START -----*/ // Add your own code alarms.vlock->readerIn(); for(alarm_container_t::iterator i = alarms.v_alarm.begin(); i!= alarms.v_alarm.end(); i++) { i->second.freq_counter = 0; } alarms.vlock->readerOut(); timespec now; clock_gettime(CLOCK_MONOTONIC, &now); double dnow = (now.tv_sec) + ((double)(now.tv_nsec))/1000000000; last_statistics_reset_time = dnow; /*----- PROTECTED REGION END -----*/ // AlarmHandler::reset_statistics } //-------------------------------------------------------- /** * Command StopNew related method * Description: Stop audible indications on the GUI * */ //-------------------------------------------------------- void AlarmHandler::stop_new() { DEBUG_STREAM << "AlarmHandler::StopNew() - " << device_name << endl; /*----- PROTECTED REGION ID(AlarmHandler::stop_new) ENABLED START -----*/ // Add your own code //12-06-08: StopNew command set is_new to 0 // Add your own code to control device here alarm_container_t::iterator ai; alarms.vlock->readerIn(); for (ai = alarms.v_alarm.begin(); ai != alarms.v_alarm.end(); ai++) { ai->second.is_new = 0; //set all alarm as no more new } alarms.vlock->readerOut(); prepare_alarm_attr(); 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 { //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); 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); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } /*----- PROTECTED REGION END -----*/ // AlarmHandler::stop_new } //-------------------------------------------------------- /** * Command GetAlarmInfo related method * Description: Returns the complete attribute info as an array of key=value * * @param argin Alarm name followed optionally by wanted key names * @returns Complete attribute info as an array of key=value */ //-------------------------------------------------------- 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 -----*/ 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(); 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 '" << 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); } 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) << ")"; ostringstream tmp_ex; tmp_ex.str(""); if(it->second.error) { tmp_ex << "{\"Reason\":\"" << it->second.ex_reason << "\",\"Desc\":\"" << it->second.ex_desc << "\",\"Origin\":\"" << it->second.ex_origin << "\"}"; info.insert(make_pair(VALUE_KEY,string("ERROR"))); complete.push_back(KEY(VALUE_KEY)+string("ERROR")); 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()); } 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); } ostringstream tmp_qual; 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()); ostringstream tmp; //#if 0 tmp.str(""); 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 tmp.str(""); 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 tmp.str(""); tmp << (it->second.is_new ? "1" : "0"); info.insert(make_pair(AUDIBLE_KEY,tmp.str())); complete.push_back(KEY(AUDIBLE_KEY)+tmp.str()); tmp.str(""); 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); 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); info.insert(make_pair(ONDELAY_KEY,tmp.str())); complete.push_back(KEY(ONDELAY_KEY)+tmp.str()); tmp.str(""); tmp << (it->second.off_delay); 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); info.insert(make_pair(SILENT_TIME_KEY,tmp.str())); complete.push_back(KEY(SILENT_TIME_KEY)+tmp.str()); tmp.str(""); tmp << (it->second.silenced); 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(URL_KEY,it->second.url)); complete.push_back(KEY(URL_KEY)+it->second.url); 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(); 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 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 } //-------------------------------------------------------- /** * Method : AlarmHandler::add_dynamic_commands() * Description : Create the dynamic commands if any * for specified device. */ //-------------------------------------------------------- void AlarmHandler::add_dynamic_commands() { /*----- PROTECTED REGION ID(AlarmHandler::add_dynamic_commands) ENABLED START -----*/ // Add your own code to create and add dynamic commands if any /*----- PROTECTED REGION END -----*/ // AlarmHandler::add_dynamic_commands } /*----- PROTECTED REGION ID(AlarmHandler::namespace_ending) ENABLED START -----*/ // Additional Methods /* * private methods */ void AlarmHandler::load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn) { DEBUG_STREAM << "AlarmHandler::load_alarm(): Creating Spirit Parser... ->" << alarm_string << endl; 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.error = false; alm.ts_err_delay = gettime(); alm.ts_err_delay.tv_sec -= errorDelay; alm.err_counter = 0; alm.formula.clear(); alm.msg.clear(); alm.url.clear(); alm.lev.clear(); alm.grp=0; alm.to_be_evaluated = false; alm.on_delay = 0; alm.off_delay = 0; 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; alm.enabled = 1; 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; #if 0 alm.attr_name = std::regex_replace(alm.attr_name, std::regex("/"), "_"); #endif } //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 ";" if(alm.cmd_name_a.length() > 0) { const char *c = alm.cmd_name_a.c_str(); int j = 0; while (*c) { if (*c == '/') j++; if (j < 3) alm.cmd_dp_a.push_back(*c); else if (*c != '/') alm.cmd_action_a.push_back(*c); c++; } } if(alm.cmd_name_n.length() > 0) { const char *c = alm.cmd_name_n.c_str(); int j = 0; while (*c) { if (*c == '/') j++; if (j < 3) alm.cmd_dp_n.push_back(*c); else if (*c != '/') alm.cmd_action_n.push_back(*c); c++; } } alm.silenced = (alm.silent_time > 0) ? 0 : -1; //0: can be silenced, -1: cannot be silenced DEBUG_STREAM << "Parsing succeeded! ->" << alm.name << endl; find_event_formula(alm.formula_tree,evn); //populate event list found in this formula ostringstream dbg_msg; dbg_msg << "In " << alm.name << " Event ="; for (vector<string>::iterator i = evn.begin(); i != evn.end(); i++) dbg_msg << *i << ", "; dbg_msg; 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 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); } alm.ts = gettime(); DEBUG_STREAM << "AlarmHandler::load_alarm(): name = '" << alm.name << "'" << endl; DEBUG_STREAM << " attr_name = '" << alm.attr_name << "'" << endl; DEBUG_STREAM << " formula = '" << alm.formula << "'" << 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 << " url = '" << alm.url << "'" << 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; if ((alm.name.empty() == false) && \ (alm.formula.empty() == false) && \ (alm.msg.empty() == false) && \ ((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))) { 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 << "'"; WARN_STREAM << o.str() << endl; Tango::Except::throw_exception( \ (const char*)o.str().c_str(), \ (const char*)"", \ (const char*)"AlarmHandler::load_alarm()", Tango::ERR); } if (alarms.exist(alm.name)) { ostringstream o; o << "AlarmHandler::load_alarm(): alarm '" << alm.name << "' already exist"; 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); } } #if 0 void AlarmHandler::init_alarms(map< string,vector<string> > &alarm_events) { 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; 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; 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; //break; ??? } /* if */ } /* for */ } } alarms.vlock->readerOut(); } #endif void AlarmHandler::init_events(vector<string> &evn) { 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)); j++; } } /* if */ } void AlarmHandler::add_alarm(alarm_t& a, bool starting) { alarms.push_back(a); //take and release writer vlock DEBUG_STREAM << "AlarmHandler::add_alarm(): added alarm '" \ << a.name << "'" << endl; if(!starting) { alarms.vlock->readerIn(); 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 alarms.vlock->readerOut(); } } void AlarmHandler::add_event(alarm_t& a, vector<string> &evn) throw(string&) { DEBUG_STREAM << "AlarmHandler::add_event(): formula '" << a.formula << "' found " << evn.size() << " events" << endl; /* * 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 } } 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->m_alarm.push(a.name); a.to_be_evaluated = true; DEBUG_STREAM << "AlarmHandler::add_event(): '" << *j << "' found, added " \ << " 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 '" << a.name << "'" << endl; } alarms.vlock->readerOut(); } else { /* * new event; add to event table */ //event e(*j); //events->push_back(e); /* * update per-alarm event list */ DEBUG_STREAM << "AlarmHandler::add_event(): adding '" << *j \ << "' 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 '" << a.name << "'" << endl; } alarms.vlock->readerOut(); /* * now, for the just-added event */ k = find(events->v_event.begin(), events->v_event.end(), *j); if (k != events->v_event.end()) { k->m_alarm.push(a.name); #if 0 //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); k->valid = true; ostringstream msg; msg << "AlarmHandler::add_event(): initial values of " << k->name << " = "; 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->m_alarm.pop(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->m_alarm.pop(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(); } #endif } } } //for (vector<string>::iterator j = evn.begin(); ... 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 already present { string name=*j; events->start(name);//throws exception if not found } } } /* * because called asynchronously by alarm evaluating thread * will use an alarm to report errors */ void AlarmHandler::do_alarm(bei_t& e) { bool changed=true; int num_changed=0; //if (e.name == INTERNAL_ERROR) { if(e.type == TYPE_TANGO_ERR || e.type == TYPE_GENERIC_ERR) { ostringstream o; o << e.msg; WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl; events->veclock.readerIn(); 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; 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; 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; set_internal_alarm(e.ev_name, gettime(), o.str()); } } if(found_ev != events->v_event.end()) { Tango::TimeVal ts = gettime(); 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()) { it->second.err_counter++; //if first error, reset ACK if(it->second.ex_reason.empty() && it->second.ex_desc.empty() && it->second.ex_origin.empty()) { it->second.ack = NOT_ACK; it->second.ts_err_delay = gettime(); //first occurrance of this error, now begin to wait for err delay } 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; if(errorDelay > 0) { 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.is_new = 1; it->second.error = true; } } else { if(!it->second.error) it->second.is_new = 1; it->second.error = true; } alarm_t alm = it->second; alarms.vlock->readerOut(); 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) {} } else { alarms.vlock->readerOut(); } j++; } 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 { //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_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); } return; } DEBUG_STREAM << "AlarmHandler::"<<__func__<<": arrived event=" << e.ev_name << endl; formula_res_t res; events->veclock.readerIn(); 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; 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; 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; 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; found->valid = true; found->ts = e.ts; found->type = e.type; found->read_size = e.read_size; 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(); prepare_alm_mtx->lock(); 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(); alarms.vlock->readerOut(); 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 { //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_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); } else { 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 prev_error = false; 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) { prev_error = true; DEBUG_STREAM << "AlarmHandler::"<<__func__<<": before evaluating exception {"<<ex_reason<<","<<ex_desc.length()<<","<<ex_origin<<"}"<<endl; } try { it->second.attr_values = string("{"); 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); 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) { timeval now; gettimeofday(&now, NULL); 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 { 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()); errors[0].origin = CORBA::string_dup(ex_origin.c_str()); Tango::DevFailed except(errors); push_change_event(attr_name, &except); push_archive_event(attr_name, &except); } } catch(Tango::DevFailed & ex) { WARN_STREAM << "AlarmHandler::"<<__func__<<": " << attr_name << " - EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } } catch(std::out_of_range& ex) { changed = !prev_error; it->second.to_be_evaluated = 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); alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks push_change_event(attr_name, &except); push_archive_event(attr_name, &except); } catch(Tango::DevFailed & ex) { WARN_STREAM << "AlarmHandler::"<<__func__<<": " << attr_name << " - EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } } catch(string & ex) { changed = !prev_error; it->second.to_be_evaluated = 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); alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks push_change_event(attr_name, &except); push_archive_event(attr_name, &except); } catch(Tango::DevFailed & ex) { WARN_STREAM << "AlarmHandler::"<<__func__<<": " << attr_name << " - EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } } } 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) { WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; } #endif } //alarms.vlock->readerOut(); return changed; } void AlarmHandler::timer_update() { bool changed=true; //DEBUG_STREAM << "AlarmHandler::timer_update(): entering..." << endl; 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);*/ } if(!changed) { return; } prepare_alarm_attr();//TODO: frequencyAlarm should be updated anyway 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 { //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_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); } catch(Tango::DevFailed& e) { ostringstream err; err << "error pushing alarm change event err=" << e.errors[0].desc; INFO_STREAM << __func__<<": " << err.str() << endl; } } bool AlarmHandler::remove_alarm(string& s) throw(string&) { DEBUG_STREAM << "AlarmHandler::"<<__func__<<": entering alm name=" << s << endl; alarms.vlock->writerIn(); alarm_container_t::iterator i = alarms.v_alarm.find(s); if (i != alarms.v_alarm.end()) { DEBUG_STREAM << "AlarmHandler::"<<__func__<<": found in table alm name=" << s << endl; for (set<string>::iterator j = i->second.s_event.begin(); \ j != i->second.s_event.end(); j++) { DEBUG_STREAM << "AlarmHandler::"<<__func__<<": looping event =" << *j << endl; /* * for each event into the per-alarm event list find * the event table entry and remove this alarm from * per-event alarm list */ vector<event>::iterator k = \ find(events->v_event.begin(), events->v_event.end(), *j); if (k != events->v_event.end()) { DEBUG_STREAM << "AlarmHandler::"<<__func__<<": found event =" << *j << " in vector events, removing from its alarm list name=" << i->second.name << endl; /* * remove alarm */ k->m_alarm.pop(i->second.name); DEBUG_STREAM << "AlarmHandler::"<<__func__<<": after m_alarm.pop" << endl; if (k->m_alarm.empty()) { /* * no more alarms associated to this event, unsubscribe * and remove from event table */ DEBUG_STREAM << "AlarmHandler::remove_alarm(): removing event '" \ << k->name << "' from event table" << endl; try { events->stop(k->name); events->remove(k->name, false); } catch (...) { ostringstream o; o << "unsubscribe_event() failed for " \ << k->name; WARN_STREAM << "AlarmHandler::remove_alarm(): " << o.str() << endl; alarms.vlock->writerOut(); throw o.str(); //return false; } //events->v_event.erase(k); } } else { /* * shouldn't happen!!! */ ostringstream o; o << "event '" << *j \ << "' not found in event table"; WARN_STREAM << "AlarmHandler::remove_alarm(): " << o.str() << endl; alarms.vlock->writerOut(); throw o.str(); //return false; } } /* for */ events->update_property(); //delete proxy for actions if(i->second.dp_a) delete i->second.dp_a; i->second.dp_a = NULL; if(i->second.dp_n) delete i->second.dp_n; i->second.dp_n = NULL; try { remove_AlarmState_dynamic_attribute(i->second.attr_name); } catch(Tango::DevFailed &e) { ostringstream o; o << "AlarmHandler::" << __func__<<": attname '" << i->second.attr_name << "' exception removing attribute err="<<e.errors[0].desc ; INFO_STREAM << o.str() << endl; } #if _FORMULA_ATTR CORBA::string_free(*(i->second.attr_value_formula)); try { remove_AlarmFormula_dynamic_attribute(i->second.attr_name_formula); } catch(Tango::DevFailed &e) { ostringstream o; o << "AlarmHandler::" << __func__<<": attname '" << i->second.attr_name_formula << "' exception removing attribute err="<<e.errors[0].desc ; INFO_STREAM << o.str() << endl; } #endif /* * remove this alarm from alarm table */ alarms.vlock->writerOut(); alarms.erase(i); //takes vlock writer lock return true; } else { WARN_STREAM << "AlarmHandler::"<<__func__<<": NOT found in table alm name=" << s << endl; } alarms.vlock->writerOut(); ostringstream o; o << "alarm '" \ << s << "' not found in alarm table"; WARN_STREAM << "AlarmHandler::remove_alarm(): " << o.str() << endl; throw o.str(); //return false; } /* remove_alarm() */ /*void AlarmHandler::add_to_database(alarm_t& a) throw(string&) { Tango::DbDatum alarm("alarm"); Tango::DbData db_data; alarm << (short)1; db_data.push_back(alarm); string tmpname; tmpname = a.name; while (true) { string::size_type j = tmpname.find_first_of("/."); if (j == string::npos) break; tmpname.replace(j, 1, "_"); } Tango::DbDatum property(tmpname); ostringstream num; num.clear(); num << a.grp << ends; // sprintf(buf, "%02X-", buf2[j]);//change here the format of saved data // string pro = a.name+"\t"+"$"+a.formula+"$"+"\t"+"\""+a.msg+"\""+"\t"+num.str(); //DEBUG_STREAM << "AlarmHandler::add_to_database(): a.name=" << a.name << " a.formula=" << a.formula << " a.lev=" << a.lev << " a.grp=" << a.grp2str() << " a.msg=" << a.msg << endl; string pro = a.name+"\t"+a.formula+"\t"+string(a.time_threshold)+"\t"+ a.lev+"\t"+a.grp2str()+"\t"+"\""+a.msg+"\""+"\t"+a.cmd_name+"\t"; //grp has been transformed to string DEBUG_STREAM << "AlarmHandler::add_to_database(): adding to database property=" << pro << endl; property << pro; db_data.push_back(property); try { get_db_device()->put_attribute_property(db_data); } catch (...) { ostringstream o; o << "AlarmHandler::add_to_database(): put_device_attribute_property()" \ << " failed" << ends; ERROR_STREAM << o.str() << endl; throw o.str(); } }*/ void AlarmHandler::set_internal_alarm(string name, Tango::TimeVal t, string msg, unsigned int count) { #if 0 alarm_t alm; bool existing=false; ostringstream o; //o << (internal.size() + 1); if(internal.size() == 0) internal_counter = 0; o << internal_counter; internallock->writerIn(); vector<alarm_t>::iterator it; for(it = internal.begin(); it != internal.end(); it++) { if(name == INTERNAL_ERROR) { if(it->msg == msg) { existing=true; break; } } else //for tango error log only one internal error per event { if(it->msg.find(name) != string::npos) { existing=true; if(it->on_counter < count) it->on_counter = count; break; } } } if(existing) { /*size_t index; int count; index = it->stat.find("*"); ostringstream temp; if((index != std::string::npos) && (index+1 != std::string::npos)) { size_t last = it->stat.size(); string str_count= it->stat.substr(index+1, last - index+1); count = strtol(str_count.c_str(), 0,10); count++; temp << it->stat.substr(0,index+1) << count; it->stat = temp.str(); } else it->stat += "*2";*/ it->on_counter++; it->msg = msg; //update with the last message } else { alm.name = string(INTERNAL_ERROR) + "_" + o.str(); internal_counter++; alm.ts = t; /*ostringstream stat; if(count==0) stat << S_ALARM; else stat << S_ALARM << "*" << count;*/ alm.on_counter = count; //alm.stat = stat.str(); alm.stat = S_ALARM; alm.ack = NOT_ACK; alm.done = false; alm.msg = msg; //alm.grp = GR_DEFAULT; if(!alm.grp_str.empty()) alm.grp = (alm.grp_str.begin())->second; //set groupe 'none' to internal alarms else alm.grp = GR_DEFAULT; //alm.lev = LEV_DEFAULT; alm.lev = LEV_LOWEST; internal.push_back(alm); } internallock->writerOut(); #endif } //============================================================== //------------------- AST evaluation methods ------------------- //============================================================== formula_res_t AlarmHandler::eval_formula(tree_parse_info_t tree, string &attr_values) { return eval_expression(tree.trees.begin(), attr_values); } formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values, int ev_ind) //throw (string &), std::out_of_range { ostringstream err; err << "Evaluating formula: "; //iter_t it = i->children.begin(); if (i->value.id() == formula_grammar::val_rID) { if(i->children.size() != 0) { err << "in node val_rID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } string val_d(i->value.begin(), i->value.end()); formula_res_t res; res.value = strtod(val_d.c_str(), 0); #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node value real = " << val_d << "(value="<<res.value<<" quality="<<res.quality<<")" << endl; #endif return res; } else if (i->value.id() == formula_grammar::val_hID) { if(i->children.size() != 0) { err << "in node val_hID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } string val_d(i->value.begin(), i->value.end()); #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node value hex = " << val_d << endl; #endif formula_res_t res; res.value = strtod(val_d.c_str(), 0); return res; } else if (i->value.id() == formula_grammar::val_stID) { if(i->children.size() != 0) { err << "in node val_stID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } string val_st(i->value.begin(), i->value.end()); double st = i->value.value(); //get value directly from node saved with access_node_d #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node value state : " << val_st << "=" << st << endl; #endif formula_res_t res; res.value = st; return res; } else if (i->value.id() == formula_grammar::val_alarm_enum_stID) { if(i->children.size() != 0) { err << "in node val_alarm_enum_stID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } string val_st(i->value.begin(), i->value.end()); double st = i->value.value(); //get value directly from node saved with access_node_d #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node value alarm enum state : " << val_st << "=" << st << endl; #endif formula_res_t res; res.value = st; return res; } else if (i->value.id() == formula_grammar::val_qualityID) { if(i->children.size() != 0) { err << "in node val_qualityID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } string val_quality(i->value.begin(), i->value.end()); double quality = i->value.value(); //get value directly from node saved with access_node_d #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node value quality : " << val_quality << "=" << quality << endl; #endif formula_res_t res; res.value = quality; return res; } else if (i->value.id() == formula_grammar::unary_exprID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node unary expression: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 1) { err << "in node unary_exprID(" << 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 (*i->value.begin() == '+') { res.value = + res.value; } else if (*i->value.begin() == '-') { res.value = - res.value; } else if (*i->value.begin() == '!') { res.value = ! res.value; } else { err << "in node unary_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; throw err.str(); } return res; } else if (i->value.id() == formula_grammar::mult_exprID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node mult expression: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 2) { err << "in node mult_exprID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } if (*i->value.begin() == '*') { return eval_expression(i->children.begin(), attr_values) * eval_expression(i->children.begin()+1, attr_values); } else if (*i->value.begin() == '/') { return eval_expression(i->children.begin(), attr_values) / eval_expression(i->children.begin()+1, attr_values); } else { err << "in node mult_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; throw err.str(); } } else if (i->value.id() == formula_grammar::add_exprID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node add expression: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 2) { err << "in node add_exprID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } if (*i->value.begin() == '+') { return eval_expression(i->children.begin(), attr_values) + eval_expression(i->children.begin()+1, attr_values); } else if (*i->value.begin() == '-') { return eval_expression(i->children.begin(), attr_values) - eval_expression(i->children.begin()+1, attr_values); } else { err << "in node add_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; throw err.str(); } } else if (i->value.id() == formula_grammar::event_ID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node event" << string(i->value.begin(), i->value.end()) << endl; #endif formula_res_t ind; if(i->children.size() != 2) { err << "in node event_ID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size();; throw err.str(); } if((i->children.begin()+1)->value.id() == formula_grammar::indexID) ind = eval_expression(i->children.begin()+1, attr_values); //array index else if((i->children.begin()+1)->value.id() == formula_grammar::propertyID) { if(string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) == ".quality") { formula_res_t res = eval_expression(i->children.begin(), attr_values, (int)ind.value); res.value = res.quality; #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node event.quality -> " << res.value << endl; #endif return res; } else if(string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) == ".alarm") { formula_res_t res = eval_expression(i->children.begin(), attr_values, (int)ind.value); res.value = (res.value == _UNACK) || (res.value == _ACKED); #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node event.alarm -> " << res.value << endl; #endif return res; } else if(string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) == ".normal") { formula_res_t res = eval_expression(i->children.begin(), attr_values, (int)ind.value); res.value = (res.value == _NORM) || (res.value == _RTNUN); #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node event.normal -> " << res.value << endl; #endif return res; } } else { err << "in node event_ID(" << string(i->value.begin(), i->value.end()) << ") children2 is not an index ->" << string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()); throw err.str(); } return eval_expression(i->children.begin(), attr_values, (int)ind.value); } else if (i->value.id() == formula_grammar::nameID) { if(i->children.size() != 0) { err << "in node nameID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } events->veclock.readerIn(); vector<event>::iterator it = events->v_event.begin(); string s(i->value.begin(), i->value.end()); std::transform(s.begin(), s.end(), s.begin(), (int(*)(int))tolower); //transform to lowercase while ((it != events->v_event.end()) && (it->name != s)) it++; if (it != events->v_event.end()) { if(!it->valid) { 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!"; events->veclock.readerOut(); 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!!"; events->veclock.readerOut(); throw err.str(); } ostringstream temp_attr_val; if(it->value.size() > 1) temp_attr_val << "\"" << it->name << "[" << ev_ind << "]\":" <<it->value.at(ev_ind) << ",";//throw std::out_of_range else temp_attr_val << "\"" << it->name << "\":" <<it->value.at(ev_ind) << ",";//throw std::out_of_range attr_values += temp_attr_val.str(); formula_res_t res; res.quality = it->quality; res.ex_reason = it->ex_reason; res.ex_desc = it->ex_desc; res.ex_origin = it->ex_origin; #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node name -> " << temp_attr_val.str() << " quality=" << res.quality << endl; #endif res.value = it->value.at(ev_ind); //throw std::out_of_range events->veclock.readerOut(); return res; } else { events->veclock.readerOut(); err << "in event: (" << string(i->value.begin(), i->value.end()) << ") not found in event table"; throw err.str(); } } else if (i->value.id() == formula_grammar::indexID) { if(i->children.size() != 0) { err << "in node indexID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } string val_d(i->value.begin(), i->value.end()); #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node index = " << val_d << endl; #endif formula_res_t res; res.value = strtod(val_d.c_str(), 0); return res; } else if (i->value.id() == formula_grammar::logical_exprID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node logical expression: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 2) { err << "in node logical_exprID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } if (string(i->value.begin(), i->value.end()) == string("&&")) { return eval_expression(i->children.begin(), attr_values) && eval_expression(i->children.begin()+1, attr_values); } else if (string(i->value.begin(), i->value.end()) == string("||")) { return eval_expression(i->children.begin(), attr_values) || eval_expression(i->children.begin()+1, attr_values); } else { err << "in node logical_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; throw err.str(); } } else if (i->value.id() == formula_grammar::bitwise_exprID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node bitwise expression: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 2) { err << "in node bitwise_exprID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } formula_res_t res_1=eval_expression(i->children.begin(), attr_values), res_2=eval_expression(i->children.begin()+1, attr_values); long val_l1,val_l2; string err2("ERROR: non-int value in bitwise operation!"); val_l1 = (long)trunc(res_1.value); //transform to long val_l2 = (long)trunc(res_2.value); //transform to long if((val_l1 != res_1.value) || (val_l2 != res_2.value)) //if different, lost something with truncf throw err2; if (*i->value.begin() == '&') { formula_res_t res; res.value = (double)(val_l1 & val_l2); res.quality = res.combine_quality(res_1.quality, res_2.quality); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); return res; } else if (*i->value.begin() == '|') { formula_res_t res; res.value = (double)(val_l1 | val_l2); res.quality = res.combine_quality(res_1.quality, res_2.quality); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); return res; } else if (*i->value.begin() == '^') { formula_res_t res; res.value = (double)(val_l1 ^ val_l2); res.quality = res.combine_quality(res_1.quality, res_2.quality); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); return res; } else { err << "in node bitwise_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; throw err.str(); } } else if (i->value.id() == formula_grammar::shift_exprID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node shift expression: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 2) { err << "in node shift_exprID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } formula_res_t res_1=eval_expression(i->children.begin(), attr_values), res_2=eval_expression(i->children.begin()+1, attr_values); long val_l1,val_l2; string err2("ERROR: non-int value in bitwise operation!"); val_l1 = (long)trunc(res_1.value); //transform to long val_l2 = (long)trunc(res_2.value); //transform to long if((val_l1 != res_1.value) || (val_l2 != res_2.value)) //if different, lost something with truncf throw err2; if (string(i->value.begin(), i->value.end()) == string("<<")) { formula_res_t res; res.value = (double)(val_l1 << val_l2); res.quality = res.combine_quality(res_1.quality, res_2.quality); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); return res; } else if (string(i->value.begin(), i->value.end()) == string(">>")) { formula_res_t res; res.value = (double)(val_l1 >> val_l2); res.quality = res.combine_quality(res_1.quality, res_2.quality); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); return res; } else { err << "in node shift_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; throw err.str(); } } else if (i->value.id() == formula_grammar::equality_exprID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node equality expression: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 2) { err << "in node equality_exprID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } //string comparison here iter_t const& i2_1 = i->children.begin(); iter_t const& i2_2 = i->children.begin()+1; //OK only attr == 'string' or attr != 'string' if(i2_1->value.id() == formula_grammar::nameID && i2_2->value.id() == formula_grammar::val_stringID) { if(i2_1->children.size() == 0 && i2_2->children.size() == 0) { //retrieve string from attribute: string attr_val = ""; string name_id(i2_1->value.begin(), i2_1->value.end()); std::transform(name_id.begin(), name_id.end(), name_id.begin(), (int(*)(int))tolower); //transform to lowercase formula_res_t res; events->veclock.readerIn(); vector<event>::iterator it = events->v_event.begin(); while ((it != events->v_event.end()) && (it->name != name_id)) it++; if (it != events->v_event.end()) { if(!it->valid) { err << "in node equality_exprID -> nameID(" << string(i2_1->value.begin(), i2_1->value.end()) << ") value not valid!"; if(it->ex_desc.length() > 0) err << " EX: '" << it->ex_desc << "'"; events->veclock.readerOut(); throw err.str(); } else if(it->type != Tango::DEV_STRING && it->value.empty()) { err << "in node nameID(" << string(i2_1->value.begin(), i2_1->value.end()) << ") value not initialized!!"; if(it->ex_desc.length() > 0) err << " EX: '" << it->ex_desc << "'"; events->veclock.readerOut(); throw err.str(); } ostringstream temp_attr_val; temp_attr_val << "\"" << it->name << "\":\"" <<it->value_string << "\","; 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; #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node name -> " << temp_attr_val.str() << " quality=" << res.quality << endl; #endif attr_val = string("'") + it->value_string + string("'"); events->veclock.readerOut(); } else { events->veclock.readerOut(); err << "in event: (" << string(i->value.begin(), i->value.end()) << ") not found in event table"; throw err.str(); } //retrieve string from formula string val_string(i2_2->value.begin(), i2_2->value.end()); if (string(i->value.begin(), i->value.end()) == string("!=")) { res.value = attr_val != val_string; return res; } else if (string(i->value.begin(), i->value.end()) == string("==")) { res.value = attr_val == val_string; return res; } else { err << "in node equality_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed (val_stringID)"; throw err.str(); } } } else { if (string(i->value.begin(), i->value.end()) == string("!=")) { return eval_expression(i->children.begin(), attr_values) != eval_expression(i->children.begin()+1, attr_values); } else if (string(i->value.begin(), i->value.end()) == string("==")) { return eval_expression(i->children.begin(), attr_values) == eval_expression(i->children.begin()+1, attr_values); } else { err << "in node equality_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; throw err.str(); } } } else if (i->value.id() == formula_grammar::compare_exprID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node compare expression: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 2) { err << "in node compare_exprID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } if (string(i->value.begin(), i->value.end()) == string("<=")) { return eval_expression(i->children.begin(), attr_values) <= eval_expression(i->children.begin()+1, attr_values); } else if (string(i->value.begin(), i->value.end()) == string(">=")) { return eval_expression(i->children.begin(), attr_values) >= eval_expression(i->children.begin()+1, attr_values); } else if (*i->value.begin() == '<') { return eval_expression(i->children.begin(), attr_values) < eval_expression(i->children.begin()+1, attr_values); } else if (*i->value.begin() == '>') { return eval_expression(i->children.begin(), attr_values) > eval_expression(i->children.begin()+1, attr_values); } else { err << "in node equality_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; throw err.str(); } } else if (i->value.id() == formula_grammar::funcID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node function: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 1) { err << "in node funcID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } formula_res_t res; 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) { events->veclock.readerIn(); 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 #ifdef _DEBUG_FORMULA DEBUG_STREAM << " -> " << string(i->value.begin(), i->value.end()) << "(" << s << ")" << endl; #endif 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!"; events->veclock.readerOut(); 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!!"; events->veclock.readerOut(); 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; #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node name -> " << temp_attr_val.str() << " quality=" << res.quality << endl; #endif res.value = result; events->veclock.readerOut(); return res; } else { events->veclock.readerOut(); 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) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node function dual: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 2) { err << "in node func_dualID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } formula_res_t res_1=eval_expression(i->children.begin(), attr_values), res_2=eval_expression(i->children.begin()+1, attr_values); if (string(i->value.begin(), i->value.end()) == string("min")) { formula_res_t res; res.value = min(res_1.value, res_2.value); res.quality = res.combine_quality(res_1.quality, res_2.quality); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); return res; } else if (string(i->value.begin(), i->value.end()) == string("max")) { formula_res_t res; res.value = max(res_1.value, res_2.value); res.quality = res.combine_quality(res_1.quality, res_2.quality); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); return res; } else if (string(i->value.begin(), i->value.end()) == string("pow")) { formula_res_t res; res.value = pow(res_1.value, res_2.value); res.quality = res.combine_quality(res_1.quality, res_2.quality); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); return res; } else { err << "in node func_dualID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; throw err.str(); } } else if (i->value.id() == formula_grammar::cond_exprID) { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node ternary_if expression: " << string(i->value.begin(), i->value.end()) << endl; #endif if(i->children.size() != 3) { err << "in node ternary_ifID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } formula_res_t res_1=eval_expression(i->children.begin(), attr_values); if(res_1.value) { formula_res_t res = eval_expression(i->children.begin()+1, attr_values); return res; } else { formula_res_t res = eval_expression(i->children.begin()+2, attr_values); return res; } } else { #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node unknown id: " << string(i->value.begin(), i->value.end()) << endl; #endif { err << "node unknown!! value=" << string(i->value.begin(), i->value.end()); throw err.str(); } } formula_res_t res; res.value = 0; return res; } void AlarmHandler::find_event_formula(tree_parse_info_t tree, vector<string> & ev) { eval_node_event(tree.trees.begin(), ev); return; } void AlarmHandler::eval_node_event(iter_t const& i, vector<string> & ev) { //DEBUG_STREAM << "In eval_node_event. i->value = '" << // string(i->value.begin(), i->value.end()) << // "' i->children.size() = " << i->children.size() << " NODE=" << rule_names[i->value.id()] << endl; ostringstream err; err << "Looking for event in formula tree: "; /*if (i->value.id() == formula_grammar::event_ID) { DEBUG_STREAM << "eval_node_event(): in eventID!!!=" << string(i->value.begin(), i->value.end()) << endl; } else*/ if (i->value.id() == formula_grammar::nameID) { //DEBUG_STREAM << "eval_node_event(): find event name=" << string(i->value.begin(), i->value.end()) << endl; if(i->children.size() != 0) { err << "in node nameID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); throw err.str(); } string s(i->value.begin(), i->value.end()); std::transform(s.begin(), s.end(), s.begin(), (int(*)(int))tolower); //transform to lowercase ev.push_back(s); } //cout << endl; //iter_t it = i->children.begin(); for(iter_t it = i->children.begin(); it != i->children.end(); it++) eval_node_event(it, ev); return; } void AlarmHandler::prepare_alarm_attr() { alarm_container_t::iterator ai; vector<alarm_t>::iterator aid; bool is_audible=false; alarms.vlock->readerIn(); prepare_alm_mtx->lock(); outOfServiceAlarms_sz=0; shelvedAlarms_sz=0; acknowledgedAlarms_sz=0; unacknowledgedAlarms_sz=0; unacknowledgedNormalAlarms_sz=0; normalAlarms_sz=0; silencedAlarms_sz=0; listAlarms_sz=0; alarmSummary_sz=0; string almstate; for (ai = alarms.v_alarm.begin(); ai != alarms.v_alarm.end(); ai++) { //DEBUG_STREAM << __func__<<": looping v_alarm.size="<<alarms.v_alarm.size()<<", listAlarms_sz="<<listAlarms_sz<<" : "<<ai->second.name<<endl; #ifndef ALM_SUM_STR stringstream alm_summary; alm_summary << KEY(NAME_KEY) << ai->first << SEP; #else string alm_summary; alm_summary += KEY(NAME_KEY) + ai->first + SEP; #endif if(ai->second.enabled == false) { outOfServiceAlarms_read[outOfServiceAlarms_sz] = ai->second.name; attr_alarmOutOfService_read[outOfServiceAlarms_sz] = const_cast<char*>(outOfServiceAlarms_read[outOfServiceAlarms_sz].c_str()); /*strcpy(c_outOfServiceAlarms_read[outOfServiceAlarms_sz], ai->second.name.c_str()); attr_alarmOutOfService_read[outOfServiceAlarms_sz] = c_outOfServiceAlarms_read[outOfServiceAlarms_sz];*/ //attr_alarmOutOfService_read[outOfServiceAlarms_sz] = CORBA::string_dup(ai->second.name.c_str()); outOfServiceAlarms_sz++; almstate = "OOSRV"; } else if(ai->second.shelved) { shelvedAlarms_read[shelvedAlarms_sz] = ai->second.name; attr_alarmShelved_read[shelvedAlarms_sz] = const_cast<char*>(shelvedAlarms_read[shelvedAlarms_sz].c_str()); /*strcpy(c_shelvedAlarms_read[shelvedAlarms_sz], ai->second.name.c_str()); attr_alarmShelved_read[shelvedAlarms_sz] = c_shelvedAlarms_read[shelvedAlarms_sz];*/ //attr_alarmShelved_read[shelvedAlarms_sz] = CORBA::string_dup(ai->second.name.c_str()); shelvedAlarms_sz++; almstate = "SHLVD"; } else { if(ai->second.stat == S_ALARM && ai->second.ack == ACK) { acknowledgedAlarms_read[acknowledgedAlarms_sz] = ai->second.name; attr_alarmAcknowledged_read[acknowledgedAlarms_sz] = const_cast<char*>(acknowledgedAlarms_read[acknowledgedAlarms_sz].c_str()); /*strcpy(c_acknowledgedAlarms_read[acknowledgedAlarms_sz], ai->second.name.c_str()); attr_alarmAcknowledged_read[acknowledgedAlarms_sz] = c_acknowledgedAlarms_read[acknowledgedAlarms_sz];*/ //attr_alarmAcknowledged_read[acknowledgedAlarms_sz] = CORBA::string_dup(ai->second.name.c_str()); acknowledgedAlarms_sz++; almstate = "ACKED"; } else if(ai->second.stat == S_ALARM && ai->second.ack == NOT_ACK) { unacknowledgedAlarms_read[unacknowledgedAlarms_sz] = ai->second.name; attr_alarmUnacknowledged_read[unacknowledgedAlarms_sz] = const_cast<char*>(unacknowledgedAlarms_read[unacknowledgedAlarms_sz].c_str()); /*strcpy(c_unacknowledgedAlarms_read[unacknowledgedAlarms_sz], ai->second.name.c_str()); attr_alarmUnacknowledged_read[unacknowledgedAlarms_sz] = c_unacknowledgedAlarms_read[unacknowledgedAlarms_sz];*/ //attr_alarmUnacknowledged_read[unacknowledgedAlarms_sz] = CORBA::string_dup(ai->second.name.c_str()); unacknowledgedAlarms_sz++; almstate = "UNACK"; } else if(ai->second.stat == S_NORMAL && ai->second.ack == NOT_ACK) { unacknowledgedNormalAlarms_read[unacknowledgedNormalAlarms_sz] = ai->second.name; attr_alarmUnacknowledgedNormal_read[unacknowledgedNormalAlarms_sz] = const_cast<char*>(unacknowledgedNormalAlarms_read[unacknowledgedNormalAlarms_sz].c_str()); /*strcpy(c_unacknowledgedNormalAlarms_read[unacknowledgedNormalAlarms_sz], ai->second.name.c_str()); attr_alarmUnacknowledgedNormal_read[unacknowledgedNormalAlarms_sz] = c_unacknowledgedNormalAlarms_read[unacknowledgedNormalAlarms_sz];*/ //attr_alarmUnacknowledgedNormal_read[unacknowledgedNormalAlarms_sz] = CORBA::string_dup(ai->second.name.c_str()); unacknowledgedNormalAlarms_sz++; almstate = "RTNUN"; } else if(ai->second.stat == S_NORMAL && ai->second.ack == ACK) { normalAlarms_read[normalAlarms_sz] = ai->second.name; attr_alarmNormal_read[normalAlarms_sz] = const_cast<char*>(normalAlarms_read[normalAlarms_sz].c_str()); /*strcpy(c_normalAlarms_read[normalAlarms_sz], ai->second.name.c_str()); attr_alarmNormal_read[normalAlarms_sz] = c_normalAlarms_read[normalAlarms_sz];*/ //attr_alarmNormal_read[normalAlarms_sz] = CORBA::string_dup(ai->second.name.c_str()); normalAlarms_sz++; almstate = "NORM"; } if(ai->second.silenced > 0) { silencedAlarms_read[silencedAlarms_sz] = ai->second.name; attr_alarmSilenced_read[silencedAlarms_sz] = const_cast<char*>(silencedAlarms_read[silencedAlarms_sz].c_str()); /*strcpy(c_silencedAlarms_read[silencedAlarms_sz], ai->second.name.c_str()); attr_alarmSilenced_read[silencedAlarms_sz] = c_silencedAlarms_read[silencedAlarms_sz];*/ //attr_alarmSilenced_read[silencedAlarms_sz] = CORBA::string_dup(ai->second.name.c_str()); silencedAlarms_sz++; } } ostringstream tmp_ex; //tmp_ex.str(""); if(ai->second.error) { tmp_ex << "{\"Reason\":\"" << ai->second.ex_reason << "\",\"Desc\":\"" << ai->second.ex_desc << "\",\"Origin\":\"" << ai->second.ex_origin << "\"}"; DEBUG_STREAM << __func__ << ": " << ai->first << " -> " << tmp_ex.str(); if(almstate != "SHLVD" && almstate != "OOSRV") { almstate = S_ERROR; } } tm time_tm; time_t time_sec= ai->second.ts.tv_sec; //gmtime_r(&time_sec,&time_tm); //-> UTC localtime_r(&time_sec,&time_tm); char time_buf[64]; strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &time_tm); #ifndef ALM_SUM_STR alm_summary << KEY(VALUE_KEY) << almstate << SEP; //TODO: string or enum value? alm_summary << KEY(LEVEL_KEY) << ai->second.lev << SEP; alm_summary << KEY(ALARM_TIME_KEY) << time_buf << "." << ai->second.ts.tv_usec << SEP; alm_summary << KEY(FORMULA_KEY) << ai->second.formula << SEP; alm_summary << KEY(MESSAGE_KEY) << ai->second.msg; //TODO: escape ';' //alm_summary << KEY(URL_KEY) << ai->second.url; //TODO: escape ';' TODO: add to alarmSummary? #else alm_summary += string(KEY(VALUE_KEY)) + almstate + SEP; //TODO: string or enum value? alm_summary += KEY(LEVEL_KEY) + ai->second.lev + SEP; stringstream sval; sval << time_buf << "." << ai->second.ts.tv_usec; alm_summary += KEY(ALARM_TIME_KEY) + sval.str() + SEP; alm_summary += KEY(FORMULA_KEY) + ai->second.formula + SEP; alm_summary += KEY(MESSAGE_KEY) + ai->second.msg; //TODO: escape ';' //alm_summary += KEY(URL_KEY) + ai->second.url; //TODO: escape ';' TODO: add to alarmSummary? #endif #if 0 #ifndef ALM_SUM_STR alm_summary << SEP; alm_summary << KEY(ACKNOWLEDGED_KEY) << (ai->second.ack== ACK ? 1 : 0) << SEP; //TODO: 1/0 or ACK, NOT_ACK ? alm_summary << KEY(ENABLED_KEY) << (ai->second.enabled ? 1 : 0) << SEP; alm_summary << KEY(SHELVED_KEY) << (ai->second.shelved ? 1 : 0) << SEP; alm_summary << KEY(GROUP_KEY) << ai->second.grp2str() << SEP; alm_summary << KEY(ON_COUNTER_KEY) << ai->second.on_counter << SEP; alm_summary << KEY(OFF_COUNTER_KEY) << ai->second.off_counter << SEP; alm_summary << KEY(FREQ_COUNTER_KEY) << ai->second.freq_counter << SEP; alm_summary << KEY(QUALITY_KEY) << ai->second.quality << SEP; #else alm_summary += string(SEP); alm_summary += string(KEY(ACKNOWLEDGED_KEY)) + (ai->second.ack== ACK ? "1" : "0") + SEP; //TODO: 1/0 or ACK, NOT_ACK ? alm_summary += string(KEY(ENABLED_KEY)) + (ai->second.enabled ? "1" : "0") + SEP; alm_summary += string(KEY(SHELVED_KEY)) + (ai->second.shelved ? "1" : "0") + SEP; alm_summary += KEY(GROUP_KEY) + ai->second.grp2str() + SEP; sval.str(""); sval << ai->second.on_counter; alm_summary += KEY(ON_COUNTER_KEY) + sval.str() + SEP; sval.str(""); sval << ai->second.off_counter; alm_summary += KEY(OFF_COUNTER_KEY) + sval.str() + SEP; sval.str(""); sval << ai->second.freq_counter; alm_summary += KEY(FREQ_COUNTER_KEY) + sval.str() + SEP; sval.str(""); sval << ai->second.quality; alm_summary += KEY(QUALITY_KEY) + sval.str() + SEP; #endif #endif #if 0 #ifndef ALM_SUM_STR alm_summary << KEY(EXCEPTION_KEY) << tmp_ex.str() << SEP; #else alm_summary += KEY(EXCEPTION_KEY) + tmp_ex.str() + SEP; #endif #ifndef ALM_SUM_STR alm_summary << KEY(SILENT_TIME_REMAINING_KEY) << ai->second.silenced << SEP; #else sval.str(""); sval << ai->second.silenced; alm_summary += KEY(SILENT_TIME_REMAINING_KEY) + sval.str() + SEP; #endif #endif attr_alarmFrequency_read[listAlarms_sz] = ai->second.freq_counter; listAlarms_read[listAlarms_sz] = ai->second.name; attr_alarmList_read[listAlarms_sz] = const_cast<char*>(listAlarms_read[listAlarms_sz].c_str()); /*strcpy(c_listAlarms_read[listAlarms_sz], ai->second.name.c_str()); attr_alarmList_read[listAlarms_sz] = c_listAlarms_read[listAlarms_sz];*/ //attr_alarmList_read[listAlarms_sz] = CORBA::string_dup(ai->second.name.c_str()); listAlarms_sz++; if(!is_audible && ai->second.is_new && ai->second.silenced <= 0 && ai->second.enabled && !ai->second.shelved) is_audible = true; #if 0 #ifndef ALM_SUM_STR alm_summary << KEY(AUDIBLE_KEY) << (is_audible ? 1 : 0) << SEP; alm_summary << KEY(ATTR_VALUES_KEY) << ai->second.attr_values << SEP; #else alm_summary += string(KEY(AUDIBLE_KEY)) + (is_audible ? "1" : "0") + SEP; alm_summary += KEY(ATTR_VALUES_KEY) + ai->second.attr_values + SEP; #endif #endif if (almstate == S_ERROR) { /* * alarm status is S_ERROR */ alarmedlock->readerIn(); aid = find(alarmed.begin(), alarmed.end(),ai->second.name); if (aid != alarmed.end()) { /* * found, change stat only if switching from * S_NORMAL or S_ALARM status to S_ERROR */ //cout << "read_attr(): S_ERROR: found: " << aid->name << endl; if (aid->stat != S_ERROR) { aid->stat = S_ERROR; aid->ack = NOT_ACK; aid->ts = ai->second.ts; aid->msg = it->second.ex_desc;//tmp_ex.str();//ai->second.msg; aid->url = ai->second.url; } aid->grp = ai->second.grp; 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 #ifdef _CNT_ATOMIC aid->on_counter.store(ai->second.on_counter); aid->off_counter.store(ai->second.off_counter); #else aid->on_counter = ai->second.on_counter; aid->off_counter = ai->second.off_counter; #endif 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 } else { alarm_t at = ai->second; at.stat = S_ERROR; at.msg = it->second.ex_desc;//tmp_ex.str();//ai->second.msg; /* * not found: new "alarmed" item */ DEBUG_STREAM << __func__<<": S_ERROR: pushing new alarm: " \ << ai->second.name << "\t" << ai->second.stat << endl; alarmedlock->readerOut(); alarmedlock->writerIn(); alarmed.push_back(at); //ai->second.is_new = 0; //set state as not more new //12-06-08: StopNew command set it to 0 alarmedlock->writerOut(); alarmedlock->readerIn(); } alarmedlock->readerOut(); } else if (ai->second.stat == S_ALARM && ai->second.enabled && !ai->second.shelved) { /* * alarm status is S_ALARM */ alarmedlock->readerIn(); aid = find(alarmed.begin(), alarmed.end(),ai->second.name); if (aid != alarmed.end()) { /* * found, change stat only if switching from * S_NORMAL to S_ALARM status */ //cout << "read_attr(): S_ALARM: found: " << aid->name << endl; if (aid->stat == S_NORMAL || aid->stat == S_ERROR) { aid->stat = S_ALARM; aid->ack = NOT_ACK; aid->ts = ai->second.ts; aid->msg = ai->second.msg; aid->url = ai->second.url; } aid->grp = ai->second.grp; 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 #ifdef _CNT_ATOMIC aid->on_counter.store(ai->second.on_counter); aid->off_counter.store(ai->second.off_counter); #else aid->on_counter = ai->second.on_counter; aid->off_counter = ai->second.off_counter; #endif 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 } else { /* * not found: new "alarmed" item */ DEBUG_STREAM << __func__<<": S_ALARM: pushing new alarm: " \ << ai->second.name << "\t" << ai->second.stat << endl; alarmedlock->readerOut(); alarmedlock->writerIn(); alarmed.push_back(ai->second); //ai->second.is_new = 0; //set state as not more new //12-06-08: StopNew command set it to 0 alarmedlock->writerOut(); alarmedlock->readerIn(); } alarmedlock->readerOut(); } else if (ai->second.stat == S_NORMAL) { /* * alarm status is S_NORMAL */ alarmedlock->readerIn(); aid = find(alarmed.begin(), alarmed.end(), ai->second.name); if (aid != alarmed.end()) { /* * found, as it should; * switching from S_ALARM to S_NORMAL */ aid->stat = S_NORMAL; aid->ts = ai->second.ts; //aid->msg = " "; /* no message again */ aid->msg =ai->second.msg; aid->url = ai->second.url; aid->grp = ai->second.grp; aid->lev = ai->second.lev; #ifdef _CNT_ATOMIC aid->on_counter.store(ai->second.on_counter); aid->off_counter.store(ai->second.off_counter); #else aid->on_counter = ai->second.on_counter; aid->off_counter = ai->second.off_counter; #endif 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) aid->silent_time = ai->second.silent_time; //if already alarmed and not saved correctly in properties needed to update //ai->second.is_new = 0; //and set state as not more new //12-06-08: StopNew command set it to 0 if (aid->ack == ACK) { //if (aid->done) //TODO: done seems useless { /* * if already ACKnowledged and visualized * remove from "alarmed" list */ DEBUG_STREAM << __func__<<": S_NORMAL: " << aid->name \ << " ACKnowledged: removing" << endl; alarmedlock->readerOut(); alarmedlock->writerIn(); alarmed.erase(aid); alarmedlock->writerOut(); alarmedlock->readerIn(); } //else //{ // aid->done = true; //} } /* if */ } /* if */ alarmedlock->readerOut(); } /* if else if */ #ifndef ALM_SUM_STR alarmSummary_read[alarmSummary_sz] = alm_summary.str(); #else alarmSummary_read[alarmSummary_sz] = alm_summary; #endif attr_alarmSummary_read[alarmSummary_sz] = const_cast<char*>(alarmSummary_read[alarmSummary_sz].c_str()); /*strncpy(c_alarmSummary_read[alarmSummary_sz], alm_summary.c_str(), MAX_SUMMARY-1); c_alarmSummary_read[alarmSummary_sz][MAX_SUMMARY-1]=0; attr_alarmSummary_read[alarmSummary_sz] = c_alarmSummary_read[alarmSummary_sz];*/ //attr_alarmSummary_read[alarmSummary_sz] = CORBA::string_dup(alm_summary.c_str()); alarmSummary_sz++; } /* for */ *attr_alarmAudible_read = is_audible; prepare_alm_mtx->unlock(); alarms.vlock->readerOut(); vector<string> tmp_alarm_table; string is_new; ostringstream os1; /*os1.clear(); os1 << header << "\t" << alarmed.size() << ends;*/ //tmp_alarm_table.push_back(os1.str()); alarmedlock->readerIn(); if (!alarmed.empty()) { for (aid = alarmed.begin(); aid != alarmed.end(); aid++) { if(aid->silenced > 0) { Tango::TimeVal now = gettime(); double dnow = now.tv_sec + ((double)now.tv_usec) / 1000000; double dsilent = aid->ts_time_silenced.tv_sec + ((double)aid->ts_time_silenced.tv_usec) / 1000000; double dminutes = (dnow - dsilent)/60; //silenced already calculated in alarm_table::update, but here updated for panel also if state not changed: //to see minutes countdown if(dminutes < aid->silent_time) { aid->silenced = aid->silent_time - floor(dminutes); } else { aid->silenced = 0; aid->shelved = false; } } ostringstream os; os.clear(); is_new.clear(); 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->on_counter << "\t" << aid->lev << "\t" << aid->silenced << "\t" << aid->grp2str() << "\t" << aid->msg << "\t" << is_new; tmp_alarm_table.push_back(os.str()); } } alarmedlock->readerOut(); dslock->writerIn(); int i; // for (i = ds_num - 1; i >= 0; i--) { // CORBA::string_free(ds[i]); // //ds_num--; // } /* for (i = 0; i < ds_num; i++) { if (ds[i] != 0) { CORBA::string_free(ds[i]); ds[i] = 0; } }*/ ds_num = tmp_alarm_table.size(); if(ds_num > MAX_ALARMS) ds_num = MAX_ALARMS; for (i = 0; i < ds_num; i++) { //ds[i] = CORBA::string_dup(tmp_alarm_table[i].c_str()); size_t len=tmp_alarm_table[i].length(); if(len >= 10124) len = 10124-1; strncpy(dss[i],tmp_alarm_table[i].c_str(), len); dss[i][len]=0; } if(ds_num == 0) { ostringstream os1; ds_num++; os1.clear(); os1 << 0 << "\t" << 0 << "\t" << 0 << "\t" << 0 << "\t" << 0 << "\t" << 0 << "\t" << 0 << "\t" << -1 << "\t" << 0 << "\t" << 0 << "\t "; //ds[0] = CORBA::string_dup(os1.str().c_str()); size_t len=os1.str().length(); if(len >= 10124) len = 10124-1; strncpy(dss[i],os1.str().c_str(), len); dss[i][len]=0; } dslock->writerOut(); } void AlarmHandler::prepare_event_list() { eventList_sz=0; list<string> evl; events->show(evl); for(auto &ev : evl) { eventList_read[eventList_sz] = ev; attr_eventList_read[eventList_sz] = const_cast<char*>(eventList_read[eventList_sz].c_str()); eventList_sz++; } } void AlarmHandler::prepare_event_summary() { eventSummary_sz=0; list<string> evs; events->summary(evs); for(auto &ev : evs) { eventSummary_read[eventSummary_sz] = ev; attr_eventSummary_read[eventSummary_sz] = const_cast<char*>(eventSummary_read[eventSummary_sz].c_str()); eventSummary_sz++; } } //============================================================================= string AlarmHandler::remove_domain(string str) { string::size_type end1 = str.find("."); if (end1 == string::npos) { return str; } else { string::size_type start = str.find("tango://"); if (start == string::npos) { start = 0; } else { start = 8; //tango:// len } string::size_type end2 = str.find(":", start); if(end2 == string::npos) //not fqdn, so no tango host in the name return str; if(end1 > end2) //'.' not in the tango host part return str; string th = str.substr(0, end1); th += str.substr(end2, str.size()-end2); return th; } } //============================================================================= //============================================================================= bool AlarmHandler::compare_without_domain(string str1, string str2) { string str1_nd = remove_domain(str1); string str2_nd = remove_domain(str2); return (str1_nd==str2_nd); } //============================================================================= //============================================================================= void AlarmHandler::put_signal_property() { vector<string> prop; alarms.vlock->readerIn(); auto local_alarms(alarms.v_alarm); alarms.vlock->readerOut(); for(auto &it:local_alarms) { prop.push_back(it.first); string conf_str; it.second.confstr(conf_str); savedlock->readerIn(); auto itmap = saved_alarms.find(it.first); if(itmap == saved_alarms.end()) { savedlock->readerOut(); DEBUG_STREAM << __func__<<": SAVING '" <<it.first << "'" << endl; DECLARE_TIME_VAR t0, t1; GET_TIME(t0); alarms.save_alarm_conf_db(it.second.attr_name,it.second.name,it.second.stat,it.second.ack,it.second.enabled, it.second.formula,it.second.on_delay,it.second.off_delay,it.second.grp2str(),it.second.lev,it.second.msg,it.second.url,it.second.cmd_name_a,it.second.cmd_name_n,it.second.silent_time); GET_TIME(t1); DEBUG_STREAM << __func__ << ": SAVED '" <<it.first << "' in " << ELAPSED(t0, t1) << " ms" << endl; //alarms.vlock->readerOut();//TODO: avoid keeping lock savedlock->writerIn(); saved_alarms.insert(make_pair(it.first,conf_str)); savedlock->writerOut(); //alarms.vlock->readerIn();//TODO: avoid keeping lock } else { string conf_string; it.second.confstr(conf_string); //alarm found but configuration changed if(conf_string != itmap->second) { DEBUG_STREAM << __func__<<": UPDATING " <<it.first << " because conf changed: \""<<conf_string<<"\"<<---"<< itmap->second << endl; DECLARE_TIME_VAR t0, t1; GET_TIME(t0); itmap->second = conf_string; savedlock->readerOut(); alarms.save_alarm_conf_db(it.second.attr_name,it.second.name,it.second.stat,it.second.ack,it.second.enabled, it.second.formula,it.second.on_delay,it.second.off_delay,it.second.grp2str(),it.second.lev,it.second.msg,it.second.url,it.second.cmd_name_a,it.second.cmd_name_n,it.second.silent_time); GET_TIME(t1); DEBUG_STREAM << __func__ << ": UPDATED '" <<it.first << "' in " << ELAPSED(t0, t1) << " ms" << endl; } else { savedlock->readerOut(); } } } savedlock->readerIn(); map<string, string>::iterator it2=saved_alarms.begin(); while(it2 != saved_alarms.end()) { if(!it2->first.empty())//TODO: should not be needed, bug if it happens { auto found = local_alarms.find(it2->first); if (found == local_alarms.end()) { DEBUG_STREAM << __func__<<": DELETING '" << it2->first << "'" << endl; DECLARE_TIME_VAR t0, t1; GET_TIME(t0); alarms.delete_alarm_conf_db(it2->first); GET_TIME(t1); DEBUG_STREAM << __func__ << ": DELETED '" <<it2->first << "' in " << ELAPSED(t0, t1) << " ms" << endl; //savedlock->readerOut();//TODO: with boost shared lock to be released to take exclusive savedlock->writerIn(); saved_alarms.erase(it2); savedlock->writerOut(); //savedlock->readerIn(); } } if(it2 != saved_alarms.end()) it2++; } savedlock->readerOut(); Tango::DbData data; data.push_back(Tango::DbDatum("AlarmList")); data[0] << prop; Tango::Database *db; try { #ifndef _USE_ELETTRA_DB_RW db = new Tango::Database(); #else //save properties using host_rw e port_rw to connect to database if(host_rw != "") db = new Tango::Database(host_rw,port_rw); else db = new Tango::Database(); DEBUG_STREAM << __func__<<": connecting to db "<<host_rw<<":"<<port_rw; #endif } catch(Tango::DevFailed &e) { stringstream o; o << " Error connecting to Tango DataBase='" << e.errors[0].desc << "'"; WARN_STREAM << __FUNCTION__<< o.str(); return; } try { DECLARE_TIME_VAR t0, t1; GET_TIME(t0); db->set_timeout_millis(10000); db->put_device_property(get_name(), data); GET_TIME(t1); DEBUG_STREAM << __func__ << ": saving properties size="<<prop.size()<<" -> " << ELAPSED(t0, t1) << " ms" << endl; } catch(Tango::DevFailed &e) { stringstream o; o << " Error saving properties='" << e.errors[0].desc << "'"; WARN_STREAM << __FUNCTION__<< o.str(); } delete db; } //============================================================================= //============================================================================= bool AlarmHandler::check_signal_property() { savedlock->readerIn(); size_t saved_size=saved_alarms.size(); savedlock->readerOut(); alarms.vlock->readerIn(); size_t alarm_size=alarms.v_alarm.size(); alarms.vlock->readerOut(); if (saved_size<alarm_size) { DEBUG_STREAM << "AlarmHandler::"<<__func__<<": saved_size="<<saved_size<<" alarm_size="<< alarm_size << endl; return true; } return false; } //-------------------------------------------------------- /** * remove a AlarmState dynamic attribute without cleaning DB. * * parameter attname: attribute name to be removed. */ //-------------------------------------------------------- void AlarmHandler::remove_AlarmState_dynamic_attribute_no_clean_db(string attname) { remove_attribute(attname, true, false); map<string,Tango::DevEnum>::iterator ite; if ((ite=AlarmState_data.find(attname))!=AlarmState_data.end()) { DEBUG_STREAM << __func__<<": entering name="<<attname; AlarmState_data.erase(ite); } } void AlarmHandler::parse_alarm(string &alarm_string, alarm_t &alm) { alarm_parse al_gr(alm); // Construct Spirit grammar alm.name.clear(); alm.attr_name.clear(); alm.quality = Tango::ATTR_VALID; alm.ex_reason.clear(); alm.ex_desc.clear(); alm.ex_origin.clear(); alm.formula.clear(); alm.msg.clear(); alm.url.clear(); alm.lev.clear(); alm.grp=0; alm.to_be_evaluated = false; alm.on_delay = 0; alm.off_delay = 0; 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; alm.enabled=true; alm.shelved=false; 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) { if (alm.name.empty() || alm.formula.empty() || alm.msg.empty() || ((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()))) { ostringstream o; o << __func__<<": Parsing Failed, at least "<<NAME_KEY<<","<<FORMULA_KEY<<","<<LEVEL_KEY<<","<<MESSAGE_KEY<<" must be specified"; //TODO DEBUG_STREAM << o.str() << endl; Tango::Except::throw_exception( \ (const char*)"Parsing Failed!", \ (const char*)o.str().c_str(), \ (const char*)__func__, Tango::ERR); } std::transform(alm.name.begin(), alm.name.end(), alm.name.begin(), (int(*)(int))tolower); //transform to lowercase //std::transform(alm.formula.begin(), alm.formula.end(), alm.formula.begin(), (int(*)(int))tolower); //transform to lowercase: incorrect, state has to be written upercase 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 ";" 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++; } } } else { ostringstream o; o << __func__<<": Parsing Failed, parsed up to '" << string(alarm_string.begin(), alm.formula_tree.stop) << "' not parsed '" << string(alm.formula_tree.stop, alarm_string.end()) << "'"; //TODO DEBUG_STREAM << o.str() << endl; Tango::Except::throw_exception( \ (const char*)"Parsing Failed!", \ (const char*)o.str().c_str(), \ (const char*)__func__, Tango::ERR); } } /*----- PROTECTED REGION END -----*/ // AlarmHandler::namespace_ending } // namespace