Skip to content
Snippets Groups Projects
AlarmHandler.cpp 201 KiB
Newer Older
	//	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
			//attr.set_value(ds, ds_num, 0, false);
			push_change_event("alarm",ds, ds_num, 0, false);
		push_change_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
		push_change_event("alarmAudible",attr_alarmAudible_read);
		push_change_event("alarmSummary",attr_alarmSummary_read);
		push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
		push_archive_event("alarmAudible",attr_alarmAudible_read);
		push_archive_event("alarmSummary",attr_alarmSummary_read);
	} 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
}
//--------------------------------------------------------
/**
 *	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)
	DEBUG_STREAM << "AlarmHandler::Silence()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(AlarmHandler::silence) ENABLED START -----*/
	
	//	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)
					i->second.silenced = i->second.silent_time - floor(dminutes);
				err << "Alarm " << *si << " already silenced for " << i->second.silenced << " more minutes";
				alarms.vlock->readerOut();
				Tango::Except::throw_exception( \
							(const char*)"Alarm already silenced", \
							err.str(), \
							(const char*)"AlarmHandler::silence()", Tango::ERR);
				err << "Alarm " << *si << " cannot be silenced";
				alarms.vlock->readerOut();
				Tango::Except::throw_exception( \
							(const char*)"Alarm cannot be silenced", \
							err.str(), \
							(const char*)"AlarmHandler::silence()", Tango::ERR);
			}

			//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";
			Tango::Except::throw_exception( \
						(const char*)"Alarm not found!!", \
						err.str(), \
						(const char*)"AlarmHandler::silence()", Tango::ERR);
		}
		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
			//attr.set_value(ds, ds_num, 0, false);
			push_change_event("alarm",ds, ds_num, 0, false);
		push_change_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
		push_change_event("alarmAudible",attr_alarmAudible_read);
		push_change_event("alarmSummary",attr_alarmSummary_read);
		push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
		push_archive_event("alarmAudible",attr_alarmAudible_read);
		push_archive_event("alarmSummary",attr_alarmSummary_read);
	} 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
}
//--------------------------------------------------------
/**
 *	Command Modify related method
 *	Description: Modify an existing alarm.
 *
 *	@param argin Alarm entry
 */
