Newer
Older
/*----- PROTECTED REGION ID(AlarmHandler.cpp) ENABLED START -----*/

Graziano Scalamera
committed
//=============================================================================
//

Graziano Scalamera
committed
//
// description : C++ source for the AlarmHandler class and its commands.

Graziano Scalamera
committed
// The class is derived from Device. It represents the
// CORBA servant object which will be accessed from the
// network. All commands which can be executed on the
// AlarmHandler are implemented in this file.

Graziano Scalamera
committed
//
// project : Elettra alarm handler device server

Graziano Scalamera
committed
//
// This file is part of Tango device class.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Tango. If not, see <http://www.gnu.org/licenses/>.
//
//
//
//=============================================================================
// This file is generated by POGO
// (Program Obviously used to Generate tango Object)
//=============================================================================
#include <AlarmHandler.h>
#include <AlarmHandlerClass.h>

Graziano Scalamera
committed
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
#include <ctype.h> //for tolower
#include "alarm-thread.h"
#include "alarm_grammar.h"
#include "update-thread.h"
//#define _DUMP_TREE_XML
#ifdef _DUMP_TREE_XML
#if BOOST_VERSION < 103600
#include <boost/spirit/iterator/fixed_size_queue.hpp>
#include <boost/spirit/core.hpp>
#include <boost/spirit/tree/ast.hpp>
#include <boost/spirit/tree/tree_to_xml.hpp>
using namespace boost::spirit;
#else
#include <boost/spirit/include/classic_fixed_size_queue.hpp>
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_ast.hpp>
#include <boost/spirit/include/classic_tree_to_xml.hpp>
using namespace boost::spirit::classic;
#endif
#include <iostream>
#include <stack>
#include <functional>
#include <string>
#include <cassert>
#endif //_DUMP_TREE_XML
#include <sstream>
std::map<parser_id, std::string> rule_names; //only for log messages
int AlarmHandler_ns::AlarmHandler::instanceCounter = 0;

Graziano Scalamera
committed
#ifndef ALARM_BUILDTIME
#define ALARM_BUILDTIME __DATE__ " " __TIME__ " boost=" BOOST_LIB_VERSION
#endif
const char version_string[] = "$Build: @buildID@ " ALARM_BUILDTIME " $";
static const char __FILE__rev[] = __FILE__ " $Revision: 1.29 $";
/*----- PROTECTED REGION END -----*/ // AlarmHandler.cpp

Graziano Scalamera
committed
/**
* AlarmHandler class description:
* Elettra alarm handler device server

Graziano Scalamera
committed
*/
//================================================================
// The following table gives the correspondence
// between command and method names.
//

Graziano Scalamera
committed
// Command name | Method name

Graziano Scalamera
committed
//================================================================

Graziano Scalamera
committed
// State | Inherited (no method)
// Status | Inherited (no method)
// Ack | ack
// Load | load
// Remove | remove
// SearchAlarm | search_alarm
// StopAudible | stop_audible
// Silence | silence
// Modify | modify
// Shelve | shelve
// Enable | enable
// Disable | disable
// ResetStatistics | reset_statistics

Graziano Scalamera
committed
//================================================================
//================================================================

Graziano Scalamera
committed
// Attributes managed are:

Graziano Scalamera
committed
//================================================================

Graziano Scalamera
committed
// audibleAlarm | Tango::DevBoolean Scalar
// StatisticsResetTime | Tango::DevDouble Scalar
// alarm | Tango::DevString Spectrum ( max = 1024)
// normalAlarms | Tango::DevString Spectrum ( max = 10000)
// unacknowledgedAlarms | Tango::DevString Spectrum ( max = 10000)
// acknowledgedAlarms | Tango::DevString Spectrum ( max = 10000)
// unacknowledgedNormalAlarms | Tango::DevString Spectrum ( max = 10000)
// shelvedAlarms | Tango::DevString Spectrum ( max = 10000)
// outOfServiceAlarms | Tango::DevString Spectrum ( max = 10000)
// silencedAlarms | Tango::DevString Spectrum ( max = 10000)
// listAlarms | Tango::DevString Spectrum ( max = 10000)
// frequencyAlarms | Tango::DevDouble Spectrum ( max = 10000)

Graziano Scalamera
committed
//================================================================

