Skip to content
Snippets Groups Projects
AlarmHandler.cpp 214 KiB
Newer Older
	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;
	parse_alarm(alarm_string, alm);
	DEBUG_STREAM << "AlarmHandler::Modify: parsing ended: alm name=" << alm.name << endl;
	//------------------------------
	//2: if alarm already exist and
	//   formula is not changed
	//------------------------------
	alarms.vlock->writerIn(); //TODO: use readerIn instead?
	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;

			i->second.stat = S_NORMAL;
			i->second.ack = ACK;
			i->second.done = false;

			i->second.msg = alm.msg;
			i->second.url = alm.url;
			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.silent_time = alm.silent_time;
			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;

			//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())
		{
			alarms.vlock->readerOut();
		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();
		alarm_t alm = i->second;
		alarms.vlock->readerOut();
		Tango::DevEnum *attr_value = get_AlarmState_data_ptr(alm.attr_name);
			if(alm.ex_reason.empty())
				push_change_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false);
				push_archive_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false);
				errors[0].desc = CORBA::string_dup(alm.ex_desc.c_str());
				errors[0].reason = CORBA::string_dup(alm.ex_reason.c_str());
				errors[0].origin = CORBA::string_dup(alm.ex_origin.c_str());
				push_change_event(alm.attr_name, &except);
				push_archive_event(alm.attr_name, &except);
			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;
	}

	/*----- 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;
	alarm_t alm = i->second;
	alarms.vlock->readerOut();
	Tango::DevEnum *attr_value = get_AlarmState_data_ptr(alm.attr_name);
	if((alm.stat == S_NORMAL) && alm.ack == ACK)
	else if((alm.stat == S_ALARM) && alm.ack == NOT_ACK)
	else if((alm.stat == S_ALARM) && alm.ack == ACK)
	else if((alm.stat == S_NORMAL) && alm.ack == NOT_ACK)
		*attr_value = _RTNUN;
	try
	{	//DevFailed for push events
		if(alm.ex_reason.empty())
			push_change_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false);
			push_archive_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false);
			errors[0].desc = CORBA::string_dup(alm.ex_desc.c_str());
			errors[0].reason = CORBA::string_dup(alm.ex_reason.c_str());
			errors[0].origin = CORBA::string_dup(alm.ex_origin.c_str());
			push_change_event(alm.attr_name, &except);
			push_archive_event(alm.attr_name, &except);
		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;
	alarm_t alm = i->second;
	alarms.vlock->readerOut();
	Tango::DevEnum *attr_value = get_AlarmState_data_ptr(alm.attr_name);
		if(alm.ex_reason.empty())
			push_change_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false);
			push_archive_event(alm.attr_name,(Tango::DevEnum *)attr_value,now,(Tango::AttrQuality)alm.quality, 1/*size*/, 0, false);
			errors[0].desc = CORBA::string_dup(alm.ex_desc.c_str());
			errors[0].reason = CORBA::string_dup(alm.ex_reason.c_str());
			errors[0].origin = CORBA::string_dup(alm.ex_origin.c_str());
			push_change_event(alm.attr_name, &except);
			push_archive_event(alm.attr_name, &except);
		WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;

	/*
	 * 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;
	}
	alarms.vlock->readerOut();
	timespec now;
	clock_gettime(CLOCK_MONOTONIC, &now);
	double dnow = (now.tv_sec) + ((double)(now.tv_nsec))/1000000000;
	last_statistics_reset_time = dnow;
	/*----- 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;
	}

	/*----- PROTECTED REGION END -----*/	//	AlarmHandler::stop_new
}
//--------------------------------------------------------
/**
 *	Command GetAlarmInfo related method
 *	Description: Returns the complete attribute info as an array of key=value
 *
 *	@param argin Alarm name followed optionally by wanted key names
 *	@returns Complete attribute info as an array of key=value
 */
