From 46109c47384749413362f28cc5437b7f6f1a55e9 Mon Sep 17 00:00:00 2001
From: gscalamera <graziano.scalamera@elettra.eu>
Date: Fri, 18 Dec 2020 09:46:51 +0100
Subject: [PATCH] Add ErrorDelay Class,Device property

---
 src/AlarmHandler.cpp      | 18 ++++++++++++++---
 src/AlarmHandler.h        |  2 ++
 src/AlarmHandler.xmi      | 10 ++++++++++
 src/AlarmHandlerClass.cpp | 41 +++++++++++++++++++++++++++++++++++++++
 src/AlarmHandlerClass.h   |  2 ++
 src/alarm_table.h         |  5 +++--
 6 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/src/AlarmHandler.cpp b/src/AlarmHandler.cpp
index 61b88fb..d03982a 100644
--- a/src/AlarmHandler.cpp
+++ b/src/AlarmHandler.cpp
@@ -367,7 +367,7 @@ void AlarmHandler::init_device()
 	internallock = new(ReadersWritersLock);
 	dslock = new(ReadersWritersLock);
 	alarms.set_dev(this);
-	alarms.set_err_delay(30); //TODO: device property
+	alarms.set_err_delay(errorDelay);
 
 	/*----- PROTECTED REGION END -----*/	//	AlarmHandler::init_device_before
 	
@@ -807,6 +807,7 @@ void AlarmHandler::get_device_property()
 	dev_prop.push_back(Tango::DbDatum("GroupNames"));
 	dev_prop.push_back(Tango::DbDatum("SubscribeRetryPeriod"));
 	dev_prop.push_back(Tango::DbDatum("StatisticsTimeWindow"));
+	dev_prop.push_back(Tango::DbDatum("ErrorDelay"));
 
 	//	is there at least one property to be read ?
 	if (dev_prop.size()>0)
@@ -854,6 +855,17 @@ void AlarmHandler::get_device_property()
 		//	And try to extract StatisticsTimeWindow value from database
 		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  statisticsTimeWindow;
 
+		//	Try to initialize ErrorDelay from class property
+		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+		if (cl_prop.is_empty()==false)	cl_prop  >>  errorDelay;
+		else {
+			//	Try to initialize ErrorDelay from default device value
+			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+			if (def_prop.is_empty()==false)	def_prop  >>  errorDelay;
+		}
+		//	And try to extract ErrorDelay value from database
+		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  errorDelay;
+
 	}
 
 	/*----- PROTECTED REGION ID(AlarmHandler::get_device_property_after) ENABLED START -----*/
@@ -3475,9 +3487,9 @@ void AlarmHandler::do_alarm(bei_t& e)
 						it->second.ex_reason = found_ev->ex_reason;
 					it->second.ex_desc = found_ev->ex_desc;
 					it->second.ex_origin = found_ev->ex_origin;
-					if(alarms.err_delay > 0)
+					if(errorDelay > 0)
 					{
-						if((it->second.ts.tv_sec - alarms.err_delay) > it->second.ts_err_delay.tv_sec)	//error is present and err delay has passed
+						if((it->second.ts.tv_sec - errorDelay) > it->second.ts_err_delay.tv_sec)	//error is present and err delay has passed
 							it->second.error = true;
 					}
 					else
diff --git a/src/AlarmHandler.h b/src/AlarmHandler.h
index f006574..c484aa2 100644
--- a/src/AlarmHandler.h
+++ b/src/AlarmHandler.h
@@ -151,6 +151,8 @@ public:
 	Tango::DevLong	subscribeRetryPeriod;
 	//	StatisticsTimeWindow:	Time window to compute statistics in seconds
 	vector<Tango::DevLong>	statisticsTimeWindow;
+	//	ErrorDelay:	Delay in seconds before changing to ERROR state after an exception is received.
+	Tango::DevULong	errorDelay;
 
 //	Attribute data members
 public:
diff --git a/src/AlarmHandler.xmi b/src/AlarmHandler.xmi
index 60c8e86..bef601f 100644
--- a/src/AlarmHandler.xmi
+++ b/src/AlarmHandler.xmi
@@ -19,6 +19,11 @@
       <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
       <DefaultPropValue>60</DefaultPropValue>
     </classProperties>
+    <classProperties name="ErrorDelay" description="Delay in seconds before changing to ERROR state after an exception is received.">
+      <type xsi:type="pogoDsl:UIntType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+      <DefaultPropValue>30</DefaultPropValue>
+    </classProperties>
     <deviceProperties name="GroupNames" description="Labels for Group mask, first is for mask 0x00">
       <type xsi:type="pogoDsl:StringVectorType"/>
       <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