Graziano Scalamera
committed
{
/*----- PROTECTED REGION ID(AlarmHandler::namespace_starting) ENABLED START -----*/

Graziano Scalamera
committed
// static initializations
/*----- PROTECTED REGION END -----*/ // AlarmHandler::namespace_starting

Graziano Scalamera
committed
//--------------------------------------------------------
/**
* Method : AlarmHandler::AlarmHandler()

Graziano Scalamera
committed
* Description : Constructors for a Tango device
* implementing the classAlarmHandler

Graziano Scalamera
committed
*/
//--------------------------------------------------------
AlarmHandler::AlarmHandler(Tango::DeviceClass *cl, string &s)

Graziano Scalamera
committed
: TANGO_BASE_CLASS(cl, s.c_str())
{
/*----- PROTECTED REGION ID(AlarmHandler::constructor_1) ENABLED START -----*/

Graziano Scalamera
committed
init_device();
/*----- PROTECTED REGION END -----*/ // AlarmHandler::constructor_1

Graziano Scalamera
committed
}
//--------------------------------------------------------
AlarmHandler::AlarmHandler(Tango::DeviceClass *cl, const char *s)

Graziano Scalamera
committed
: TANGO_BASE_CLASS(cl, s)
{
/*----- PROTECTED REGION ID(AlarmHandler::constructor_2) ENABLED START -----*/

Graziano Scalamera
committed
init_device();
/*----- PROTECTED REGION END -----*/ // AlarmHandler::constructor_2

Graziano Scalamera
committed
}
//--------------------------------------------------------
AlarmHandler::AlarmHandler(Tango::DeviceClass *cl, const char *s, const char *d)

Graziano Scalamera
committed
: TANGO_BASE_CLASS(cl, s, d)
{
/*----- PROTECTED REGION ID(AlarmHandler::constructor_3) ENABLED START -----*/

Graziano Scalamera
committed
init_device();
/*----- PROTECTED REGION END -----*/ // AlarmHandler::constructor_3

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::delete_device()

Graziano Scalamera
committed
* Description : will be called at device destruction or at init command
*/
//--------------------------------------------------------
void AlarmHandler::delete_device()

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::delete_device() " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::delete_device) ENABLED START -----*/

Graziano Scalamera
committed
// Delete device allocated objects

Graziano Scalamera
committed
* unsubscribe events and release memory
*/
bool starting = Tango::Util::instance()->is_svr_starting();
bool shutting_down = Tango::Util::instance()->is_svr_shutting_down();
bool restarting = Tango::Util::instance()->is_device_restarting(device_name);
DEBUG_STREAM << __func__ << " starting="<<(int)starting << " shutting_down="<<(int)shutting_down<<" restarting="<<(int)restarting;

Graziano Scalamera
committed
abortflag = true;
DEBUG_STREAM << "AlarmHandler::delete_device(): after abortflag=true..." << endl;

Graziano Scalamera
committed
try {

Graziano Scalamera
committed
} catch (string& err) {
ERROR_STREAM << err << endl;
}
DEBUG_STREAM << "AlarmHandler::delete_device(): events unsubscribed!" << endl;

Graziano Scalamera
committed
/*
* kill alarm thread
*/

Graziano Scalamera
committed
bei_t e;
e.ev_name = ALARM_THREAD_EXIT;
e.value.push_back(ALARM_THREAD_EXIT_VALUE);
e.value.push_back(ALARM_THREAD_EXIT_VALUE);
evlist.push_back(e);
//alarms.del_rwlock(); moved in alarm_table destructor

Graziano Scalamera
committed
alarms.stop_cmdthread();
sleep(1); //wait for alarm_thread and log_thread to exit
//delete almloop;
DEBUG_STREAM << "AlarmHandler::delete_device(): stopped alarm and log threads!" << endl;

Graziano Scalamera
committed
//delete proxy for actions
for(alarm_container_t::iterator i = alarms.v_alarm.begin(); i!=alarms.v_alarm.end(); i++)
{
if(i->second.dp_a)
delete i->second.dp_a;
i->second.dp_a = NULL;
if(i->second.dp_n)
delete i->second.dp_n;
i->second.dp_n = NULL;
}
if(restarting || shutting_down) //TODO: handle init, restart device
{
for(alarm_container_t::iterator it = alarms.v_alarm.begin(); it != alarms.v_alarm.end(); it++)
{
try
{
remove_AlarmState_dynamic_attribute_no_clean_db(it->second.attr_name);
}
catch(Tango::DevFailed &e)
{
INFO_STREAM << __func__<<": exception removing " << it->second.attr_name << ": " << e.errors[0].desc;
}
try
{
remove_AlarmFormula_dynamic_attribute(it->second.attr_name_formula);
}
catch(Tango::DevFailed &e)
{
INFO_STREAM << __func__<<": exception removing " << it->second.attr_name_formula << ": " << e.errors[0].desc;
}
}
}

Graziano Scalamera
committed
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
/*
* clear all data structures
*/
alarms.v_alarm.clear();
events->v_event.clear();
evlist.clear();
/* for (int i = ds_num - 1; i >= 0; i--) {
CORBA::string_free(ds[i]);
}*/
ds_num = 0;
/*
* store current "alarmed" table status
*/
vector<string> vs;
for (vector<alarm_t>::iterator i = alarmed.begin(); \
i != alarmed.end(); i++) {
vs.push_back(i->alm2str());
}
Tango::DbDatum as("AlarmStatus");
Tango::DbData data_del;
data_del.push_back(as);
//get_db_device()->delete_property(data_del);
as << vs;
Tango::DbData data_put;
data_put.push_back(as);
#ifndef _USE_ELETTRA_DB_RW
Tango::Database *db = new Tango::Database();
#else
//salvataggio proprietà usando host_rw e port_rw per connettersi al database
Tango::Database *db;
if(host_rw != "")
db = new Tango::Database(host_rw,port_rw);
else
db = new Tango::Database();
#endif
try {
db->put_device_property(get_name(), data_put);
}
catch(Tango::DevFailed &e)
{
ERROR_STREAM << __FUNCTION__<< " error saving properties='" << e.errors[0].desc << "'";
}
delete db;
/*
* clear storage
*/
alarmed.clear();
delete alarmedlock;
delete internallock;
delete dslock;
delete events;
DEBUG_STREAM << "AlarmHandler::delete_device(): saved AlarmStatus in properties!!" << endl;

Graziano Scalamera
committed
//Tango::leavefunc();
/*----- PROTECTED REGION END -----*/ // AlarmHandler::delete_device

Graziano Scalamera
committed
delete[] attr_audibleAlarm_read;
delete[] attr_StatisticsResetTime_read;
delete[] attr_normalAlarms_read;
delete[] attr_unacknowledgedAlarms_read;
delete[] attr_acknowledgedAlarms_read;
delete[] attr_unacknowledgedNormalAlarms_read;
delete[] attr_shelvedAlarms_read;
delete[] attr_outOfServiceAlarms_read;
delete[] attr_silencedAlarms_read;
delete[] attr_listAlarms_read;
delete[] attr_frequencyAlarms_read;

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::init_device()

Graziano Scalamera
committed
* Description : will be called at device initialization.
*/
//--------------------------------------------------------
void AlarmHandler::init_device()

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::init_device() create device " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::init_device_before) ENABLED START -----*/
bool starting = Tango::Util::instance()->is_svr_starting();
bool shutting_down = Tango::Util::instance()->is_svr_shutting_down();
bool restarting = Tango::Util::instance()->is_device_restarting(device_name);
DEBUG_STREAM << __func__ << " starting="<<(int)starting << " shutting_down="<<(int)shutting_down<<" restarting="<<(int)restarting;

Graziano Scalamera
committed
// Initialization before get_device_property() call
int dbPortint=0;
abortflag = false;
instanceCounter++;
events = new event_table(this);
thread = new SubscribeThread(this);

Graziano Scalamera
committed
//because of static map<string, unsigned int> grp_str and of exception while subscribing
//more than one time the same event in the same executable, control the number of instances
if(instanceCounter > 1)
{
ERROR_STREAM << "More than one instance in the same executable of Alarm Server is not allowed!!" << endl;
cout << "ERROR: second instance of Alarm Server, exiting..." << endl;
exit(-1);
} //-------------------------------------------
alarmedlock = new(ReadersWritersLock);
internallock = new(ReadersWritersLock);
dslock = new(ReadersWritersLock);
alarms.set_dev(this);

Graziano Scalamera
committed

Graziano Scalamera
committed
normalAlarms_read.reserve(MAX_ALARMS);
unacknowledgedAlarms_read.reserve(MAX_ALARMS);
acknowledgedAlarms_read.reserve(MAX_ALARMS);
unacknowledgedNormalAlarms_read.reserve(MAX_ALARMS);
shelvedAlarms_read.reserve(MAX_ALARMS);
outOfServiceAlarms_read.reserve(MAX_ALARMS);
silencedAlarms_read.reserve(MAX_ALARMS);
listAlarms_read.reserve(MAX_ALARMS);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::init_device_before

Graziano Scalamera
committed
// Get the device properties from database
get_device_property();

Graziano Scalamera
committed
attr_audibleAlarm_read = new Tango::DevBoolean[1];
attr_StatisticsResetTime_read = new Tango::DevDouble[1];
attr_normalAlarms_read = new Tango::DevString[10000];
attr_unacknowledgedAlarms_read = new Tango::DevString[10000];
attr_acknowledgedAlarms_read = new Tango::DevString[10000];
attr_unacknowledgedNormalAlarms_read = new Tango::DevString[10000];
attr_shelvedAlarms_read = new Tango::DevString[10000];
attr_outOfServiceAlarms_read = new Tango::DevString[10000];
attr_silencedAlarms_read = new Tango::DevString[10000];
attr_listAlarms_read = new Tango::DevString[10000];
attr_frequencyAlarms_read = new Tango::DevDouble[10000];
/*----- PROTECTED REGION ID(AlarmHandler::init_device) ENABLED START -----*/

Graziano Scalamera
committed
// Initialize device
thread->period = subscribeRetryPeriod;

Graziano Scalamera
committed
#ifdef _USE_ELETTRA_DB_RW
host_rw = "";
Tango::Database *db = new Tango::Database();
try
{
Tango::DbData db_data;
db_data.push_back((Tango::DbDatum("Host")));
db_data.push_back((Tango::DbDatum("Port")));
db->get_property("Database",db_data);
db_data[0] >> host_rw;
db_data[1] >> port_rw;
}catch(Tango::DevFailed &e)
{
ERROR_STREAM << __FUNCTION__ << " Error reading Database property='" << e.errors[0].desc << "'";
}
delete db;
#endif

Graziano Scalamera
committed

Graziano Scalamera
committed
ds_num = 0; //initialize number of lines returned by read_alarm
internal_counter = 0;
/*Tango::DbData db_data;
db_data.push_back(Tango::DbDatum("alarm"));
get_db_device()->get_attribute_property(db_data);*/
/*
* connect to log database
*/
alarms.new_rwlock();
try {
alarms.init_cmdthread();
} catch(...)
{
WARN_STREAM << "AlarmHandler::init_device(): error creating cmd thread" << endl;

Graziano Scalamera
committed
}
rule_names[formula_grammar::val_rID] = "ValReal";
rule_names[formula_grammar::val_hID] = "ValHex";
rule_names[formula_grammar::val_stID] = "ValStatus";
rule_names[formula_grammar::event_ID] = "EventFather";
rule_names[formula_grammar::nameID] = "EventName";
rule_names[formula_grammar::indexID] = "EventIndex";
rule_names[formula_grammar::funcID] = "Function";
rule_names[formula_grammar::logical_exprID] = "LogicalE";
rule_names[formula_grammar::bitwise_exprID] = "BitwiseE";
rule_names[formula_grammar::equality_exprID] = "EqualityE";
rule_names[formula_grammar::compare_exprID] = "CompareE";
rule_names[formula_grammar::add_exprID] = "AddE";
rule_names[formula_grammar::mult_exprID] = "MultE";
rule_names[formula_grammar::expr_atomID] = "AtomicE";
rule_names[formula_grammar::shift_exprID] = "ShiftE";
rule_names[formula_grammar::unary_exprID] = "UnaryE";
rule_names[formula_grammar::val_stringID] = "ValString";
rule_names[formula_grammar::func_dualID] = "FuncDualE";
rule_names[formula_grammar::logical_expr_parenID] = "LogicalParenE";
rule_names[formula_grammar::cond_exprID] = "ConditionalE";
rule_names[formula_grammar::nonempty_exprID] = "NonEmptyE";
rule_names[formula_grammar::exprID] = "Expression";
rule_names[formula_grammar::val_qualityID] = "ValQuality";
rule_names[formula_grammar::val_alarm_enum_stID] = "ValAlarmEnumStatus";
rule_names[formula_grammar::propertyID] = "EventProperty";

Graziano Scalamera
committed
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
/*
* get device attribute properties and initialize internal
* data structures
*/
// short n_prop;
string expr;
string pr_name;
vector<string> tmp_alm_vec;
/* db_data[0] >> n_prop;
INFO_STREAM << "Number alarm to load = " << n_prop << endl;
for (int i = 1; i <= n_prop; i++)
{
pr_name = db_data[i].name;
db_data[i] >> expr;
DEBUG_STREAM << " -> attr property: " << pr_name << " = " << expr << endl;
size_t pos = pr_name.find('_');
int count_ = 1;
while(pos != string::npos) //TODO: better this control
{
pos = pr_name.find('_', pos+1);
count_++;
if((count_ == 3) && (pos != string::npos)) //if at least 3 _ in the attr property name, expr is OK //TODO: better this control
{
tmp_alm_vec.push_back(expr);
break;
}
}
}*/
try {
alarms.get_alarm_list_db(tmp_alm_vec, saved_alarms);

Graziano Scalamera
committed
} catch(string & e)
{
ERROR_STREAM << "AlarmHandler::init_device(): " << e << endl;

Graziano Scalamera
committed
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
cout << "Error: " << e << ". Exiting..." << endl;
exit(-4);
}
/*
* store the alarms into alarm table vector
*/
map< string,vector<string> > alarm_event; //map alarm->vector event popolated by parser
vector<string> evn; //vector with all event (possibly duplicated) popolated by parser
vector<string> temp_evn;
vector<string> tmp_alm_name_lst;
//alarms.init(tmp_alm_vec, evn, alarm_event);
alarm_t tmp_alm;
evn.clear();
for(vector<string>::iterator it_al = tmp_alm_vec.begin(); it_al!= tmp_alm_vec.end(); it_al++)
{
tmp_alm.clear();
temp_evn.clear();
try {
load_alarm(*it_al, tmp_alm, temp_evn);
add_alarm(tmp_alm);
tmp_alm_name_lst.push_back(tmp_alm.name);
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << "error loading alarm=" << tmp_alm.name << " , " << e.errors[0].desc << ends;
WARN_STREAM << "AlarmHandler::init_device(): " << err.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());
continue;
} catch (string& err) {
ostringstream err_out;
err_out << "error loading alarm=" << tmp_alm.name << " , " << err << ends;
WARN_STREAM << "AlarmHandler::init_device(): " << err_out.str() << endl;

Graziano Scalamera
committed
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
set_internal_alarm(INTERNAL_ERROR, gettime(), err_out.str());
continue;
}
//eliminate duplicated event
if (temp_evn.empty() == false)
{
sort(temp_evn.begin(), temp_evn.end());
vector<string>::iterator new_end = \
unique(temp_evn.begin(), temp_evn.end());
while (temp_evn.end() != new_end)
temp_evn.pop_back();
}
alarm_event.insert(make_pair(tmp_alm.name,temp_evn));
evn.insert(evn.end(),temp_evn.begin(),temp_evn.end());
/* alarms.log_alarm_db(TYPE_LOG_DESC_SYNC, gettime(), tmp_alm.name, "", "", //remove if alarm with the same name exist but is changed
tmp_alm.formula, tmp_alm.grp2str(), tmp_alm.lev, tmp_alm.msg);
alarms.log_alarm_db(TYPE_LOG_DESC_ADD, gettime(), tmp_alm.name, "", "", //add new alarm if there is not already one active with the same name
tmp_alm.formula, tmp_alm.grp2str(), tmp_alm.lev, tmp_alm.msg);*/
}
/* alarms.log_alarm_db(TYPE_LOG_DESC_UPD_OLD, gettime(), "", "", "", //set as not active all alarms not present in this list
"", "", "", "", tmp_alm_name_lst);*/
DEBUG_STREAM << "alarms table size = " << alarms.size() << endl;
vector<string> al_table_string;
alarms.show(al_table_string);
for(vector<string>::iterator str_it=al_table_string.begin(); str_it!=al_table_string.end(); str_it++)
DEBUG_STREAM << (*str_it) << endl;
/*
* check 'stored' alarms against current alarm table for consistency
*/
vector<string> to_remove_from_stored;
if (stored.empty() == false) {
for (vector<alarm_t>::iterator i = stored.begin(); \
i != stored.end(); i++) {
alarm_container_t::iterator found = alarms.v_alarm.find(i->name);
if (found == alarms.v_alarm.end()) {
to_remove_from_stored.push_back(i->name);
//stored.erase(i);
}
}
}
for(vector<string>::iterator k=to_remove_from_stored.begin(); k != to_remove_from_stored.end(); k++)
{
vector<alarm_t>::iterator rmv = find(stored.begin(),stored.end(),*k);
if(rmv != stored.end())
{
ERROR_STREAM << "init_device(): alarm '" << *k \
<< "' NOT found in alarm table! " \
<< "Removing from 'stored' alarms" << endl;
stored.erase(rmv);
}
else
WARN_STREAM << "init_device(): alarm " << *k << " not found while removing from stored !!!" << endl;
}
/*
* update "alarm" table with "stored" alarms
*/
alarms.stored(stored);
/*
* update "alarmed" table with "stored" alarms
*/
if (stored.empty() == false) {
alarmedlock->writerIn();
for (vector<alarm_t>::iterator i = stored.begin(); \
i != stored.end(); i++) {
alarmed.push_back(*i);
}
alarmedlock->writerOut();
}
for(alarm_container_t::iterator i = alarms.v_alarm.begin(); \
i!=alarms.v_alarm.end(); i++)
{
if(i->second.cmd_name_a.length() > 0)
{
try {
i->second.dp_a = new Tango::DeviceProxy(i->second.cmd_dp_a);
i->second.dp_a->ping();
Tango::CommandInfo info = i->second.dp_a->command_query(i->second.cmd_action_a);
if((info.in_type != Tango::DEV_STRING) && (info.in_type != Tango::DEV_VOID))
{
ostringstream err;
err << i->second.name << ": error, command " << i->second.cmd_name_a << " does not accept a Tango::DevString or a Tango::DevVoid as input value" << ends;
ERROR_STREAM << "AlarmHandler::init_device(): " << err.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());
}
else
{
if(info.in_type == Tango::DEV_STRING)
i->second.send_arg_a = true;
else
i->second.send_arg_a = false;
DEBUG_STREAM << "AlarmHandler::init_device(): " << i->second.name << ": successfully connected to proxy=" << i->second.cmd_dp_a << " for action=" << i->second.cmd_action_a << endl;

Graziano Scalamera
committed
}
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << i->second.name << ": error connecting to device proxy=" << i->second.cmd_dp_a << ", err=" << e.errors[0].desc << ends;
WARN_STREAM << "AlarmHandler::init_device(): " << err.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());
i->second.dp_a = NULL;
}
}
if(i->second.cmd_name_n.length() > 0)
{
try {
i->second.dp_n = new Tango::DeviceProxy(i->second.cmd_dp_n);
i->second.dp_n->ping();
Tango::CommandInfo info = i->second.dp_n->command_query(i->second.cmd_action_n);
if((info.in_type != Tango::DEV_STRING) && (info.in_type != Tango::DEV_VOID))
{
ostringstream err;
err << i->second.name << ": error, command " << i->second.cmd_name_n << " does not accept a Tango::DevString or a Tango::DevVoid as input value" << ends;
ERROR_STREAM << "AlarmHandler::init_device(): " << err.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());
}
else
{
if(info.in_type == Tango::DEV_STRING)
i->second.send_arg_n = true;
else
i->second.send_arg_n = false;
DEBUG_STREAM << "AlarmHandler::init_device(): " << i->second.name << ": successfully connected to proxy=" << i->second.cmd_dp_n << " for action=" << i->second.cmd_action_n << endl;

Graziano Scalamera
committed
}
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << i->second.name << ": error connecting to device proxy=" << i->second.cmd_dp_n << ", err=" << e.errors[0].desc << ends;
WARN_STREAM << "AlarmHandler::init_device(): " << err.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());
i->second.dp_n = NULL;
}
}
}
alarms.startup_complete = gettime(); //enable actions execution in 10 seconds

