Newer
Older

Graziano Scalamera
committed
/*
* alarm_table.cpp
*
* $Author: graziano $
*
* $Revision: 1.5 $
*
* $Log: alarm_table.cpp,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
*/
#include <sys/time.h>
#include <tango.h>
#include "alarm_table.h"
#include "alarm_grammar.h"
#include "cmd_thread.h"

Graziano Scalamera
committed
static const char __FILE__rev[] = __FILE__ " $Revision: 1.5 $";
/*
* alarm_t class methods
*/
bool alarm_t::operator==(const alarm_t &that)
{
// return((stat == that.stat) && (ack == that.ack));
//verify if stat not equal but only contained because added *n in internal alarm
return((stat.find(that.stat) != std::string::npos) && (ack == that.ack));
}
bool alarm_t::operator==(const string &n)
{
return(name == n);
}
void alarm_t::str2alm(const string &s)
{
istringstream is(s);
ostringstream temp_msg;
string temp_grp;
unsigned int on_cnt;
is >> ts.tv_sec >> ts.tv_usec >> name >> stat >> ack >> on_cnt >> lev >> silent_time >> temp_grp >> msg; //stop at first white space in msg
#ifdef _CNT_ATOMIC
on_counter.store(on_cnt);
#else
on_counter = on_cnt;
#endif

Graziano Scalamera
committed
temp_msg << is.rdbuf(); //read all remaining characters as msg
msg += temp_msg.str();
str2grp(temp_grp);
}
string alarm_t::alm2str(void)
{
ostringstream os;
os.clear();
#ifdef _CNT_ATOMIC
os << ts.tv_sec << "\t" << ts.tv_usec << "\t" << name << "\t" \
<< stat << "\t" << ack << "\t" << on_counter.load() << "\t" << lev << "\t" << silent_time << "\t" << grp2str() << "\t" << msg << ends;
#else

Graziano Scalamera
committed
os << ts.tv_sec << "\t" << ts.tv_usec << "\t" << name << "\t" \
<< stat << "\t" << ack << "\t" << on_counter << "\t" << lev << "\t" << silent_time << "\t" << grp2str() << "\t" << msg << ends;

Graziano Scalamera
committed
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
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
return(os.str());
}
map<string, unsigned int> alarm_t::grp_str; //needed here because static
void alarm_t::init_static_map(vector<string> &group_names)
{
//LOG_STREAM << "alarm_table::init_static_map(vector<string> &group_names): Entering..." << endl;
int j=0;
vector<string>::iterator i;
if(grp_str.size() > 0)
return;
if(group_names.empty())
{
//LOG_STREAM << "alarm_table::init_static_map(): inserting: default group " << GR_NONE_NAME << " = " << showbase << hex << GR_NONE << endl;
grp_str.insert(make_pair(string(GR_NONE_NAME), GR_NONE));
}
for (i = group_names.begin(); i != group_names.end(); i++)
{
if((*i) == string(GR_ALL_NAME))
continue;
if(i == group_names.begin())
{
//LOG_STREAM << "alarm_table::init_static_map(): inserting: group " << *i << " = " << showbase << hex << GR_NONE << endl;
grp_str.insert(make_pair(*i, GR_NONE));
}
else
{
//LOG_STREAM << "alarm_table::init_static_map(): inserting: group " << *i << " = " << showbase << hex << int(0x1 << j) << endl;
grp_str.insert(make_pair(*i, 0x1 << j));
j++;
}
}
//LOG_STREAM << "alarm_table::init_static_map(): inserting: group " << GR_ALL_NAME << " = " << showbase << hex << GR_ALL << endl;
grp_str.insert(make_pair(string(GR_ALL_NAME), GR_ALL));
}
string alarm_t::grp2str(void)
{
map<string, unsigned int>::iterator i = grp_str.begin();
bool first=true;
string argout;
if(grp == GR_ALL)
argout = string(GR_ALL_NAME);
else if(grp == GR_NONE)
{
if(i != grp_str.end())
argout = i->first;
else
argout = string(GR_NONE_NAME);
}
else
{
for (; i != grp_str.end(); i++)
{
if(i->first == string(GR_ALL_NAME))
continue;
if(grp & i->second)
{
if(first)
{
argout = i->first;
first = false;
}
else
argout += string("|") + i->first;
}
}
}
return argout;
}
void alarm_t::add_grp_from_str(string &s)
{
map<string, unsigned int>::iterator i = grp_str.find(s);
if(i != grp_str.end())
grp |= (*i).second;
}
void alarm_t::str2grp(string &s)
{
for(map<string, unsigned int>::iterator i=grp_str.begin(); i != grp_str.end(); i++)
if(s.find(i->first) != string::npos)
grp |= i->second;
}
void alarm_t::insert(const string& s)
{
s_event.insert(s);
}
void alarm_t::clear()
{
name.clear();
formula.clear();
msg.clear();
lev.clear();
grp=0;
s_event.clear();
to_be_evaluated = false;
stat.clear();
ack.clear();
done = false;
// ts = 0;
}
void alarm_t::confstr(string &s)
{
ostringstream conf;
conf <<
KEY(NAME_KEY)<<name << SEP <<
KEY(FORMULA_KEY)<<formula << SEP <<
KEY(ONDELAY_KEY)<<on_delay << SEP <<
KEY(OFFDELAY_KEY)<<off_delay << SEP <<
KEY(LEVEL_KEY)<< lev << SEP <<
KEY(SILENT_TIME_KEY)<<silent_time << SEP <<
KEY(GROUP_KEY)<< grp2str() << SEP <<
KEY(MESSAGE_KEY)<< msg << SEP <<
KEY(ON_COMMAND_KEY)<< cmd_name_a << SEP <<
KEY(OFF_COMMAND_KEY)<< cmd_name_n << SEP <<
KEY(ENABLED_KEY)<< (enabled ? "1" : "0");
s = conf.str();
}

