From 1189893096dbc0244cea58edb899afe2038e613f Mon Sep 17 00:00:00 2001 From: gscalamera <graziano.scalamera@elettra.eu> Date: Mon, 14 Dec 2020 12:37:23 +0100 Subject: [PATCH] Handle ERROR state in alarm attribute --- src/AlarmHandler.cpp | 96 +++++++++++++++++++++++++++++++++++++++++--- src/alarm_table.h | 1 + src/event_table.cpp | 33 +++++++++++++-- 3 files changed, 122 insertions(+), 8 deletions(-) diff --git a/src/AlarmHandler.cpp b/src/AlarmHandler.cpp index 9dab8ac..da9930a 100644 --- a/src/AlarmHandler.cpp +++ b/src/AlarmHandler.cpp @@ -3611,6 +3611,11 @@ void AlarmHandler::do_alarm(bei_t& e) alarm_container_t::iterator it = alarms.v_alarm.find(*j); if(it != alarms.v_alarm.end()) { + //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; + } if(e.type == TYPE_TANGO_ERR) it->second.ex_reason = found_ev->ex_reason; else @@ -3640,6 +3645,41 @@ void AlarmHandler::do_alarm(bei_t& e) } 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; } @@ -5103,7 +5143,7 @@ void AlarmHandler::prepare_alarm_attr() DEBUG_STREAM << __func__ << ": " << ai->first << " -> " << tmp_ex.str(); if(almstate != "SHLVD" && almstate != "OOSRV") { - almstate = "ERROR"; + almstate = S_ERROR; } } @@ -5196,7 +5236,50 @@ void AlarmHandler::prepare_alarm_attr() alm_summary += KEY(ATTR_VALUES_KEY) + ai->second.attr_values + SEP; #endif #endif - if (ai->second.stat == S_ALARM && ai->second.enabled && !ai->second.shelved) { + 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 = ai->second.msg; + } + 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 + aid->on_counter = ai->second.on_counter; + aid->off_counter = ai->second.off_counter; + 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; + /* + * 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 */ @@ -5262,7 +5345,8 @@ void AlarmHandler::prepare_alarm_attr() 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) { + //if (aid->done) //TODO: done seems useless + { /* * if already ACKnowledged and visualized * remove from "alarmed" list @@ -5274,9 +5358,11 @@ void AlarmHandler::prepare_alarm_attr() alarmed.erase(aid); alarmedlock->writerOut(); alarmedlock->readerIn(); - } else { - aid->done = true; } + //else + //{ + // aid->done = true; + //} } /* if */ } /* if */ alarmedlock->readerOut(); diff --git a/src/alarm_table.h b/src/alarm_table.h index 4756d9a..5cdf551 100644 --- a/src/alarm_table.h +++ b/src/alarm_table.h @@ -69,6 +69,7 @@ typedef parse_tree_match_t::tree_iterator iter_t; #define S_NORMAL "NORMAL" #define S_ALARM "ALARM" +#define S_ERROR "ERROR" #define NOT_ACK "NACK" #define ACK "ACK" diff --git a/src/event_table.cpp b/src/event_table.cpp index 73ad651..c7821de 100644 --- a/src/event_table.cpp +++ b/src/event_table.cpp @@ -876,13 +876,26 @@ void event_table::subscribe_events() } catch (Tango::DevFailed &e) { - //Tango::Except::print_exception(e); - INFO_STREAM << "event_table::subscribe_events: error adding " << sig->name <<" err="<< e.errors[0].desc << endl; + ostringstream o; + o << "Error adding'" \ + << sig->name << "' error=" << e.errors[0].desc << ends; + INFO_STREAM << "event_table::subscribe_events: " << o.str() << endl; v_event[i].ex_reason = e.errors[0].reason; v_event[i].ex_desc = e.errors[0].desc; // v_event[i].ex_desc.erase(std::remove(v_event[i].ex_desc.begin(), v_event[i].ex_desc.end(), '\n'), v_event[i].ex_desc.end()); v_event[i].ex_origin = e.errors[0].origin; v_event[i].siglock->writerOut(); + //TODO: since event callback not called for this attribute, need to manually trigger do_alarm to update interlan structures ? + bei_t ex; + ex.ev_name = sig->name; + ex.quality = Tango::ATTR_INVALID; + ex.ex_reason = e.errors[0].reason; + ex.ex_desc = e.errors[0].desc; + ex.ex_origin = e.errors[0].origin; + ex.type = TYPE_TANGO_ERR; + ex.ts = gettime(); + ex.msg=o.str(); + static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->do_alarm(ex); continue; } } @@ -916,7 +929,10 @@ void event_table::subscribe_events() } catch (Tango::DevFailed &e) { - INFO_STREAM <<"event_table::"<<__func__<<": sig->attr->subscribe_event EXCEPTION:" << endl; + ostringstream o; + o << "Event exception for'" \ + << sig->name << "' error=" << e.errors[0].desc << ends; + INFO_STREAM <<"event_table::"<<__func__<<": sig->attr->subscribe_event: " << o.str() << endl; err = true; Tango::Except::print_exception(e); sig->siglock->writerIn(); @@ -926,6 +942,17 @@ void event_table::subscribe_events() sig->event_id = SUB_ERR; delete sig->event_cb; sig->siglock->writerOut(); + //since event callback not called for this attribute, need to manually trigger do_alarm to update interlan structures + bei_t ex; + ex.ev_name = sig->name; + ex.quality = Tango::ATTR_INVALID; + ex.ex_reason = e.errors[0].reason; + ex.ex_desc = e.errors[0].desc; + ex.ex_origin = e.errors[0].origin; + ex.type = TYPE_TANGO_ERR; + ex.ts = gettime(); + ex.msg=o.str(); + static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->do_alarm(ex); } if(!err) { -- GitLab