Graziano Scalamera
committed
for(map<string, vector<string> >::iterator al_ev_it=alarm_event.begin(); \
al_ev_it!=alarm_event.end(); al_ev_it++)
{
alarm_container_t::iterator i = alarms.v_alarm.find(al_ev_it->first);
if(i != alarms.v_alarm.end())
{

Graziano Scalamera
committed
try {
add_event(i->second, al_ev_it->second);//moved after events->add
if(i->second.to_be_evaluated)
bei_t e;
e.ev_name = ALARM_THREAD_TO_BE_EVAL;
e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE);
e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE);
evlist.push_back(e);

Graziano Scalamera
committed
} catch (string& err) {
WARN_STREAM << "AlarmHandler::init_device(): " << err << endl;

Graziano Scalamera
committed
for(vector<string>::iterator j=al_ev_it->second.begin(); j!=al_ev_it->second.end(); j++)
{
DEBUG_STREAM << "AlarmHandler::init_device(): Removing alarm=" << i->second.name << " from event=" << *j << endl;

Graziano Scalamera
committed
vector<event>::iterator k = \
find(events->v_event.begin(), events->v_event.end(), *j);
if (k != events->v_event.end())
{
k->pop_alarm(i->second.name); //remove alarm/formula just added to event
DEBUG_STREAM << "AlarmHandler::init_device(): Removed!!!! alarm=" << i->second.name << " from event=" << *j << endl;

Graziano Scalamera
committed
if(k->m_alarm.empty())
{
events->v_event.erase(k); //remove event just added to event_table
DEBUG_STREAM << "AlarmHandler::init_device(): event=" << *j << " no more used, REMOVED!!!" << endl;

Graziano Scalamera
committed
}
}
}
set_internal_alarm(INTERNAL_ERROR, gettime(), err);
}
#else
try {
add_event(i->second, al_ev_it->second);
} catch (string& err) {
WARN_STREAM << "AlarmHandler::init_device(): " << err << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err);
}
try {
subscribe_event(i->second, ecb, al_ev_it->second);
} catch (string& err) {
WARN_STREAM << "AlarmHandler::init_device(): " << err << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err);
}
#endif
}
}

Graziano Scalamera
committed
set_change_event("alarm",true,false);
/*
* create alarm processing thread
*/
//almloop = new alarm_thread::alarm_thread(/*this*/);
almloop = new alarm_thread(this);
almloop->start();
updateloop = new update_thread(this);
updateloop->start();
thread->start();
events->start_all();

Graziano Scalamera
committed
set_state(Tango::RUNNING);
set_status("Alarm server is running");
//
// for (int i=0; i< MAX_ALARMS ; i++) ds[i]=0;
// ds_num = 0;
for (int i=0; i< MAX_ALARMS ; i++)
ds[i]=(char *) (dss[i]);