Graziano Scalamera
committed
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
265
266
267
268
269
270
271
272
273
274
275
276
277
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
/*
* alarm_table class methods
*/
/* typedef std::string::iterator iterator_t;
typedef boost::spirit::node_val_data_factory<unsigned int> factory_t; /////TEMP!!!!!!!!!!!!!!!!!!!
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;
*/
/*
void alarm_table::init(vector<string>& avs, vector<string> &evn, map< string,vector<string> > &alarm_event)
{
//LOG_STREAM << "alarm_table::init(vector<string>& avs,map< string,vector<string> > &alarm_event): Entering..." << endl;
alarm_t tmp_alm;
LOG_STREAM << gettime().tv_sec << " " << __FILE__rev << endl;
LOG_STREAM << gettime().tv_sec << " alarm_table::init(): Creating Spirit Parser..." << endl;
alarm_parse al(tmp_alm); // Construct Spirit grammar
if (avs.empty() == false) {
for (vector<string>::iterator i = avs.begin(); \
i != avs.end(); i++) {
tmp_alm.name.clear();
tmp_alm.formula.clear();
tmp_alm.msg.clear();
tmp_alm.lev.clear();
tmp_alm.grp=0;
tree_parse_info_t info = ast_parse<factory_t>(i->begin(), i->end(), al, space_p);
if (info.full)
{
LOG_STREAM << gettime().tv_sec << " Parsing succeeded: " << tmp_alm.name << endl;
for (vector<string>::iterator i = evn.begin(); i != evn.end(); i++)
LOG_STREAM << gettime().tv_sec << " READ Event! ->" << *i << endl;
}
else
{
LOG_STREAM << gettime().tv_sec << " Parsing failed, stopped at: " << string(info.stop, i->end()) << ends; //TODO
}
if ((tmp_alm.name.empty() == false) && \
(tmp_alm.formula.empty() == false) && \
((tmp_alm.lev==LEV_LOG)||(tmp_alm.lev==LEV_WARNING)|| \
(tmp_alm.lev==LEV_FAULT)||(tmp_alm.lev.empty() == true)))
{
tmp_alm.stat = S_NORMAL;
tmp_alm.ack = ACK;
tmp_alm.done = false;
if(tmp_alm.grp == 0)
tmp_alm.grp = GR_DEFAULT;
if(tmp_alm.lev.empty() == true)
tmp_alm.lev = LEV_DEFAULT;
push_back(tmp_alm);
} else {
cerr << gettime().tv_sec << " alarm_table::init(): syntax error in '" << *i \
<< "', skipping!" << endl;
}
}
}
}*/
void alarm_table::push_back(alarm_t &a)
{
vlock->writerIn();
//v_alarm.push_back(a);
v_alarm.insert(make_pair(a.name,a));
vlock->writerOut();
}
void alarm_table::show(vector<string> &al_table_string)
{
vlock->readerIn();
ostringstream log_msg;
string log_str;
if (v_alarm.empty() == false) {
log_msg << "### alarms table: ###" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
alarm_container_t::iterator i = v_alarm.begin();
unsigned int j = 0;
while (i != v_alarm.end()) {
log_msg << j << " - name: '" << i->second.name << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " formula: '" << i->second.formula << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " stat: '" << i->second.stat << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " ack: '" << i->second.ack << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " msg: '" << i->second.msg << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " grp: '" << showbase << hex << i->second.grp << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
log_msg << " lev: '" << i->second.lev << "'" << ends;
al_table_string.push_back(log_msg.str());
log_msg.str(string());
i++;
j++;
}
}
vlock->readerOut();
}
unsigned int alarm_table::size(void)
{
return(v_alarm.size());
}
alarm_container_t& alarm_table::get(void)
{
return(v_alarm);
}
void alarm_table::stored(vector<alarm_t>& a)
{
vlock->readerIn();
if (a.empty() == false) {
for (vector<alarm_t>::iterator i = a.begin(); i != a.end(); i++)
{
alarm_container_t::iterator found = v_alarm.find(i->name);
if (found != v_alarm.end()) {
found->second.ts = i->ts;
found->second.stat = i->stat;
found->second.ack = i->ack;
found->second.done = i->done;
found->second.is_new = i->is_new;
} else {
/*
* shouldn't happen!!!
*/
LOG_STREAM << "alarm_table::stored(): " << i->name \
<< " NOT found in alarm table" << endl;
}
} /* for */
} /* if */
vlock->readerOut();
}
bool alarm_table::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 ret_changed=false;

