From 2da801aa3099f09d003ca92336e0b78d37d7246a Mon Sep 17 00:00:00 2001 From: gscalamera <graziano.scalamera@elettra.eu> Date: Fri, 24 Feb 2017 12:28:43 +0100 Subject: [PATCH] Transformed alarm attributes to DevEnum and added formula attributes --- src/Alarm.cpp | 93 +++++++++++++++++++++++++++++---- src/Alarm.h | 31 +++++++++-- src/Alarm.xmi | 23 +++++++-- src/AlarmClass.h | 17 +++++- src/AlarmDynAttrUtils.cpp | 106 +++++++++++++++++++++++++++++++++++--- src/AlarmStateMachine.cpp | 16 ++++++ src/alarm_table.h | 4 +- 7 files changed, 265 insertions(+), 25 deletions(-) diff --git a/src/Alarm.cpp b/src/Alarm.cpp index 5389647..7c66d61 100644 --- a/src/Alarm.cpp +++ b/src/Alarm.cpp @@ -1105,14 +1105,14 @@ void Alarm::read_alarm(Tango::Attribute &attr) * Read attribute AlarmState related method * Description: * - * Data type: Tango::DevBoolean + * Data type: Tango::DevEnum (AlarmStateEnum) * Attr type: Scalar */ //-------------------------------------------------------- void Alarm::read_AlarmState(Tango::Attribute &attr) { DEBUG_STREAM << "Alarm::read_AlarmState(Tango::Attribute &attr) entering... " << endl; - Tango::DevBoolean *att_value = get_AlarmState_data_ptr(attr.get_name()); + Tango::DevEnum *att_value = get_AlarmState_data_ptr(attr.get_name()); /*----- PROTECTED REGION ID(Alarm::read_AlarmState) ENABLED START -----*/ string reason(""); string desc(""); @@ -1166,6 +1166,25 @@ void Alarm::read_AlarmState(Tango::Attribute &attr) /*----- PROTECTED REGION END -----*/ // Alarm::read_AlarmState } //-------------------------------------------------------- +/** + * Read attribute AlarmFormula related method + * Description: + * + * Data type: Tango::DevString + * Attr type: Scalar + */ +//-------------------------------------------------------- +void Alarm::read_AlarmFormula(Tango::Attribute &attr) +{ + DEBUG_STREAM << "Alarm::read_AlarmFormula(Tango::Attribute &attr) entering... " << endl; + Tango::DevString *att_value = get_AlarmFormula_data_ptr(attr.get_name()); + /*----- PROTECTED REGION ID(Alarm::read_AlarmFormula) ENABLED START -----*/ + // Set the attribute value + attr.set_value(att_value); + + /*----- PROTECTED REGION END -----*/ // Alarm::read_AlarmFormula +} +//-------------------------------------------------------- /** * Method : Alarm::add_dynamic_attributes() * Description : Create the dynamic attributes if any @@ -1177,6 +1196,7 @@ void Alarm::add_dynamic_attributes() // Example to add dynamic attribute: // Copy inside the following protected area to create instance(s) at startup. // add_AlarmState_dynamic_attribute("MyAlarmStateAttribute"); + // add_AlarmFormula_dynamic_attribute("MyAlarmFormulaAttribute"); /*----- PROTECTED REGION ID(Alarm::add_dynamic_attributes) ENABLED START -----*/ @@ -1192,8 +1212,13 @@ void Alarm::add_dynamic_attributes() i != alarms.v_alarm.end(); i++) { add_AlarmState_dynamic_attribute(i->second.attr_name); - Tango::DevBoolean *attr_value = get_AlarmState_data_ptr(i->second.attr_name); + Tango::DevEnum *attr_value = get_AlarmState_data_ptr(i->second.attr_name); i->second.attr_value = attr_value; + i->second.attr_name_formula = i->second.attr_name + string("Formula"); + add_AlarmFormula_dynamic_attribute(i->second.attr_name_formula); + Tango::DevString *attr_value_formula = get_AlarmFormula_data_ptr(i->second.attr_name_formula); + *attr_value_formula = CORBA::string_dup(i->second.formula.c_str()); + i->second.attr_value_formula = attr_value_formula; } } #ifndef _RW_LOCK @@ -1201,7 +1226,6 @@ void Alarm::add_dynamic_attributes() #else alarms.vlock->readerOut(); #endif - /*----- PROTECTED REGION END -----*/ // Alarm::add_dynamic_attributes } @@ -1247,8 +1271,44 @@ void Alarm::ack(const Tango::DevVarStringArray *argin) { alarms.log_alarm_db(TYPE_LOG_STATUS, gettime(), found->name, found->stat, ACK, "", 0, "", "", "", "", -1); + + Tango::DevEnum *attr_value = get_AlarmState_data_ptr(i->second.attr_name); + //TODO: if not _SHLVD, _DSUPR, _OOSRV + if((i->second.stat == S_NORMAL) && i->second.ack == ACK) + *attr_value = _NORM; + else if((i->second.stat == S_ALARM) && i->second.ack == NOT_ACK) + *attr_value = _UNACK; + else if((i->second.stat == S_ALARM) && i->second.ack == ACK) + *attr_value = _ACKED; + else if((i->second.stat == S_NORMAL) && i->second.ack == NOT_ACK) + *attr_value = _RTNUN; + try + { //DevFailed for push events + if(i->second.ex_reason.length() == 0) + { + timeval now; + gettimeofday(&now, NULL); + push_change_event(i->second.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)i->second.quality, 1/*size*/, 0, false); + push_archive_event(i->second.attr_name,(Tango::DevEnum *)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); + push_change_event(i->second.attr_name, &except); + push_archive_event(i->second.attr_name, &except); + } + } catch(Tango::DevFailed & ex) + { + WARN_STREAM << "Alarm::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl; + } } - found->ack = ACK; + found->ack = ACK; } else { internallock->readerIn(); found = find(internal.begin(), internal.end(), *si); @@ -2344,8 +2404,13 @@ void Alarm::load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn) (const char*)"Alarm::load_alarm()", Tango::ERR); } add_AlarmState_dynamic_attribute(alm.attr_name); - Tango::DevBoolean *attr_value = get_AlarmState_data_ptr(alm.attr_name); + Tango::DevEnum *attr_value = get_AlarmState_data_ptr(alm.attr_name); alm.attr_value = attr_value; + alm.attr_name_formula = alm.attr_name + string("Formula"); + add_AlarmFormula_dynamic_attribute(alm.attr_name_formula); + Tango::DevString *attr_value_formula = get_AlarmFormula_data_ptr(alm.attr_name_formula); + *attr_value_formula = CORBA::string_dup(alm.formula.c_str()); + alm.attr_value_formula = attr_value_formula; if (alarms.exist(alm.name)) { ostringstream o; o << "Alarm::load_alarm(): alarm '" << alm.name << "' already exist" << ends; @@ -2786,16 +2851,24 @@ bool Alarm::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ts) res = eval_formula(it->second.formula_tree, attr_values); DEBUG_STREAM << "Alarm::"<<__func__<<": Evaluation of " << it->second.formula << "; result=" << res.value << " quality=" << res.quality << endl; changed = alarms.update(tmpname, ts, res, attr_values, it->second.grp2str(), it->second.msg, it->second.formula); //update internal structure and log to db - Tango::DevBoolean *attr_value = get_AlarmState_data_ptr(it->second.attr_name); - *attr_value = (it->second.stat == S_ALARM); + Tango::DevEnum *attr_value = get_AlarmState_data_ptr(it->second.attr_name); + //TODO: if not _SHLVD, _DSUPR, _OOSRV + if((it->second.stat == S_NORMAL) && it->second.ack == ACK) + *attr_value = _NORM; + else if((it->second.stat == S_ALARM) && it->second.ack == NOT_ACK) + *attr_value = _UNACK; + else if((it->second.stat == S_ALARM) && it->second.ack == ACK) + *attr_value = _ACKED; + else if((it->second.stat == S_NORMAL) && it->second.ack == NOT_ACK) + *attr_value = _RTNUN; try { //DevFailed for push events if(it->second.ex_reason.length() == 0) { timeval now; gettimeofday(&now, NULL); - push_change_event(it->second.attr_name,(Tango::DevBoolean *)attr_value,now,(Tango::AttrQuality)it->second.quality, 1/*size*/, 0, false); - push_archive_event(it->second.attr_name,(Tango::DevBoolean *)attr_value,now,(Tango::AttrQuality)it->second.quality, 1/*size*/, 0, false); + push_change_event(it->second.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)it->second.quality, 1/*size*/, 0, false); + push_archive_event(it->second.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)it->second.quality, 1/*size*/, 0, false); } else { diff --git a/src/Alarm.h b/src/Alarm.h index 39e2af9..7cf0aa0 100644 --- a/src/Alarm.h +++ b/src/Alarm.h @@ -77,6 +77,17 @@ class update_thread; namespace Alarm_ns { +enum _AlarmStateEnum { + _NORM, + _UNACK, + _ACKED, + _RTNUN, + _SHLVD, + _DSUPR, + _OOSRV, +} ; +typedef _AlarmStateEnum AlarmStateEnum; + /*----- PROTECTED REGION ID(Alarm::Additional Class Declarations) ENABLED START -----*/ // Additional Class Declarations @@ -204,15 +215,29 @@ public: * Attribute AlarmState related methods * Description: * - * Data type: Tango::DevBoolean + * Data type: Tango::DevEnum * Attr type: Scalar */ virtual void read_AlarmState(Tango::Attribute &attr); virtual bool is_AlarmState_allowed(Tango::AttReqType type); void add_AlarmState_dynamic_attribute(string attname); void remove_AlarmState_dynamic_attribute(string attname); - Tango::DevBoolean *get_AlarmState_data_ptr(string &name); - map<string,Tango::DevBoolean> AlarmState_data; + Tango::DevEnum *get_AlarmState_data_ptr(string &name); + map<string,Tango::DevEnum> AlarmState_data; + + /** + * Attribute AlarmFormula related methods + * Description: + * + * Data type: Tango::DevString + * Attr type: Scalar + */ + virtual void read_AlarmFormula(Tango::Attribute &attr); + virtual bool is_AlarmFormula_allowed(Tango::AttReqType type); + void add_AlarmFormula_dynamic_attribute(string attname); + void remove_AlarmFormula_dynamic_attribute(string attname); + Tango::DevString *get_AlarmFormula_data_ptr(string &name); + map<string,Tango::DevString> AlarmFormula_data; //-------------------------------------------------------- /** diff --git a/src/Alarm.xmi b/src/Alarm.xmi index 07e0ecb..8259fc3 100644 --- a/src/Alarm.xmi +++ b/src/Alarm.xmi @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="ASCII"?> <pogoDsl:PogoSystem xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pogoDsl="http://www.esrf.fr/tango/pogo/PogoDsl"> - <classes name="Alarm" pogoRevision="9.1"> - <description description="Elettra alarm device server" title="Elettra alarm device server" sourcePath="/home/graziano/workspace/git/alarm/src" language="Cpp" filestogenerate="XMI file,Code files,Protected Regions" license="GPL" copyright="" hasMandatoryProperty="false" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false"> + <classes name="Alarm" pogoRevision="9.4"> + <description description="Elettra alarm device server" title="Elettra alarm device server" sourcePath="/home/graziano/ws/alarm/src" language="Cpp" filestogenerate="XMI file,Code files,Protected Regions" license="GPL" copyright="" hasMandatoryProperty="false" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false"> <inheritances classname="Device_4Impl" sourcePath=""/> <identification contact="at elettra.eu - graziano.scalamera" author="graziano.scalamera" emailDomain="elettra.eu" classFamily="SoftwareSystem" siteSpecific="" platform="Unix Like" bus="Not Applicable" manufacturer="" reference=""/> </description> @@ -134,13 +134,28 @@ <properties description="" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> <dynamicAttributes name="AlarmState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="true"> - <dataType xsi:type="pogoDsl:BooleanType"/> + <dataType xsi:type="pogoDsl:EnumType"/> <changeEvent fire="true" libCheckCriteria="true"/> <archiveEvent fire="true" libCheckCriteria="true"/> <dataReadyEvent fire="false" libCheckCriteria="true"/> <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> <properties description="" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <enumLabels>NORM</enumLabels> + <enumLabels>UNACK</enumLabels> + <enumLabels>ACKED</enumLabels> + <enumLabels>RTNUN</enumLabels> + <enumLabels>SHLVD</enumLabels> + <enumLabels>DSUPR</enumLabels> + <enumLabels>OOSRV</enumLabels> </dynamicAttributes> - <preferences docHome="./doc_html" makefileHome="/usr/local/tango-9.2.2/share/pogo/preferences"/> + <dynamicAttributes name="AlarmFormula" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="true"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="true" libCheckCriteria="false"/> + <archiveEvent fire="true" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </dynamicAttributes> + <preferences docHome="./doc_html" makefileHome="/usr/local/tango-9.2.5a/share/pogo/preferences"/> </classes> </pogoDsl:PogoSystem> diff --git a/src/AlarmClass.h b/src/AlarmClass.h index e215eb1..0d1676b 100644 --- a/src/AlarmClass.h +++ b/src/AlarmClass.h @@ -80,12 +80,27 @@ class AlarmStateAttrib: public Tango::Attr { public: AlarmStateAttrib(const string &att_name):Attr(att_name.c_str(), - Tango::DEV_BOOLEAN, Tango::READ) {}; + Tango::DEV_ENUM, Tango::READ) {}; ~AlarmStateAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast<Alarm *>(dev))->read_AlarmState(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast<Alarm *>(dev))->is_AlarmState_allowed(ty);} + virtual bool same_type(const type_info &in_type) {return typeid(AlarmStateEnum) == in_type;} + virtual string get_enum_type() {return string("AlarmStateEnum");} +}; + +// Attribute AlarmFormula class definition +class AlarmFormulaAttrib: public Tango::Attr +{ +public: + AlarmFormulaAttrib(const string &att_name):Attr(att_name.c_str(), + Tango::DEV_STRING, Tango::READ) {}; + ~AlarmFormulaAttrib() {}; + virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) + {(static_cast<Alarm *>(dev))->read_AlarmFormula(att);} + virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) + {return (static_cast<Alarm *>(dev))->is_AlarmFormula_allowed(ty);} }; diff --git a/src/AlarmDynAttrUtils.cpp b/src/AlarmDynAttrUtils.cpp index 122abfe..4a9991b 100644 --- a/src/AlarmDynAttrUtils.cpp +++ b/src/AlarmDynAttrUtils.cpp @@ -42,9 +42,10 @@ static const char *RcsId = "$Id: $"; /*----- PROTECTED REGION END -----*/ // Alarm::DynAttrUtils.cpp //================================================================ -// Attributes managed is: +// Attributes managed are: //================================================================ -// AlarmState | Tango::DevBoolean Scalar +// AlarmState | Tango::DevEnum Scalar +// AlarmFormula | Tango::DevString Scalar //================================================================ // For compatibility reason, this file (AlarmDynAttrUtils) @@ -94,13 +95,24 @@ void Alarm::add_AlarmState_dynamic_attribute(string attname) DEBUG_STREAM << __func__<<": entering name="<<attname; /*----- PROTECTED REGION END -----*/ // Alarm::att_AlarmState_dynamic_attribute + { + vector<string> labels; + labels.push_back("NORM"); + labels.push_back("UNACK"); + labels.push_back("ACKED"); + labels.push_back("RTNUN"); + labels.push_back("SHLVD"); + labels.push_back("DSUPR"); + labels.push_back("OOSRV"); + alarmstate_prop.set_enum_labels(labels); + } alarmstate->set_default_properties(alarmstate_prop); // Not Polled alarmstate->set_disp_level(Tango::OPERATOR); // Not Memorized alarmstate->set_change_event(true, true); alarmstate->set_archive_event(true, true); - AlarmState_data.insert(make_pair(attname, false)); + AlarmState_data.insert(make_pair(attname, 0)); add_attribute(alarmstate); } //-------------------------------------------------------- @@ -113,7 +125,7 @@ void Alarm::add_AlarmState_dynamic_attribute(string attname) void Alarm::remove_AlarmState_dynamic_attribute(string attname) { remove_attribute(attname, true); - map<string,Tango::DevBoolean>::iterator ite; + map<string,Tango::DevEnum>::iterator ite; if ((ite=AlarmState_data.find(attname))!=AlarmState_data.end()) { /*----- PROTECTED REGION ID(Alarm::remove_AlarmState_dynamic_attribute) ENABLED START -----*/ @@ -122,6 +134,67 @@ void Alarm::remove_AlarmState_dynamic_attribute(string attname) AlarmState_data.erase(ite); } } +//-------------------------------------------------------- +/** + * Add a AlarmFormula dynamic attribute. + * + * parameter attname: attribute name to be cretated and added. + */ +//-------------------------------------------------------- +void Alarm::add_AlarmFormula_dynamic_attribute(string attname) +{ + // Attribute : AlarmFormula + AlarmFormulaAttrib *alarmformula = new AlarmFormulaAttrib(attname); + Tango::UserDefaultAttrProp alarmformula_prop; + // description not set for AlarmFormula + // label not set for AlarmFormula + // unit not set for AlarmFormula + // standard_unit not set for AlarmFormula + // display_unit not set for AlarmFormula + // format not set for AlarmFormula + // max_value not set for AlarmFormula + // min_value not set for AlarmFormula + // max_alarm not set for AlarmFormula + // min_alarm not set for AlarmFormula + // max_warning not set for AlarmFormula + // min_warning not set for AlarmFormula + // delta_t not set for AlarmFormula + // delta_val not set for AlarmFormula + + /*----- PROTECTED REGION ID(Alarm::att_AlarmFormula_dynamic_attribute) ENABLED START -----*/ + DEBUG_STREAM << __func__<<": entering name="<<attname; + + /*----- PROTECTED REGION END -----*/ // Alarm::att_AlarmFormula_dynamic_attribute + alarmformula->set_default_properties(alarmformula_prop); + // Not Polled + alarmformula->set_disp_level(Tango::OPERATOR); + // Not Memorized + alarmformula->set_change_event(true, false); + alarmformula->set_archive_event(true, false); + char array[1]; + array[0] = '\0'; + AlarmFormula_data.insert(make_pair(attname, array)); + add_attribute(alarmformula); +} +//-------------------------------------------------------- +/** + * remove a AlarmFormula dynamic attribute. + * + * parameter attname: attribute name to be removed. + */ +//-------------------------------------------------------- +void Alarm::remove_AlarmFormula_dynamic_attribute(string attname) +{ + remove_attribute(attname, true); + map<string,Tango::DevString>::iterator ite; + if ((ite=AlarmFormula_data.find(attname))!=AlarmFormula_data.end()) + { + /*----- PROTECTED REGION ID(Alarm::remove_AlarmFormula_dynamic_attribute) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // Alarm::remove_AlarmFormula_dynamic_attribute + AlarmFormula_data.erase(ite); + } +} //============================================================ @@ -134,9 +207,9 @@ void Alarm::remove_AlarmState_dynamic_attribute(string attname) * parameter attname: the specified attribute name. */ //-------------------------------------------------------- -Tango::DevBoolean *Alarm::get_AlarmState_data_ptr(string &name) +Tango::DevEnum *Alarm::get_AlarmState_data_ptr(string &name) { - map<string,Tango::DevBoolean>::iterator ite; + map<string,Tango::DevEnum>::iterator ite; if ((ite=AlarmState_data.find(name))==AlarmState_data.end()) { TangoSys_OMemStream tms; @@ -148,6 +221,27 @@ Tango::DevBoolean *Alarm::get_AlarmState_data_ptr(string &name) } return &(ite->second); } +//-------------------------------------------------------- +/** + * Return a pointer on AlarmFormula data. + * + * parameter attname: the specified attribute name. + */ +//-------------------------------------------------------- +Tango::DevString *Alarm::get_AlarmFormula_data_ptr(string &name) +{ + map<string,Tango::DevString>::iterator ite; + if ((ite=AlarmFormula_data.find(name))==AlarmFormula_data.end()) + { + TangoSys_OMemStream tms; + tms << "Dynamic attribute " << name << " has not been created"; + Tango::Except::throw_exception( + (const char *)"ATTRIBUTE_NOT_FOUND", + tms.str().c_str(), + (const char *)"Alarm::get_AlarmFormula_data_ptr()"); + } + return &(ite->second); +} //============================================================= diff --git a/src/AlarmStateMachine.cpp b/src/AlarmStateMachine.cpp index 558ee6f..b38f2ae 100644 --- a/src/AlarmStateMachine.cpp +++ b/src/AlarmStateMachine.cpp @@ -82,6 +82,22 @@ bool Alarm::is_AlarmState_allowed(TANGO_UNUSED(Tango::AttReqType type)) return true; } +//-------------------------------------------------------- +/** + * Method : Alarm::is_AlarmFormula_allowed() + * Description : Execution allowed for AlarmFormula attribute + */ +//-------------------------------------------------------- +bool Alarm::is_AlarmFormula_allowed(TANGO_UNUSED(Tango::AttReqType type)) +{ + + // Not any excluded states for AlarmFormula attribute in read access. + /*----- PROTECTED REGION ID(Alarm::AlarmFormulaStateAllowed_READ) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // Alarm::AlarmFormulaStateAllowed_READ + return true; +} + //================================================= // Commands Allowed Methods diff --git a/src/alarm_table.h b/src/alarm_table.h index e829767..0bdf7b0 100644 --- a/src/alarm_table.h +++ b/src/alarm_table.h @@ -258,7 +258,9 @@ class alarm_t { string name, formula; string attr_name; - Tango::DevBoolean *attr_value; + string attr_name_formula; + Tango::DevEnum *attr_value; + Tango::DevString *attr_value_formula; int quality; string ex_reason; string ex_desc; -- GitLab