Skip to content
Snippets Groups Projects
Commit 25f53137 authored by Ruud Overeem's avatar Ruud Overeem
Browse files

Bug 1189: MacScheduler now uses ClaimManager and produces three observation-lists:

planned-, active- and finished-obervations.
Not fully tested yet.
parent 591a6c90
No related branches found
No related tags found
No related merge requests found
...@@ -62,6 +62,7 @@ lofar_INTERNAL(MAC/MACIO, MACIO, , 1, MACIO/MACServiceInfo.h,,) ...@@ -62,6 +62,7 @@ lofar_INTERNAL(MAC/MACIO, MACIO, , 1, MACIO/MACServiceInfo.h,,)
lofar_INTERNAL(MAC/GCF/TM, GCFTM, , 1, GCF/TM/GCF_Task.h,,) lofar_INTERNAL(MAC/GCF/TM, GCFTM, , 1, GCF/TM/GCF_Task.h,,)
lofar_INTERNAL(MAC/GCF/RTDB, GCFRTDB, , 1, GCF/RTDB/RTDB_PropertySet.h,,) lofar_INTERNAL(MAC/GCF/RTDB, GCFRTDB, , 1, GCF/RTDB/RTDB_PropertySet.h,,)
lofar_INTERNAL(MAC/APL/APLCommon, APLCommon, , 1, APL/APLCommon/APL_Defines.h,,) lofar_INTERNAL(MAC/APL/APLCommon, APLCommon, , 1, APL/APLCommon/APL_Defines.h,,)
lofar_INTERNAL(MAC/APL/RTDBCommon, RTDBCommon, , 1, APL/RTDBCommon/RTDButilities.h,,)
lofar_INTERNAL(Appl/ApplCommon, ApplCommon, , 1, ApplCommon/Observation.h,,) lofar_INTERNAL(Appl/ApplCommon, ApplCommon, , 1, ApplCommon/Observation.h,,)
lofar_EXTERNAL(boost,1,boost/date_time/date.hpp, boost_date_time) lofar_EXTERNAL(boost,1,boost/date_time/date.hpp, boost_date_time)
lofar_EXTERNAL(pqxx,2.5.5,pqxx/pqxx, pqxx) lofar_EXTERNAL(pqxx,2.5.5,pqxx/pqxx, pqxx)
......
//# MACScheduler.cc: Implementation of the MAC Scheduler task //# MACScheduler.cc: Implementation of the MAC Scheduler task
//# //#
//# Copyright (C) 2002-2004 //# Copyright (C) 2004-2008
//# ASTRON (Netherlands Foundation for Research in Astronomy) //# ASTRON (Netherlands Foundation for Research in Astronomy)
//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl //# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
//# //#
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <lofar_config.h> #include <lofar_config.h>
#include <Common/LofarLogger.h> #include <Common/LofarLogger.h>
#include <Common/SystemUtil.h> #include <Common/SystemUtil.h>
#include <Common/StringUtil.h>
#include <Common/Version.h> #include <Common/Version.h>
#include <APS/ParameterSet.h> #include <APS/ParameterSet.h>
...@@ -33,6 +34,7 @@ ...@@ -33,6 +34,7 @@
#include <APL/APLCommon/StationInfo.h> #include <APL/APLCommon/StationInfo.h>
#include <APL/APLCommon/Controller_Protocol.ph> #include <APL/APLCommon/Controller_Protocol.ph>
#include <GCF/RTDB/DP_Protocol.ph> #include <GCF/RTDB/DP_Protocol.ph>
#include <APL/RTDBCommon/CM_Protocol.ph>
#include <OTDB/TreeStateConv.h> #include <OTDB/TreeStateConv.h>
#include <signal.h> #include <signal.h>
...@@ -59,27 +61,32 @@ static MACScheduler* pMacScheduler = 0; ...@@ -59,27 +61,32 @@ static MACScheduler* pMacScheduler = 0;
// MACScheduler() // MACScheduler()
// //
MACScheduler::MACScheduler() : MACScheduler::MACScheduler() :
GCFTask ((State)&MACScheduler::initial_state,string(MS_TASKNAME)), GCFTask ((State)&MACScheduler::initial_state,string("MACScheduler")),
itsPropertySet (0), itsPropertySet (0),
itsObservations (),
itsPVSSObsList (),
itsTimerPort (0),
itsChildControl (0), itsChildControl (0),
itsChildPort (0), itsChildPort (0),
itsClaimerTask (0),
itsClaimerPort (0),
itsTimerPort (0),
itsSecondTimer (0), itsSecondTimer (0),
itsQueuePeriod (0), itsNextPlannedTime (0),
itsClaimPeriod (0), itsNextActiveTime (0),
itsOTDBconnection (0), itsNextFinishedTime (0),
itsOTDBpollInterval (0), itsOTDBconnection (0)
itsNextOTDBpolltime (0)
{ {
LOG_TRACE_OBJ ("MACscheduler construction"); LOG_TRACE_OBJ ("MACscheduler construction");
LOG_INFO_STR("MACProcessScope: " << globalParameterSet()->getString("prefix")); LOG_INFO_STR("MACProcessScope: " << PSN_MAC_SCHEDULER);
LOG_INFO(Version::getInfo<MainCUVersion>("MACScheduler")); LOG_INFO(Version::getInfo<MainCUVersion>("MACScheduler"));
// Readin some parameters from the ParameterSet. // Read timersettings from the ParameterSet
itsOTDBpollInterval = globalParameterSet()->getTime("OTDBpollInterval"); itsPlannedItv = globalParameterSet()->getTime("pollIntervalPlanned", 60);
itsActiveItv = globalParameterSet()->getTime("pollIntervalExecute", 5);
itsFinishedItv = globalParameterSet()->getTime("pollIntervalFinished", 60);
itsPlannedPeriod = globalParameterSet()->getTime("plannedPeriod", 86400) / 60; // in minutes
itsFinishedPeriod= globalParameterSet()->getTime("finishedPeriod", 86400) / 60; // in minutes
// Read the schedule periods for starting observations.
itsQueuePeriod = globalParameterSet()->getTime("QueuePeriod"); itsQueuePeriod = globalParameterSet()->getTime("QueuePeriod");
itsClaimPeriod = globalParameterSet()->getTime("ClaimPeriod"); itsClaimPeriod = globalParameterSet()->getTime("ClaimPeriod");
...@@ -90,13 +97,17 @@ MACScheduler::MACScheduler() : ...@@ -90,13 +97,17 @@ MACScheduler::MACScheduler() :
ASSERTSTR(itsChildPort, "Cannot allocate ITCport for childcontrol"); ASSERTSTR(itsChildPort, "Cannot allocate ITCport for childcontrol");
itsChildPort->open(); // will result in F_CONNECTED itsChildPort->open(); // will result in F_CONNECTED
// create an PVSSprepare Task
itsClaimerTask = new ObsClaimer(this);
ASSERTSTR(itsClaimerTask, "Cannot construct a ObsClaimerTask");
itsClaimerPort = new GCFITCPort (*this, *itsClaimerTask, "ObsClaimerPort",
GCFPortInterface::SAP, CM_PROTOCOL);
// need port for timers // need port for timers
itsTimerPort = new GCFTimerPort(*this, "Timerport"); itsTimerPort = new GCFTimerPort(*this, "Timerport");
itsObservations.reserve(10); // already reserve memory for 10 observations.
registerProtocol(CONTROLLER_PROTOCOL, CONTROLLER_PROTOCOL_STRINGS); registerProtocol(CONTROLLER_PROTOCOL, CONTROLLER_PROTOCOL_STRINGS);
registerProtocol(DP_PROTOCOL, DP_PROTOCOL_STRINGS); registerProtocol(DP_PROTOCOL, DP_PROTOCOL_STRINGS);
} }
...@@ -135,12 +146,13 @@ void MACScheduler::sigintHandler(int signum) ...@@ -135,12 +146,13 @@ void MACScheduler::sigintHandler(int signum)
void MACScheduler::_databaseEventHandler(GCFEvent& event) void MACScheduler::_databaseEventHandler(GCFEvent& event)
{ {
LOG_DEBUG_STR ("_databaseEventHandler:" << eventName(event)); // LOG_DEBUG_STR ("_databaseEventHandler:" << eventName(event));
switch(event.signal) { switch(event.signal) {
case DP_CHANGED: { case DP_CHANGED: {
DPChangedEvent dpEvent(event); DPChangedEvent dpEvent(event);
#if 0
// TODO: implement something usefull. // TODO: implement something usefull.
if (strstr(dpEvent.DPname.c_str(), PVSSNAME_MS_QUEUEPERIOD) != 0) { if (strstr(dpEvent.DPname.c_str(), PVSSNAME_MS_QUEUEPERIOD) != 0) {
uint32 newVal = ((GCFPVUnsigned*) (dpEvent.value._pValue))->getValue(); uint32 newVal = ((GCFPVUnsigned*) (dpEvent.value._pValue))->getValue();
...@@ -152,6 +164,7 @@ void MACScheduler::_databaseEventHandler(GCFEvent& event) ...@@ -152,6 +164,7 @@ void MACScheduler::_databaseEventHandler(GCFEvent& event)
LOG_INFO_STR ("Changing ClaimPeriod from " << itsClaimPeriod << " to " << newVal); LOG_INFO_STR ("Changing ClaimPeriod from " << itsClaimPeriod << " to " << newVal);
itsClaimPeriod = newVal; itsClaimPeriod = newVal;
} }
#endif
} }
break; break;
...@@ -199,12 +212,15 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& ...@@ -199,12 +212,15 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface&
case F_TIMER: { // must be timer that PropSet is enabled. case F_TIMER: { // must be timer that PropSet is enabled.
// update PVSS. // update PVSS.
LOG_TRACE_FLOW ("Updateing state to PVSS"); LOG_TRACE_FLOW ("Updateing state to PVSS");
itsPropertySet->setValue(PVSSNAME_FSM_CURACT, GCFPVString ("initial")); itsPropertySet->setValue(PN_FSM_CURRENT_ACTION, GCFPVString ("initial"));
itsPropertySet->setValue(PVSSNAME_FSM_ERROR, GCFPVString ("")); itsPropertySet->setValue(PN_FSM_ERROR, GCFPVString (""));
itsPropertySet->setValue(PN_MS_OTDB_CONNECTED, GCFPVBool (false)); itsPropertySet->setValue(PN_MS_OTDB_CONNECTED, GCFPVBool (false));
itsPropertySet->setValue(PN_MS_OTDB_LAST_POLL, GCFPVString ("")); itsPropertySet->setValue(PN_MS_OTDB_LAST_POLL, GCFPVString (""));
itsPropertySet->setValue(PN_MS_OTDB_POLLINTERVAL, GCFPVInteger (itsOTDBpollInterval)); itsPropertySet->setValue(PN_MS_OTDB_POLLINTERVAL, GCFPVInteger (itsActiveItv));
itsPropertySet->setValue(PN_MS_ACTIVE_OBSERVATIONS, GCFPVDynArr(LPT_STRING, itsPVSSObsList)); GCFPValueArray emptyArr;
itsPropertySet->setValue(PN_MS_ACTIVE_OBSERVATIONS, GCFPVDynArr(LPT_STRING, emptyArr));
itsPropertySet->setValue(PN_MS_PLANNED_OBSERVATIONS, GCFPVDynArr(LPT_STRING, emptyArr));
itsPropertySet->setValue(PN_MS_FINISHED_OBSERVATIONS, GCFPVDynArr(LPT_STRING, emptyArr));
// Try to connect to the SAS database. // Try to connect to the SAS database.
...@@ -228,6 +244,11 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& ...@@ -228,6 +244,11 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface&
itsChildControl->openService(MAC_SVCMASK_SCHEDULERCTRL, 0); itsChildControl->openService(MAC_SVCMASK_SCHEDULERCTRL, 0);
itsChildControl->registerCompletionPort(itsChildPort); itsChildControl->registerCompletionPort(itsChildPort);
// setup initial schedule: first planned, next run active, second run finished
itsNextPlannedTime = time(0);
itsNextActiveTime = itsNextPlannedTime + itsPlannedItv;
itsNextFinishedTime = itsNextPlannedTime + 2*itsPlannedItv;
TRAN(MACScheduler::recover_state); // go to next state. TRAN(MACScheduler::recover_state); // go to next state.
} }
break; break;
...@@ -265,8 +286,8 @@ GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface& ...@@ -265,8 +286,8 @@ GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface&
case F_ENTRY: { case F_ENTRY: {
// update PVSS // update PVSS
itsPropertySet->setValue(string(PVSSNAME_FSM_CURACT),GCFPVString("recover")); itsPropertySet->setValue(string(PN_FSM_CURRENT_ACTION),GCFPVString("recover"));
itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); itsPropertySet->setValue(string(PN_FSM_ERROR),GCFPVString(""));
// //
// TODO: do recovery // TODO: do recovery
...@@ -287,7 +308,7 @@ GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface& ...@@ -287,7 +308,7 @@ GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface&
// //
// active_state(event, port) // active_state(event, port)
// //
// Normal operation state. Check OTDB every OTDBpollInterval seconds and control // Normal operation state. Check OTDB every itsActiveItv seconds and control
// the running observations. // the running observations.
// //
GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& port) GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& port)
...@@ -308,10 +329,10 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& ...@@ -308,10 +329,10 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface&
signal (SIGTERM, MACScheduler::sigintHandler); // kill signal (SIGTERM, MACScheduler::sigintHandler); // kill
// update PVSS // update PVSS
itsPropertySet->setValue(string(PVSSNAME_FSM_CURACT),GCFPVString("active")); itsPropertySet->setValue(string(PN_FSM_CURRENT_ACTION),GCFPVString("active"));
itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); itsPropertySet->setValue(string(PN_FSM_ERROR),GCFPVString(""));
// Timers must be connected to ports, so abuse serverPort for second timer. // Start heartbeat timer.
itsSecondTimer = itsTimerPort->setTimer(1L); itsSecondTimer = itsTimerPort->setTimer(1L);
break; break;
} }
...@@ -335,16 +356,31 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& ...@@ -335,16 +356,31 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface&
_databaseEventHandler(event); _databaseEventHandler(event);
break; break;
case CM_CLAIM_RESULT: {
// some observation was claimed by the claimMgr. Update our prepare_list.
CMClaimResultEvent cmEvent(event);
LOG_INFO_STR(cmEvent.nameInAppl << " is mapped to " << cmEvent.DPname);
ltrim(cmEvent.nameInAppl, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_");
int obsID = atoi(cmEvent.nameInAppl.c_str());
LOG_DEBUG_STR("PVSS preparation of observation " << obsID << " ready.");
itsPreparedObs[obsID] = true;
}
break;
case F_TIMER: { // secondTimer or reconnectTimer. case F_TIMER: { // secondTimer or reconnectTimer.
GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event); GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event);
if (timerEvent.id == itsSecondTimer) { if (timerEvent.id == itsSecondTimer) {
// time to poll the OTDB? // time to poll the OTDB?
if (time(0) >= itsNextOTDBpolltime) { // Note: We assume here that the PlannedItv is smaller than the ActiveItv and the FinishedItv.
// When it is not smaller (very unlikely) than the ActiveItv and FinishedItv those two
// intervals will default to the PlannedItv.
if (time(0) >= itsNextPlannedTime) { // check shortest interval
_doOTDBcheck(); _doOTDBcheck();
// reinit polltime at multiple of intervaltime. // reinit polltime at multiple of intervaltime.
// (=more change to hit hh.mm:00) // (=more change to hit hh.mm:00)
itsNextOTDBpolltime = time(0) + itsOTDBpollInterval; itsNextPlannedTime = time(0) + itsPlannedItv;
itsNextOTDBpolltime -= (itsNextOTDBpolltime % itsOTDBpollInterval); itsNextPlannedTime -= (itsNextPlannedTime % itsPlannedItv);
} }
port.cancelTimer(itsSecondTimer); port.cancelTimer(itsSecondTimer);
itsSecondTimer = port.setTimer(1.0); itsSecondTimer = port.setTimer(1.0);
...@@ -359,7 +395,10 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& ...@@ -359,7 +395,10 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface&
} }
// -------------------- EVENTS FROM CHILDCONTROL -------------------- // -------------------- EVENTS FROM CHILDCONTROL --------------------
//
// That must be events from the ObservationControllers that are currently
// started or running.
//
case CONTROL_STARTED: { case CONTROL_STARTED: {
// Child control received a message from the startDaemon that the // Child control received a message from the startDaemon that the
// observationController was started (or not) // observationController was started (or not)
...@@ -367,30 +406,13 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& ...@@ -367,30 +406,13 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface&
if (msg.successful) { if (msg.successful) {
LOG_DEBUG_STR("Start of " << msg.cntlrName << LOG_DEBUG_STR("Start of " << msg.cntlrName <<
" was successful, waiting for connection."); " was successful, waiting for connection.");
#if 0
// TODO: this code became obsolete because the Obscontroller now sends
// CONTROL_CONNECTED events.
// ---
// Ok, controller is really up, update SAS so that obs will not appear in
// in the SAS list again.
Observation* theObs(_findActiveObservation(msg.cntlrName));
if (!theObs) {
LOG_WARN_STR("Cannot find controller " << msg.cntlrName <<
". Can't update the SAS database");
break;
}
OTDB::TreeMaintenance tm(itsOTDBconnection);
TreeStateConv tsc(itsOTDBconnection);
tm.setTreeState(theObs->obsID, tsc.get("queued"));
// ---
#endif
} }
else { else {
LOG_ERROR_STR("Observation controller " << msg.cntlrName << LOG_ERROR_STR("Observation controller " << msg.cntlrName <<
" could not be started"); " could not be started");
LOG_INFO_STR("Observation is be removed from administration, " << LOG_INFO_STR("Observation is be removed from administration, " <<
"restart will occur in next cycle"); "restart will occur in next cycle");
_removeActiveObservation(msg.cntlrName); itsControllerMap.erase(msg.cntlrName);
} }
break; break;
} }
...@@ -402,15 +424,15 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& ...@@ -402,15 +424,15 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface&
// Ok, controller is really up, update SAS so that obs will not appear in // Ok, controller is really up, update SAS so that obs will not appear in
// in the SAS list again. // in the SAS list again.
Observation* theObs(_findActiveObservation(conEvent.cntlrName)); CMiter theObs(itsControllerMap.find(conEvent.cntlrName));
if (!theObs) { if (theObs == itsControllerMap.end()) {
LOG_WARN_STR("Cannot find controller " << conEvent.cntlrName << LOG_WARN_STR("Cannot find controller " << conEvent.cntlrName <<
". Can't update the SAS database"); ". Can't update the SAS database");
break; break;
} }
OTDB::TreeMaintenance tm(itsOTDBconnection); OTDB::TreeMaintenance tm(itsOTDBconnection);
TreeStateConv tsc(itsOTDBconnection); TreeStateConv tsc(itsOTDBconnection);
tm.setTreeState(theObs->obsID, tsc.get("queued")); tm.setTreeState(theObs->second, tsc.get("queued"));
break; break;
} }
...@@ -420,8 +442,8 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& ...@@ -420,8 +442,8 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface&
LOG_DEBUG_STR("Received QUITED(" << quitedEvent.cntlrName << "," << quitedEvent.result << ")"); LOG_DEBUG_STR("Received QUITED(" << quitedEvent.cntlrName << "," << quitedEvent.result << ")");
// update SAS database. // update SAS database.
Observation* theObs(_findActiveObservation(quitedEvent.cntlrName)); CMiter theObs(itsControllerMap.find(quitedEvent.cntlrName));
if (!theObs) { if (theObs == itsControllerMap.end()) {
LOG_WARN_STR("Cannot find controller " << quitedEvent.cntlrName << LOG_WARN_STR("Cannot find controller " << quitedEvent.cntlrName <<
". Can't update the SAS database"); ". Can't update the SAS database");
break; break;
...@@ -429,31 +451,31 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& ...@@ -429,31 +451,31 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface&
OTDB::TreeMaintenance tm(itsOTDBconnection); OTDB::TreeMaintenance tm(itsOTDBconnection);
TreeStateConv tsc(itsOTDBconnection); TreeStateConv tsc(itsOTDBconnection);
if (quitedEvent.result == CT_RESULT_NO_ERROR) { if (quitedEvent.result == CT_RESULT_NO_ERROR) {
tm.setTreeState(theObs->obsID, tsc.get("finished")); tm.setTreeState(theObs->second, tsc.get("finished"));
} }
else { else {
tm.setTreeState(theObs->obsID, tsc.get("aborted")); tm.setTreeState(theObs->second, tsc.get("aborted"));
} }
// update our administration // update our administration
LOG_DEBUG_STR("Removing observation " << quitedEvent.cntlrName << LOG_DEBUG_STR("Removing observation " << quitedEvent.cntlrName <<
" from activeList"); " from activeList");
_removeActiveObservation(quitedEvent.cntlrName); // _removeActiveObservation(quitedEvent.cntlrName);
break; break;
} }
case CONTROL_RESUMED: { case CONTROL_RESUMED: {
// update SAS database. // update SAS database.
CONTROLResumedEvent msg(event); CONTROLResumedEvent msg(event);
Observation* theObs(_findActiveObservation(msg.cntlrName)); CMiter theObs(itsControllerMap.find(msg.cntlrName));
if (!theObs) { if (theObs == itsControllerMap.end()) {
LOG_WARN_STR("Cannot find controller " << msg.cntlrName << LOG_WARN_STR("Cannot find controller " << msg.cntlrName <<
". Can't update the SAS database"); ". Can't update the SAS database");
break; break;
} }
OTDB::TreeMaintenance tm(itsOTDBconnection); OTDB::TreeMaintenance tm(itsOTDBconnection);
TreeStateConv tsc(itsOTDBconnection); TreeStateConv tsc(itsOTDBconnection);
tm.setTreeState(theObs->obsID, tsc.get("active")); tm.setTreeState(theObs->second, tsc.get("active"));
} }
// NOTE: ignore all other CONTROL events, we are not interested in the // NOTE: ignore all other CONTROL events, we are not interested in the
...@@ -485,9 +507,9 @@ GCFEvent::TResult MACScheduler::finishing_state(GCFEvent& event, GCFPortInterfac ...@@ -485,9 +507,9 @@ GCFEvent::TResult MACScheduler::finishing_state(GCFEvent& event, GCFPortInterfac
case F_ENTRY: { case F_ENTRY: {
// update PVSS // update PVSS
itsPropertySet->setValue(string(PVSSNAME_FSM_CURACT),GCFPVString("finished")); itsPropertySet->setValue(PN_FSM_CURRENT_ACTION, GCFPVString("finished"));
itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR), GCFPVString("")); itsPropertySet->setValue(PN_FSM_ERROR, GCFPVString(""));
itsPropertySet->setValue(PN_MS_OTDB_CONNECTED, GCFPVBool (false)); itsPropertySet->setValue(PN_MS_OTDB_CONNECTED, GCFPVBool (false));
itsTimerPort->setTimer(1L); itsTimerPort->setTimer(1L);
break; break;
...@@ -524,190 +546,173 @@ void MACScheduler::finish() ...@@ -524,190 +546,173 @@ void MACScheduler::finish()
void MACScheduler::_doOTDBcheck() void MACScheduler::_doOTDBcheck()
{ {
// update PVSS database with polltime // update PVSS database with polltime
ptime currentTime = from_time_t(time(0)); time_t now = time(0);
itsPropertySet->setValue(string(PN_MS_OTDB_LAST_POLL), ptime currentTime = from_time_t(now);
GCFPVString(to_simple_string(currentTime))); itsPropertySet->setValue(string(PN_MS_OTDB_LAST_POLL), GCFPVString(to_simple_string(currentTime)));
// always update planned list because we might need to start some of those
// (and we assumed that the PlannedItv was the smallest)
_updatePlannedList();
// update active lists when its time to do so.
if (now >= itsNextActiveTime) {
_updateActiveList();
while (itsNextActiveTime <= now) {
itsNextActiveTime += itsActiveItv;
}
}
// update finished lists when its time to do so.
if (now >= itsNextFinishedTime) {
_updateFinishedList();
while (itsNextFinishedTime <= now) {
itsNextFinishedTime += itsFinishedItv;
}
}
}
//
// _updatePlannedList()
//
void MACScheduler::_updatePlannedList()
{
LOG_DEBUG("_updatePlannedList()");
// get new list (list is ordered on starttime) // get new list (list is ordered on starttime)
vector<OTDBtree> newTreeList = itsOTDBconnection->getExecutableTrees(); vector<OTDBtree> plannedDBlist = itsOTDBconnection->getTreeGroup(1, itsPlannedPeriod); // planned observations
if (newTreeList.empty()) { if (plannedDBlist.empty()) {
return; return;
} }
LOG_DEBUG(formatString("OTDBCheck:First observation is at %s (tree=%d)", LOG_DEBUG(formatString("OTDBCheck:First planned observation is at %s (tree=%d)",
to_simple_string(newTreeList[0].starttime).c_str(), newTreeList[0].treeID())); to_simple_string(plannedDBlist[0].starttime).c_str(), plannedDBlist[0].treeID()));
// walk through the list and bring each observation in the right state when necc. // walk through the list, prepare PVSS for the new obs, update own admin lists.
uint32 listSize = newTreeList.size(); GCFPValueArray plannedArr;
uint32 idx = 0; uint32 listSize = plannedDBlist.size();
uint32 idx = 0;
time_t now = time(0);
ptime currentTime = from_time_t(now);
ASSERTSTR (currentTime != not_a_date_time, "Can't determine systemtime, bailing out"); ASSERTSTR (currentTime != not_a_date_time, "Can't determine systemtime, bailing out");
while (idx < listSize) { while (idx < listSize) {
// timediff = time to go before start of Observation // construct name and timings info for observation
time_duration timediff = newTreeList[idx].starttime - currentTime; treeIDType obsID = plannedDBlist[idx].treeID();
LOG_TRACE_VAR_STR("timediff=" << timediff); string obsName(formatString("Observation_%d", obsID));
// when queuetime is not reached yet we are finished with the list. // must we claim this observation at the claimMgr?
if (timediff > seconds(itsQueuePeriod)) { OLiter prepIter = itsPreparedObs.find(obsID);
break; if ((prepIter == itsPreparedObs.end()) || (prepIter->second == false)) {
} // create a ParameterFile for this Observation
TreeMaintenance tm(itsOTDBconnection);
// note: as soon as observation is up it will not show up anymore in the OTDBnode topNode = tm.getTopNode(obsID);
// SAS list because we changed the state. string filename(formatString("%s/Observation_%d", LOFAR_SHARE_LOCATION, obsID));
// If startup is in progress, it is in the SAS list but also in our admin. if (!tm.exportTree(obsID, topNode.nodeID(), filename)) {
string cntlrName = controllerName(CNTLRTYPE_OBSERVATIONCTRL, LOG_ERROR_STR ("Cannot create ParameterSet '" << filename <<
0, newTreeList[idx].treeID()); "' for new observatio. Observation CANNOT BE STARTED!");
if (_findActiveObservation(cntlrName)) { }
LOG_DEBUG_STR("Skipping " << cntlrName); else {
idx++; // Claim a DP in PVSS and write obssettings to it so the operator can see it.
continue; LOG_DEBUG_STR("Requesting preparation of PVSS for " << obsName);
itsClaimerTask->prepareObservation(obsName);
itsPreparedObs[obsID] = false; // requested claim but no answer yet.
}
} }
// get current state of Observation // always add to PVSS list.
// CTState cts; plannedArr.push_back(new GCFPVString(obsName));
// CTState::CTstateNr curState = itsChildControl->getCurrentState(cntlrName);
// LOG_DEBUG_STR(cntlrName << ":cur=" << cts.name(curState)); // should this observation (have) be(en) started?
time_duration timeBeforeStart(plannedDBlist[idx].starttime - currentTime);
// When in startup or claimtime we should try to start the controller. // LOG_TRACE_VAR_STR(obsName << " starts over " << timeBeforeStart << " seconds");
// if ((timediff > seconds(0)) && (curState < CTState::CREATED)) { if (timeBeforeStart > seconds(0) && timeBeforeStart <= seconds(itsQueuePeriod)) {
if (itsPreparedObs[obsID] == false) {
// Obs is unknown so try to start it up as long as we didn't reach its starttime. LOG_ERROR_STR("Observation " << obsID << " must be started but is not claimed yet.");
if (timediff > seconds(0)) {
// Let database construct the parset for the whole observation
OTDB::TreeMaintenance tm(itsOTDBconnection);
OTDB::treeIDType obsID = newTreeList[idx].treeID();
OTDBnode topNode = tm.getTopNode(obsID);
// NOTE: this name must be the same as in the ChildControl.
string filename = formatString("%s/Observation_%d",
LOFAR_SHARE_LOCATION, obsID);
if (!tm.exportTree(obsID, topNode.nodeID(), filename)) {
LOG_ERROR_STR ("Cannot create parset file " << filename <<
" for new observation. Observation CANNOT BE STARTED!");
} }
else { else {
// fire request for new controller, will result in CONTROL_STARTED // starttime of observation lays in queuePeriod. Start the controller-chain,
// this will result in CONTROL_STARTED event in our main task
// Note: as soon as the ObservationController has reported itself to the MACScheduler
// the observation will not be returned in the 'plannedDBlist' anymore.
LOG_DEBUG_STR("Requesting start of " << obsName);
itsChildControl->startChild(CNTLRTYPE_OBSERVATIONCTRL, itsChildControl->startChild(CNTLRTYPE_OBSERVATIONCTRL,
obsID, plannedDBlist[idx].treeID(),
0, // instanceNr 0, // instanceNr
myHostname(true)); myHostname(true));
// Note: controller is now in state NO_STATE/CONNECTED (C/R) // Note: controller is now in state NO_STATE/CONNECTED (C/R)
// register this Observation
ParameterSet obsPS(filename);
Observation newObs(&obsPS);
newObs.name = cntlrName;
newObs.obsID = obsID;
_addActiveObservation(newObs);
LOG_DEBUG_STR("Observation " << cntlrName << " added to active Observations");
} }
// TODO: due to problems with the PA we only start one obs every cycle.
break;
// idx++;
// continue;
} }
idx++;
} // while processing all planned obs'
#if 0 // Finally we can pass the list with planned observations to PVSS.
// in CLAIM period? itsPropertySet->setValue(PN_MS_PLANNED_OBSERVATIONS, GCFPVDynArr(LPT_DYNSTRING, plannedArr));
if ((timediff > seconds(0)) && (timediff <= seconds(itsClaimPeriod))) {
// Observation is somewhere in the claim period its should be up by now.
if (curState < CTState::CLAIMED) {
LOG_ERROR_STR("Observation " << cntlrName <<
" should have reached the CLAIMING state by now," <<
" check state of observation.");
LOG_DEBUG_STR("Its state is: " << cts.name(curState));
}
idx++;
continue;
}
// observation must be running (otherwise it would not be in the newTreeList)
// TODO: check if endtime is reached and observation is still running.
idx++;
#endif
} // while
} }
// //
// _findActiveObservation(name) // _updateActiveList()
// //
Observation* MACScheduler::_findActiveObservation(const string& name) void MACScheduler::_updateActiveList()
{ {
vector<Observation>::iterator end = itsObservations.end(); LOG_DEBUG("_updateActiveList()");
vector<Observation>::iterator iter = itsObservations.begin();
while (iter != end) {
if (iter->name == name) {
return (&(*iter));
}
iter++;
}
return ((Observation*) 0); // get new list (list is ordered on starttime)
} vector<OTDBtree> activeDBlist = itsOTDBconnection->getTreeGroup(2, 0);
if (activeDBlist.empty()) {
// LOG_DEBUG ("No active Observations");
// _addActiveObservation(name) return;
//
void MACScheduler::_addActiveObservation(const Observation& newObs)
{
// Observation already in vector?
vector<Observation>::iterator end = itsObservations.end();
vector<Observation>::iterator iter = itsObservations.begin();
while (iter != end) {
if (iter->name == newObs.name) {
return;
}
iter++;
} }
// update own admin and PVSS datapoint // walk through the list, prepare PVSS for the new obs, update own admin lists.
itsObservations.push_back(newObs); GCFPValueArray activeArr;
itsPVSSObsList.push_back(new GCFPVString(formatString("Observation%d", newObs.obsID))); uint32 listSize = activeDBlist.size();
itsPropertySet->setValue(PN_MS_ACTIVE_OBSERVATIONS, GCFPVDynArr(LPT_STRING, itsPVSSObsList)); uint32 idx = 0;
while (idx < listSize) {
// construct name and timings info for observation
string obsName(formatString("Observation_%d", activeDBlist[idx].treeID()));
activeArr.push_back(new GCFPVString(obsName));
// remove obs from planned-list if its still their.
OLiter prepIter = itsPreparedObs.find(activeDBlist[idx].treeID());
if (prepIter != itsPreparedObs.end()) {
itsPreparedObs.erase(prepIter);
}
LOG_DEBUG_STR("Added observation " << newObs.name << " to active observation-list"); idx++;
} // while
itsPropertySet->setValue(PN_MS_ACTIVE_OBSERVATIONS, GCFPVDynArr(LPT_DYNSTRING, activeArr));
} }
// //
// _removeActiveObservation(name) // _updateFinishedList()
// //
void MACScheduler::_removeActiveObservation(const string& name) void MACScheduler::_updateFinishedList()
{ {
// search observation. LOG_DEBUG("_updateFinishedList()");
OTDB::treeIDType obsID;
vector<Observation>::iterator end = itsObservations.end();
vector<Observation>::iterator iter = itsObservations.begin();
bool found(false);
while (!found && (iter != end)) {
if (iter->name == name) {
found = true;
obsID = iter->obsID;
itsObservations.erase(iter);
LOG_DEBUG_STR("Removed observation " << name << " from active observationList");
}
iter++;
}
if (!found) { // get new list (list is ordered on starttime)
vector<OTDBtree> finishedDBlist = itsOTDBconnection->getTreeGroup(3, itsFinishedPeriod);
if (finishedDBlist.empty()) {
LOG_DEBUG ("No finished Observations");
return; return;
} }
string obsName(formatString("Observation%d", obsID)); // walk through the list, prepare PVSS for the new obs, update own admin lists.
GCFPValueArray::iterator pEnd = itsPVSSObsList.end(); GCFPValueArray finishedArr;
GCFPValueArray::iterator pIter = itsPVSSObsList.begin(); uint32 listSize = finishedDBlist.size();
while (pIter != pEnd) { uint32 idx = 0;
if ((static_cast<GCFPVString*>(*pIter))->getValue() == obsName) { while (idx < listSize) {
delete *pIter; // construct name and timings info for observation
itsPVSSObsList.erase(pIter); string obsName(formatString("Observation_%d", finishedDBlist[idx].treeID()));
break; finishedArr.push_back(new GCFPVString(obsName));
} idx++;
pIter++; } // while
}
itsPropertySet->setValue(PN_MS_ACTIVE_OBSERVATIONS, GCFPVDynArr(LPT_STRING, itsPVSSObsList)); // write those value to PVSS as well.
itsPropertySet->setValue(PN_MS_FINISHED_OBSERVATIONS,
GCFPVDynArr(LPT_DYNSTRING, finishedArr));
} }
......
# new setup # Startup parameters for the MACScheduler.
prefix = LOFAR.PermSW.MACScheduler
# OTDB connection info
OTDBdatabasename = overeem OTDBdatabasename = overeem
OTDBhostname = dop50.astron.nl OTDBhostname = dop50.astron.nl
OTDBusername = paulus OTDBusername = paulus
OTDBpassword = boskabouter OTDBpassword = boskabouter
OTDBpollInterval = 5s OTDBpollInterval = 5s
# startup periods of Observations
QueuePeriod = 15m QueuePeriod = 15m
ClaimPeriod = 2m ClaimPeriod = 2m
# manage lists of observations
pollIntervalPlanned = 5s # check if observations must be started
pollIntervalExecute = 1m # check if observations are still active
pollIntervalFinished= 1m # update the list with finished observations
plannedPeriod = 24h # period you will see in the Navigator
finishedPeriod = 24h # period you will see in the Navigator
# next parameters are optional, defaultvalues are shown # next parameters are optional, defaultvalues are shown
#ChildControl.StartupRetryInterval = 10s #ChildControl.StartupRetryInterval = 10s
#ChildControl.MaxStartupRetry = 5 #ChildControl.MaxStartupRetry = 5
......
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
#include <OTDB/OTDBnode.h> #include <OTDB/OTDBnode.h>
#include <APS/ParameterSet.h> #include <APS/ParameterSet.h>
#include "ObsClaimer.h"
// forward declaration // forward declaration
namespace LOFAR { namespace LOFAR {
...@@ -94,38 +96,59 @@ private: ...@@ -94,38 +96,59 @@ private:
MACScheduler(const MACScheduler&); MACScheduler(const MACScheduler&);
MACScheduler& operator=(const MACScheduler&); MACScheduler& operator=(const MACScheduler&);
Observation* _findActiveObservation(const string& name);
void _addActiveObservation(const Observation& newObs);
void _removeActiveObservation(const string& name);
void _connectedHandler(GCFPortInterface& port); void _connectedHandler(GCFPortInterface& port);
void _disconnectedHandler(GCFPortInterface& port); void _disconnectedHandler(GCFPortInterface& port);
void _databaseEventHandler(GCFEvent& event); void _databaseEventHandler(GCFEvent& event);
void _doOTDBcheck(); void _doOTDBcheck();
void _updatePlannedList();
RTDBPropertySet* itsPropertySet; void _updateActiveList();
void _updateFinishedList();
// Information about the Observations. Not used yet.
vector<Observation> itsObservations; // ----- DATA MEMBERS -----
GCF::PVSS::GCFPValueArray itsPVSSObsList; // Our own propertySet in PVSS to inform the operator
RTDBPropertySet* itsPropertySet;
// pointers to other tasks
ChildControl* itsChildControl;
GCFITCPort* itsChildPort;
ObsClaimer* itsClaimerTask;
GCFITCPort* itsClaimerPort;
// <ctlrName, ObsId>
typedef map<string, int> CtlrMap;
typedef map<string, int>::iterator CMiter;
CtlrMap itsControllerMap; // Own admin
// Define a list in which we keep the obsID's of the observations we prepared PVSS for.
// When an obs is in the list we at least have sent a claim request to PVSS. When the
// second value it true we succeeded the claim and we don't have to claim it again.
typedef map<int /*obsID*/, bool /*prepReady*/> ObsList;
typedef map<int ,bool>::iterator OLiter;
ObsList itsPreparedObs; // Observations we already prepared PVSS for.
// Ports for StartDaemon and ObservationControllers. // Ports for StartDaemon and ObservationControllers.
GCFTimerPort* itsTimerPort; // for timers GCFTimerPort* itsTimerPort; // for timers
// pointer to child control task
ChildControl* itsChildControl;
GCFITCPort* itsChildPort;
// Second timer used for internal timing. // Second timer used for internal timing.
uint32 itsSecondTimer; // 1 second hardbeat uint32 itsSecondTimer; // 1 second heartbeat
// Timer admin for the lists
uint32 itsPlannedItv; // interval to update the planned obs list
uint32 itsActiveItv; // interval to update the active obs list
uint32 itsFinishedItv; // interval to update the finished obs list
uint32 itsPlannedPeriod; // period a planned observation is visible
uint32 itsFinishedPeriod; // period a finished observation is visible
int32 itsNextPlannedTime; // time to update the planned obs list again
int32 itsNextActiveTime; // time to update the active obs list again
int32 itsNextFinishedTime; // time to update the finished obs list again
// Scheduling settings // Scheduling settings
uint32 itsQueuePeriod; // period between queueing and start uint32 itsQueuePeriod; // period between queueing and start
uint32 itsClaimPeriod; // period between claiming and start uint32 itsClaimPeriod; // period between claiming and start
// OTDB related variables. // OTDB related variables.
OTDB::OTDBconnection* itsOTDBconnection; // connection to the database OTDB::OTDBconnection* itsOTDBconnection; // connection to the database
uint32 itsOTDBpollInterval; // itv between OTDB polls
int32 itsNextOTDBpolltime; // when next OTDB poll is scheduled
}; };
......
//# MACScheduler_Defines.h: preprocessor definitions of various constants // This file was generated by create_db_files v1.0 on Mon Jun 23 06:58:37 UTC 2008
//#
//# Copyright (C) 2002-2003 #ifndef LOFAR_DEPLOYMENT_PVSSDATAPOINTS_H
//# ASTRON (Netherlands Foundation for Research in Astronomy) #define LOFAR_DEPLOYMENT_PVSSDATAPOINTS_H
//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl // process
//# #define PN_FSM_PROCESSID "process.processID"
//# This program is free software; you can redistribute it and/or modify #define PN_FSM_START_TIME "process.startTime"
//# it under the terms of the GNU General Public License as published by #define PN_FSM_STOP_TIME "process.stopTime"
//# the Free Software Foundation; either version 2 of the License, or #define PN_FSM_LOG_MSG "process.logMsg"
//# (at your option) any later version. #define PN_FSM_ERROR "process.error"
//# #define PN_FSM_CURRENT_ACTION "process.currentAction"
//# This program is distributed in the hope that it will be useful, // object
//# but WITHOUT ANY WARRANTY; without even the implied warranty of #define PN_OBJ_STATE "object.state"
//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #define PN_OBJ_CHILD_STATE "object.childState"
//# GNU General Public License for more details. #define PN_OBJ_MESSAGE "object.message"
//#
//# You should have received a copy of the GNU General Public License // Station
//# along with this program; if not, write to the Free Software #define PSN_STATION "LOFAR_PIC_@ring@_@station@"
//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define PST_STATION "Station"
//# #define PN_STS__CHILD_DP "__childDp"
//# $Id$
// MACScheduler
#ifndef MACScheduler_DEFINES_H #define PSN_MAC_SCHEDULER "LOFAR_PermSW_MACScheduler"
#define MACScheduler_DEFINES_H #define PST_MAC_SCHEDULER "MACScheduler"
#define PN_MS_PLANNED_OBSERVATIONS "plannedObservations"
namespace LOFAR { #define PN_MS_ACTIVE_OBSERVATIONS "activeObservations"
namespace MCU { #define PN_MS_FINISHED_OBSERVATIONS "finishedObservations"
#define PN_MS_OTDB_CONNECTED "OTDB.connected"
#define MS_TASKNAME "MACScheduler" #define PN_MS_OTDB_LAST_POLL "OTDB.lastPoll"
#define PN_MS_OTDB_POLLINTERVAL "OTDB.pollinterval"
#define PSN_MAC_SCHEDULER "LOFAR_PermSW_MACScheduler"
#define PST_MAC_SCHEDULER "MACScheduler" // Observation
#define PN_MS_ACTIVE_OBSERVATIONS "activeObservations" #define PSN_OBSERVATION "LOFAR_ObsSW_@observation@"
#define PN_MS_OTDB_CONNECTED "OTDB.connected" #define PST_OBSERVATION "Observation"
#define PN_MS_OTDB_LAST_POLL "OTDB.lastPoll" #define PN_OBS_CLAIM_CLAIM_DATE "claim.claimDate"
#define PN_MS_OTDB_POLLINTERVAL "OTDB.pollinterval" #define PN_OBS_RECEIVER_BITMAP "receiverBitmap"
#define PN_OBS_CLAIM_PERIOD "claimPeriod"
#define PVSSNAME_MS_QUEUEPERIOD "QueuePeriod" #define PN_OBS_PREPARE_PERIOD "preparePeriod"
#define PVSSNAME_MS_CLAIMPERIOD "ClaimPeriod" #define PN_OBS_START_TIME "startTime"
#define PN_OBS_STOP_TIME "stopTime"
// next lines should be defined somewhere in Common. #define PN_OBS_BAND_FILTER "bandFilter"
#define PVSSNAME_FSM_CURACT "currentAction" #define PN_OBS_NYQUISTZONE "nyquistzone"
#define PVSSNAME_FSM_ERROR "error" #define PN_OBS_ANTENNA_ARRAY "antennaArray"
#define PVSSNAME_FSM_LOGMSG "logMsg" #define PN_OBS_RECEIVER_LIST "receiverList"
#define PVSSNAME_FSM_STATE "state" #define PN_OBS_SAMPLE_CLOCK "sampleClock"
#define PVSSNAME_FSM_CHILDSTATE "childState" #define PN_OBS_MEASUREMENT_SET "measurementSet"
#define PN_OBS_STATION_LIST "stationList"
#define PN_OBS_INPUT_NODE_LIST "inputNodeList"
}; // MCU #define PN_OBS_BGL_NODE_LIST "BGLNodeList"
}; // LOFAR #define PN_OBS_STORAGE_NODE_LIST "storageNodeList"
#define PN_OBS_BEAMS_ANGLE1 "Beams.angle1"
#define PN_OBS_BEAMS_ANGLE2 "Beams.angle2"
#define PN_OBS_BEAMS_DIRECTION_TYPE "Beams.directionType"
#define PN_OBS_BEAMS_BEAMLET_LIST "Beams.beamletList"
#define PN_OBS_BEAMS_SUBBAND_LIST "Beams.subbandList"
// ObsCtrl
#define PSN_OBS_CTRL "LOFAR_ObsSW_@observation@_ObsCtrl"
#define PST_OBS_CTRL "ObsCtrl"
// OnlineCtrl
#define PSN_ONLINE_CTRL "LOFAR_ObsSW_@observation@_OnlineCtrl"
#define PST_ONLINE_CTRL "OnlineCtrl"
// Correlator
#define PSN_CORRELATOR "LOFAR_ObsSW_@observation@_OnlineCtrl_Correlator"
#define PST_CORRELATOR "Correlator"
// StorageAppl
#define PSN_STORAGE_APPL "LOFAR_ObsSW_@observation@_OnlineCtrl_StorageAppl"
#define PST_STORAGE_APPL "StorageAppl"
// Cabinet
#define PSN_CABINET "LOFAR_PIC_@cabinet@"
#define PST_CABINET "Cabinet"
#define PN_CAB_DOOR_OPEN "doorOpen"
#define PN_CAB_FAN "fan"
#define PN_CAB_INLET_TEMP "inletTemp"
#define PN_CAB_FRONT_TEMP "frontTemp"
#define PN_CAB_BACK_TEMP "backTemp"
#define PN_CAB_SETPOINT_TEMP "setpointTemp"
#define PN_CAB_AMBIENT_TEMP "ambientTemp"
#define PN_CAB_CONTROL_MODE "controlMode"
// SubRack
#define PSN_SUB_RACK "LOFAR_PIC_@cabinet@_@subrack@"
#define PST_SUB_RACK "SubRack"
#define PN_SRCK_SPU__VHBA "SPU.Vhba"
#define PN_SRCK_SPU__VLBA "SPU.Vlba"
#define PN_SRCK_SPU__VDIG "SPU.Vdig"
#define PN_SRCK_SPU_TEMPERATURE "SPU.temperature"
#define PN_SRCK_CLOCK_BOARD__VFSP "clockBoard.Vfsp"
#define PN_SRCK_CLOCK_BOARD__VCLOCK "clockBoard.Vclock"
#define PN_SRCK_CLOCK_BOARD_VERSION "clockBoard.version"
#define PN_SRCK_CLOCK_BOARD_FREQ "clockBoard.freq"
#define PN_SRCK_CLOCK_BOARD_LOCK160 "clockBoard.lock160"
#define PN_SRCK_CLOCK_BOARD_LOCK200 "clockBoard.lock200"
#define PN_SRCK_CLOCK_BOARD_TEMPERATURE "clockBoard.temperature"
// RSPBoard
#define PSN_RSP_BOARD "LOFAR_PIC_@cabinet@_@subrack@_@RSPBoard@"
#define PST_RSP_BOARD "RSPBoard"
#define PN_RSP_VOLTAGE12 "voltage12"
#define PN_RSP_VOLTAGE25 "voltage25"
#define PN_RSP_VOLTAGE33 "voltage33"
#define PN_RSP_VERSION "version"
#define PN_RSP_ALERT "alert"
#define PN_RSP__ETHERNET_STATUS_STATE "Ethernet.status.state"
#define PN_RSP__ETHERNET_STATUS_CHILD_STATE "Ethernet.status.childState"
#define PN_RSP__ETHERNET_STATUS_MESSAGE "Ethernet.status.message"
#define PN_RSP_ETHERNET_PACKETS_RECEIVED "Ethernet.packetsReceived"
#define PN_RSP_ETHERNET_PACKETS_ERROR "Ethernet.packetsError"
#define PN_RSP_ETHERNET_LAST_ERROR "Ethernet.lastError"
#define PN_RSP_MEP_SEQNR "MEP.seqnr"
#define PN_RSP_MEP_ERROR "MEP.error"
#define PN_RSP_BP_STATUS_STATE "BP.status.state"
#define PN_RSP_BP_STATUS_CHILD_STATE "BP.status.childState"
#define PN_RSP_BP_STATUS_MESSAGE "BP.status.message"
#define PN_RSP_BP_TEMPERATURE "BP.temperature"
#define PN_RSP_BP_VERSION "BP.version"
#define PN_RSP_AP0_STATUS_STATE "AP0.status.state"
#define PN_RSP_AP0_STATUS_CHILD_STATE "AP0.status.childState"
#define PN_RSP_AP0_STATUS_MESSAGE "AP0.status.message"
#define PN_RSP_AP0_TEMPERATURE "AP0.temperature"
#define PN_RSP_AP0_VERSION "AP0.version"
#define PN_RSP_AP0_SYNC_SAMPLE_COUNT "AP0.SYNC.sampleCount"
#define PN_RSP_AP0_SYNC_SYNC_COUNT "AP0.SYNC.syncCount"
#define PN_RSP_AP0_SYNC_ERROR_COUNT "AP0.SYNC.errorCount"
#define PN_RSP_AP1_STATUS_STATE "AP1.status.state"
#define PN_RSP_AP1_STATUS_CHILD_STATE "AP1.status.childState"
#define PN_RSP_AP1_STATUS_MESSAGE "AP1.status.message"
#define PN_RSP_AP1_TEMPERATURE "AP1.temperature"
#define PN_RSP_AP1_VERSION "AP1.version"
#define PN_RSP_AP1_SYNC_SAMPLE_COUNT "AP1.SYNC.sampleCount"
#define PN_RSP_AP1_SYNC_SYNC_COUNT "AP1.SYNC.syncCount"
#define PN_RSP_AP1_SYNC_ERROR_COUNT "AP1.SYNC.errorCount"
#define PN_RSP_AP2_STATUS_STATE "AP2.status.state"
#define PN_RSP_AP2_STATUS_CHILD_STATE "AP2.status.childState"
#define PN_RSP_AP2_STATUS_MESSAGE "AP2.status.message"
#define PN_RSP_AP2_TEMPERATURE "AP2.temperature"
#define PN_RSP_AP2_VERSION "AP2.version"
#define PN_RSP_AP2_SYNC_SAMPLE_COUNT "AP2.SYNC.sampleCount"
#define PN_RSP_AP2_SYNC_SYNC_COUNT "AP2.SYNC.syncCount"
#define PN_RSP_AP2_SYNC_ERROR_COUNT "AP2.SYNC.errorCount"
#define PN_RSP_AP3_STATUS_STATE "AP3.status.state"
#define PN_RSP_AP3_STATUS_CHILD_STATE "AP3.status.childState"
#define PN_RSP_AP3_STATUS_MESSAGE "AP3.status.message"
#define PN_RSP_AP3_TEMPERATURE "AP3.temperature"
#define PN_RSP_AP3_VERSION "AP3.version"
#define PN_RSP_AP3_SYNC_SAMPLE_COUNT "AP3.SYNC.sampleCount"
#define PN_RSP_AP3_SYNC_SYNC_COUNT "AP3.SYNC.syncCount"
#define PN_RSP_AP3_SYNC_ERROR_COUNT "AP3.SYNC.errorCount"
// RCU
#define PSN_RCU "LOFAR_PIC_@cabinet@_@subrack@_@RSPBoard@_@rcu@"
#define PST_RCU "RCU"
#define PN_RCU_DELAY "Delay"
#define PN_RCU_INPUT_ENABLE "InputEnable"
#define PN_RCU_LBL_ENABLE "LBLEnable"
#define PN_RCU_LBH_ENABLE "LBHEnable"
#define PN_RCU_HBA_ENABLE "HBAEnable"
#define PN_RCU_BAND_SEL_LBA_HBA "bandSelLbaHba"
#define PN_RCU_HBA_FILTER_SEL "HBAFilterSel"
#define PN_RCU_VL_ENABLE "VlEnable"
#define PN_RCU_VH_ENABLE "VhEnable"
#define PN_RCU_VDD_VCC_ENABLE "VddVccEnable"
#define PN_RCU_BAND_SEL_LBL_LBH "bandSelLblLbh"
#define PN_RCU_LBA_FILTER_SEL "LBAFilterSel"
#define PN_RCU_ATTENUATION "Attenuation"
#define PN_RCU_NOF_OVERFLOW "nofOverflow"
#define PN_RCU_ADC_STATISTICS_OVERFLOW "ADCStatistics.overflow"
#define PN_RCU_TBB_ERROR "TBB.error"
#define PN_RCU_TBB_MODE "TBB.mode"
#define PN_RCU_TBB_START_ADDR "TBB.startAddr"
#define PN_RCU_TBB_BUF_SIZE "TBB.bufSize"
#define PN_RCU_TRIGGER_STARTLEVEL "Trigger.startlevel"
#define PN_RCU_TRIGGER_BASELEVEL "Trigger.baselevel"
#define PN_RCU_TRIGGER_STOPLEVEL "Trigger.stoplevel"
#define PN_RCU_TRIGGER_FILTER "Trigger.filter"
#define PN_RCU_TRIGGER_WINDOW "Trigger.window"
#define PN_RCU_TRIGGER_OPERATING_MODE "Trigger.operatingMode"
#define PN_RCU_TRIGGER_COEFF0 "Trigger.coeff0"
#define PN_RCU_TRIGGER_COEFF1 "Trigger.coeff1"
#define PN_RCU_TRIGGER_COEFF2 "Trigger.coeff2"
#define PN_RCU_TRIGGER_COEFF3 "Trigger.coeff3"
// TBBoard
#define PSN_TB_BOARD "LOFAR_PIC_@cabinet@_@subrack@_@TBBoard@"
#define PST_TB_BOARD "TBBoard"
#define PN_TBB_BOARDID "boardID"
#define PN_TBB_RAM_SIZE "RAMSize"
#define PN_TBB_SW_VERSION "SWVersion"
#define PN_TBB_BOARD_VERSION "boardVersion"
#define PN_TBB_TP_VERSION "TPVersion"
#define PN_TBB_MP0_VERSION "MP0Version"
#define PN_TBB_MP1_VERSION "MP1Version"
#define PN_TBB_MP2_VERSION "MP2Version"
#define PN_TBB_MP3_VERSION "MP3Version"
#define PN_TBB_VOLTAGE12 "voltage12"
#define PN_TBB_VOLTAGE25 "voltage25"
#define PN_TBB_VOLTAGE33 "voltage33"
#define PN_TBB_TEMPPCB "tempPCB"
#define PN_TBB_TEMPTP "tempTP"
#define PN_TBB_TEMPMP0 "tempMP0"
#define PN_TBB_TEMPMP1 "tempMP1"
#define PN_TBB_TEMPMP2 "tempMP2"
#define PN_TBB_TEMPMP3 "tempMP3"
#define PN_TBB_IMAGE_INFO_VERSION "imageInfo.version"
#define PN_TBB_IMAGE_INFO_WRITE_DATE "imageInfo.writeDate"
#define PN_TBB_IMAGE_INFO_TP_FILE "imageInfo.TPFile"
#define PN_TBB_IMAGE_INFO_MP_FILE "imageInfo.MPFile"
// StationClock
#define PSN_STATION_CLOCK "LOFAR_PIC_StationClock"
#define PST_STATION_CLOCK "StationClock"
#define PN_SCK_CLOCK "clock"
// LogProcessor
#define PSN_LOG_PROCESSOR "LOFAR_PermSW_Daemons_LogProcessor"
#define PST_LOG_PROCESSOR "LogProcessor"
// SASGateway
#define PSN_SAS_GATEWAY "LOFAR_PermSW_Daemons_SASGateway"
#define PST_SAS_GATEWAY "SASGateway"
// HardwareMonitor
#define PSN_HARDWARE_MONITOR "LOFAR_PermSW_HardwareMonitor"
#define PST_HARDWARE_MONITOR "HardwareMonitor"
#define PN_HWM_RSP_CONNECTED "RSP.connected"
#define PN_HWM_TBB_CONNECTED "TBB.connected"
// SoftwareMonitor
#define PSN_SOFTWARE_MONITOR "LOFAR_PermSW_SoftwareMonitor"
#define PST_SOFTWARE_MONITOR "SoftwareMonitor"
// TemperatureMonitor
#define PSN_TEMPERATURE_MONITOR "LOFAR_PermSW_TemperatureMonitor"
#define PST_TEMPERATURE_MONITOR "TemperatureMonitor"
// MACInfoServer
#define PSN_MAC_INFO_SERVER "LOFAR_PermSW_MACInfoServer"
#define PST_MAC_INFO_SERVER "MACInfoServer"
// StationCtrl
#define PSN_STATION_CTRL "LOFAR_PermSW_StationCtrl"
#define PST_STATION_CTRL "StationCtrl"
// DigBoardCtrl
#define PSN_DIG_BOARD_CTRL "LOFAR_PermSW_DigBoardCtrl"
#define PST_DIG_BOARD_CTRL "DigBoardCtrl"
#define PN_DBC_CONNECTED "connected"
#define PN_DBC_CLOCK "clock"
// StnObservation
#define PSN_STN_OBSERVATION "LOFAR_ObsSW_@observation@"
#define PST_STN_OBSERVATION "StnObservation"
#define PN_OBS_NAME "name"
#define PN_OBS_CLAIM_CLAIM_DATE "claim.claimDate"
// BeamCtrl
#define PSN_BEAM_CTRL "LOFAR_ObsSW_@observation@_BeamCtrl"
#define PST_BEAM_CTRL "BeamCtrl"
#define PN_BC_CONNECTED "connected"
#define PN_BC_SUB_ARRAY "subArray"
#define PN_BC_SUBBAND_LIST "subbandList"
#define PN_BC_BEAMLET_LIST "beamletList"
#define PN_BC_ANGLE1 "angle1"
#define PN_BC_ANGLE2 "angle2"
#define PN_BC_DIRECTION_TYPE "directionType"
#define PN_BC_BEAM_NAME "beamName"
// CalCtrl
#define PSN_CAL_CTRL "LOFAR_ObsSW_@observation@_CalCtrl"
#define PST_CAL_CTRL "CalCtrl"
#define PN_CC_CONNECTED "connected"
#define PN_CC_BEAM_NAMES "beamNames"
#define PN_CC_ANTENNA_ARRAY "antennaArray"
#define PN_CC_FILTER "filter"
#define PN_CC_NYQUISTZONE "nyquistzone"
#define PN_CC_RCUS "rcus"
// TBBCtrl
#define PSN_TBB_CTRL "LOFAR_ObsSW_@observation@_TBBCtrl"
#define PST_TBB_CTRL "TBBCtrl"
#define PN_TBC_CONNECTED "connected"
#define PN_TBC_TRIGGER_RCU_NR "trigger.rcuNr"
#define PN_TBC_TRIGGER_SEQUENCE_NR "trigger.sequenceNr"
#define PN_TBC_TRIGGER_TIME "trigger.time"
#define PN_TBC_TRIGGER_SAMPLE_NR "trigger.sampleNr"
#define PN_TBC_TRIGGER_SUM "trigger.sum"
#define PN_TBC_TRIGGER_NR_SAMPLES "trigger.nrSamples"
#define PN_TBC_TRIGGER_PEAK_VALUE "trigger.peakValue"
#define PN_TBC_TRIGGER_FLAGS "trigger.flags"
#define PN_TBC_TRIGGER_TABLE "trigger.table"
#endif #endif
...@@ -7,12 +7,14 @@ MACScheduler_CPPFLAGS = -DBOOST_DISABLE_THREADS \ ...@@ -7,12 +7,14 @@ MACScheduler_CPPFLAGS = -DBOOST_DISABLE_THREADS \
MACScheduler_SOURCES = ../Package__Version.cc \ MACScheduler_SOURCES = ../Package__Version.cc \
MACScheduler.cc \ MACScheduler.cc \
ObsClaimer.cc \
MACSchedulerMain.cc MACSchedulerMain.cc
MACScheduler_LDADD = -lpqxx $(LOFAR_DEPEND) MACScheduler_LDADD = -lpqxx $(LOFAR_DEPEND)
MACScheduler_DEPENDENCIES = $(LOFAR_DEPEND) MACScheduler_DEPENDENCIES = $(LOFAR_DEPEND)
NOINSTHDRS = MACScheduler.h \ NOINSTHDRS = MACScheduler.h \
ObsClaimer.h \
MACSchedulerDefines.h MACSchedulerDefines.h
INSTHDRS = INSTHDRS =
......
//# ObsClaimer.cc: Implementation of the MAC Scheduler task
//#
//# Copyright (C) 2002-2004
//# ASTRON (Netherlands Foundation for Research in Astronomy)
//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
//#
//# This program is free software; you can redistribute it and/or modify
//# it under the terms of the GNU General Public License as published by
//# the Free Software Foundation; either version 2 of the License, or
//# (at your option) any later version.
//#
//# This program is distributed in the hope that it will be useful,
//# but WITHOUT ANY WARRANTY; without even the implied warranty of
//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//# GNU General Public License for more details.
//#
//# You should have received a copy of the GNU General Public License
//# along with this program; if not, write to the Free Software
//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//#
//# $Id$
#include <lofar_config.h>
#include <Common/LofarLogger.h>
#include <Common/SystemUtil.h>
#include <Common/StreamUtil.h>
#include <Common/Version.h>
#include <APS/ParameterSet.h>
#include <GCF/TM/GCF_Protocols.h>
#include <GCF/TM/GCF_PortInterface.h>
#include <MACIO/MACServiceInfo.h>
#include <GCF/PVSS/GCF_PVTypes.h>
#include <APL/APLCommon/APL_Defines.h>
#include <APL/APLCommon/ControllerDefines.h>
#include <APL/APLCommon/StationInfo.h>
#include <GCF/RTDB/DP_Protocol.ph>
#include <APL/RTDBCommon/CM_Protocol.ph>
#include <APL/RTDBCommon/ClaimMgrTask.h>
#include <signal.h>
#include "MACSchedulerDefines.h"
#include "ObsClaimer.h"
using namespace LOFAR::GCF::PVSS;
using namespace LOFAR::GCF::TM;
using namespace LOFAR::GCF::RTDB;
using namespace LOFAR::APL::RTDBCommon;
using namespace LOFAR::Deployment;
using namespace std;
namespace LOFAR {
using namespace APLCommon;
using namespace ACC::APS;
namespace MainCU {
//
// ObsClaimer()
//
ObsClaimer::ObsClaimer(GCFTask* mainTask) :
GCFTask ((State)&ObsClaimer::idle_state, string("MS-ObsClaimer")),
itsClaimMgrTask (0),
itsITCPort (0),
itsHeartBeat (0),
itsTimerPort (0)
{
LOG_TRACE_OBJ ("ObsClaimer construction");
// construct the resources we need
itsTimerPort = new GCFTimerPort(*this, "OStimerport");
ASSERTSTR(itsTimerPort, "Can't construct a timer");
itsHeartBeat = new GCFTimerPort(*this, "OSHeartBeat");
ASSERTSTR(itsHeartBeat, "Can't construct a heatbeat timer");
itsITCPort = new GCFITCPort(*mainTask, *this, "ITCPort", GCFPortInterface::SAP, CM_PROTOCOL);
ASSERTSTR(itsITCPort, "Can't construct an ITC port");
itsClaimMgrTask = ClaimMgrTask::instance();
ASSERTSTR(itsClaimMgrTask, "Can't construct a claimMgrTask");
registerProtocol(CM_PROTOCOL, CM_PROTOCOL_STRINGS);
}
//
// ~ObsClaimer()
//
ObsClaimer::~ObsClaimer()
{
LOG_TRACE_OBJ ("~ObsClaimer");
if (itsTimerPort) { delete itsTimerPort; }
if (itsHeartBeat) { delete itsHeartBeat; }
if (itsITCPort) { delete itsITCPort; }
}
// -------------------- The only public function --------------------
//
// prepareObservation(const string& observationName);
//
// Just add the observationname to our prepareList and trigger main-loop.
void ObsClaimer::prepareObservation(const string& observationName)
{
OMiter iter = itsObsMap.find(observationName);
if (iter == itsObsMap.end()) { // new?
obsInfo* newObs = new obsInfo();
newObs->obsName = observationName;
newObs->state = OS_NEW;
// newObs->observation;
itsObsMap["LOFAR_ObsSW_"+observationName] = newObs;
LOG_DEBUG_STR("Added observation " << observationName << " to the prepareList");
}
else {
LOG_DEBUG_STR("Observation " << observationName << " already in the prepareList with state " << iter->second->state);
}
// Wake up state-machine asap.
itsHeartBeat->cancelAllTimers();
itsHeartBeat->setTimer(0.0);
}
//
// idle_state(event, port)
//
// Wait for new actions.
//
GCFEvent::TResult ObsClaimer::idle_state (GCFEvent& event, GCFPortInterface& port)
{
LOG_DEBUG_STR ("idle_state:" << eventName(event) << "@" << port.getName());
GCFEvent::TResult status = GCFEvent::HANDLED;
switch (event.signal) {
case F_ENTRY:
itsHeartBeat->setTimer(0.0); // check if there is something to do.
break;
case F_TIMER: {
// search the (first) observation that needs to be started; ask the claimMgr the name
// of the real DP.
OMiter iter = itsObsMap.begin();
OMiter end = itsObsMap.end();
while (iter != end) {
if (iter->second->state == OS_NEW) {
iter->second->state = OS_CLAIMING;
itsClaimMgrTask->claimObject("Observation", "LOFAR_ObsSW_"+iter->second->obsName, *itsITCPort);
// will result in CM_CLAIM_RESULT event
break;
}
++iter;
}
}
break;
case CM_CLAIM_RESULT: {
CMClaimResultEvent cmEvent(event);
LOG_INFO_STR(cmEvent.nameInAppl << " is mapped to " << cmEvent.DPname);
OMiter iter = itsObsMap.find(cmEvent.nameInAppl);
ASSERTSTR(iter != itsObsMap.end(), "Cannot find " << cmEvent.nameInAppl << " in admin");
iter->second->DPname = cmEvent.DPname;
itsCurrentObs = iter;
TRAN(ObsClaimer::preparePVSS_state);
}
break;
default:
LOG_DEBUG ("ObsClaimer::initial, default");
status = GCFEvent::NOT_HANDLED;
break;
}
return (status);
}
//
// preparePVSS_state(event, port)
//
// Fill all fields of the Observation in PVSS.
//
GCFEvent::TResult ObsClaimer::preparePVSS_state (GCFEvent& event, GCFPortInterface& port)
{
LOG_DEBUG_STR ("preparePVSS_state:" << eventName(event) << "@" << port.getName());
GCFEvent::TResult status = GCFEvent::HANDLED;
switch (event.signal) {
case F_ENTRY: {
// Create a PropSet for the Observation
LOG_DEBUG_STR ("Connecting to DP(" << itsCurrentObs->second->DPname << ") from observation "
<< itsCurrentObs->second->obsName);
itsCurrentObs->second->state = OS_FILLING;
itsCurrentObs->second->propSet = new RTDBPropertySet(itsCurrentObs->second->DPname,
"Observation",
PSAT_RW,
this);
}
break;
case DP_CREATED: {
// NOTE: thsi function may be called DURING the construction of the PropertySet.
// Always exit this event in a way that GCF can end the construction.
DPCreatedEvent dpEvent(event);
LOG_DEBUG_STR("Result of creating " << dpEvent.DPname << " = " << dpEvent.result);
itsTimerPort->cancelAllTimers();
itsTimerPort->setTimer(0.0);
}
break;
case F_TIMER: { // must be timer that PropSet is enabled.
// update PVSS.
LOG_TRACE_FLOW ("Updateing observation-fields in PVSS");
ParameterSet obsPS(formatString("%s/%s", LOFAR_SHARE_LOCATION, itsCurrentObs->second->obsName.c_str()));
Observation theObs(&obsPS);
RTDBPropertySet* theObsPS = itsCurrentObs->second->propSet;
// theObsPS->setValue(PN_OBS_CLAIM_PERIOD, GCFPVInteger(itsClaimPeriod), 0.0, false);
// theObsPS->setValue(PN_OBS_PREPARE_PERIOD, GCFPVInteger(itsPreparePeriod), 0.0, false);
// theObsPS->setValue(PN_OBS_START_TIME, GCFPVString (to_simple_string(itsStartTime)), 0.0, false);
// theObsPS->setValue(PN_OBS_STOP_TIME, GCFPVString (to_simple_string(itsStopTime)), 0.0, false);
theObsPS->setValue(PN_OBS_BAND_FILTER, GCFPVString (theObs.filter), 0.0, false);
theObsPS->setValue(PN_OBS_NYQUISTZONE, GCFPVInteger(theObs.nyquistZone), 0.0, false);
theObsPS->setValue(PN_OBS_ANTENNA_ARRAY, GCFPVString (theObs.antennaArray), 0.0, false);
theObsPS->setValue(PN_OBS_RECEIVER_LIST, GCFPVString (theObs.receiverList), 0.0, false);
theObsPS->setValue(PN_OBS_SAMPLE_CLOCK, GCFPVInteger(theObs.sampleClock), 0.0, false);
theObsPS->setValue(PN_OBS_MEASUREMENT_SET, GCFPVString (theObs.MSNameMask), 0.0, false);
theObsPS->setValue(PN_OBS_STATION_LIST, GCFPVString (theObs.stationList), 0.0, false);
theObsPS->setValue(PN_OBS_BGL_NODE_LIST, GCFPVString (theObs.BGLNodeList), 0.0, false);
theObsPS->setValue(PN_OBS_STORAGE_NODE_LIST,GCFPVString (theObs.storageNodeList), 0.0, false);
// for the beams we have to construct dyn arrays first.
GCFPValueArray subbandArr;
GCFPValueArray beamletArr;
GCFPValueArray angle1Arr;
GCFPValueArray angle2Arr;
GCFPValueArray dirTypesArr;
for (uint32 i(0); i < theObs.beams.size(); i++) {
stringstream os;
writeVector(os, theObs.beams[i].subbands);
subbandArr.push_back (new GCFPVString(os.str()));
os.clear();
writeVector(os, theObs.beams[i].beamlets);
beamletArr.push_back (new GCFPVString(os.str()));
angle1Arr.push_back (new GCFPVDouble(theObs.beams[i].angle1));
angle2Arr.push_back (new GCFPVDouble(theObs.beams[i].angle2));
dirTypesArr.push_back (new GCFPVString(theObs.beams[i].directionType));
}
// Finally we can write those value to PVSS as well.
theObsPS->setValue(PN_OBS_BEAMS_SUBBAND_LIST, GCFPVDynArr(LPT_DYNSTRING, subbandArr), 0.0, false);
theObsPS->setValue(PN_OBS_BEAMS_BEAMLET_LIST, GCFPVDynArr(LPT_DYNSTRING, beamletArr), 0.0, false);
theObsPS->setValue(PN_OBS_BEAMS_ANGLE1, GCFPVDynArr(LPT_DYNDOUBLE, angle1Arr), 0.0, false);
theObsPS->setValue(PN_OBS_BEAMS_ANGLE2, GCFPVDynArr(LPT_DYNDOUBLE, angle2Arr), 0.0, false);
theObsPS->setValue(PN_OBS_BEAMS_DIRECTION_TYPE, GCFPVDynArr(LPT_DYNSTRING, dirTypesArr), 0.0, false);
theObsPS->flush();
// send Maintask a signal we are ready.
LOG_DEBUG_STR("Sending Maintask ready signal for " << itsCurrentObs->second->obsName);
CMClaimResultEvent cmEvent;
cmEvent.nameInAppl = itsCurrentObs->second->obsName;
cmEvent.DPname = itsCurrentObs->second->DPname;
itsITCPort->sendBack(cmEvent);
// remove observation from list
LOG_DEBUG_STR("Removing " << itsCurrentObs->second->obsName << " from my prepareList");
delete itsCurrentObs->second;
itsObsMap.erase(itsCurrentObs);
itsCurrentObs = 0;
// back to idle state.
TRAN(ObsClaimer::idle_state);
}
break;
default:
LOG_DEBUG("updateObsInPVSS, default");
status = GCFEvent::NOT_HANDLED;
break;
}
return (status);
}
}; // namespace MAINCU
}; // namespace LOFAR
//# ObsClaimer.h: Prepares PVSS for an Observation that is going to run.
//#
//# Copyright (C) 2008
//# ASTRON (Netherlands Foundation for Research in Astronomy)
//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
//#
//# This program is free software; you can redistribute it and/or modify
//# it under the terms of the GNU General Public License as published by
//# the Free Software Foundation; either version 2 of the License, or
//# (at your option) any later version.
//#
//# This program is distributed in the hope that it will be useful,
//# but WITHOUT ANY WARRANTY; without even the implied warranty of
//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//# GNU General Public License for more details.
//#
//# You should have received a copy of the GNU General Public License
//# along with this program; if not, write to the Free Software
//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//#
//# $Id$
#ifndef MAINCU_OBSSTARTER_H
#define MAINCU_OBSSTARTER_H
//# Common Includes
#include <Common/lofar_string.h>
#include <Common/lofar_vector.h>
#include <Common/LofarLogger.h>
//# GCF Includes
#include <MACIO/GCF_Event.h>
#include <GCF/TM/GCF_Control.h>
#include <GCF/PVSS/GCF_PVTypes.h>
#include <GCF/RTDB/RTDB_PropertySet.h>
#include <ApplCommon/Observation.h>
#include <APL/RTDBCommon/ClaimMgrTask.h>
//# ACC Includes
#include <APS/ParameterSet.h>
// forward declaration
namespace LOFAR {
using MACIO::GCFEvent;
using GCF::TM::GCFTimerPort;
using GCF::TM::GCFPortInterface;
using GCF::TM::GCFTask;
using GCF::RTDB::RTDBPropertySet;
using APL::RTDBCommon::ClaimMgrTask;
namespace MainCU {
class ObsClaimer : public GCFTask
{
public:
ObsClaimer(GCFTask* mainTask);
~ObsClaimer();
// ask the ObsClaimer to prepare the PVSS database for the given observation.
void prepareObservation(const string& observationName);
private:
// Connect to the PS of the claimManager
GCFEvent::TResult connect2claimMgr_state (GCFEvent& e, GCFPortInterface& p);
// Wait for call from MACScheduler task
GCFEvent::TResult idle_state (GCFEvent& e, GCFPortInterface& p);
// Fill all fields of the Observation.
GCFEvent::TResult preparePVSS_state (GCFEvent& e, GCFPortInterface& p);
// avoid copying
ObsClaimer(const ObsClaimer&);
ObsClaimer& operator=(const ObsClaimer&);
// internal datatypes
typedef struct obsInfo_t {
string obsName; // name used by user.
string DPname; // name of real DP.
Observation observation; // corresponding observation info.
int state; // state of handling this obs.
RTDBPropertySet* propSet;
} obsInfo;
enum {
OS_NEW = 0,
OS_CLAIMING,
OS_FILLING,
OS_STARTING
};
// ----- DATAMEMBERS -----
// admin for observations
map<string, obsInfo*> itsObsMap;
typedef map<string, obsInfo*>::iterator OMiter;
OMiter itsCurrentObs; // Obs currently handled by claimMgr.
ClaimMgrTask* itsClaimMgrTask; // Pointer to claimMgr.
GCFITCPort* itsITCPort; // Answer back from CMtask.
GCFTimerPort* itsHeartBeat; // 1 second tick
GCFTimerPort* itsTimerPort; // general purpose timer
};
};//MainCU
};//LOFAR
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment