Newer
Older

Graziano Scalamera
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
* 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;
//#define _ACCESS_NODE_D 1
#if BOOST_VERSION < 103600
#ifndef _ACCESS_NODE_D
typedef char const* iterator_t;
typedef boost::spirit::tree_match<iterator_t> parse_tree_match_t;
typedef boost::spirit::tree_parse_info<> tree_parse_info_t;
#else
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;
#endif
#else
#ifndef _ACCESS_NODE_D
typedef char const* iterator_t;
typedef boost::spirit::classic::tree_match<iterator_t> parse_tree_match_t;
typedef boost::spirit::classic::tree_parse_info<> 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
#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;
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
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();
}*/
};

Graziano Scalamera
committed
/*
* store the alarm-name/alarm-formula pair
*/
class alarm_t {
public:
string name,
formula;
string attr_name;
Tango::DevBoolean *attr_value;
int quality;
string ex_reason;
string ex_desc;
string ex_origin;

Graziano Scalamera
committed
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
Tango::TimeVal ts;
string stat,
ack;
unsigned int 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_time_threshold; //says when it has gone in alarm status for the first time
unsigned int time_threshold; //TODO: seconds, is it enough precision?
Tango::TimeVal ts_time_silenced; //says when it has been silenced
int silent_time; //minutes max to be silent
int silenced; //minutes still to be silent
string attr_values_time_threshold; //attr_values of first occurrence of alarm waiting for time threshold
string 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();
protected:
private:
};
typedef map<string,alarm_t> alarm_container_t;
#ifndef _RW_LOCK
class alarm_table : public omni_mutex {
#else
class alarm_table {
#endif
public:
alarm_table() {}
~alarm_table() {}
void set_dev(Tango::DeviceImpl* devImpl) {mydev=devImpl;}

Graziano Scalamera
committed
//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);

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

Graziano Scalamera
committed
//vector<alarm_t> v_alarm;
alarm_container_t v_alarm;
#ifdef _RW_LOCK
ReadersWritersLock *vlock;
void new_rwlock();
void del_rwlock();
#endif
void init_logdb(string dbhost, string dbuser, string dbpw, string dbname, int dbport, string instance_name);
void stop_logdb();
void log_alarm_db(unsigned int type, Tango::TimeVal ts, string name, string status, string ack,
string formula, unsigned int time_threshold, string grp, string lev, string msg, string action, int silent_time, vector<string> alm_list=vector<string>());
void get_alarm_list_db(vector<string> &al_list);
void init_cmdthread();
void stop_cmdthread();
Tango::TimeVal startup_complete; //to disable action execution at startup
protected:
private:
Tango::DeviceImpl* mydev;

Graziano Scalamera
committed
log_thread *logloop;
cmd_thread *cmdloop;
};
#endif /* ALARM_TABLE_H */