//--------------------------------------------------------
Tango::DevVarStringArray *AlarmHandler::get_alarm_info(const Tango::DevVarStringArray *argin)
{
	Tango::DevVarStringArray *argout;
	DEBUG_STREAM << "AlarmHandler::GetAlarmInfo()  - " << device_name << endl;
	/*----- PROTECTED REGION ID(AlarmHandler::get_alarm_info) ENABLED START -----*/
	
	if(argin->length() < 1)
	{
       	Tango::Except::throw_exception( \
				(const char*)"BAD PARAMETERS", \
				(const char*)"At least alarm name expected", \
				(const char*)__func__, Tango::ERR);
	}
	//	Add your own code
	alarms.vlock->readerIn();

	alarm_container_t::iterator it = alarms.v_alarm.find(string((*argin)[0]));
	map<string,string> info;
	vector<string> complete;

	if(it == alarms.v_alarm.end())
	{
		alarms.vlock->readerOut();
       	ostringstream o;
		o << "Alarm '" << string((*argin)[0]) << "' not found";
       	DEBUG_STREAM <<__func__ << ": " << o.str() << endl;
       	Tango::Except::throw_exception( \
				(const char*)"NOT FOUND", \
				(const char*)o.str().c_str(), \
				(const char*)__func__, Tango::ERR);
	}

	info.insert(make_pair(NAME_KEY,it->first));
	complete.push_back(KEY(NAME_KEY)+it->first);

	Tango::MultiAttribute *m_attr = get_device_attr();
	int attr_ind = m_attr->get_attr_ind_by_name(it->second.attr_name.c_str());
	Tango::Attribute &attribute = m_attr->get_attr_by_ind(attr_ind);

	ostringstream tmp_val;
	vector<string> enum_labels = attribute.get_enum_labels();
	if(*(it->second.attr_value) >= 0 && *(it->second.attr_value) < enum_labels.size())
		tmp_val << enum_labels[*(it->second.attr_value)];
	else
		tmp_val << "UNKNOWN_ENUM(" << *(it->second.attr_value) << ")";

	if(it->second.error)
		tmp_ex << "{\"Reason\":\"" << it->second.ex_reason << "\",\"Desc\":\"" << it->second.ex_desc << "\",\"Origin\":\"" << it->second.ex_origin << "\"}";
		info.insert(make_pair(VALUE_KEY,string("ERROR")));
		complete.push_back(KEY(VALUE_KEY)+string("ERROR"));
		info.insert(make_pair(FORMULA_KEY,it->second.formula));
		complete.push_back(KEY(FORMULA_KEY)+it->second.formula);
		info.insert(make_pair(ATTR_VALUES_KEY,tmp_ex.str()));
		complete.push_back(KEY(ATTR_VALUES_KEY)+tmp_ex.str());
	}
	else
	{
		info.insert(make_pair(VALUE_KEY,tmp_val.str()));
		complete.push_back(KEY(VALUE_KEY)+tmp_val.str());
		info.insert(make_pair(FORMULA_KEY,it->second.formula));
		complete.push_back(KEY(FORMULA_KEY)+it->second.formula);
		info.insert(make_pair(ATTR_VALUES_KEY,it->second.attr_values));
		complete.push_back(KEY(ATTR_VALUES_KEY)+it->second.attr_values);
	}



	ostringstream tmp_qual;
	try
	{
		tmp_qual << quality_labels.at(it->second.quality);
	} catch(std::out_of_range& ex)
	{
		tmp_qual << it->second.quality;
	}
	info.insert(make_pair(QUALITY_KEY,tmp_qual.str()));
	complete.push_back(KEY(QUALITY_KEY)+tmp_qual.str());
	ostringstream tmp;
	tmp.str("");
	tmp << (it->second.enabled ? "1" : "0");
	info.insert(make_pair(ENABLED_KEY,tmp.str()));	//TODO: redundant, information already in attr_value
	complete.push_back(KEY(ENABLED_KEY)+tmp.str());	//TODO: redundant, information already in attr_value
	tmp.str("");
	tmp << (it->second.shelved ? "1" : "0");
	info.insert(make_pair(SHELVED_KEY,tmp.str()));	//TODO: redundant, information already in attr_value
	complete.push_back(KEY(SHELVED_KEY)+tmp.str());	//TODO: redundant, information already in attr_value
	tmp.str("");
	tmp << ((it->second.ack == "ACK") ? "1" : "0");
	info.insert(make_pair(ACKNOWLEDGED_KEY,tmp.str()));	//TODO: redundant, information already in attr_value
	complete.push_back(KEY(ACKNOWLEDGED_KEY)+tmp.str());	//TODO: redundant, information already in attr_value
//#endif
	tmp.str("");
	tmp << (it->second.is_new ? "1" : "0");
	info.insert(make_pair(AUDIBLE_KEY,tmp.str()));
	complete.push_back(KEY(AUDIBLE_KEY)+tmp.str());
	tmp.str("");
	if(it->second.stat == S_ALARM)
	{
		tmp << (it->second.on_counter);
	}
	else
	{
		tmp << (it->second.off_counter);
	}
	info.insert(make_pair(COUNTER_KEY,tmp.str()));
	complete.push_back(KEY(COUNTER_KEY)+tmp.str());
	tmp.str("");
	tmp << (it->second.freq_counter);
	info.insert(make_pair(FREQ_COUNTER_KEY,tmp.str()));
	complete.push_back(KEY(FREQ_COUNTER_KEY)+tmp.str());

	tmp.str("");
	tmp << (it->second.on_delay);
	info.insert(make_pair(ONDELAY_KEY,tmp.str()));
	complete.push_back(KEY(ONDELAY_KEY)+tmp.str());
	tmp.str("");
	tmp << (it->second.off_delay);
	info.insert(make_pair(OFFDELAY_KEY,tmp.str()));
	complete.push_back(KEY(OFFDELAY_KEY)+tmp.str());
	info.insert(make_pair(LEVEL_KEY,it->second.lev));
	complete.push_back(KEY(LEVEL_KEY)+it->second.lev);
	tmp.str("");
	tmp << (it->second.silent_time);
	info.insert(make_pair(SILENT_TIME_KEY,tmp.str()));
	complete.push_back(KEY(SILENT_TIME_KEY)+tmp.str());
	tmp.str("");
	tmp << (it->second.silenced);
	info.insert(make_pair(SILENT_TIME_REMAINING_KEY,tmp.str()));
	complete.push_back(KEY(SILENT_TIME_REMAINING_KEY)+tmp.str());
	info.insert(make_pair(GROUP_KEY,it->second.grp2str()));
	complete.push_back(KEY(GROUP_KEY)+it->second.grp2str());
	tmp.str("");
	tmp << "\"" << it->second.msg << "\"";
	info.insert(make_pair(MESSAGE_KEY,tmp.str()));
	complete.push_back(KEY(MESSAGE_KEY)+tmp.str());
	info.insert(make_pair(URL_KEY,it->second.url));
	complete.push_back(KEY(URL_KEY)+it->second.url);
	info.insert(make_pair(ON_COMMAND_KEY,it->second.cmd_name_a));
	complete.push_back(KEY(ON_COMMAND_KEY)+it->second.cmd_name_a);
	info.insert(make_pair(OFF_COMMAND_KEY,it->second.cmd_name_n));
	complete.push_back(KEY(OFF_COMMAND_KEY)+it->second.cmd_name_n);

	alarms.vlock->readerOut();
	argout = new Tango::DevVarStringArray();