From 85272690bee335699971fe7692751e141c61934a Mon Sep 17 00:00:00 2001
From: Ruud Overeem <overeem@astron.nl>
Date: Wed, 26 Jul 2006 15:08:21 +0000
Subject: [PATCH] BugID: 797 The ObservationController still used the
 ObservationController.conf file during startup in stead of the
 ObservationController[x]{y} file in /opt/lofar/share. Introduced timers for
 the claim/prepare/start and stop events. Supporting changes of these times in
 PVSS.

---
 .../MainCU/src/ObservationControl/Makefile.am |   9 +-
 .../ObservationControl/ObservationControl.cc  | 175 +++++++++++++++---
 .../ObservationControl.conf.example           |  30 +++
 .../ObservationControl.conf.in                |  11 --
 .../ObservationControl/ObservationControl.h   |  20 +-
 .../ObservationControl.log_prop.in            |   2 +-
 .../ObservationControlDefines.h               |  12 +-
 7 files changed, 206 insertions(+), 53 deletions(-)
 create mode 100644 MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.example
 delete mode 100644 MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in

diff --git a/MAC/APL/MainCU/src/ObservationControl/Makefile.am b/MAC/APL/MainCU/src/ObservationControl/Makefile.am
index 20ba1eca523..af5e030346f 100644
--- a/MAC/APL/MainCU/src/ObservationControl/Makefile.am
+++ b/MAC/APL/MainCU/src/ObservationControl/Makefile.am
@@ -26,18 +26,11 @@ configfilesdir=$(bindir)
 configfiles_DATA 	= 
 #customPrepPVSSDB.ctl
 
-sysconf_DATA		= ObservationControl.conf \
-					  ObservationControl.log_prop
+sysconf_DATA		= ObservationControl.log_prop
 
 %.log_prop: %.log_prop.in
 	cp $< $@
 
-%.conf: %.conf.in
-	cp $< $@
-
-%.ctl: %.ctl.in
-	cp $< $@
-
 clean-local:
 	rm -f *.ph
 
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
index 6cdb12527cb..cc9757446ee 100644
--- a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
@@ -32,6 +32,7 @@
 #include <APL/APLCommon/APL_Defines.h>
 #include <APL/APLCommon/APLCommonExceptions.h>
 #include <APL/APLCommon/Controller_Protocol.ph>
+#include <Deployment/StationInfo.h>
 
 #include "ObservationControl.h"
 #include "ObservationControlDefines.h"
@@ -59,15 +60,31 @@ ObservationControl::ObservationControl(const string&	cntlrName) :
 	itsParentControl	(0),
 	itsParentPort		(0),
 	itsTimerPort		(0),
-	itsState			(CTState::NOSTATE)
+	itsState			(CTState::NOSTATE),
+	itsClaimTimer		(0),
+	itsPrepareTimer		(0),
+	itsStartTimer		(0),
+	itsStopTimer		(0),
+	itsHeartBeat		(0)
 {
 	LOG_TRACE_OBJ_STR (cntlrName << " construction");
 
+	// First readin our observation related config file.
+	LOG_DEBUG_STR("Reading parset file:" << LOFAR_SHARE_LOCATION << "/" << cntlrName);
+	globalParameterSet()->adoptFile(string(LOFAR_SHARE_LOCATION)+"/"+cntlrName);
+
 	// Readin some parameters from the ParameterSet.
+	itsStartTime     = time_from_string(globalParameterSet()->
+											 getString("Observation.startTime"));
+	itsStopTime      = time_from_string(globalParameterSet()->
+											 getString("Observation.stopTime"));
+	itsClaimPeriod   = globalParameterSet()->getTime  ("Observation.claimPeriod");
+	itsPreparePeriod = globalParameterSet()->getTime  ("Observation.preparePeriod");
+
+	// My own parameters
 	itsTreePrefix = globalParameterSet()->getString("prefix");
-	itsInstanceNr = globalParameterSet()->getUint32(itsTreePrefix + ".instanceNr");
-	itsStartTime  = globalParameterSet()->getTime  (itsTreePrefix + ".starttime");
-	itsStopTime   = globalParameterSet()->getTime  (itsTreePrefix + ".stoptime");
+	itsInstanceNr = globalParameterSet()->getUint32("_instanceNr");
+	itsHeartBeat  = globalParameterSet()->getUint32("heartbeatInterval");
 
 	// attach to child control task
 	itsChildControl = ChildControl::instance();
@@ -115,11 +132,14 @@ void	ObservationControl::setState(CTState::CTstateNr		newState)
 {
 	itsState = newState;
 
+	CTState		cts;
+	LOG_DEBUG_STR(getName() << " now in state " << cts.name(newState));
+
 	if (itsPropertySet) {
-		CTState		cts;
 		itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),
-								 GCFPVString(cts.name(newState)));
+									 GCFPVString(cts.name(newState)));
 	}
