2 #include "ErrorHandler/MessageAnalyzer/ma_rule.h"
3 #include "ErrorHandler/MessageAnalyzer/ma_parse.h"
7 using fhicl::ParameterSet;
8 using namespace novadaq::errorhandler;
10 ma_rule::ma_rule(std::string
const& rule_name, std::string
const& rule_desc,
bool repeat,
int holdoff_time)
16 , description_(rule_desc)
25 , itor_last_alarm(alarms.end())
26 , repeat_alarm(repeat)
27 , holdoff(holdoff_time)
34 void ma_rule::parse(std::string
const& cond_expr, std::string
const& alarm_message, ParameterSet
const& act_pset, cond_map_t* cond_map_ptr)
36 cond_map = cond_map_ptr;
37 condition_expr = cond_expr;
40 if (!parse_condition_expr(cond_expr,
this))
41 throw std::runtime_error(
"rule parsing failed");
44 alarm_msg.init(
this, alarm_message);
47 std::vector<std::string> keys = act_pset.get_pset_names();
48 for (
size_t i = 0; i < keys.size(); ++i)
50 ParameterSet param = act_pset.get<ParameterSet>(keys[i]);
51 actions.push_back(ma_action_factory::create_instance(keys[i],
this, param));
55 if (domain_expr.empty())
56 domains.push_back(ma_domain_ctor_any(conditions.size()));
62 ma_rule::insert_condition_ptr(std::string
const& name,
bool primitive)
65 assert(cond_map != NULL);
67 TLOG(TLVL_DEBUG) <<
"insert_cond_ptr: name = " << name <<
" "
68 <<
"primitive = " << primitive;
72 idx_t::const_iterator it = conditions_idx.find(name);
73 if (it != conditions_idx.end())
76 primitive_cond[it->second] = primitive_cond[it->second] | primitive;
77 return cond_idx_t(conditions[it->second], it->second);
83 cond_map_t::iterator it = cond_map->find(name);
85 if (it == cond_map->end())
86 throw std::runtime_error(
"insert_cond_ptr: condition " + name +
" not found");
89 it->second.push_notify_status(
this);
92 cond_names_.push_back(name);
93 conditions.push_back(&it->second);
94 primitive_cond.push_back(primitive);
96 assert(conditions.size() == primitive_cond.size());
97 size_t idx = conditions.size() - 1;
99 conditions_idx.insert(std::make_pair(name, idx));
101 return cond_idx_t(&it->second, idx);
104 void ma_rule::evaluate_domain()
110 domain_expr.evaluate(domains);
112 TLOG(TLVL_DEBUG) << description_
113 <<
": domain evaluated, size = " << domains.size();
116 bool ma_rule::recursive_evaluate(ma_domain& value, ma_domain& alarm, ma_domain
const& domain,
size_t n)
119 assert(!domain_is_null(domain[n]));
122 ma_cond_range src(D_NIL, D_NIL);
123 ma_cond_range target(D_NIL, D_NIL);
127 if (primitive_cond[n])
128 conditions[n]->get_cond_range(domain[n], src, target);
130 TLOG(TLVL_DEBUG) <<
"depth: " << n <<
" "
131 <<
"primitive_cond[n]: " << primitive_cond[n];
133 for (
int s = src.first; s <= src.second; ++s)
135 for (
int t = target.first; t <= target.second; ++t)
140 TLOG(TLVL_DEBUG) <<
"depth: " << n <<
" "
141 <<
"src: " << s <<
" "
144 if (n != domain.size() - 1)
146 if (recursive_evaluate(value, alarm, domain, n + 1))
152 if (boolean_evaluate(value, alarm, domain))
161 bool ma_rule::evaluate()
166 if (!enabled)
return false;
168 TLOG(TLVL_DEBUG) << description_ <<
": evaluate boolean expr...";
171 for (ma_domains::const_iterator ait = domains.begin(); ait != domains.end(); ++ait)
174 ma_domain
const& domain = *ait;
177 assert(!domain_is_null(domain));
180 ma_domain value = ma_domain_ctor_null(domain.size());
181 ma_domain alarm = ma_domain_ctor_null(domain.size());
184 if (recursive_evaluate(value, alarm, domain, 0))
191 bool ma_rule::boolean_evaluate(ma_domain& value, ma_domain& alarm, ma_domain
const& domain)
193 TLOG(TLVL_DEBUG) <<
"now evaluate boolean_expr with given value";
196 if (boolean_expr.evaluate(value, alarm, domain))
198 TLOG(TLVL_DEBUG) <<
"alarm (" << alarm[0].first <<
", "
199 << alarm[0].second <<
")";
201 std::map<ma_domain, timeval>::iterator it = alarms.find(alarm);
202 if (it == alarms.end())
206 gettimeofday(&tv, 0);
207 itor_last_alarm = alarms.insert(std::make_pair(alarm, tv)).first;
210 alarm = ma_domain_ctor_null(domain.size());
220 else if (repeat_alarm)
224 gettimeofday(&tv, 0);
225 timeval lt = it->second;
226 if (tv.tv_sec - lt.tv_sec > holdoff)
229 itor_last_alarm = alarms.insert(it, std::make_pair(alarm, tv));
232 alarm = ma_domain_ctor_null(domain.size());
245 TLOG(TLVL_DEBUG) <<
"this alarm has already been triggered";
250 alarm = ma_domain_ctor_null(domain.size());
258 for (ma_actions::const_iterator it = actions.begin(), e = actions.end(); it != e; ++it)
260 if ((*it)->exec()) ++mask;
265 void ma_rule::reset()
268 boolean_expr.reset();
271 cond_vec_t::iterator it = conditions.begin();
272 for (; it != conditions.end(); ++it) (*it)->reset();
276 itor_last_alarm = alarms.end();
280 ma_domain
const& ma_rule::get_alarm()
const
283 throw std::runtime_error(
"get_alarm_message(): no alarm has been triggerd");
286 assert(itor_last_alarm != alarms.end());
288 return itor_last_alarm->first;
291 std::string ma_rule::get_alarm_message()
293 return alarm_msg.message();
300 ma_rule::get_cond_idx(std::string
const& name)
const
302 idx_t::const_iterator it = conditions_idx.find(name);
303 if (it == conditions_idx.end())
304 throw std::runtime_error(
"get_cond_idx: name '" + name +
"' not found");
305 return cond_idx_t(conditions[it->second], it->second);
310 ma_rule::get_cond(std::string
const& name)
const
312 idx_t::const_iterator it = conditions_idx.find(name);
313 if (it == conditions_idx.end())
314 throw std::runtime_error(
"get_cond: name '" + name +
"' not found");
315 return conditions[it->second];
320 ma_rule::get_idx(std::string
const& name)
const
322 idx_t::const_iterator it = conditions_idx.find(name);
323 if (it == conditions_idx.end())
324 throw std::runtime_error(
"get_cond: name '" + name +
"' not found");
330 ma_rule::get_cond_size()
const
332 assert(conditions.size() == conditions_idx.size());
333 return conditions.size();
338 void ma_rule::update_notify_list(std::string
const& name, arg_t arg)
340 idx_t::const_iterator it = conditions_idx.find(name);
342 if (it == conditions_idx.end())
343 throw std::runtime_error(
"update_notify_list: name '" + name +
"' not found");
345 (arg == SOURCE) ? conditions[it->second]->push_notify_source(
this)
346 : conditions[it->second]->push_notify_target(
this);