Graziano Scalamera
committed
TangoSys_MemStream out_stream;
vlock->readerIn();
alarm_container_t::iterator found = v_alarm.find(alm_name);
if (found != v_alarm.end())
{
if(found->second.silenced > 0)
{
Tango::TimeVal now = gettime();
double dnow = now.tv_sec + ((double)now.tv_usec) / 1000000;
double dsilent = found->second.ts_time_silenced.tv_sec + ((double)found->second.ts_time_silenced.tv_usec) / 1000000;
double dminutes = (dnow - dsilent)/60;
if(dminutes < found->second.silent_time)

Graziano Scalamera
committed
{

Graziano Scalamera
committed
found->second.silenced = found->second.silent_time - floor(dminutes);

Graziano Scalamera
committed
}

Graziano Scalamera
committed
else

Graziano Scalamera
committed
{

Graziano Scalamera
committed
found->second.silenced = 0;

Graziano Scalamera
committed
found->second.shelved = false;
found->second.is_new = 0;
found->second.ack = ACK;
}

Graziano Scalamera
committed
}
bool status_err_delay;
if(err_delay > 0)
status_err_delay = (!res.ex_reason.empty() || !res.ex_desc.empty() || !res.ex_origin.empty()) && (found->second.err_counter >= 1) && ((now.tv_sec - err_delay) > found->second.ts_err_delay.tv_sec); //error is present and err delay has passed
else
status_err_delay = (!res.ex_reason.empty() || !res.ex_desc.empty() || !res.ex_origin.empty());
found->second.quality = res.quality;
found->second.ex_reason = res.ex_reason;
found->second.ex_desc = res.ex_desc;
found->second.ex_origin = res.ex_origin;
bool status_on_delay;
if(found->second.on_delay > 0) //if enabled on delay
status_on_delay = ((bool)(res.value != 0)) && (found->second.on_counter >= 1) && ((ts.tv_sec - found->second.on_delay) > found->second.ts_on_delay.tv_sec); //formula gives true and on delay has passed
status_on_delay = (bool)(res.value != 0);
bool status_off_delay;
if(found->second.off_delay > 0) //if enabled off delay
status_off_delay = (!(bool)(res.value != 0)) && (found->second.off_counter >= 1) && ((ts.tv_sec - found->second.off_delay) > found->second.ts_off_delay.tv_sec); //formula gives false and off delay has passed

Graziano Scalamera
committed
else
status_off_delay = !(bool)(res.value != 0);

Graziano Scalamera
committed
//if status changed:
// - from S_NORMAL to S_ALARM considering also on delay

Graziano Scalamera
committed
//or
// - from S_ALARM to S_NORMAL considering also off delay
if((status_on_delay && (found->second.stat == S_NORMAL)) || (status_off_delay && (found->second.stat == S_ALARM)))

Graziano Scalamera
committed
{
ret_changed=true;
if((bool)(res.value != 0))

Graziano Scalamera
committed
found->second.ack = NOT_ACK; //if changing from NORMAL to ALARM -> NACK
//a.grp = found->second.grp2str();

Graziano Scalamera
committed
found->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts only if status changed
if((bool)(res.value != 0))

Graziano Scalamera
committed
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
{
found->second.is_new = 1; //here set this alarm as new, read attribute set it to 0 //12-06-08: StopNew command set it to 0
if(found->second.dp_a && ((ts.tv_sec - startup_complete.tv_sec) > 10)) //action from S_NORMAL to S_ALARM
{
/*try {
long call_id;
ostringstream tmp;
tmp << alm_name << ";" << attr_values;
Tango::DevString str = CORBA::string_dup(tmp.str().c_str());
Tango::DeviceData Din;
Din << str;
CORBA::string_free(str);
//found->second.dp_a->ping();
cmdloop->mutex_dp->lock();
//call_id = found->second.dp_a->command_inout_asynch(found->second.cmd_action_a, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer
call_id = found->second.dp_a->command_inout_asynch(found->second.cmd_action_a, Din); //true -> "fire and forget" mode: client do not care at all about the server answer
cmdloop->mutex_dp->unlock();
LOG_STREAM << "alarm_table::update() executed action: " << found->second.cmd_name_a << " !!!" << endl;
cmd_t arg;
arg.cmd_id = call_id;
arg.dp_add = (long)found->second.dp_a;
arg.arg_s = found->second.cmd_name_a;
cmdloop->list.push_back(arg);
} catch(Tango::DevFailed e)
{
string err(e.errors[0].desc);
if(err.find("is not yet arrived") == string::npos) //TODO: change this!!
out_stream << "Failed to execute action " << found->second.cmd_name_a << ", err=" << e.errors[0].desc << ends;
//LOG_STREAM << "alarm_table::update() ERROR: " << out_stream.str() << endl;
}*/
ostringstream tmp;
string tmp_attr_val = attr_values;
replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ',');
string tmp_msg = msg;
replace(tmp_msg.begin(), tmp_msg.end(), ';' , ',');
tmp << "name=" << alm_name << ";groups=" << grp << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<formula;
cmd_t arg;
arg.cmd_id = CMD_COMMAND;
arg.dp_add = (long)found->second.dp_a;
arg.arg_s1 = tmp.str();
arg.arg_s2 = found->second.cmd_action_a;
arg.arg_s3 = found->second.cmd_name_a;
arg.arg_b = found->second.send_arg_a;
cmdloop->list.push_back(arg);
}
}
else
{
if(found->second.dp_n && ((ts.tv_sec - startup_complete.tv_sec) > 10)) //action from S_ALARM to S_NORMAL
{
/*try {
long call_id;
ostringstream tmp;
tmp << alm_name << ";" << attr_values;
Tango::DevString str = CORBA::string_dup(tmp.str().c_str());
Tango::DeviceData Din;
Din << str;
CORBA::string_free(str);
//found->second.dp_n->ping();
cmdloop->mutex_dp->lock();
//call_id = found->second.dp_n->command_inout_asynch(found->second.cmd_action_n, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer
call_id = found->second.dp_n->command_inout_asynch(found->second.cmd_action_n, Din); //true -> "fire and forget" mode: client do not care at all about the server answer
cmdloop->mutex_dp->unlock();
LOG_STREAM << "alarm_table::update() executed action: " << found->second.cmd_name_n << " !!!" << endl;
cmd_t arg;
arg.cmd_id = call_id;
arg.dp_add = (long)found->second.dp_n;
arg.arg_s = found->second.cmd_name_n;
cmdloop->list.push_back(arg);
} catch(Tango::DevFailed e)
{
string err(e.errors[0].desc);
if(err.find("is not yet arrived") == string::npos) //TODO: change this!!
out_stream << "Failed to execute action " << found->second.cmd_name_n << ", err=" << e.errors[0].desc << ends;
//LOG_STREAM << "alarm_table::update() ERROR: " << out_stream.str() << endl;
}*/
ostringstream tmp;
string tmp_attr_val = attr_values;
replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ',');
string tmp_msg = msg;
replace(tmp_msg.begin(), tmp_msg.end(), ';' , ',');
tmp << "name=" << alm_name << ";groups=" << grp << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<formula;
cmd_t arg;
arg.cmd_id = CMD_COMMAND;
arg.dp_add = (long)found->second.dp_n;
arg.arg_s1 = tmp.str();
arg.arg_s2 = found->second.cmd_action_n;
arg.arg_s3 = found->second.cmd_name_n;
arg.arg_b = found->second.send_arg_n;
cmdloop->list.push_back(arg);
}
}
}
if (status_on_delay) {

Graziano Scalamera
committed
found->second.stat = S_ALARM;
//found->second.ack = NOT_ACK;
}
else if (status_off_delay) {
found->second.stat = S_NORMAL;
}
//if error changed:
// - from false to true considering also err delay
//or
// - from true to false
if((status_err_delay && !found->second.error) || (!status_err_delay))
{
ret_changed=true;
}
if(status_err_delay)
{
if(!found->second.error)
found->second.is_new = 1;
if((bool)(res.value != 0)) {
found->second.on_counter++;
found->second.off_counter = 0;

Graziano Scalamera
committed
} else {
found->second.on_counter = 0;
found->second.off_counter++;

Graziano Scalamera
committed
}
if(!found->second.ex_reason.empty() || !found->second.ex_desc.empty() || !found->second.ex_origin.empty())
{
found->second.err_counter++;
}
else
{
found->second.err_counter = 0;
found->second.error = false;
}
found->second.attr_values_delay = attr_values; //save last attr_values to be used in timer_update if this alarm pass over on or off delay
if(found->second.on_counter == 1)
found->second.ts_on_delay = gettime(); //first occurrance of this alarm, now begin to wait for on delay
if(found->second.off_counter == 1)
found->second.ts_off_delay = gettime(); //first occurrance of back to normal, now begin to wait for off delay
if(found->second.err_counter == 1)
found->second.ts_err_delay = gettime(); //first occurrance of this error, now begin to wait for err delay

Graziano Scalamera
committed
//found->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts everytime
} else {
/*
* shouldn't happen!!!!
*/
out_stream << "couldn't find alarm '" << alm_name << "' in 'alarms' table" << ends;
LOG_STREAM << gettime().tv_sec << " alarm_table::update(): " << out_stream.str() << endl;
}
vlock->readerOut();
if(out_stream.str().length() > 0)
throw out_stream.str();
return ret_changed;
}
bool alarm_table::timer_update()
{
bool ret_changed=false;
Tango::TimeVal ts = gettime();
TangoSys_MemStream out_stream;
vlock->readerIn();
for(alarm_container_t::iterator i = v_alarm.begin(); i != v_alarm.end(); i++)
{
bool status_on_delay=false;
bool status_off_delay=false;
bool status_err_delay=false;
if(err_delay > 0) //if enabled off delay
status_err_delay = (i->second.err_counter >= 1) && ((ts.tv_sec - err_delay) > i->second.ts_err_delay.tv_sec); //waiting for err delay has passed
if(i->second.on_delay == 0 && i->second.off_delay == 0 && err_delay == 0 && !i->second.shelved && i->second.silenced <=0)

Graziano Scalamera
committed
continue; //if not enabled on or off delay or not shelved, nothing to do in timer
if(i->second.on_delay > 0) //if enabled on delay
status_on_delay = (i->second.on_counter >= 1) && ((ts.tv_sec - i->second.on_delay) > i->second.ts_on_delay.tv_sec); //waiting for on delay has passed
if(i->second.off_delay > 0) //if enabled off delay
status_off_delay = (i->second.off_counter >= 1) && ((ts.tv_sec - i->second.off_delay) > i->second.ts_off_delay.tv_sec); //waiting for off delay has passed

Graziano Scalamera
committed

Graziano Scalamera
committed
//look here also if shelved time ended
bool old_shelved = i->second.shelved;
int old_silenced = i->second.silenced;
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;
if(dminutes < i->second.silent_time)
{
i->second.silenced = i->second.silent_time - floor(dminutes);
}
else
{
i->second.silenced = 0;
i->second.shelved = false;
i->second.is_new = 0;
i->second.ack = ACK;
}
}
//if just ended silence time, set ret_changed to true so to push events
//TODO: not interested in executing commands?
if(old_silenced>0 && i->second.silenced == 0)

Graziano Scalamera
committed
{

Graziano Scalamera
committed
ret_changed = true;

Graziano Scalamera
committed
}
//if status changed:
// - from S_NORMAL to S_ALARM considering also on delay
//or
// - from S_ALARM to S_NORMAL considering also off delay

Graziano Scalamera
committed
//or
// - from shelved to not shelved
if((status_on_delay && (i->second.stat == S_NORMAL)) || (status_off_delay && (i->second.stat == S_ALARM)) || (old_shelved && !i->second.shelved) || (status_err_delay && !i->second.error))

Graziano Scalamera
committed
{

Graziano Scalamera
committed
if(old_shelved && !i->second.shelved) //TODO: ok to execute on command and off command after shelving ends?
{
status_on_delay = i->second.stat == S_ALARM;
status_off_delay = i->second.stat == S_NORMAL;
}

Graziano Scalamera
committed
ret_changed = true;
if(!i->second.error)
i->second.is_new = 1;

Graziano Scalamera
committed
if(status_on_delay)

Graziano Scalamera
committed
i->second.ack = NOT_ACK; //if changing from NORMAL to ALARM but not ended shelved time -> NACK

Graziano Scalamera
committed
i->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts only if status changed
if(status_on_delay)

Graziano Scalamera
committed
{
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
i->second.is_new = 1; //here set this alarm as new, read attribute set it to 0 //12-06-08: StopNew command set it to 0
if(i->second.dp_a && ((ts.tv_sec - startup_complete.tv_sec) > 10))
{
/*try {
long call_id;
ostringstream tmp;
tmp << i->second.name << ";" << i->second.attr_values_on_delay;
Tango::DevString str = CORBA::string_dup(tmp.str().c_str());
Tango::DeviceData Din;
Din << str;
CORBA::string_free(str);
//i->second.dp_a->ping();
cmdloop->mutex_dp->lock();
//call_id = i->second.dp_a->command_inout_asynch(i->second.cmd_action_a, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer
call_id = i->second.dp_a->command_inout_asynch(i->second.cmd_action_a, Din);
cmdloop->mutex_dp->unlock();
LOG_STREAM << gettime().tv_sec << " alarm_table::timer_update() executed action: " << i->second.cmd_name_a << " !!!" << endl;
cmd_t arg;
arg.cmd_id = call_id;
arg.dp_add = (long)i->second.dp_a;
arg.arg_s = i->second.cmd_name_a;
cmdloop->list.push_back(arg);
} catch(Tango::DevFailed e)
{
string err(e.errors[0].desc);
if(err.find("is not yet arrived") == string::npos) //TODO: change this!!
out_stream << "Failed to execute action " << i->second.cmd_name_a << ", err=" << e.errors[0].desc << ends;
//LOG_STREAM << "alarm_table::timer_update() ERROR: " << out_stream.str() << endl;
}*/

Graziano Scalamera
committed
ostringstream tmp;
string tmp_attr_val = i->second.attr_values_delay;
replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ',');
string tmp_msg = i->second.msg;
replace(tmp_msg.begin(), tmp_msg.end(), ';' , ',');
tmp << "name=" << i->second.name << ";groups=" << i->second.grp2str() << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<i->second.formula<<";url="<<i->second.url;

Graziano Scalamera
committed
cmd_t arg;
arg.cmd_id = CMD_COMMAND;

Graziano Scalamera
committed
arg.dp_add = (long)i->second.dp_a;
arg.arg_s1 = tmp.str();
arg.arg_s2 = i->second.cmd_action_a;
arg.arg_s3 = i->second.cmd_name_a;
arg.arg_b = i->second.send_arg_a;
cmdloop->list.push_back(arg);
}
}
else if(status_off_delay && (i->second.stat == S_ALARM))
if(i->second.dp_n && ((ts.tv_sec - startup_complete.tv_sec) > 10))

Graziano Scalamera
committed
{
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
/*try {
long call_id;
ostringstream tmp;
tmp << i->second.name << ";" << i->second.attr_values_off_delay;
Tango::DevString str = CORBA::string_dup(tmp.str().c_str());
Tango::DeviceData Din;
Din << str;
CORBA::string_free(str);
//i->second.dp_n->ping();
cmdloop->mutex_dp->lock();
//call_id = i->second.dp_n->command_inout_asynch(i->second.cmd_action_n, Din, true); //true -> "fire and forget" mode: client do not care at all about the server answer
call_id = i->second.dp_n->command_inout_asynch(i->second.cmd_action_n, Din);
cmdloop->mutex_dp->unlock();
LOG_STREAM << gettime().tv_sec << " alarm_table::timer_update() executed action: " << i->second.cmd_name_n << " !!!" << endl;
cmd_t arg;
arg.cmd_id = call_id;
arg.dp_add = (long)i->second.dp_n;
arg.arg_s = i->second.cmd_name_n;
cmdloop->list.push_back(arg);
} catch(Tango::DevFailed e)
{
string err(e.errors[0].desc);
if(err.find("is not yet arrived") == string::npos) //TODO: change this!!
out_stream << "Failed to execute action " << i->second.cmd_name_n << ", err=" << e.errors[0].desc << ends;
//LOG_STREAM << "alarm_table::timer_update() ERROR: " << out_stream.str() << endl;
}*/
ostringstream tmp;
string tmp_attr_val = i->second.attr_values_delay;
replace(tmp_attr_val.begin(), tmp_attr_val.end(), ';' , ',');
string tmp_msg = i->second.msg;
replace(tmp_msg.begin(), tmp_msg.end(), ';' , ',');
tmp << "name=" << i->second.name << ";groups=" << i->second.grp2str() << ";msg="<<tmp_msg<<";values="<<tmp_attr_val<<";formula="<<i->second.formula<<";url="<<i->second.url;
cmd_t arg;
arg.cmd_id = CMD_COMMAND;
arg.dp_add = (long)i->second.dp_n;
arg.arg_s1 = tmp.str();
arg.arg_s2 = i->second.cmd_action_n;
arg.arg_s3 = i->second.cmd_name_n;
arg.arg_b = i->second.send_arg_n;
cmdloop->list.push_back(arg);
}

Graziano Scalamera
committed
}
if((int)(status_on_delay)) {
i->second.off_counter = 0;
} else if(status_off_delay) {
i->second.on_counter = 0;
}

