-
Graziano Scalamera authored0078250a
Forked from
cs / ds / alarm-handler
126 commits behind the upstream repository.
alarm_table.h 11.71 KiB
/*
* alarm_table.h
*
* $Author: graziano $
*
* $Revision: 1.5 $
*
* $Log: alarm_table.h,v $
*
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#ifndef ALARM_TABLE_H
#define ALARM_TABLE_H
#define _RW_LOCK
#include <iostream>
#include <string>
#include <map>
#include <tango.h>
//spirit defines have to be put befor first inclusion of spirit headers
#ifndef BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT
#define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 2 //tmp scanner_list
#endif
/*#ifndef BOOST_SPIRIT_THREADSAFE
#define BOOST_SPIRIT_THREADSAFE
#endif
#ifndef PHOENIX_THREADSAFE
#define PHOENIX_THREADSAFE
#endif
*/
//#include "spirit-parser.h"
//#include <boost/spirit/core.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION < 103600
#include <boost/spirit/tree/ast.hpp> //for ast parse trees (in tree_formula)
#else
#include <boost/spirit/include/classic_ast.hpp> //for ast parse trees (in tree_formula)
#endif
//#include "log_thread.h"
#define LOG_STREAM cout
using namespace std;
#if BOOST_VERSION < 103600
typedef std::string::iterator iterator_t;
typedef boost::spirit::node_val_data_factory<unsigned int> factory_t; //want a modified node to contain an unsigned int value
typedef boost::spirit::tree_match<iterator_t, factory_t> parse_tree_match_t;
typedef boost::spirit::tree_parse_info<iterator_t, factory_t> tree_parse_info_t;
#else
typedef std::string::iterator iterator_t;
typedef boost::spirit::classic::node_val_data_factory<unsigned int> factory_t; //want a modified node to contain an unsigned int value
typedef boost::spirit::classic::tree_match<iterator_t, factory_t> parse_tree_match_t;
typedef boost::spirit::classic::tree_parse_info<iterator_t, factory_t> tree_parse_info_t;
#endif
typedef parse_tree_match_t::tree_iterator iter_t;
#define S_NORMAL "NORMAL"
#define S_ALARM "ALARM"
#define NOT_ACK "NACK"
#define ACK "ACK"
#define GR_ALL 0xffffffff
#define GR_NONE 0x00000000
#define GR_DEFAULT GR_NONE //or GR_ALL??
//#define MAX_GRP 32
#define GR_ALL_NAME "gr_all"
#define GR_NONE_NAME "gr_none"
#define LEV_LOG "log"
#define LEV_WARNING "warning"
#define LEV_FAULT "fault"
#define LEV_DEFAULT LEV_FAULT
class alarm_t;
class alarm_table;
class log_thread;
class cmd_thread;
struct formula_res_t
{
formula_res_t(){value=0;quality=Tango::ATTR_VALID;ex_reason=string("");ex_desc=string("");ex_origin=string("");}
double value;
int quality;
Tango::DevErrorList errors; //TODO: error stack
string ex_reason;
string ex_desc;
string ex_origin;
int combine_quality(int quality1, int quality2)
{
int res;
if(quality1 == Tango::ATTR_INVALID || quality2 == Tango::ATTR_INVALID)
res = Tango::ATTR_INVALID;
else if(quality1 == Tango::ATTR_ALARM || quality2 == Tango::ATTR_ALARM)
res = Tango::ATTR_ALARM;
else if(quality1 == Tango::ATTR_WARNING || quality2 == Tango::ATTR_WARNING)
res = Tango::ATTR_WARNING;
else if(quality1 == Tango::ATTR_CHANGING || quality2 == Tango::ATTR_CHANGING)
res = Tango::ATTR_CHANGING;
else
res = (quality1 > quality2) ? quality1 : quality2; //TODO: decide priority in enum AttrQuality { ATTR_VALID, ATTR_INVALID, ATTR_ALARM, ATTR_CHANGING, ATTR_WARNING /*, __max_AttrQuality=0xffffffff */ };
return res;
}
string combine_exception(string ex_1, string ex_2)
{
if(ex_1.length() > 0)
return ex_1;
else
return ex_2;
}
formula_res_t operator==(const formula_res_t& e)
{
formula_res_t res;
res.value = value == e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator!=(const formula_res_t& e)
{
formula_res_t res;
res.value = value != e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator<=(const formula_res_t& e)
{
formula_res_t res;
res.value = value <= e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator>=(const formula_res_t& e)
{
formula_res_t res;
res.value = value >= e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator<(const formula_res_t& e)
{
formula_res_t res;
res.value = value < e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator>(const formula_res_t& e)
{
formula_res_t res;
res.value = value > e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator||(const formula_res_t& e)
{
formula_res_t res;
res.value = value || e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator&&(const formula_res_t& e)
{
formula_res_t res;
res.value = value && e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator+(const formula_res_t& e)
{
formula_res_t res;
res.value = value + e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator-(const formula_res_t& e)
{
formula_res_t res;
res.value = value - e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator*(const formula_res_t& e)
{
formula_res_t res;
res.value = value * e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
formula_res_t operator/(const formula_res_t& e)
{
formula_res_t res;
res.value = value / e.value;
res.quality = combine_quality(quality, e.quality);
res.ex_reason = combine_exception(ex_reason, e.ex_reason);
res.ex_desc = combine_exception(ex_desc, e.ex_desc);
res.ex_origin = combine_exception(ex_origin, e.ex_origin);
return res;
}
/*string operator<<(const formula_res_t& e)
{
stringstream res;
res << "value="<<e.value<<" quality="<<e.quality<<" EX reason="<<e.ex_reason<<" desc="<<e.ex_desc<<" origin="<<e.ex_origin;
return res.str();
}*/
};
/*
* store the alarm-name/alarm-formula pair
*/
class alarm_t {
public:
string name,
formula;
string attr_name;
string attr_name_formula;
Tango::DevEnum *attr_value;
Tango::DevString *attr_value_formula;
int quality;
string ex_reason;
string ex_desc;
string ex_origin;
Tango::TimeVal ts;
string stat,
ack;
bool enabled;
bool shelved;
unsigned int on_counter;
unsigned int off_counter;
unsigned int freq_counter;
tree_parse_info_t formula_tree;
static map<string, unsigned int> grp_str;
bool done;
bool to_be_evaluated;
string msg;
unsigned int grp;
string lev;
set<string> s_event;
int is_new;
Tango::TimeVal ts_on_delay; //says when it has gone in alarm status for the first time
unsigned int on_delay; //TODO: seconds, is it enough precision?
Tango::TimeVal ts_off_delay; //says when it returned normal status
unsigned int off_delay; //TODO: seconds, is it enough precision?
Tango::TimeVal ts_time_silenced; //says when it has been silenced
int silent_time; //minutes max to be silent
int silenced; //minutes still to be silent
string attr_values_delay; //attr_values of first occurrence of alarm waiting for on or off delay
string cmd_name_a; //action to execute: when NORMAL -> ALARM, cmd_name = cmd_dp_a/cmd_action_a
string cmd_dp_a; //device proxy part of cmd_name_a
string cmd_action_a; //action part of cmd_name_a
bool send_arg_a; //send as string argument alarm name and attr values
Tango::DeviceProxy *dp_a;
string cmd_name_n; //action to execute: when ALARM -> NORMAL, cmd_name_n = cmd_dp_n/cmd_action_n
string cmd_dp_n; //device proxy part of cmd_name_n
string cmd_action_n; //action part of cmd_name_n
bool send_arg_n; //send as string argument alarm name and attr values
Tango::DeviceProxy *dp_n;
/*
* methods
*/
alarm_t(); //constructor
void init_static_map(vector<string> &group_names);
bool operator==(const alarm_t& that);
bool operator==(const string& n);
void str2alm(const string &s);
string alm2str(void);
string grp2str(void);
void add_grp_from_str(string &s);
void str2grp(string &s);
void insert(const string& s);
void clear();
void confstr(string &s);
protected:
private:
};
typedef map<string,alarm_t> alarm_container_t;
class alarm_table {
public:
alarm_table() {}
~alarm_table() {del_rwlock();}
void set_dev(Tango::DeviceImpl* devImpl) {mydev=devImpl;}
//void init(vector<string>& avs);
//void init(vector<string>& avs, vector<string> &evn, map< string,vector<string> > &alarm_event);
void push_back(alarm_t& a);
void show(vector<string> &al_table_string);
unsigned int size(void);
alarm_container_t& get(void);
void stored(vector<alarm_t>& a);
bool update(const string& alm_name, Tango::TimeVal ts, formula_res_t res, string &attr_values, string grp, string msg, string formula);
bool timer_update();
void erase(alarm_container_t::iterator i);
bool exist(string& s);
unsigned int to_be_evaluated_num();
vector<string> to_be_evaluated_list();
//vector<alarm_t> v_alarm;
alarm_container_t v_alarm;
ReadersWritersLock *vlock;
void new_rwlock();
void del_rwlock();
void save_alarm_conf_db(string att_name, string name, string status, string ack, bool enabled,
string formula, unsigned int on_delay, unsigned int off_delay, string grp, string lev, string msg, string cmd_a, string cmd_n, int silent_time, vector<string> alm_list=vector<string>());
void delete_alarm_conf_db(string att_name);
void get_alarm_list_db(vector<string> &al_list, map<string, string> &saved_alarms);
void init_cmdthread();
void stop_cmdthread();
Tango::TimeVal startup_complete; //to disable action execution at startup
protected:
private:
Tango::DeviceImpl* mydev;
log_thread *logloop;
cmd_thread *cmdloop;
};
#endif /* ALARM_TABLE_H */