//--------------------------------------------------------
void AlarmHandler::modify(Tango::DevString argin)
	DEBUG_STREAM << "AlarmHandler::Modify()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(AlarmHandler::modify) ENABLED START -----*/
	
	//	Add your own code
	DEBUG_STREAM << "AlarmHandler::Modify: " << argin << endl;
	//	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();
	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;
	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;

	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);
				else if (*c != '/')
					alm.cmd_action_n.push_back(*c);
				c++;
			}
    	}

	}
    else
    {
       	ostringstream o;
		o << __func__<<": Parsing Failed, parsed up to '" << string(alarm_string.begin(), alm.formula_tree.stop) << "' not parsed '" << string(alm.formula_tree.stop, alarm_string.end()) << "'"; //TODO
       	DEBUG_STREAM << o.str() << endl;
       	Tango::Except::throw_exception( \
				(const char*)"Parsing Failed!", \
				(const char*)o.str().c_str(), \
				(const char*)__func__, Tango::ERR);
    }

	DEBUG_STREAM << "AlarmHandler::Modify: parsing ended: alm name=" << alm.name << endl;
	//------------------------------
	//2: if alarm already exist and
	//   formula is not changed
	//------------------------------
	alarms.vlock->writerIn();
	alarm_container_t::iterator i = alarms.v_alarm.find(alm.name);
	if (i != alarms.v_alarm.end())
	{
		if(i->second.formula == alm.formula)
		{
			Tango::TimeVal ts = gettime();
			string cmd_name_full = alm.cmd_name_a + string(";") + alm.cmd_name_n;

			if ((alm.name.empty() == false) && \
					(alm.formula.empty() == false) && \
					((alm.lev==LEV_LOG)||(alm.lev==LEV_WARNING)|| \
					(alm.lev==LEV_FAULT)||(alm.lev.empty() == true))) {
				i->second.stat = S_NORMAL;
				i->second.ack = ACK;
				i->second.done = false;

				i->second.msg = alm.msg;
				i->second.lev = alm.lev;
				i->second.grp = alm.grp;
				//i->second.to_be_evaluated = alm.to_be_evaluated;
				i->second.on_delay = alm.on_delay;
				i->second.off_delay = alm.off_delay;
				i->second.silenced = (i->second.silent_time > 0) ? 0 : -1;	//0: can be silenced, -1: cannot be silencedd;
				i->second.cmd_name_a = alm.cmd_name_a;
				i->second.cmd_dp_a = alm.cmd_dp_a;
				i->second.cmd_action_a = alm.cmd_action_a;
				//i->second.send_arg_a = alm.send_arg_a;
				i->second.cmd_name_n = alm.cmd_name_n;
				i->second.cmd_dp_n = alm.cmd_dp_n;
				i->second.cmd_action_n = alm.cmd_action_n;
				//i->second.send_arg_n = alm.send_arg_n;
				i->second.enabled = alm.enabled;
				o << __func__<<": syntax error in '" << alarm_string << "'";
				WARN_STREAM << o.str() << endl;
				alarms.vlock->writerOut();
				Tango::Except::throw_exception( \
						(const char*)o.str().c_str(), \
						(const char*)"", \
						(const char*)__func__, Tango::ERR);
			}

			//update attribute properties
			events->update_property();

			//delete proxy for actions
			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(alm.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)
					{
						ostringstream err;
						err << "Error: command " << i->second.cmd_name_a << " does not accept a Tango::DevString as input value";
						ERROR_STREAM << __func__<<": " << err.str() << endl;
						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 << __func__<<": successfully connected to proxy=" << i->second.cmd_dp_a << " for action=" << i->second.cmd_action_a << endl;
					}
				} catch(Tango::DevFailed& e)
				{
					ostringstream err;
					err << alm.name << ": error connecting to device proxy=" << i->second.cmd_dp_a << ", err=" << e.errors[0].desc;
					WARN_STREAM << __func__<<": " << err.str() << endl;
					set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());
				}
			}
			if(alm.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_a);
					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";
						ERROR_STREAM << __func__<<": " << err.str() << endl;
						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 << __func__<<": successfully connected to proxy=" << i->second.cmd_dp_n << " for action=" << i->second.cmd_action_n << endl;
					}
				} catch(Tango::DevFailed& e)
				{
					ostringstream err;
					err << alm.name << ": error connecting to device proxy=" << i->second.cmd_dp_n << ", err=" << e.errors[0].desc;
					WARN_STREAM << __func__<<": " << err.str() << endl;
					set_internal_alarm(INTERNAL_ERROR, gettime(), err.str());
				}
			}
			alarms.vlock->writerOut();
			return;
		}
	}
	else
	{
		alarms.vlock->writerOut();
       	ostringstream o;
       	o << "Alarm '"<<alm.name<<"' not found";
       	DEBUG_STREAM << o.str() << endl;
       	Tango::Except::throw_exception( \
				(const char*)"Not found", \
				(const char*)o.str().c_str(), \
				(const char*)__func__, Tango::ERR);
	}
	alarms.vlock->writerOut();

	//------------------------------
	//3: remove (set active=0 on db)
	//------------------------------
	remove((Tango::DevString)alm.name.c_str());
	DEBUG_STREAM << "AlarmHandler::Modify: removed alm name=" << alm.name << endl;
	//------------------------------
	//4: load modified alarm
	//------------------------------
	load(argin);

	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);
		}
		push_change_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
		push_change_event("alarmAudible",attr_alarmAudible_read);
		push_change_event("alarmSummary",attr_alarmSummary_read);
		push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
		push_archive_event("alarmAudible",attr_alarmAudible_read);
		push_archive_event("alarmSummary",attr_alarmSummary_read);
	} 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::modify
}
//--------------------------------------------------------
/**
 *	Command Shelve related method
 *	Description: Shelve an alarm: no state transition recorded, no audible nor visual indication
 *
 *	@param argin String array containing alarm to be shelved
 */