+
 }
 
 
@@ -162,24 +182,40 @@ void ObservationControl::handlePropertySetAnswer(GCFEvent& answer)
 		// check which property changed
 		GCFPropValueEvent* pPropAnswer=static_cast<GCFPropValueEvent*>(&answer);
 
-		// TODO: implement something usefull.
-		// change of queueTime
-		if ((strstr(pPropAnswer->pPropName, OC_PROPSET_NAME) != 0) &&
-			(pPropAnswer->pValue->getType() == LPT_INTEGER)) {
-			uint32	newVal = (uint32) ((GCFPVInteger*)pPropAnswer->pValue)->getValue();
-#if 0
-			if (strstr(pPropAnswer->pPropName, PVSSNAME_MS_QUEUEPERIOD) != 0) {
-				LOG_INFO_STR ("Changing QueuePeriod from " << itsQueuePeriod <<
-							  " to " << newVal);
-				itsQueuePeriod = newVal;
-			}
-			else if (strstr(pPropAnswer->pPropName, PVSSNAME_MS_CLAIMPERIOD) != 0) {
+		string PropSetName = createPropertySetName(PSN_OBS_CTRL, getName());
+		if (strstr(pPropAnswer->pPropName, PropSetName.c_str()) == 0) {
+			break;
+		}
+
+		if	(pPropAnswer->pValue->getType() == LPT_INTEGER) {
+			uint32  newVal = (uint32) ((GCFPVInteger*)pPropAnswer->pValue)->getValue();
+
+			if (strstr(pPropAnswer->pPropName, PN_OC_CLAIM_PERIOD) != 0) {
 				LOG_INFO_STR ("Changing ClaimPeriod from " << itsClaimPeriod <<
 							  " to " << newVal);
 				itsClaimPeriod = newVal;
 			}
-#endif
+			else if (strstr(pPropAnswer->pPropName, PN_OC_PREPARE_PERIOD) != 0) {
+				LOG_INFO_STR ("Changing PreparePeriod from " << itsPreparePeriod <<
+							  " to " << newVal);
+				itsPreparePeriod = newVal;
+			}
 		}
+		else if	(pPropAnswer->pValue->getType() == LPT_STRING) {
+			string  newVal = (string) ((GCFPVString*)pPropAnswer->pValue)->getValue();
+			ptime	newTime = time_from_string(newVal);
+			if (strstr(pPropAnswer->pPropName, PN_OC_START_TIME) != 0) {
+				LOG_INFO_STR ("Changing startTime from " << to_simple_string(itsStartTime)
+							 << " to " << newVal);
+				itsStartTime = newTime;
+			}
+			else if (strstr(pPropAnswer->pPropName, PN_OC_STOP_TIME) != 0) {
+				LOG_INFO_STR ("Changing stopTime from " << to_simple_string(itsStopTime)
+							 << " to " << newVal);
+				itsStopTime = newTime;
+			}
+		}
+		setObservationTimers();
 		break;
 	}  
 
@@ -219,9 +255,9 @@ GCFEvent::TResult ObservationControl::initial_state(GCFEvent& event,
 	case F_ENTRY: {
 		// Get access to my own propertyset.
 		LOG_DEBUG ("Activating PropertySet");
-		string	propSetName = formatString(OC_PROPSET_NAME, itsInstanceNr);
+		string	propSetName(createPropertySetName(PSN_OBS_CTRL, getName()));
 		itsPropertySet = GCFMyPropertySetPtr(new GCFMyPropertySet(propSetName.c_str(),
-																  OC_PROPSET_TYPE,
+																  PST_OBS_CTRL,
 																  PS_CAT_TEMPORARY,
 																  &itsPropertySetAnswer));
 		itsPropertySet->enable();
@@ -279,9 +315,9 @@ GCFEvent::TResult ObservationControl::active_state(GCFEvent& event, GCFPortInter
 		break;
 
 	case F_ENTRY: {
-		// update PVSS
-		itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("active"));
-		itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString(""));
+		// convert times and periods to timersettings.
+		setObservationTimers();
+		itsHeartBeat = itsTimerPort->setTimer(1.0 * itsHeartBeat);
 		break;
 	}
 
@@ -296,9 +332,33 @@ GCFEvent::TResult ObservationControl::active_state(GCFEvent& event, GCFPortInter
 		_disconnectedHandler(port);
 		break;
 
-	case F_TIMER: 
-//		GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event);
+	case F_TIMER:  {
+		GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event);
+		if (timerEvent.id == itsClaimTimer) {
+			setState(CTState::CLAIM);
+			itsClaimTimer = 0;
+			// TODO: do something else?
+		}
+		else if (timerEvent.id == itsPrepareTimer) {
+			setState(CTState::PREPARE);
+			itsPrepareTimer = 0;
+			// TODO: do something else?
+		}
+		else if (timerEvent.id == itsStartTimer) {
+			setState(CTState::ACTIVE);
+			itsStartTimer = 0;
+			// TODO: do something else?
+		}
+		else if (timerEvent.id == itsStopTimer) {
+			setState(CTState::FINISH);
+			itsStopTimer = 0;
+			// TODO: do something else?
+		}
+		// some other timer;
+
 		break;
+	}
+	
 
 	// -------------------- EVENT RECEIVED FROM CHILD CONTROL --------------------
 	case CONTROL_STARTED: {
@@ -379,6 +439,68 @@ GCFEvent::TResult ObservationControl::active_state(GCFEvent& event, GCFPortInter
 	return (status);
 }
 
+//
+// setObservationTimers()
+//
+void ObservationControl::setObservationTimers()
+{
+	//   |                  |  claim   |    prepare   |       observation       |
+	//---+------------------+----------+--------------+-------------------------+-
+	//  now               Tclaim    Tprepare       Tstart                    Tstop
+
+	time_t	now   = to_time_t(second_clock::universal_time());
+	time_t	start = to_time_t(itsStartTime);
+	time_t	stop  = to_time_t(itsStopTime);
+	int32	sec2go;
+
+	// (re)set the claim timer
+	itsTimerPort->cancelTimer(itsClaimTimer);
+	if (itsState < CTState::CLAIM) { 				// claim state not done yet?
+		sec2go = start - now - itsPreparePeriod - itsClaimPeriod;
+		if (sec2go > 0) {
+			itsClaimTimer = itsTimerPort->setTimer(1.0 * sec2go);
+			LOG_DEBUG_STR ("Claimperiod starts over " << sec2go << " seconds");
+		}
+		else {
+			itsClaimTimer = itsTimerPort->setTimer(0.0);
+			LOG_DEBUG_STR ("Claimperiod started " << -sec2go << " seconds AGO!");
+		}
+	}
+		
+	// (re)set the prepare timer
+	itsTimerPort->cancelTimer(itsPrepareTimer);
+	if (itsState < CTState::PREPARE) { 				// prepare state not done yet?
+		sec2go = start - now - itsPreparePeriod;
+		if (sec2go > 0) {
+			itsPrepareTimer = itsTimerPort->setTimer(1.0 * sec2go);
+			LOG_DEBUG_STR ("PreparePeriod starts over " << sec2go << " seconds");
+		}
+		else {
+			itsPrepareTimer = itsTimerPort->setTimer(0.0);
+			LOG_DEBUG_STR ("PreparePeriod started " << -sec2go << " seconds AGO!");
+		}
+	}
+
+	// (re)set the start timer
+	itsTimerPort->cancelTimer(itsStartTimer);
+	if (itsState < CTState::ACTIVE) { 				// not yet active?
+		sec2go = start - now;
+		if (sec2go > 0) {
+			itsStartTimer = itsTimerPort->setTimer(1.0 * sec2go);
+			LOG_DEBUG_STR ("Observation starts over " << sec2go << " seconds");
+		}
+		else {
+			itsStartTimer = itsTimerPort->setTimer(0.0);
+			LOG_DEBUG_STR ("Observation started " << -sec2go << " seconds AGO!");
+		}
+	}
+
+	// always set stoptimer to new value (if stop was reached we would be dead).
+	itsTimerPort->cancelTimer(itsStopTimer);
+	itsStopTimer = itsTimerPort->setTimer(1.0 * stop - now);
+	LOG_DEBUG_STR ("Observation ends over " << (stop-now)/60 << " minutes");
+}
+
 
 //
 // _connectedHandler(port)
@@ -387,6 +509,7 @@ void ObservationControl::_connectedHandler(GCFPortInterface& port)
 {
 }
 
+
 //
 // _disconnectedHandler(port)
 //
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.example b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.example
new file mode 100644
index 00000000000..211431eefec
--- /dev/null
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.example
@@ -0,0 +1,30 @@
+# modulename=ObsCtrl
+# pathname=LOFAR.ObsSW.Observation.ObsCtrl.
+# treeID=9
+Observation.MSName=/data2/ObservationA.MS
+Observation.ObsCtrl.heartbeatInterval=10
+Observation.VirtualInstrument.BGLNodeList=[BGL001,BGL002,BGL003]
+Observation.VirtualInstrument.imageNodeList=[IMG005,IMG002,IMG003]
+Observation.VirtualInstrument.inputNodeList=[INP002,INP003,INP004,INP005]
+Observation.VirtualInstrument.stationList=[CS001,CS002,CS003]
+Observation.VirtualInstrument.storageCapacity=760
+Observation.VirtualInstrument.storageNodeList=[STOR005,STOR006]
+Observation.channelsPerSubband=256
+Observation.claimPeriod=0
+Observation.clockMode=<<Clock160
+Observation.nyguistZone=0
+Observation.nyquistZone=0
+Observation.preparePeriod=0
+Observation.sampleClock=160
+Observation.startTime=0
+Observation.stopTime=0
+Observation.subbandList=[0]
+_instanceNr=0
+_treeID=9
+heartbeatInterval=10
+prefix=LOFAR.ObsSW.Observation.ObsCtrl.
+
+# next parameters are optional, defaultvalues are shown
+#ChildControl.StartupRetryInterval = 10s
+#ChildControl.MaxStartupRetry	   = 5
+
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in
deleted file mode 100644
index a92957c18ce..00000000000
--- a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in
+++ /dev/null
@@ -1,11 +0,0 @@
-# new setup
-prefix	=	Observation0
-
-Observation0.instanceNr = 0
-Observation0.starttime	= 0
-Observation0.stoptime	= 1
-
-# next parameters are optional, defaultvalues are shown
-#ChildControl.StartupRetryInterval = 10s
-#ChildControl.MaxStartupRetry	   = 5
-
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h
index e2c00591382..b91c4af3b49 100644
--- a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h
@@ -48,6 +48,7 @@
 #include <Common/lofar_string.h>
 #include <Common/lofar_vector.h>
 #include <Common/LofarLogger.h>
+#include <Common/lofar_datetime.h>
 
 //# ACC Includes
 #include <APS/ParameterSet.h>
@@ -92,8 +93,10 @@ private:
    	ObservationControl& operator=(const ObservationControl&);
 
 	void setState(CTState::CTstateNr	newState);
-   	void _connectedHandler(GCFPortInterface& port);
-   	void _disconnectedHandler(GCFPortInterface& port);
+
+	void	setObservationTimers();
+   	void 	_connectedHandler(GCFPortInterface& port);
+   	void	_disconnectedHandler(GCFPortInterface& port);
    	boost::shared_ptr<ACC::APS::ParameterSet> 
 		 readObservationParameters (APLCommon::OTDBtreeIDType	ObsTreeID);
 
@@ -126,12 +129,21 @@ private:
 	GCFTimerPort*			itsTimerPort;
 
 	CTState::CTstateNr		itsState;
+	
+	// timers for the several stages.
+	uint32					itsClaimTimer;
+	uint32					itsPrepareTimer;
+	uint32					itsStartTimer;
+	uint32					itsStopTimer;
+	uint32					itsHeartBeat;
 
 	// ParameterSet variables
 	string					itsTreePrefix;
 	uint32					itsInstanceNr;
-	time_t					itsStartTime;
-	time_t					itsStopTime;
+	uint32					itsClaimPeriod;
+	uint32					itsPreparePeriod;
+	ptime					itsStartTime;
+	ptime					itsStopTime;
 };
 
   };//MainCU
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.log_prop.in b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.log_prop.in
index c8bd123789e..e671bccda67 100644
--- a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.log_prop.in
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.log_prop.in
@@ -3,7 +3,7 @@
 
 log4cplus.rootLogger=DEBUG, STDOUT, FILE
 
-log4cplus.logger.TRC=TRACE2
+log4cplus.logger.TRC=TRACE3
 log4cplus.additivity.TRC=FALSE
 
 log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControlDefines.h b/MAC/APL/MainCU/src/ObservationControl/ObservationControlDefines.h
index 1944eb625d3..da8fb5bccfb 100644
--- a/MAC/APL/MainCU/src/ObservationControl/ObservationControlDefines.h
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControlDefines.h
@@ -27,11 +27,17 @@ namespace LOFAR {
   namespace MCU {
 
 #define OC_TASKNAME					"ObsCtrl"
-
-#define OC_PROPSET_NAME				"LOFAR_ObsSW_ObsCtrl%d"
-#define OC_PROPSET_TYPE				"ObsCtrl"
 #define OC_OBSERVATIONSTATE			"observationState"
 
+// ObsCtrl
+#define PSN_OBS_CTRL    "LOFAR_ObsSW_@observation@_ObsCtrl"
+#define PST_OBS_CTRL    "ObsCtrl"
+#define PN_OC_CLAIM_PERIOD  "claimPeriod"
+#define PN_OC_PREPARE_PERIOD    "preparePeriod"
+#define PN_OC_START_TIME    "startTime"
+#define PN_OC_STOP_TIME "stopTime"
+
+
 // next lines should be defined somewhere in Common.
 #define PVSSNAME_FSM_STATE			"state"
 #define PVSSNAME_FSM_ERROR			"error"
-- 
GitLab