Graziano Scalamera
committed
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
double dnow = (now.tv_sec) + ((double)(now.tv_nsec))/1000000000;
last_statistics_reset_time = dnow;
INFO_STREAM << __func__ << ": exiting!";

Graziano Scalamera
committed
/*----- PROTECTED REGION END -----*/ // AlarmHandler::init_device

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::get_device_property()

Graziano Scalamera
committed
* Description : Read database to initialize property data members.
*/
//--------------------------------------------------------
void AlarmHandler::get_device_property()

Graziano Scalamera
committed
{
/*----- PROTECTED REGION ID(AlarmHandler::get_device_property_before) ENABLED START -----*/

Graziano Scalamera
committed
// Initialize property data members
/*----- PROTECTED REGION END -----*/ // AlarmHandler::get_device_property_before

Graziano Scalamera
committed
// Read device properties from database.
Tango::DbData dev_prop;
dev_prop.push_back(Tango::DbDatum("GroupNames"));
dev_prop.push_back(Tango::DbDatum("SubscribeRetryPeriod"));

Graziano Scalamera
committed
dev_prop.push_back(Tango::DbDatum("StatisticsTimeWindow"));

Graziano Scalamera
committed
// is there at least one property to be read ?
if (dev_prop.size()>0)
{
// Call database and extract values
if (Tango::Util::instance()->_UseDb==true)
get_db_device()->get_property(dev_prop);
// get instance on AlarmHandlerClass to get class property

Graziano Scalamera
committed
Tango::DbDatum def_prop, cl_prop;
AlarmHandlerClass *ds_class =
(static_cast<AlarmHandlerClass *>(get_device_class()));

Graziano Scalamera
committed
int i = -1;
// Try to initialize GroupNames from class property
cl_prop = ds_class->get_class_property(dev_prop[++i].name);
if (cl_prop.is_empty()==false) cl_prop >> groupNames;
else {
// Try to initialize GroupNames from default device value
def_prop = ds_class->get_default_device_property(dev_prop[i].name);
if (def_prop.is_empty()==false) def_prop >> groupNames;
}
// And try to extract GroupNames value from database
if (dev_prop[i].is_empty()==false) dev_prop[i] >> groupNames;
// Try to initialize SubscribeRetryPeriod from class property
cl_prop = ds_class->get_class_property(dev_prop[++i].name);
if (cl_prop.is_empty()==false) cl_prop >> subscribeRetryPeriod;
else {
// Try to initialize SubscribeRetryPeriod from default device value
def_prop = ds_class->get_default_device_property(dev_prop[i].name);
if (def_prop.is_empty()==false) def_prop >> subscribeRetryPeriod;
}
// And try to extract SubscribeRetryPeriod value from database
if (dev_prop[i].is_empty()==false) dev_prop[i] >> subscribeRetryPeriod;

Graziano Scalamera
committed
// Try to initialize StatisticsTimeWindow from class property
cl_prop = ds_class->get_class_property(dev_prop[++i].name);
if (cl_prop.is_empty()==false) cl_prop >> statisticsTimeWindow;
else {
// Try to initialize StatisticsTimeWindow from default device value
def_prop = ds_class->get_default_device_property(dev_prop[i].name);
if (def_prop.is_empty()==false) def_prop >> statisticsTimeWindow;
}
// And try to extract StatisticsTimeWindow value from database
if (dev_prop[i].is_empty()==false) dev_prop[i] >> statisticsTimeWindow;

Graziano Scalamera
committed
}
/*----- PROTECTED REGION ID(AlarmHandler::get_device_property_after) ENABLED START -----*/

Graziano Scalamera
committed
// Check device property data members init
/*
* initialize groups
*/
alarm_t tmp_alm;
tmp_alm.init_static_map(groupNames);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::get_device_property_after

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::always_executed_hook()

Graziano Scalamera
committed
* Description : method always executed before any command is executed
*/
//--------------------------------------------------------
void AlarmHandler::always_executed_hook()

Graziano Scalamera
committed
{
//DEBUG_STREAM << "AlarmHandler::always_executed_hook() " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::always_executed_hook) ENABLED START -----*/

Graziano Scalamera
committed
// code always executed before all requests
/*----- PROTECTED REGION END -----*/ // AlarmHandler::always_executed_hook

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Method : AlarmHandler::read_attr_hardware()

Graziano Scalamera
committed
* Description : Hardware acquisition for attributes
*/
//--------------------------------------------------------
void AlarmHandler::read_attr_hardware(TANGO_UNUSED(vector<long> &attr_list))

Graziano Scalamera
committed
{
//DEBUG_STREAM << "AlarmHandler::read_attr_hardware(vector<long> &attr_list) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_attr_hardware) ENABLED START -----*/

Graziano Scalamera
committed
// Add your own code
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_attr_hardware

Graziano Scalamera
committed
}

Graziano Scalamera
committed
//--------------------------------------------------------
/**
* Read attribute audibleAlarm related method
* Description: True if there is at least one alarm that needs audible indication on the GUI
*
* Data type: Tango::DevBoolean
* Attr type: Scalar
*/
//--------------------------------------------------------
void AlarmHandler::read_audibleAlarm(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_audibleAlarm(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_audibleAlarm) ENABLED START -----*/

Graziano Scalamera
committed
// Set the attribute value
attr.set_value(attr_audibleAlarm_read);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_audibleAlarm

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Read attribute StatisticsResetTime related method
* Description: Time elapsed in seconds since last Resetstatistics
*
* Data type: Tango::DevDouble
* Attr type: Scalar
*/
//--------------------------------------------------------
void AlarmHandler::read_StatisticsResetTime(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_StatisticsResetTime(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_StatisticsResetTime) ENABLED START -----*/

Graziano Scalamera
committed
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
double dnow = (now.tv_sec) + ((double)(now.tv_nsec))/1000000000;
*attr_StatisticsResetTime_read = dnow - last_statistics_reset_time;
// Set the attribute value
attr.set_value(attr_StatisticsResetTime_read);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_StatisticsResetTime

Graziano Scalamera
committed
}

Graziano Scalamera
committed
//--------------------------------------------------------
/**
* Read attribute alarm related method
* Description:
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 1024
*/
//--------------------------------------------------------
void AlarmHandler::read_alarm(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_alarm(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_alarm) ENABLED START -----*/

Graziano Scalamera
committed
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
// Add your own code here
#if 0
alarm_container_t::iterator ai;
vector<alarm_t>::iterator aid;
for (ai = alarms.v_alarm.begin(); ai != alarms.v_alarm.end(); ai++) {
if (ai->second.stat == S_ALARM) {
/*
* alarm status is S_ALARM
*/
aid = find(alarmed.begin(), alarmed.end(),ai->second.name);
if (aid != alarmed.end()) {
/*
* found, change stat only if switching from
* S_NORMAL to S_ALARM status
*/
//cout << "read_attr(): S_ALARM: found: " << aid->name << endl;
if (aid->stat == S_NORMAL) {
aid->stat = S_ALARM;
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->counter = ai->second.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 {
/*
* not found: new "alarmed" item
*/
DEBUG_STREAM << "read_attr(): S_ALARM: pushing new alarm: " \
<< ai->second.name << "\t" << ai->second.stat << endl;
alarmed.push_back(ai->second);
//ai->second.is_new = 0; //set state as not more new //12-06-08: StopNew command set it to 0
}
} else if (ai->second.stat == S_NORMAL) {
/*
* alarm status is S_NORMAL
*/
aid = find(alarmed.begin(), alarmed.end(), ai->second.name);
if (aid != alarmed.end()) {
/*
* found, as it should;
* switching from S_ALARM to S_NORMAL
*/
aid->stat = S_NORMAL;
aid->ts = ai->second.ts;
//aid->msg = " "; /* no message again */
aid->msg =ai->second.msg;
aid->grp = ai->second.grp;
aid->lev = ai->second.lev;
aid->counter = ai->second.counter;
aid->ack = ai->second.ack; //if already acknowledged but has arrived new alarm ack is reset
aid->is_new = ai->second.is_new; //copy is_new state
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
//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 already ACKnowledged and visualized
* remove from "alarmed" list
*/
DEBUG_STREAM << "read_attr(): S_NORMAL: " << aid->name \
<< " ACKnowledged: removing" << endl;
alarmed.erase(aid);
} else {
aid->done = true;
}
} /* if */
} /* if */
} /* if else if */
} /* for */
vector<string> tmp_alarm_table;
string is_new;
ostringstream os1;
/*os1.clear();
os1 << header << "\t" << alarmed.size() << ends;*/
//tmp_alarm_table.push_back(os1.str());
if (alarmed.empty() == false) {
for (aid = alarmed.begin(); aid != alarmed.end(); aid++) {
if(aid->silenced > 0)
{
Tango::TimeVal now = gettime();
double dnow = now.tv_sec + ((double)now.tv_usec) / 1000000;
double dsilent = aid->ts_time_silenced.tv_sec + ((double)aid->ts_time_silenced.tv_usec) / 1000000;
double dminutes = (dnow - dsilent)/60;
//silenced already calculated in alarm_table::update, but here updated for panel also if state not changed:
//to see minutes countdown
if(dminutes < aid->silent_time)
aid->silenced = aid->silent_time - floor(dminutes);
else
aid->silenced = 0;
}
ostringstream os;
os.clear();
is_new.clear();
is_new = (aid->is_new && aid->silenced <= 0) ? "NEW" : " ";
os << aid->ts.tv_sec << "\t" << aid->ts.tv_usec << "\t" \
<< aid->name << "\t" << aid->stat << "\t" << aid->ack \
<< "\t" << aid->counter << "\t" << aid->lev << "\t" << aid->silenced << "\t" << aid->grp2str() << "\t" << aid->msg << "\t" << is_new << ends;
tmp_alarm_table.push_back(os.str());
}
}
if (internal.empty() == false) {
for (aid = internal.begin(); aid != internal.end(); aid++) {
/* size_t index;
int count = 1;
index = aid->stat.find("*");
if((index != std::string::npos) && (index+1 != std::string::npos))
{
size_t last = aid->stat.size();
string str_count= aid->stat.substr(index+1, last - index+1);
count = strtol(str_count.c_str(), 0,10);
}
//do not show internal alarms that have a molteplicity less then errThreshold
if((aid->msg.find()) && (count < errThreshold))
continue;*/
ostringstream os;
os.clear();
os << aid->ts.tv_sec << "\t" << aid->ts.tv_usec << "\t" \
<< aid->name << "\t" << aid->stat << "\t" << aid->ack \
<< "\t" << aid->counter << "\t" << aid->lev << "\t"<< -1/*silenced*/ <<"\t" << aid->grp2str() << "\t" << aid->msg << "\t "<< ends; //TODO: silenced for internal errors?
tmp_alarm_table.push_back(os.str());
}
}
int i;
for (i = ds_num - 1; i >= 0; i--) {
CORBA::string_free(ds[i]);
}
ds_num = tmp_alarm_table.size();
if(ds_num > MAX_ALARMS)
ds_num = MAX_ALARMS;
for (i = 0; i < ds_num; i++) {
ds[i] = CORBA::string_dup(tmp_alarm_table[i].c_str());
}
if(ds_num == 0)
{
ostringstream os1;
ds_num++;
os1.clear();
os1 << 0 << "\t" << 0 << "\t" << 0 << "\t" << 0 << "\t" << 0 << "\t" << 0 << "\t" << 0 << "\t" << -1 << "\t" << 0 << "\t" << 0 << "\t "<< ends;
ds[0] = CORBA::string_dup(os1.str().c_str());
}
#else
//bool changed;
//prepare_alarm_attr(changed);//moved in do_alarm;
#endif
if(ds_num == 0)
{
attr.set_value_date_quality(ds,0/*gettime()*/,Tango::ATTR_WARNING, ds_num, 0, false);
}
else
attr.set_value(ds, ds_num, 0, false);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_alarm

Graziano Scalamera
committed
}

Graziano Scalamera
committed
//--------------------------------------------------------
/**
* Read attribute normalAlarms related method
* Description: List of alarms in normal state
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 10000
*/
//--------------------------------------------------------
void AlarmHandler::read_normalAlarms(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_normalAlarms(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_normalAlarms) ENABLED START -----*/

Graziano Scalamera
committed
// Set the attribute value
attr.set_value(attr_normalAlarms_read, normalAlarms_sz);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_normalAlarms

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Read attribute unacknowledgedAlarms related method
* Description: List of alarms in unacknowledged state
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 10000
*/
//--------------------------------------------------------
void AlarmHandler::read_unacknowledgedAlarms(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_unacknowledgedAlarms(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_unacknowledgedAlarms) ENABLED START -----*/

Graziano Scalamera
committed
// Set the attribute value
attr.set_value(attr_unacknowledgedAlarms_read, unacknowledgedAlarms_sz);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_unacknowledgedAlarms

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Read attribute acknowledgedAlarms related method
* Description: List of alarms in acknowledged state
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 10000
*/
//--------------------------------------------------------
void AlarmHandler::read_acknowledgedAlarms(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_acknowledgedAlarms(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_acknowledgedAlarms) ENABLED START -----*/

Graziano Scalamera
committed
// Set the attribute value
attr.set_value(attr_acknowledgedAlarms_read, acknowledgedAlarms_sz);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_acknowledgedAlarms

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Read attribute unacknowledgedNormalAlarms related method
* Description: List of alarms in unacknowledged normal state
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 10000
*/
//--------------------------------------------------------
void AlarmHandler::read_unacknowledgedNormalAlarms(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_unacknowledgedNormalAlarms(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_unacknowledgedNormalAlarms) ENABLED START -----*/

Graziano Scalamera
committed
// Set the attribute value
attr.set_value(attr_unacknowledgedNormalAlarms_read, unacknowledgedNormalAlarms_sz);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_unacknowledgedNormalAlarms

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Read attribute shelvedAlarms related method
* Description: List of alarms in shelved state
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 10000
*/
//--------------------------------------------------------
void AlarmHandler::read_shelvedAlarms(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_shelvedAlarms(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_shelvedAlarms) ENABLED START -----*/

Graziano Scalamera
committed
// Set the attribute value
attr.set_value(attr_shelvedAlarms_read, shelvedAlarms_sz);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_shelvedAlarms

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Read attribute outOfServiceAlarms related method
* Description: List of alarms in out of service state
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 10000
*/
//--------------------------------------------------------
void AlarmHandler::read_outOfServiceAlarms(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_outOfServiceAlarms(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_outOfServiceAlarms) ENABLED START -----*/

Graziano Scalamera
committed
// Set the attribute value
attr.set_value(attr_outOfServiceAlarms_read, outOfServiceAlarms_sz);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_outOfServiceAlarms

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Read attribute silencedAlarms related method
* Description: List of alarms in silenced state
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 10000
*/
//--------------------------------------------------------
void AlarmHandler::read_silencedAlarms(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_silencedAlarms(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_silencedAlarms) ENABLED START -----*/

Graziano Scalamera
committed
// Set the attribute value
attr.set_value(attr_silencedAlarms_read, silencedAlarms_sz);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_silencedAlarms

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Read attribute listAlarms related method
* Description: List of all alarms
*
* Data type: Tango::DevString
* Attr type: Spectrum max = 10000
*/
//--------------------------------------------------------
void AlarmHandler::read_listAlarms(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_listAlarms(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_listAlarms) ENABLED START -----*/

Graziano Scalamera
committed
// Set the attribute value
attr.set_value(attr_listAlarms_read, listAlarms_sz);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_listAlarms

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Read attribute frequencyAlarms related method
* Description: List of frequency of evaluation of all alarms
*
* Data type: Tango::DevDouble
* Attr type: Spectrum max = 10000
*/
//--------------------------------------------------------
void AlarmHandler::read_frequencyAlarms(Tango::Attribute &attr)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::read_frequencyAlarms(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(AlarmHandler::read_frequencyAlarms) ENABLED START -----*/

Graziano Scalamera
committed
// Set the attribute value
attr.set_value(attr_frequencyAlarms_read, listAlarms_sz);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_frequencyAlarms

Graziano Scalamera
committed
}

Graziano Scalamera
committed
//--------------------------------------------------------
/**
* Read attribute AlarmState related method
* Description:
*
* Data type: Tango::DevEnum (AlarmStateEnum)
* Attr type: Scalar
*/
//--------------------------------------------------------
void AlarmHandler::read_AlarmState(Tango::Attribute &attr)
DEBUG_STREAM << "AlarmHandler::read_AlarmState(Tango::Attribute &attr) entering... " << endl;
Tango::DevEnum *att_value = get_AlarmState_data_ptr(attr.get_name());
/*----- PROTECTED REGION ID(AlarmHandler::read_AlarmState) ENABLED START -----*/
string reason("");
string desc("");
string origin("");
int quality = Tango::ATTR_VALID;
alarms.vlock->readerIn();
alarm_container_t::iterator it;
for(it = alarms.v_alarm.begin(); it != alarms.v_alarm.end(); it++)
{
if(it->second.attr_name == attr.get_name())
{
break;
}
}
if(it != alarms.v_alarm.end())
{
reason = it->second.ex_reason;
desc = it->second.ex_desc;
origin = it->second.ex_origin;
quality = it->second.quality;
}
DEBUG_STREAM << "AlarmHandler::read_AlarmState: " << attr.get_name() << " desc=" << desc << endl;
alarms.vlock->readerOut();
if(desc.length() > 0)
{
Tango::Except::throw_exception(
reason,
desc,
origin, Tango::ERR);
}
// Set the attribute value
if(quality != Tango::ATTR_VALID)
{
timeval now;
gettimeofday(&now, NULL);
attr.set_value_date_quality(att_value, now/*TODO timestamp*/, (Tango::AttrQuality)quality);
}
else
{
attr.set_value(att_value);
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_AlarmState

Graziano Scalamera
committed
//--------------------------------------------------------
/**
* Read attribute AlarmFormula related method
* Description:
*
* Data type: Tango::DevString
* Attr type: Scalar
*/
//--------------------------------------------------------
void AlarmHandler::read_AlarmFormula(Tango::Attribute &attr)
{
DEBUG_STREAM << "AlarmHandler::read_AlarmFormula(Tango::Attribute &attr) entering... " << endl;
Tango::DevString *att_value = get_AlarmFormula_data_ptr(attr.get_name());
/*----- PROTECTED REGION ID(AlarmHandler::read_AlarmFormula) ENABLED START -----*/
// Set the attribute value
attr.set_value(att_value);
/*----- PROTECTED REGION END -----*/ // AlarmHandler::read_AlarmFormula
}
//--------------------------------------------------------

Graziano Scalamera
committed
/**
* Method : AlarmHandler::add_dynamic_attributes()

Graziano Scalamera
committed
* Description : Create the dynamic attributes if any
* for specified device.
*/
//--------------------------------------------------------
void AlarmHandler::add_dynamic_attributes()

Graziano Scalamera
committed
{
// 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(AlarmHandler::add_dynamic_attributes) ENABLED START -----*/

Graziano Scalamera
committed
// Add your own code to create and add dynamic attributes if any
alarms.vlock->readerIn();
if (alarms.v_alarm.empty() == false)
{
for (alarm_container_t::iterator i = alarms.v_alarm.begin(); \
i != alarms.v_alarm.end(); i++)
{
add_AlarmState_dynamic_attribute(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;
}
}
alarms.vlock->readerOut();

Graziano Scalamera
committed
/*----- PROTECTED REGION END -----*/ // AlarmHandler::add_dynamic_attributes

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Command Ack related method
* Description: Alarm acknowledge
*
* @param argin String array containing the alarms to be acknowledged
*/
//--------------------------------------------------------
void AlarmHandler::ack(const Tango::DevVarStringArray *argin)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::Ack() - " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::ack) ENABLED START -----*/

Graziano Scalamera
committed
// Add your own code
vector<string> str;
str << (*argin);
vector<string>::iterator si;
for (si = str.begin(); si != str.end(); si++) {
alarms.vlock->readerIn();
alarmedlock->readerIn();
vector<alarm_t>::iterator found = \
find(alarmed.begin(), alarmed.end(), *si);
if (found != alarmed.end())
{
alarm_container_t::iterator i = alarms.v_alarm.find(*si);

Graziano Scalamera
committed
if(i == alarms.v_alarm.end())

Graziano Scalamera
committed
{

Graziano Scalamera
committed
INFO_STREAM << __func__ << ": alarm '" << *si << "' not found";
alarmedlock->readerOut();
alarms.vlock->readerOut();
continue;
}
if(!i->second.enabled || i->second.shelved)
{
DEBUG_STREAM << __func__ << ": alarm '" << *si << "' not enabled";
alarmedlock->readerOut();
alarms.vlock->readerOut();
continue;

Graziano Scalamera
committed
}

Graziano Scalamera
committed
//update alarm ack in alarm table
i->second.ack = ACK;
//update alarm status from alarm table
found->stat = i->second.stat;

Graziano Scalamera
committed
if(found->ack == NOT_ACK)
{
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(i->second.attr_name);

Graziano Scalamera
committed
if(!i->second.enabled)
*attr_value = _OOSRV;
else if(i->second.shelved && i->second.silenced > 0)
*attr_value = _SHLVD;
else if((i->second.stat == S_NORMAL) && i->second.ack == ACK)
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
*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 << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;
}

Graziano Scalamera
committed
}
found->ack = ACK;

Graziano Scalamera
committed
}
alarmedlock->readerOut();
alarms.vlock->readerOut();
}
/*
* remove S_NORMAL status ACKnowledged alarms
*/
alarm_t to_be_removed;
to_be_removed.name = "";
to_be_removed.formula = "";
to_be_removed.stat = S_NORMAL;
to_be_removed.ack = ACK;
bool go = true;
while (go) {
alarmedlock->writerIn();
vector<alarm_t>::iterator found = \
find(alarmed.begin(), alarmed.end(), to_be_removed);
if (found != alarmed.end()) {
DEBUG_STREAM << "AlarmHandler::ack(): " << found->name \

Graziano Scalamera
committed
<< " S_NORMAL and ACK, removing" << endl;
alarmed.erase(found);
} else {
go = false;
}
alarmedlock->writerOut();
}
prepare_alarm_attr();
try
{
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

Graziano Scalamera
committed
{

Graziano Scalamera
committed
//attr.set_value(ds, ds_num, 0, false);
push_change_event("alarm",ds, ds_num, 0, false);

Graziano Scalamera
committed
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
}
push_change_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_change_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_change_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_change_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_change_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_change_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_change_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_change_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_change_event("audibleAlarm",attr_audibleAlarm_read);
push_archive_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_archive_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_archive_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_archive_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_archive_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_archive_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_archive_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_archive_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_archive_event("audibleAlarm",attr_audibleAlarm_read);

Graziano Scalamera
committed
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << "error pushing alarm change event err=" << e.errors[0].desc;
INFO_STREAM << __func__<<": " << err.str() << endl;
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::ack

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Command Load related method
* Description: Load a new alarm.
*
* @param argin Alarm entry
*/
//--------------------------------------------------------
void AlarmHandler::load(Tango::DevString argin)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::Load() - " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::load) ENABLED START -----*/

Graziano Scalamera
committed
// Add your own code
string s;
alarm_t alm;
vector<string> evn;
s = argin;
//std::transform(s.begin(), s.end(), s.begin(), (int(*)(int))tolower); //transform to lowercase
Tango::TimeVal ts = gettime();
try {
load_alarm(s, alm, evn);
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << "error loading alarm=" << alm.name << " , " << e.errors[0].desc << ends;
WARN_STREAM << "AlarmHandler::load(): " << err.str() << endl;

Graziano Scalamera
committed
Tango::Except::throw_exception( \
(const char*)"AlarmHandler::load()", \

Graziano Scalamera
committed
err.str(), \
(const char*)"AlarmHandler::load()", Tango::ERR);

Graziano Scalamera
committed
}
try {
add_alarm(alm);
} catch (string& err) {
WARN_STREAM << "AlarmHandler::load(): " << err << endl;

Graziano Scalamera
committed
Tango::Except::throw_exception( \
(const char*)"AlarmHandler::load()", \

Graziano Scalamera
committed
(const char*)err.c_str(), \
(const char*)"AlarmHandler::load()", Tango::ERR);

Graziano Scalamera
committed
}
#if 0
try
{
Tango::Attribute attr = this->get_device_attr()->get_attr_by_name(alm.attr_name.c_str());
push_att_conf_event(&attr);
}
catch(Tango::DevFailed &e)
{
ostringstream o;
o << "AlarmHandler::" << __func__<<": alarm '" << alm.name << "' cannot push att_conf event, err="<<e.errors[0].desc ;
INFO_STREAM << o.str() << endl;
}
#endif

Graziano Scalamera
committed
try {
add_event(alm, evn);
} catch (string& err) {
WARN_STREAM << "AlarmHandler::load(): " << err << endl;

Graziano Scalamera
committed
alarms.vlock->writerIn();
alarm_container_t::iterator i = alarms.v_alarm.find(alm.name); //look for alarm just added
if (i != alarms.v_alarm.end())
alarms.erase(i); //and remove from alarm_table
alarms.vlock->writerOut();
Tango::Except::throw_exception( \
(const char*)"AlarmHandler::load()", \

Graziano Scalamera
committed
(const char*)err.c_str(), \
(const char*)"AlarmHandler::load()", Tango::ERR);

Graziano Scalamera
committed
}
alarms.save_alarm_conf_db(alm.attr_name, alm.name, "", "", alm.enabled, //add new alarm on log before subscribe event
alm.formula, alm.on_delay, alm.off_delay, alm.grp2str(), alm.lev, alm.msg, alm.cmd_name_a, alm.cmd_name_n, alm.silent_time); //but if it fails remove it from table
string conf_str;
alm.confstr(conf_str);
saved_alarms.insert(make_pair(alm.attr_name,conf_str));
alarm_container_t::iterator i = alarms.v_alarm.find(alm.name);
if(i != alarms.v_alarm.end())
{
try {
add_event(i->second, evn);//moved after events->add
} catch (string& err) {
WARN_STREAM << "AlarmHandler::"<<__func__<<": string exception=" << err << endl;
//TODO: handle error
#if 0
for(vector<string>::iterator j = evn.begin(); j != evn.end(); j++)
{
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": Removing alarm=" << i->second.name << " from event=" << *j << endl;
vector<event>::iterator k = \
find(events->v_event.begin(), events->v_event.end(), *j);
if (k != events->v_event.end())
{
k->pop_alarm(i->second.name); //remove alarm/formula just added to event
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": Removed!!!! alarm=" << i->second.name << " from event=" << *j << endl;
if(k->m_alarm.empty())
{
events->v_event.erase(k); //remove event just added to event_table
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event=" << *j << " no more used, REMOVED!!!" << endl;
}
}
}
set_internal_alarm(INTERNAL_ERROR, gettime(), err);
#endif
}
catch (Tango::DevFailed &e) {
WARN_STREAM << "AlarmHandler::"<<__func__<<": Tango exception=" << e.errors[0].desc << endl;
if(i->second.cmd_name_a.length() > 0)

Graziano Scalamera
committed
{
try {
i->second.dp_a = new Tango::DeviceProxy(i->second.cmd_dp_a);
i->second.dp_a->ping();
Tango::CommandInfo info = i->second.dp_a->command_query(i->second.cmd_action_a);
if(info.in_type != Tango::DEV_STRING)
{
ostringstream err;
err << "Error: command " << i->second.cmd_name_a << " does not accept a Tango::DevString as input value" << ends;
ERROR_STREAM << "AlarmHandler::load(): " << err.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());
}
else
{
if(info.in_type == Tango::DEV_STRING)
i->second.send_arg_a = true;
else
i->second.send_arg_a = false;
DEBUG_STREAM << "AlarmHandler::load(): successfully connected to proxy=" << i->second.cmd_dp_a << " for action=" << i->second.cmd_action_a << endl;

Graziano Scalamera
committed
}
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << alm.name << ": error connecting to device proxy=" << i->second.cmd_dp_a << ", err=" << e.errors[0].desc << ends;
WARN_STREAM << "AlarmHandler::load(): " << err.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());

Graziano Scalamera
committed
}
if(i->second.cmd_name_n.length() > 0)

Graziano Scalamera
committed
{
try {
i->second.dp_n = new Tango::DeviceProxy(i->second.cmd_dp_n);
i->second.dp_n->ping();
Tango::CommandInfo info = i->second.dp_n->command_query(i->second.cmd_action_n);

Graziano Scalamera
committed
if(info.in_type != Tango::DEV_STRING)
{
ostringstream err;
err << "Error: command " << i->second.cmd_name_n << " does not accept a Tango::DevString as input value" << ends;
ERROR_STREAM << "AlarmHandler::load(): " << err.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());
}
else
{
if(info.in_type == Tango::DEV_STRING)
i->second.send_arg_n = true;
else
i->second.send_arg_n = false;
DEBUG_STREAM << "AlarmHandler::load(): successfully connected to proxy=" << i->second.cmd_dp_n << " for action=" << i->second.cmd_action_n << endl;

Graziano Scalamera
committed
}
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << alm.name << ": error connecting to device proxy=" << i->second.cmd_dp_n << ", err=" << e.errors[0].desc << ends;
WARN_STREAM << "AlarmHandler::load(): " << err.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());
}
}
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": created command proxy, to_be_evaluated=" << (int)alm.to_be_evaluated << endl;
//TODO: to be moved in subscribe thread after subscription
//if at least one event was already existing, evaluate formula of just added alarm
if(i->second.to_be_evaluated) //TODO: remove this evaluation of the formula that is not necessary
{
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": to_be_evaluated!!" << endl;
bei_t e;
e.ev_name = ALARM_THREAD_TO_BE_EVAL;
e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE);
e.value.push_back(ALARM_THREAD_TO_BE_EVAL_VALUE);
evlist.push_back(e);
}
}

Graziano Scalamera
committed
#if 0//TODO

Graziano Scalamera
committed
prepare_alarm_attr();
try
{
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);
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << "error pushing alarm change event err=" << e.errors[0].desc;
INFO_STREAM << __func__<<": " << err.str() << endl;
}
#endif

Graziano Scalamera
committed
/*----- PROTECTED REGION END -----*/ // AlarmHandler::load

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Command Remove related method
* Description: Remove alarm.
*
* @param argin Alarm name
*/
//--------------------------------------------------------
void AlarmHandler::remove(Tango::DevString argin)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::Remove() - " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::remove) ENABLED START -----*/

Graziano Scalamera
committed
// Add your own code
string s, log_alm_name;
s = argin;
log_alm_name = argin;
bool ret = false;
alarmedlock->readerIn();
vector<alarm_t>::iterator found = find(alarmed.begin(), alarmed.end(), s);
if (found != alarmed.end())
{
ostringstream err;
err << s << " is in ALARM status! Acknowledge it before removing." << ends;
if((found->stat == S_ALARM) && (found->ack == NOT_ACK))
{
alarmedlock->readerOut();
Tango::Except::throw_exception( \
(const char*)"Error removing alarm", \
(const char*)err.str().c_str(), \
(const char*)"AlarmHandler::remove", Tango::ERR);

Graziano Scalamera
committed
}
}
alarmedlock->readerOut();
try {
ret = remove_alarm(s);
} catch (string& err) {
Tango::Except::throw_exception( \
(const char*)"Error removing alarm", \
(const char*)err.c_str(), \
(const char*)"AlarmHandler::remove", Tango::ERR);

Graziano Scalamera
committed
}
if (ret) {
DEBUG_STREAM << "AlarmHandler::remove(): removing alarm '" \

Graziano Scalamera
committed
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
<< s << "'" << endl;
while (true) {
string::size_type i = s.find_first_of("/.");
if (i == string::npos)
break;
s.replace(i, 1, "_");
}
} /* end if */
alarmedlock->writerIn();
found = find(alarmed.begin(), alarmed.end(), s); //look again because in the meanwhile lock was not acquired
if (found != alarmed.end())
{
alarmed.erase(found); //remove from alarmed table
}
alarmedlock->writerOut();
prepare_alarm_attr();
try
{
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

Graziano Scalamera
committed
{

Graziano Scalamera
committed
//attr.set_value(ds, ds_num, 0, false);
push_change_event("alarm",ds, ds_num, 0, false);

Graziano Scalamera
committed
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
}
push_change_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_change_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_change_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_change_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_change_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_change_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_change_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_change_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_change_event("audibleAlarm",attr_audibleAlarm_read);
push_archive_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_archive_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_archive_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_archive_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_archive_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_archive_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_archive_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_archive_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_archive_event("audibleAlarm",attr_audibleAlarm_read);

Graziano Scalamera
committed
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << "error pushing alarm change event err=" << e.errors[0].desc;
INFO_STREAM << __func__<<": " << err.str() << endl;
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::remove

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**

Graziano Scalamera
committed
* Command SearchAlarm related method
* Description: Return list of configured alarms matching the filter string

Graziano Scalamera
committed
*

Graziano Scalamera
committed
* @param argin String containing a filter for output, if empty or * return all alarms
* @returns Configured alarms

Graziano Scalamera
committed
*/
//--------------------------------------------------------
Tango::DevVarStringArray *AlarmHandler::search_alarm(Tango::DevString argin)

Graziano Scalamera
committed
{
Tango::DevVarStringArray *argout;
DEBUG_STREAM << "AlarmHandler::SearchAlarm() - " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::search_alarm) ENABLED START -----*/

Graziano Scalamera
committed
// Add your own code
// POGO has generated a method core with argout allocation.
// If you would like to use a static reference without copying,
// See "TANGO Device Server Programmer's Manual"
// (chapter : Writing a TANGO DS / Exchanging data)
//------------------------------------------------------------
argout = new Tango::DevVarStringArray();
//argout->length(1);
//(*argout)[0] = CORBA::string_dup("dummy");
DEBUG_STREAM << "AlarmHandler::configured(): entering... !" << endl;

Graziano Scalamera
committed
// Add your own code to control device here
string filter(argin);

Graziano Scalamera
committed
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
string filter_begin(filter);
string filter_end("");
size_t start_pos = 0;
/* string from("*");
string to("");
while((start_pos = filter.find(from, start_pos)) != std::string::npos)
{
filter.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}*/
start_pos = filter.find("*", start_pos);
if(start_pos != std::string::npos && start_pos == filter.size()-1) //* is the only character or at the end of the filter
{
filter.replace(start_pos, 1, "");
filter_begin = filter;
DEBUG_STREAM << __func__ << ": updated filter to: " << filter_begin;
}
/*else if(start_pos != std::string::npos) //* is in the middle of the filter
{
string filter_begin=filter.substr(0,start_pos);
string filter_end=filter.substr(start_pos+1);
DEBUG_STREAM << __func__ << ": splitted filter to: " << filter_begin << " - " << filter_end;
}*/

Graziano Scalamera
committed
size_t found;
vector<string> alarm_filtered;
ostringstream os1;
os1.clear();
/*os1 << headerConfig << "\t" << alarms.v_alarm.size() << ends;
alarm_filtered.push_back(os1.str());*/
alarm_container_t::iterator ai;
alarms.vlock->readerIn();
for (ai = alarms.v_alarm.begin(); ai != alarms.v_alarm.end(); ai++)
{
found = 0;

Graziano Scalamera
committed
if(filter_begin.length() != 0)

Graziano Scalamera
committed
{

Graziano Scalamera
committed
found = ai->first.find(filter_begin);

Graziano Scalamera
committed
}

Graziano Scalamera
committed
if((filter_begin.length() == 0) || (found != string::npos))

Graziano Scalamera
committed
{
ostringstream os;
os.clear();
os << ai->second.ts.tv_sec << SEP << KEY(NAME_KEY) << ai->second.name << SEP << KEY(FORMULA_KEY) << ai->second.formula << SEP << KEY(ONDELAY_KEY) << ai->second.on_delay << SEP << KEY(OFFDELAY_KEY) << ai->second.off_delay <<
SEP << KEY(LEVEL_KEY) << ai->second.lev << SEP << KEY(SILENT_TIME_KEY) << ai->second.silent_time << SEP << KEY(GROUP_KEY) << ai->second.grp2str() << SEP << KEY(MESSAGE_KEY) << ai->second.msg <<
SEP << KEY(ON_COMMAND_KEY) << ai->second.cmd_name_a << SEP << KEY(OFF_COMMAND_KEY) << ai->second.cmd_name_n << SEP << KEY(ENABLED_KEY) << (ai->second.enabled ? "1" : "0") << ends;

Graziano Scalamera
committed
alarm_filtered.push_back(os.str());
}
} /* for */
alarms.vlock->readerOut();
argout->length(alarm_filtered.size());
int i = 0;
for (vector<string>::iterator it= alarm_filtered.begin(); it != alarm_filtered.end(); it++)
{
(*argout)[i] = CORBA::string_dup(it->c_str());
i++;
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::search_alarm

Graziano Scalamera
committed
return argout;
}
//--------------------------------------------------------
/**

Graziano Scalamera
committed
* Command StopAudible related method
* Description: Stop audible indications on the GUI

Graziano Scalamera
committed
*
*/
//--------------------------------------------------------
void AlarmHandler::stop_audible()

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::StopAudible() - " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::stop_audible) ENABLED START -----*/

Graziano Scalamera
committed
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
// Add your own code
//12-06-08: StopNew command set is_new to 0
// Add your own code to control device here
alarm_container_t::iterator ai;
alarms.vlock->readerIn();
for (ai = alarms.v_alarm.begin(); ai != alarms.v_alarm.end(); ai++) {
ai->second.is_new = 0; //set all alarm as no more new
}
alarms.vlock->readerOut();
prepare_alarm_attr();
try
{
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

Graziano Scalamera
committed
{

Graziano Scalamera
committed
//attr.set_value(ds, ds_num, 0, false);
push_change_event("alarm",ds, ds_num, 0, false);

Graziano Scalamera
committed
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
}
push_change_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_change_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_change_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_change_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_change_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_change_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_change_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_change_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_change_event("audibleAlarm",attr_audibleAlarm_read);
push_archive_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_archive_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_archive_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_archive_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_archive_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_archive_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_archive_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_archive_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_archive_event("audibleAlarm",attr_audibleAlarm_read);

Graziano Scalamera
committed
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << "error pushing alarm change event err=" << e.errors[0].desc;
INFO_STREAM << __func__<<": " << err.str() << endl;
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::stop_audible

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Command Silence related method
* Description: Alarm temporarily silence
*
* @param argin String array containing the alarms to be silenced
*/
//--------------------------------------------------------
void AlarmHandler::silence(const Tango::DevVarStringArray *argin)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::Silence() - " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::silence) ENABLED START -----*/

Graziano Scalamera
committed
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
// Add your own code
vector<string> str;
str << (*argin);
vector<string>::iterator si;
for (si = str.begin(); si != str.end(); si++)
{
alarms.vlock->readerIn();
alarm_container_t::iterator i = alarms.v_alarm.find(*si);
if(i != alarms.v_alarm.end())
{
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;
//silenced already calculated in alarm_table::update, but here updated for panel also if state not changed:
//to see minutes countdown
if(dminutes < i->second.silent_time)

Graziano Scalamera
committed
{

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

Graziano Scalamera
committed
}

Graziano Scalamera
committed
else

Graziano Scalamera
committed
{

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

Graziano Scalamera
committed
i->second.shelved = false;
}

Graziano Scalamera
committed
}
if(i->second.silenced > 0)
{
ostringstream err;
err << "Alarm " << *si << " already silenced for " << i->second.silenced << " more minutes" << ends;
alarms.vlock->readerOut();
Tango::Except::throw_exception( \
(const char*)"Alarm already silenced", \
err.str(), \
(const char*)"AlarmHandler::silence()", Tango::ERR);

Graziano Scalamera
committed
}
if(i->second.silent_time <= 0)
{
ostringstream err;
err << "Alarm " << *si << " cannot be silenced" << ends;
alarms.vlock->readerOut();
Tango::Except::throw_exception( \
(const char*)"Alarm cannot be silenced", \
err.str(), \
(const char*)"AlarmHandler::silence()", Tango::ERR);

Graziano Scalamera
committed
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
}
//load silent time
i->second.ts_time_silenced = gettime();
i->second.silenced = i->second.silent_time;
//search also in alarmed
alarmedlock->readerIn();
vector<alarm_t>::iterator found = \
find(alarmed.begin(), alarmed.end(), *si);
if (found != alarmed.end())
{
//load silent time from alarm table
found->silenced = i->second.silent_time;
found->ts_time_silenced = i->second.ts_time_silenced;
}
alarmedlock->readerOut();
}
//alarms.unlock();
if(i == alarms.v_alarm.end())
{
alarms.vlock->readerOut();
ostringstream err;
err << "Alarm " << *si << " not found" << ends;
Tango::Except::throw_exception( \
(const char*)"Alarm not found!!", \
err.str(), \
(const char*)"AlarmHandler::silence()", Tango::ERR);

Graziano Scalamera
committed
}
alarms.vlock->readerOut();
}
prepare_alarm_attr();
try
{
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

Graziano Scalamera
committed
{

Graziano Scalamera
committed
//attr.set_value(ds, ds_num, 0, false);
push_change_event("alarm",ds, ds_num, 0, false);

Graziano Scalamera
committed
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
}
push_change_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_change_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_change_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_change_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_change_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_change_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_change_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_change_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_change_event("audibleAlarm",attr_audibleAlarm_read);
push_archive_event("normalAlarms",&attr_normalAlarms_read[0], normalAlarms_sz);
push_archive_event("unacknowledgedAlarms",&attr_unacknowledgedAlarms_read[0], unacknowledgedAlarms_sz);
push_archive_event("acknowledgedAlarms",&attr_acknowledgedAlarms_read[0], acknowledgedAlarms_sz);
push_archive_event("unacknowledgedNormalAlarms",&attr_unacknowledgedNormalAlarms_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("shelvedAlarms",&attr_shelvedAlarms_read[0], shelvedAlarms_sz);
push_archive_event("outOfServiceAlarms",&attr_outOfServiceAlarms_read[0], outOfServiceAlarms_sz);
push_archive_event("silencedAlarms",&attr_silencedAlarms_read[0], silencedAlarms_sz);
push_archive_event("listAlarms",&attr_listAlarms_read[0], listAlarms_sz);
push_archive_event("frequencyAlarms",&attr_frequencyAlarms_read[0], listAlarms_sz);
push_archive_event("audibleAlarm",attr_audibleAlarm_read);

Graziano Scalamera
committed
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << "error pushing alarm change event err=" << e.errors[0].desc;
INFO_STREAM << __func__<<": " << err.str() << endl;
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::silence

Graziano Scalamera
committed
}
//--------------------------------------------------------
/**
* Command Modify related method
* Description: Modify an existing alarm.
*
* @param argin Alarm entry
*/
//--------------------------------------------------------
void AlarmHandler::modify(Tango::DevString argin)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::Modify() - " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::modify) ENABLED START -----*/
// Add your own code
DEBUG_STREAM << "AlarmHandler::Modify: " << argin << endl;

Graziano Scalamera
committed
// Add your own code
//------------------------------
//1: parse to get alarm name
//------------------------------
string alarm_string(argin);
alarm_t alm;
alarm_parse al_gr(alm); // Construct Spirit grammar
alm.name.clear();
alm.attr_name.clear();
alm.quality = Tango::ATTR_VALID;
alm.ex_reason.clear();
alm.ex_desc.clear();
alm.ex_origin.clear();

Graziano Scalamera
committed
alm.formula.clear();
alm.msg.clear();
alm.lev.clear();
alm.grp=0;
alm.to_be_evaluated = false;
alm.on_delay = 0;
alm.off_delay = 0;

Graziano Scalamera
committed
alm.silent_time = -1;
alm.silenced = -1;
alm.cmd_name_a.clear();
alm.cmd_dp_a.clear();
alm.cmd_action_a.clear();
alm.send_arg_a = false;
alm.dp_a = NULL;
alm.cmd_name_n.clear();
alm.cmd_dp_n.clear();
alm.cmd_action_n.clear();
alm.send_arg_n = false;
alm.dp_n = NULL;

Graziano Scalamera
committed
alm.enabled=true;
alm.shelved=false;

Graziano Scalamera
committed
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
alm.formula_tree =
//boost::spirit::tree_parse_info< std::string::iterator, factory_t> tmp =
ast_parse<factory_t>(alarm_string.begin(), alarm_string.end(), al_gr, space_p); //parse string s with grammar al_gr, skipping white spaces
if (alm.formula_tree.full)
{
std::transform(alm.name.begin(), alm.name.end(), alm.name.begin(), (int(*)(int))tolower); //transform to lowercase
//std::transform(alm.formula.begin(), alm.formula.end(), alm.formula.begin(), (int(*)(int))tolower); //transform to lowercase: incorrect, state has to be written upercase
std::transform(alm.lev.begin(), alm.lev.end(), alm.lev.begin(), (int(*)(int))tolower); //transform to lowercase
if(alm.cmd_name_a.length() > 0)
{
const char *c = alm.cmd_name_a.c_str();
int j = 0;
while (*c) {
if (*c == '/')
j++;
if (j < 3)
alm.cmd_dp_a.push_back(*c);
else if (*c != '/')
alm.cmd_action_a.push_back(*c);
c++;
}
}
if(alm.cmd_name_n.length() > 0)
{
const char *c = alm.cmd_name_n.c_str();
int j = 0;
while (*c) {
if (*c == '/')
j++;
if (j < 3)
alm.cmd_dp_n.push_back(*c);
Loading full blame...