Graziano Scalamera
committed
if(!i->second.enabled)
*(i->second.attr_value) = _OOSRV;
else if(i->second.shelved && i->second.silenced > 0)
*(i->second.attr_value) = _SHLVD;
else if((status_off_delay) && i->second.ack == ACK)
*(i->second.attr_value) = _NORM;
else if((status_on_delay) && i->second.ack == NOT_ACK)
*(i->second.attr_value) = _UNACK;
else if((status_on_delay) && i->second.ack == ACK)
*(i->second.attr_value) = _ACKED;
else if((status_off_delay) && i->second.ack == NOT_ACK)
*(i->second.attr_value) = _RTNUN;
try
{
{
timeval now;
gettimeofday(&now, NULL);

Graziano Scalamera
committed
mydev->push_change_event(i->second.attr_name,(Tango::DevEnum *)i->second.attr_value,now,(Tango::AttrQuality)i->second.quality, 1/*size*/, 0, false);
mydev->push_archive_event(i->second.attr_name,(Tango::DevEnum *)i->second.attr_value,now,(Tango::AttrQuality)i->second.quality, 1/*size*/, 0, false);
}
else
{
Tango::DevErrorList errors(1);
errors.length(1);
errors[0].desc = CORBA::string_dup(i->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(i->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(i->second.ex_origin.c_str());
Tango::DevFailed except(errors);
mydev->push_change_event(i->second.attr_name, &except);
mydev->push_archive_event(i->second.attr_name, &except);
}
} catch(Tango::DevFailed &e)
{}

Graziano Scalamera
committed
}
if (status_on_delay) {

Graziano Scalamera
committed
i->second.stat = S_ALARM;
}
else if (status_off_delay) {
i->second.stat = S_NORMAL;

Graziano Scalamera
committed
}
//found->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts everytime
}
vlock->readerOut();
if(out_stream.str().length() > 0)
throw out_stream.str();
return ret_changed;
}
void alarm_table::erase(alarm_container_t::iterator i)
{
vlock->writerIn();
v_alarm.erase(i);
vlock->writerOut();
}
bool alarm_table::exist(string& s)
{
alarm_container_t::iterator found = v_alarm.find(s);
if (found != v_alarm.end())
return true;
else
return false;
}
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
unsigned int alarm_table::to_be_evaluated_num()
{
unsigned int ret=0;
vlock->readerIn();
for(alarm_container_t::iterator i = v_alarm.begin(); i != v_alarm.end(); i++)
{
if(i->second.to_be_evaluated == true)
ret++;
}
vlock->readerOut();
return ret;
}
vector<string> alarm_table::to_be_evaluated_list()
{
vector<string> ret;
vlock->readerIn();
for(alarm_container_t::iterator i = v_alarm.begin(); i != v_alarm.end(); i++)
{
if(i->second.to_be_evaluated == true)
ret.push_back(i->first);
}
vlock->readerOut();
return ret;
}