//--------------------------------------------------------
void AlarmHandler::shelve(const Tango::DevVarStringArray *argin)
	DEBUG_STREAM << "AlarmHandler::Shelve()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(AlarmHandler::shelve) ENABLED START -----*/
	
	//	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())
		{
			ostringstream err;
			err << *si << " not found in configured alarms";
			alarms.vlock->readerOut();
			Tango::Except::throw_exception( \
				(const char*)"NOT_FOUND", \
				(const char*)err.str().c_str(), \
				(const char*)__func__, Tango::ERR);
		}
		if(!i->second.enabled)
		{
			ostringstream err;
			err << *si << " is not enabled";
			alarms.vlock->readerOut();
			Tango::Except::throw_exception( \
				(const char*)"NOT_ENABLED", \
				(const char*)err.str().c_str(), \
				(const char*)__func__, Tango::ERR);
		}
		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)//TODO: shelve_time ?
			{
				i->second.silenced = i->second.silent_time - floor(dminutes);//TODO: shelve_time ?
			}
			else
			{
				i->second.silenced = 0;
				i->second.shelved = false;
			}
		}
		if(i->second.shelved)
		{
			ostringstream err;
			err << *si << " is already shelved";
			alarms.vlock->readerOut();
			Tango::Except::throw_exception( \
				(const char*)"ALREADY_SHELVED", \
				(const char*)err.str().c_str(), \
				(const char*)__func__, Tango::ERR);
		}
		if(i->second.silent_time <= 0)
		{
			ostringstream err;
			err << "Alarm " << *si << " cannot be shelved";
			alarms.vlock->readerOut();
			Tango::Except::throw_exception( \
						(const char*)"NOT_ALLOWED", \
						err.str(), \
						(const char*)__func__, Tango::ERR);
		}
		alarms.vlock->readerOut();
	}

	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())
			continue;
		i->second.shelved = true;

		//load silent time
		i->second.ts_time_silenced = gettime();
		i->second.silenced = i->second.silent_time;	//TODO: shelve_time ?
		//search also in alarmed
		alarmedlock->writerIn();
		vector<alarm_t>::iterator found = \
				find(alarmed.begin(), alarmed.end(), *si);
		if (found != alarmed.end())
		{
			alarmed.erase(found);
		}
		alarmedlock->writerOut();


		Tango::DevEnum *attr_value = get_AlarmState_data_ptr(i->second.attr_name);

		*attr_value = _SHLVD;
		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;
		}
		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
		{
			//attr.set_value(ds, ds_num, 0, false);
			push_change_event("alarm",ds, ds_num, 0, false);
		}
		push_change_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_change_event("alarmSummary",attr_alarmSummary_read);
		push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_archive_event("alarmSummary",attr_alarmSummary_read);
	} 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::shelve
}
//--------------------------------------------------------
/**
 *	Command Enable related method
 *	Description: Enable an alarm from Out of service state
 *
 *	@param argin Alarm name
 */
//--------------------------------------------------------
void AlarmHandler::enable(Tango::DevString argin)
	DEBUG_STREAM << "AlarmHandler::Enable()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(AlarmHandler::enable) ENABLED START -----*/
	
	//	Add your own code
	string arginname(argin);

	alarms.vlock->readerIn();
	alarm_container_t::iterator i = alarms.v_alarm.find(arginname);
	if(i == alarms.v_alarm.end())
	{
		ostringstream err;
		err << arginname << " not found in configured alarms";
		alarms.vlock->readerOut();
		Tango::Except::throw_exception( \
			(const char*)"NOT_FOUND", \
			(const char*)err.str().c_str(), \
			(const char*)__func__, Tango::ERR);
	}

	i->second.enabled = true;

	i->second.silenced = (i->second.silent_time > 0) ? 0 : -1;	//0: can be silenced, -1: cannot be silenced
	i->second.shelved = false;

	Tango::DevEnum *attr_value = get_AlarmState_data_ptr(i->second.attr_name);

	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 << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;
	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);
		}
		push_change_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_change_event("alarmSummary",attr_alarmSummary_read);
		push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_archive_event("alarmSummary",attr_alarmSummary_read);
	} catch(Tango::DevFailed& e)
	{
		ostringstream err;
		err << "error pushing alarm change event err=" << e.errors[0].desc;
		INFO_STREAM << __func__<<": " << err.str() << endl;
	}
	//update attribute properties
	events->update_property();
	/*----- PROTECTED REGION END -----*/	//	AlarmHandler::enable
}
//--------------------------------------------------------
/**
 *	Command Disable related method
 *	Description: Put an alarm in Out of service state
 *
 *	@param argin Alarm name
 */