@@ -33,6 +38,11 @@
       <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
       <DefaultPropValue>60</DefaultPropValue>
     </deviceProperties>
+    <deviceProperties name="ErrorDelay" description="Delay in seconds before changing to ERROR state after an exception is received.">
+      <type xsi:type="pogoDsl:UIntType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+      <DefaultPropValue>30</DefaultPropValue>
+    </deviceProperties>
     <commands name="State" description="This command gets the device state (stored in its &lt;i>device_state&lt;/i> data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0">
       <argin description="none.">
         <type xsi:type="pogoDsl:VoidType"/>
diff --git a/src/AlarmHandlerClass.cpp b/src/AlarmHandlerClass.cpp
index 02edbc2..d2c5d11 100644
--- a/src/AlarmHandlerClass.cpp
+++ b/src/AlarmHandlerClass.cpp
@@ -490,6 +490,7 @@ void AlarmHandlerClass::get_class_property()
 	cl_prop.push_back(Tango::DbDatum("GroupNames"));
 	cl_prop.push_back(Tango::DbDatum("SubscribeRetryPeriod"));
 	cl_prop.push_back(Tango::DbDatum("StatisticsTimeWindow"));
+	cl_prop.push_back(Tango::DbDatum("ErrorDelay"));
 	
 	//	Call database and extract values
 	if (Tango::Util::instance()->_UseDb==true)
@@ -533,6 +534,18 @@ void AlarmHandlerClass::get_class_property()
 			cl_prop[i]  <<  statisticsTimeWindow;
 		}
 	}
+	//	Try to extract ErrorDelay value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  errorDelay;
+	else
+	{
+		//	Check default value for ErrorDelay
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop    >>  errorDelay;
+			cl_prop[i]  <<  errorDelay;
+		}
+	}
 	/*----- PROTECTED REGION ID(AlarmHandlerClass::get_class_property_after) ENABLED START -----*/
 	
 	//	Check class property data members init
@@ -597,6 +610,20 @@ void AlarmHandlerClass::set_default_property()
 		cl_def_prop.push_back(data);
 		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
 	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+	prop_name = "ErrorDelay";
+	prop_desc = "Delay in seconds before changing to ERROR state after an exception is received.";
+	prop_def  = "30";
+	vect_data.clear();
+	vect_data.push_back("30");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
 	else
 		add_wiz_class_prop(prop_name, prop_desc);
 
@@ -642,6 +669,20 @@ void AlarmHandlerClass::set_default_property()
 	}
 	else
 		add_wiz_dev_prop(prop_name, prop_desc);
+	prop_name = "ErrorDelay";
+	prop_desc = "Delay in seconds before changing to ERROR state after an exception is received.";
+	prop_def  = "30";
+	vect_data.clear();
+	vect_data.push_back("30");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
 }
 
 //--------------------------------------------------------
diff --git a/src/AlarmHandlerClass.h b/src/AlarmHandlerClass.h
index fd49b66..5df7fbe 100644
--- a/src/AlarmHandlerClass.h
+++ b/src/AlarmHandlerClass.h
@@ -605,6 +605,8 @@ class AlarmHandlerClass : public Tango::DeviceClass
 		Tango::DevLong	subscribeRetryPeriod;
 		//	StatisticsTimeWindow:	Time window to compute statistics in seconds
 		vector<Tango::DevLong>	statisticsTimeWindow;
+		//	ErrorDelay:	Delay in seconds before changing to ERROR state after an exception is received.
+		Tango::DevULong	errorDelay;
 	public:
 		//	write class properties data members
 		Tango::DbData	cl_prop;
diff --git a/src/alarm_table.h b/src/alarm_table.h
index 46dddf5..b6ea4f7 100644
--- a/src/alarm_table.h
+++ b/src/alarm_table.h
@@ -371,13 +371,14 @@ class alarm_table {
 		void stop_cmdthread();
 		Tango::TimeVal startup_complete;			//to disable action execution at startup
 		void set_err_delay(unsigned int delay){err_delay=delay;};
-		unsigned int err_delay; //TODO: private	
+	
 	protected:
 	private:
 
 		Tango::DeviceImpl* mydev;
 		log_thread *logloop;
-		cmd_thread *cmdloop;		
+		cmd_thread *cmdloop;
+		unsigned int err_delay;
 };
 
 
-- 
GitLab