Graziano Scalamera
committed
void alarm_table::new_rwlock()
{

Graziano Scalamera
committed
vlock = new(ReadersWritersLock);
#else
vlock = new rwlock_t("VLOCK");
#endif

Graziano Scalamera
committed
}
void alarm_table::del_rwlock()
{
delete vlock;
}
void alarm_table::init_cmdthread()
{
cmdloop = new cmd_thread();
cmdloop->start();
}
void alarm_table::stop_cmdthread()
{
cmd_t arg;
//arg.arg_s = CMD_THREAD_EXIT;
arg.cmd_id = CMD_THREAD_EXIT;
cmdloop->list.push_back(arg);
}
void alarm_table::save_alarm_conf_db(const string &att_name, const string &name, const string &status, const string &ack, bool enabled,
const string &formula, unsigned int on_delay, unsigned int off_delay, const string &grp, const string &lev, const string &msg, const string &url, const string &cmd_a, const string &cmd_n, int silent_time)
{
// We want to put properties for attribute "att_name"
Tango::DbDatum dbd_att_name(att_name);
Tango::DbDatum dbd_name(NAME_KEY);
Tango::DbDatum dbd_formula(FORMULA_KEY);
Tango::DbDatum dbd_on_delay(ONDELAY_KEY);
Tango::DbDatum dbd_off_delay(OFFDELAY_KEY);
Tango::DbDatum dbd_level(LEVEL_KEY);
Tango::DbDatum dbd_silence_time(SILENT_TIME_KEY); //TODO: silent_time
Tango::DbDatum dbd_group(GROUP_KEY);
Tango::DbDatum dbd_message(MESSAGE_KEY);
Tango::DbDatum dbd_oncommand(ON_COMMAND_KEY);
Tango::DbDatum dbd_offcommand(OFF_COMMAND_KEY);
Tango::DbDatum dbd_enabled(ENABLED_KEY);
Tango::DbData db_data;
dbd_att_name << (short int)12; // Twelve properties for attribute "att_name"
dbd_name << name.c_str();
dbd_formula << formula.c_str();
dbd_on_delay << (Tango::DevLong)on_delay;
dbd_off_delay << (Tango::DevLong)off_delay;
dbd_silence_time << (Tango::DevLong)silent_time;
dbd_group << grp.c_str();
dbd_message << msg.c_str();
dbd_url << url.c_str();
dbd_oncommand << cmd_a.c_str();
dbd_offcommand << cmd_n.c_str();
dbd_enabled << (enabled ? (short int)1 : (short int)0);
db_data.push_back(dbd_att_name);
db_data.push_back(dbd_name);
db_data.push_back(dbd_formula);
db_data.push_back(dbd_on_delay);
db_data.push_back(dbd_off_delay);
db_data.push_back(dbd_level);
db_data.push_back(dbd_silence_time);
db_data.push_back(dbd_group);
db_data.push_back(dbd_message);
db_data.push_back(dbd_oncommand);
db_data.push_back(dbd_offcommand);
db_data.push_back(dbd_enabled);
string dev_name(mydev->get_name());
try
{
Tango::DbDevice *db_dev = mydev->get_db_device();
db_dev->get_dbase()->put_device_attribute_property(dev_name,db_data);
//Tango::Util::instance()->get_database()->put_device_attribute_property(dev_name,db_data);
}
catch(Tango::DevFailed &e)
{
cout << __func__ << ": Exception saving configuration = " << e.errors[0].desc<<endl;
}
void alarm_table::delete_alarm_conf_db(string att_name)

Graziano Scalamera
committed
{
// We want to put properties for attribute "att_name"
Tango::DbDatum dbd_att_name(att_name);
Tango::DbDatum dbd_name(NAME_KEY);
Tango::DbDatum dbd_formula(FORMULA_KEY);
Tango::DbDatum dbd_on_delay(ONDELAY_KEY);
Tango::DbDatum dbd_off_delay(OFFDELAY_KEY);
Tango::DbDatum dbd_level(LEVEL_KEY);
Tango::DbDatum dbd_silence_time(SILENT_TIME_KEY); //TODO: silent_time
Tango::DbDatum dbd_group(GROUP_KEY);
Tango::DbDatum dbd_message(MESSAGE_KEY);
Tango::DbDatum dbd_oncommand(ON_COMMAND_KEY);
Tango::DbDatum dbd_offcommand(OFF_COMMAND_KEY);
Tango::DbDatum dbd_enabled(ENABLED_KEY);
db_data.push_back(dbd_att_name);
db_data.push_back(dbd_name);
db_data.push_back(dbd_formula);
db_data.push_back(dbd_on_delay);
db_data.push_back(dbd_off_delay);
db_data.push_back(dbd_level);
db_data.push_back(dbd_silence_time);
db_data.push_back(dbd_group);
db_data.push_back(dbd_message);
db_data.push_back(dbd_oncommand);
db_data.push_back(dbd_offcommand);
db_data.push_back(dbd_enabled);
string dev_name(mydev->get_name());
try
{
Tango::DbDevice *db_dev = mydev->get_db_device();
db_dev->get_dbase()->delete_device_attribute_property(dev_name,db_data);
}
catch(Tango::DevFailed &e)
{
cout << __func__ << ": Exception deleting " << att_name << " = " << e.errors[0].desc<<endl;
}
}
void alarm_table::get_alarm_list_db(vector<string> &al_list, map<string, string> &saved_alarms, ReadersWritersLock *savedlock)
string dev_name(mydev->get_name());
vector<string> att_list;
Tango::DbDevice *db_dev = mydev->get_db_device();
db_dev->get_dbase()->get_device_attribute_list(dev_name,att_list);
Tango::DbData db_data;
vector<string>::iterator it;
for(it = att_list.begin(); it!=att_list.end(); it++)
{
db_data.push_back(Tango::DbDatum(*it));
}
try
{
db_dev->get_attribute_property(db_data);
}
catch(Tango::DevFailed &e)
{
cout << __func__ << ": Exception reading configuration = " << e.errors[0].desc<<endl;
}
savedlock->writerIn();
saved_alarms.clear();
for (size_t i=0;i < db_data.size();/*i++*/)
{
Tango::DevLong64 nb_prop;
string &att_name = db_data[i].name;
db_data[i] >> nb_prop;
i++;
string alm_name;
string alm_formula;
string alm_on_delay("0");
string alm_off_delay("0");
string alm_level;
string alm_silence_time("-1");
string alm_group;
string alm_message;
string alm_on_command("");
string alm_off_command("");
for (long k=0;k < nb_prop;k++)
{
string &prop_name = db_data[i].name;
if (prop_name == NAME_KEY)
else if (prop_name == FORMULA_KEY)
db_data[i] >> alm_formula;
else if (prop_name == ONDELAY_KEY)
db_data[i] >> alm_on_delay;