//--------------------------------------------------------
void AlarmHandler::disable(Tango::DevString argin)
	DEBUG_STREAM << "AlarmHandler::Disable()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(AlarmHandler::disable) ENABLED START -----*/
	alarms.vlock->readerIn();
	alarm_container_t::iterator i = alarms.v_alarm.find(arginname);
	if(i == alarms.v_alarm.end())
		err << arginname << " not found in configured alarms";
		alarms.vlock->readerOut();
		Tango::Except::throw_exception( \
			(const char*)"NOT_FOUND", \
			(const char*)err.str().c_str(), \
			(const char*)__func__, Tango::ERR);
	}

	i->second.enabled = false;

	i->second.silenced = (i->second.silent_time > 0) ? 0 : -1;	//0: can be silenced, -1: cannot be silenced
	i->second.shelved = false;

	Tango::DevEnum *attr_value = get_AlarmState_data_ptr(i->second.attr_name);

	*attr_value = _OOSRV;
	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;
	alarms.vlock->readerOut();
	/*
	 * remove from alarmed
	 */
	bool go = true;
	while (go) {
		alarmedlock->writerIn();
		vector<alarm_t>::iterator found = \
				find(alarmed.begin(), alarmed.end(), arginname);
		if (found != alarmed.end()) {
			DEBUG_STREAM << "AlarmHandler::"<<__func__<<": " << found->name \
					 				 << " 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
			//attr.set_value(ds, ds_num, 0, false);
			push_change_event("alarm",ds, ds_num, 0, false);
		push_change_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
		push_change_event("alarmAudible",attr_alarmAudible_read);
		push_change_event("alarmSummary",attr_alarmSummary_read);
		push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
		push_archive_event("alarmAudible",attr_alarmAudible_read);
		push_archive_event("alarmSummary",attr_alarmSummary_read);
	} catch(Tango::DevFailed& e)
	{
		ostringstream err;
		err << "error pushing alarm change event err=" << e.errors[0].desc;
		INFO_STREAM << __func__<<": " << err.str() << endl;
	}
	//update attribute properties
	events->update_property();
	/*----- PROTECTED REGION END -----*/	//	AlarmHandler::disable
}
//--------------------------------------------------------
/**
 *	Command ResetStatistics related method
 *	Description: Reset statistics
 *
 */
//--------------------------------------------------------
void AlarmHandler::reset_statistics()
	DEBUG_STREAM << "AlarmHandler::ResetStatistics()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(AlarmHandler::reset_statistics) ENABLED START -----*/
	
	//	Add your own code
	alarms.vlock->readerIn();
	for(alarm_container_t::iterator i = alarms.v_alarm.begin(); i!= alarms.v_alarm.end(); i++)
	{
		i->second.freq_counter = 0;
	}
	timespec now;
	clock_gettime(CLOCK_MONOTONIC, &now);
	double dnow = (now.tv_sec) + ((double)(now.tv_nsec))/1000000000;
	last_statistics_reset_time = dnow;
	alarms.vlock->readerOut();
	/*----- PROTECTED REGION END -----*/	//	AlarmHandler::reset_statistics
}
//--------------------------------------------------------
/**
 *	Command StopNew related method
 *	Description: Stop audible indications on the GUI
 *
 */
//--------------------------------------------------------
void AlarmHandler::stop_new()
{
	DEBUG_STREAM << "AlarmHandler::StopNew()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(AlarmHandler::stop_new) ENABLED START -----*/
	
	//	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
		{
			//attr.set_value(ds, ds_num, 0, false);
			push_change_event("alarm",ds, ds_num, 0, false);
		}
		push_change_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
		push_change_event("alarmAudible",attr_alarmAudible_read);
		push_change_event("alarmSummary",attr_alarmSummary_read);
		push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
		push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
		push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
		push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
		push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
		push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
		push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
		push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
		push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
		push_archive_event("alarmAudible",attr_alarmAudible_read);
		push_archive_event("alarmSummary",attr_alarmSummary_read);
	} catch(Tango::DevFailed& e)
	{
		ostringstream err;
		err << "error pushing alarm change event err=" << e.errors[0].desc;
		INFO_STREAM << __func__<<": " << err.str() << endl;
	}