diff --git a/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitor.cc b/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitor.cc new file mode 100644 index 0000000000000000000000000000000000000000..fd471df4d4919310061da1b16402e51c098b4820 --- /dev/null +++ b/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitor.cc @@ -0,0 +1,772 @@ +//# HardwareMonitor.cc: Implementation of the MAC Scheduler task +//# +//# Copyright (C) 2006 +//# 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 <GCF/GCF_PVTypes.h> +#include <GCF/GCF_ServiceInfo.h> +#include <APL/APLCommon/ControllerDefines.h> +#include <APL/RSP_Protocol/RSP_Protocol.ph> +#include <GCF/RTDB/DP_Protocol.ph> +//#include <APL/APLCommon/StationInfo.h> +#include <signal.h> + +#include "HardwareMonitor.h" +#include "RCUConstants.h" +#include "StationPermDatapointDefs.h" + +using namespace LOFAR::GCF::Common; +using namespace LOFAR::GCF::TM; +using namespace LOFAR::GCF::RTDB; +using namespace std; + +namespace LOFAR { + using namespace APLCommon; + namespace StationCU { + +// static pointer to this object for signal handler +static HardwareMonitor* thisHardwareMonitor = 0; + +// +// HardwareMonitor() +// +HardwareMonitor::HardwareMonitor(const string& cntlrName) : + GCFTask ((State)&HardwareMonitor::initial_state,cntlrName), + itsOwnPropertySet (), + itsTimerPort (0), + itsRSPDriver (0), + itsPollInterval (10), + itsNrRCUs (0), + itsNrRSPboards (0), + itsNrSubracks (0), + itsNrCabinets (0) +{ + LOG_TRACE_OBJ_STR (cntlrName << " construction"); + + // TODO + LOG_INFO("MACProcessScope: LOFAR.PermSW.HWmonitor"); + + // need port for timers. + itsTimerPort = new GCFTimerPort(*this, "TimerPort"); + + // prepare TCP port to RSPDriver. + itsRSPDriver = new GCFTCPPort (*this, MAC_SVCMASK_RSPDRIVER, + GCFPortInterface::SAP, RSP_PROTOCOL); + ASSERTSTR(itsRSPDriver, "Cannot allocate TCPport to RSPDriver"); + itsRSPDriver->setInstanceNr(0); + + // for debugging purposes + GCF::TM::registerProtocol (RSP_PROTOCOL, RSP_PROTOCOL_STRINGS); + GCF::TM::registerProtocol (DP_PROTOCOL, DP_PROTOCOL_STRINGS); +} + + +// +// ~HardwareMonitor() +// +HardwareMonitor::~HardwareMonitor() +{ + LOG_TRACE_OBJ_STR (getName() << " destruction"); + + if (itsRSPDriver) { + itsRSPDriver->close(); + } + + // ... +} + + +// +// sigintHandler(signum) +// +void HardwareMonitor::sigintHandler(int signum) +{ + LOG_DEBUG (formatString("SIGINT signal detected (%d)",signum)); + + if (thisHardwareMonitor) { + thisHardwareMonitor->finish(); + } +} + +// +// finish +// +void HardwareMonitor::finish() +{ + TRAN(HardwareMonitor::finishing_state); +} + + +// +// initial_state(event, port) +// +// Setup connection with PVSS +// +GCFEvent::TResult HardwareMonitor::initial_state(GCFEvent& event, + GCFPortInterface& port) +{ + LOG_DEBUG_STR ("initial:" << eventName(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: { + // Get access to my own propertyset. + LOG_DEBUG_STR ("Activating PropertySet " << PSN_HARDWARE_MONITOR); + itsTimerPort->setTimer(2.0); + itsOwnPropertySet = new RTDBPropertySet(PSN_HARDWARE_MONITOR, + PST_HARDWARE_MONITOR, + PSAT_WO, + this); + + } + break; + + case DP_CREATED: { + // NOTE: this 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: { + // first redirect signalHandler to our finishing state to leave PVSS + // in the right state when we are going down + thisHardwareMonitor = this; + signal (SIGINT, HardwareMonitor::sigintHandler); // ctrl-c + signal (SIGTERM, HardwareMonitor::sigintHandler); // kill + + // update PVSS. + LOG_TRACE_FLOW ("Updateing state to PVSS"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_CURACT, GCFPVString("initial")); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR, GCFPVString("")); + + LOG_DEBUG_STR("Going to connect to the RSPDriver."); + TRAN (HardwareMonitor::connect2RSP); + } + + default: + LOG_DEBUG_STR ("initial, DEFAULT"); + break; + } + + return (status); +} + + +// +// connect2RSP(event, port) +// +// Setup connection with RSPdriver +// +GCFEvent::TResult HardwareMonitor::connect2RSP(GCFEvent& event, + GCFPortInterface& port) +{ + LOG_DEBUG_STR ("connect2RSP:" << eventName(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_ENTRY: + // update PVSS + itsOwnPropertySet->setValue(PVSSNAME_FSM_CURACT, GCFPVString("connecting")); + itsOwnPropertySet->setValue(PN_HWM_RSP_CONNECTED,GCFPVBool(false)); + itsRSPDriver->open(); // will result in F_CONN or F_DISCONN + break; + + case F_CONNECTED: + if (&port == itsRSPDriver) { + LOG_DEBUG ("Connected with RSPDriver, going to get the configuration"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR, GCFPVString("")); + itsOwnPropertySet->setValue(PN_HWM_RSP_CONNECTED,GCFPVBool(true)); + TRAN(HardwareMonitor::askConfiguration); // go to next state. + } + break; + + case F_DISCONNECTED: + port.close(); + ASSERTSTR (&port == itsRSPDriver, + "F_DISCONNECTED event from port " << port.getName()); + LOG_DEBUG("Connection with RSPDriver failed, retry in 2 seconds"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR, GCFPVString("connection timeout")); + itsTimerPort->setTimer(2.0); + break; + + default: + LOG_DEBUG_STR ("connect2RSP, DEFAULT"); + break; + } + + return (status); +} + +// +// askConfiguration(event, port) +// +// Take subscription on clock modifications +// +GCFEvent::TResult HardwareMonitor::askConfiguration(GCFEvent& event, + GCFPortInterface& port) +{ + LOG_DEBUG_STR ("askConfiguration:" << eventName(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_ENTRY: { + itsOwnPropertySet->setValue(PVSSNAME_FSM_CURACT,GCFPVString("asking configuration")); + RSPGetconfigEvent getconfig; + itsRSPDriver->send(getconfig); + } + break; + + case F_DISCONNECTED: + _disconnectedHandler(port); // might result in transition to connect2RSP + break; + + case RSP_GETCONFIGACK: { + RSPGetconfigackEvent ack(event); + + // calc size of the propertyset vectors + itsNrRCUs = ack.n_rcus; + itsNrRSPboards = ack.n_rspboards; + itsNrSubracks = itsNrRSPboards/NR_RSPBOARDS_PER_SUBRACK + (itsNrRSPboards%NR_RSPBOARDS_PER_SUBRACK) ? 1 : 0; + itsNrCabinets = itsNrSubracks /NR_SUBRACKS_PER_CABINET + (itsNrSubracks%NR_SUBRACKS_PER_CABINET) ? 1 : 0; + + // inform user + LOG_DEBUG(formatString("nr RCUs = %d",ack.n_rcus)); + LOG_DEBUG(formatString("nr RSPboards = %d",ack.max_rspboards)); + LOG_DEBUG(formatString("nr Subracks = %d", itsNrSubracks)); + LOG_DEBUG(formatString("nr Cabinets = %d", itsNrCabinets)); + + // do some checks + if (itsNrRSPboards != (uint32)ack.max_rspboards) { + LOG_WARN_STR("RSPdriver only controls " << itsNrRSPboards << " of " << ack.max_rspboards + << " RSPboards, cannot monitor full station"); + } + if (itsNrRSPboards * NR_RCUS_PER_RSPBOARD != itsNrRCUs) { + LOG_INFO_STR("Station not fully equiped, only " << itsNrRCUs << " of " + << itsNrRSPboards * NR_RCUS_PER_RSPBOARD << "RCUs"); + } + + LOG_DEBUG ("Going to allocate the property-sets"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("")); + TRAN(HardwareMonitor::createPropertySets); // go to next state. + } + break; + + default: + LOG_DEBUG_STR ("askConfiguration, DEFAULT"); + break; + } + + return (status); +} + + +// +// createPropertySets(event, port) +// +// Retrieve sampleclock from RSP driver +// +GCFEvent::TResult HardwareMonitor::createPropertySets(GCFEvent& event, + GCFPortInterface& port) +{ + LOG_DEBUG_STR ("createPropertySets:" << eventName(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + + case F_ENTRY: { + itsOwnPropertySet->setValue(PVSSNAME_FSM_CURACT,GCFPVString("create PropertySets")); + // resize vectors. + itsCabinets.resize(itsNrCabinets, 0); + itsSubracks.resize(itsNrSubracks, 0); + itsRSPs.resize (itsNrRSPboards, 0); + itsRCUs.resize (itsNrRCUs, 0); + + int32 cabinet (-1); + int32 subrack (-1); + int32 RSP (-1); + string cabinetNameMask (createPropertySetName(PSN_CABINET, getName())); + string subrackNameMask (createPropertySetName(PSN_SUB_RACK, getName())); + string rspboardNameMask(createPropertySetName(PSN_RSP_BOARD, getName())); + string rcuNameMask (createPropertySetName(PSN_RCU, getName())); + for (uint32 rcu = 0; rcu < itsNrRCUs; rcu++) { + // new cabinet? + if (rcu % (NR_RCUS_PER_CABINET) == 0) { + cabinet++; + string PSname(formatString(cabinetNameMask.c_str(), cabinet)); + itsCabinets[cabinet] = new RTDBPropertySet(PSname, "type", PSAT_WO, this); + } + + // new subrack? + if (rcu % (NR_RCUS_PER_SUBRACK) == 0) { + subrack++; + string PSname(formatString(subrackNameMask.c_str(), cabinet, subrack)); + itsSubracks[subrack] = new RTDBPropertySet(PSname, "type", PSAT_WO, this); + } + + // new RSPboard? + if (rcu % (NR_RCUS_PER_RSPBOARD) == 0) { + RSP++; + string PSname(formatString(rspboardNameMask.c_str(), cabinet, subrack, RSP)); + itsRSPs[RSP] = new RTDBPropertySet(PSname, "type", PSAT_WO, this); + } + + // allocate RCU PS + string PSname(formatString(rcuNameMask.c_str(), cabinet, subrack, RSP, rcu)); + itsRCUs[rcu] = new RTDBPropertySet(PSname, "type", PSAT_WO, this); + } + itsTimerPort->setTimer(5.0); // give database some time to finish the job + } + break; + + case F_TIMER: { + // database should be ready by now, check if allocation was succesfull + for (uint32 cabinet = 0; cabinet < itsNrCabinets; cabinet++) { + ASSERTSTR(itsCabinets[cabinet], "Allocation of PS for cabinet " << cabinet << " failed."); + } + for (uint32 subrack = 0; subrack < itsNrSubracks; subrack++) { + ASSERTSTR(itsSubracks[subrack], "Allocation of PS for subrack " << subrack << " failed."); + } + for (uint32 rsp = 0; rsp < itsNrRSPboards; rsp++) { + ASSERTSTR(itsRSPs[rsp], "Allocation of PS for rsp " << rsp << " failed."); + } + for (uint32 rcu = 0; rcu < itsNrRCUs; rcu++) { + ASSERTSTR(itsRCUs[rcu], "Allocation of PS for rcu " << rcu << " failed."); + } + LOG_DEBUG_STR("Allocation of all propertySets successfull, going to operational mode"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("")); + TRAN(HardwareMonitor::askRSPinfo); + } + break; + + case F_DISCONNECTED: + _disconnectedHandler(port); // might result in transition to connect2RSP + break; + + default: + LOG_DEBUG_STR ("createPropertySets, DEFAULT"); + break; + } + + return (status); +} + + +// +// askVersion(event, port) +// +// Set sampleclock from RSP driver +// +GCFEvent::TResult HardwareMonitor::askVersion(GCFEvent& event, + GCFPortInterface& port) +{ + LOG_DEBUG_STR ("askVersion:" << eventName(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + + case F_ENTRY: { + itsOwnPropertySet->setValue(PVSSNAME_FSM_CURACT,GCFPVString("getting version info")); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("")); + RSPGetversionEvent getVersion; + getVersion.timestamp.setNow(); + getVersion.cache = true; + itsRSPDriver->send(getVersion); + } + break; + + case RSP_GETVERSIONACK: { + RSPGetversionackEvent ack(event); + if (ack.status != SUCCESS) { + LOG_ERROR_STR ("Failed to get the version information, trying other information"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("getVersion error")); + TRAN(HardwareMonitor::askRSPinfo); // go to next state. + break; + } + + // move the information to the database. + string versionStr; + string DPEname; + for (uint32 rsp = 0; rsp < itsNrRSPboards; rsp++) { + // RSP board version + versionStr = formatString("%d.%d", ack.versions.bp()(rsp).rsp_version >> 4, + ack.versions.bp()(rsp).rsp_version & 0xF); + itsRSPs[rsp]->setValue(PN_RSP_VERSION, GCFPVString(versionStr), double(ack.timestamp)); + + // BP version + versionStr = formatString("%d.%d", ack.versions.bp()(rsp).fpga_maj, + ack.versions.bp()(rsp).fpga_min); + itsRSPs[rsp]->setValue(PN_RSP_BP_VERSION, GCFPVString(versionStr), double(ack.timestamp)); + + // APx versions + for (int ap = 0; ap < MEPHeader::N_AP; ap++) { + versionStr = formatString("%d.%d", ack.versions.ap()(rsp * MEPHeader::N_AP + ap).fpga_maj, + ack.versions.ap()(rsp * MEPHeader::N_AP + ap).fpga_min); + DPEname = formatString (PN_RSP_AP_VERSION_MASK, ap); + itsRSPs[rsp]->setValue(DPEname, GCFPVString(versionStr), double(ack.timestamp)); + } + } + + LOG_DEBUG_STR ("Version information updated, going to status information"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("")); + TRAN(HardwareMonitor::askRSPinfo); // go to next state. + break; + } + + case F_DISCONNECTED: + _disconnectedHandler(port); // might result in transition to connect2RSP + break; + + default: + LOG_DEBUG_STR ("askVersion, DEFAULT"); + break; + } + + return (status); +} + + +// +// askRSPinfo(event, port) +// +// Set sampleclock from RSP driver +// +GCFEvent::TResult HardwareMonitor::askRSPinfo(GCFEvent& event, + GCFPortInterface& port) +{ + LOG_DEBUG_STR ("askRSPinfo:" << eventName(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + + case F_ENTRY: { + itsOwnPropertySet->setValue(PVSSNAME_FSM_CURACT,GCFPVString("updating RSP info")); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("")); + RSPGetstatusEvent getStatus; + getStatus.timestamp.setNow(); + getStatus.cache = true; + getStatus.rspmask = bitset<MAX_N_RSPBOARDS>((1<<itsNrRSPboards)-1); + itsRSPDriver->send(getStatus); + } + break; + + case RSP_GETSTATUSACK: { + RSPGetstatusackEvent ack(event); + if (ack.status != SUCCESS) { + LOG_ERROR_STR ("Failed to get the status information, trying other information"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("getStatus error")); + TRAN(HardwareMonitor::askRCUinfo); // go to next state. + break; + } + + // move the information to the database. + string versionStr; + string DPEname; + for (uint32 rsp = 0; rsp < itsNrRSPboards; rsp++) { + BoardStatus bStat = ack.sysstatus.board()(rsp); + // board voltages + itsRSPs[rsp]->setValue(PN_RSP_VOLTAGE12, GCFPVDouble(double(bStat.rsp.voltage_1_2)*(2.5/192.0)), + double(ack.timestamp)); + itsRSPs[rsp]->setValue(PN_RSP_VOLTAGE25, GCFPVDouble(double(bStat.rsp.voltage_2_5)*(3.3/192.0)), + double(ack.timestamp)); + itsRSPs[rsp]->setValue(PN_RSP_VOLTAGE33, GCFPVDouble(double(bStat.rsp.voltage_3_3)*(5.0/192.0)), + double(ack.timestamp)); + + // Ethernet status + itsRSPs[rsp]->setValue(PN_RSP_ETHERNET_PACKETS_RECEIVED, GCFPVUnsigned(bStat.eth.nof_frames), + double(ack.timestamp)); + itsRSPs[rsp]->setValue(PN_RSP_ETHERNET_PACKETS_ERROR, GCFPVUnsigned(bStat.eth.nof_errors), + double(ack.timestamp)); + itsRSPs[rsp]->setValue(PN_RSP_ETHERNET_LAST_ERROR, GCFPVUnsigned(bStat.eth.last_error), + double(ack.timestamp)); + + // MEP status + itsRSPs[rsp]->setValue(PN_RSP_MEP_SEQNR, GCFPVUnsigned(bStat.mep.seqnr), + double(ack.timestamp)); + itsRSPs[rsp]->setValue(PN_RSP_MEP_ERROR, GCFPVUnsigned(bStat.mep.error), + double(ack.timestamp)); + + // BP status + itsRSPs[rsp]->setValue(PN_RSP_BP_TEMPERATURE, GCFPVDouble(double(bStat.rsp.bp_temp)), + double(ack.timestamp)); + // AP0 + itsRSPs[rsp]->setValue(PN_RSP_AP0_TEMPERATURE, GCFPVDouble(double(bStat.rsp.ap0_temp)), + double(ack.timestamp)); + itsRSPs[rsp]->setValue(PN_RSP_AP0_SYNC_SAMPLE_COUNT, GCFPVUnsigned(bStat.ap0_sync.sample_offset), + double(ack.timestamp)); + itsRSPs[rsp]->setValue(PN_RSP_AP0_SYNC_SYNC_COUNT, GCFPVUnsigned(bStat.ap0_sync.sample_offset)), + double(ack.timestamp); + itsRSPs[rsp]->setValue(PN_RSP_AP0_SYNC_ERROR_COUNT, GCFPVUnsigned(bStat.ap0_sync.ext_count)), + double(ack.timestamp); + + // AP1 + itsRSPs[rsp]->setValue(PN_RSP_AP1_TEMPERATURE, GCFPVDouble(double(bStat.rsp.ap1_temp)), + double(ack.timestamp)); + itsRSPs[rsp]->setValue(PN_RSP_AP1_SYNC_SAMPLE_COUNT, GCFPVUnsigned(bStat.ap1_sync.sample_offset)), + double(ack.timestamp); + itsRSPs[rsp]->setValue(PN_RSP_AP1_SYNC_SYNC_COUNT, GCFPVUnsigned(bStat.ap1_sync.sample_offset)), + double(ack.timestamp); + itsRSPs[rsp]->setValue(PN_RSP_AP1_SYNC_ERROR_COUNT, GCFPVUnsigned(bStat.ap1_sync.ext_count)), + double(ack.timestamp); + + // AP2 + itsRSPs[rsp]->setValue(PN_RSP_AP2_TEMPERATURE, GCFPVDouble(double(bStat.rsp.ap2_temp)), + double(ack.timestamp)); + itsRSPs[rsp]->setValue(PN_RSP_AP2_SYNC_SAMPLE_COUNT, GCFPVUnsigned(bStat.ap2_sync.sample_offset)), + double(ack.timestamp); + itsRSPs[rsp]->setValue(PN_RSP_AP2_SYNC_SYNC_COUNT, GCFPVUnsigned(bStat.ap2_sync.sample_offset)), + double(ack.timestamp); + itsRSPs[rsp]->setValue(PN_RSP_AP2_SYNC_ERROR_COUNT, GCFPVUnsigned(bStat.ap2_sync.ext_count)), + double(ack.timestamp); + + // AP3 + itsRSPs[rsp]->setValue(PN_RSP_AP3_TEMPERATURE, GCFPVDouble(double(bStat.rsp.ap3_temp)), + double(ack.timestamp)); + itsRSPs[rsp]->setValue(PN_RSP_AP3_SYNC_SAMPLE_COUNT, GCFPVUnsigned(bStat.ap3_sync.sample_offset)), + double(ack.timestamp); + itsRSPs[rsp]->setValue(PN_RSP_AP3_SYNC_SYNC_COUNT, GCFPVUnsigned(bStat.ap3_sync.sample_offset)), + double(ack.timestamp); + itsRSPs[rsp]->setValue(PN_RSP_AP3_SYNC_ERROR_COUNT, GCFPVUnsigned(bStat.ap3_sync.ext_count)), + double(ack.timestamp); + } // for all boards + + LOG_DEBUG_STR ("RSPboard information updated, going to RCU information"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("")); + TRAN(HardwareMonitor::askRCUinfo); // go to next state. + break; + } + + case F_DISCONNECTED: + _disconnectedHandler(port); // might result in transition to connect2RSP + break; + + default: + LOG_DEBUG_STR ("askRSPinfo, DEFAULT"); + break; + } + + return (status); +} + + +// +// askRCUinfo(event, port) +// +// Normal operation state. +// +GCFEvent::TResult HardwareMonitor::askRCUinfo(GCFEvent& event, GCFPortInterface& port) +{ + LOG_DEBUG_STR ("askRCUinfo:" << eventName(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: { + // update PVSS + itsOwnPropertySet->setValue(PVSSNAME_FSM_CURACT,GCFPVString("updating RSP info")); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("")); + RSPGetrcuEvent getStatus; + getStatus.timestamp.setNow(); + getStatus.cache = true; + getStatus.rcumask = bitset<MEPHeader::MAX_N_RCUS>((1<<itsNrRCUs)-1); + itsRSPDriver->send(getStatus); + break; + } + + case RSP_GETRCUACK: { + RSPGetrcuackEvent ack(event); + if (ack.status != SUCCESS) { + LOG_ERROR_STR ("Failed to get the RCU information, trying other information"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("getRCU error")); + TRAN(HardwareMonitor::waitForNextCycle); // go to next state. + break; + } + + // move the information to the database. + string versionStr; + string DPEname; + for (uint32 rcu = 0; rcu < itsNrRCUs; rcu++) { + uint32 rawValue = ack.settings()(rcu).getRaw(); + // update all RCU variables + itsRCUs[rcu]->setValue(PN_RCU_DELAY, + GCFPVUnsigned(uint32(rawValue & DELAY_MASK)), + double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_INPUT_ENABLE, + GCFPVBool(rawValue & INPUT_ENABLE_MASK), + double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_LBL_ENABLE, + GCFPVBool(rawValue & LBL_ANT_POWER_MASK), double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_LBH_ENABLE, + GCFPVBool(rawValue & LBH_ANT_POWER_MASK), double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_HBA_ENABLE, + GCFPVBool(rawValue & HBA_ANT_POWER_MASK), double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_BAND_SELLBA_HBA, + GCFPVBool(rawValue & USE_LB_MASK), + double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_HBA_FILTER_SEL, + GCFPVUnsigned((rawValue & HB_FILTER_MASK) >> HB_FILTER_OFFSET), + double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_VL_ENABLE, + GCFPVBool(rawValue & LB_POWER_MASK), double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_VH_ENABLE, + GCFPVBool(rawValue & HB_POWER_MASK), double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_VDD_VCC_ENABLE, + GCFPVBool(rawValue & ADC_POWER_MASK), double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_BAND_SELLBL_LBH, + GCFPVBool(rawValue & USE_LBH_MASK), + double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_LBA_FILTER_SEL, + GCFPVUnsigned((rawValue & LB_FILTER_MASK) >> LB_FILTER_OFFSET), + double(ack.timestamp)); + itsRCUs[rcu]->setValue(PN_RCU_ATTENUATION, + GCFPVUnsigned(uint32((rawValue & ATT_MASK) >> ATT_OFFSET)), + double(ack.timestamp)); + } // for all boards + break; + + LOG_DEBUG ("Updated all RCU information, waiting for next cycle"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("")); + TRAN(HardwareMonitor::waitForNextCycle); // go to next state. + } + + case F_DISCONNECTED: + _disconnectedHandler(port); // might result in transition to connect2RSP + break; + + default: + LOG_DEBUG("askRCUinfo, DEFAULT"); + break; + } + + return (status); +} + +// +// waitForNextCycle(event, port) +// +// Take subscription on clock modifications +// +GCFEvent::TResult HardwareMonitor::waitForNextCycle(GCFEvent& event, + GCFPortInterface& port) +{ + LOG_DEBUG_STR ("waitForNextCycle:" << eventName(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_ENTRY: { + itsOwnPropertySet->setValue(PVSSNAME_FSM_CURACT,GCFPVString("wait for next cycle")); + int waitTime = time(0) % itsPollInterval; + if (waitTime == 0) { + waitTime = itsPollInterval; + } + itsTimerPort->cancelAllTimers(); + itsTimerPort->setTimer(double(waitTime)); + } + break; + + case F_DISCONNECTED: + _disconnectedHandler(port); // might result in transition to connect2RSP + break; + + case F_TIMER: { + TRAN(HardwareMonitor::askRSPinfo); + } + break; + + default: + LOG_DEBUG_STR ("waitForNextCycle, DEFAULT"); + break; + } + + return (status); +} + + +// +// _disconnectedHandler(port) +// +void HardwareMonitor::_disconnectedHandler(GCFPortInterface& port) +{ + port.close(); + if (&port == itsRSPDriver) { + LOG_DEBUG("Connection with RSPDriver failed, going to reconnect state"); + itsOwnPropertySet->setValue(PVSSNAME_FSM_ERROR,GCFPVString("connection lost")); + TRAN (HardwareMonitor::connect2RSP); + } +} + +// +// finishing_state(event, port) +// +// Write controller state to PVSS, wait for 1 second (using a timer) to let +// GCF handle the property change and close the controller +// +GCFEvent::TResult HardwareMonitor::finishing_state(GCFEvent& event, GCFPortInterface& port) +{ + LOG_DEBUG_STR ("finishing_state:" << eventName(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: { + // update PVSS + itsOwnPropertySet->setValue(string(PVSSNAME_FSM_CURACT),GCFPVString("finished")); + itsOwnPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); + + itsTimerPort->setTimer(1L); + break; + } + + case F_TIMER: + GCFTask::stop(); + break; + + default: + LOG_DEBUG("finishing_state, DEFAULT"); + status = GCFEvent::NOT_HANDLED; + break; + } + return (status); +} + + +}; // StationCU +}; // LOFAR diff --git a/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitor.h b/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitor.h new file mode 100644 index 0000000000000000000000000000000000000000..0f35af3998efc925b9b550ca0639d19c92fd0898 --- /dev/null +++ b/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitor.h @@ -0,0 +1,103 @@ +//# HardwareMonitor.h: Controller for the BeamServer +//# +//# Copyright (C) 2006 +//# 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 STATIONCU_HARDWARE_MONITOR_H +#define STATIONCU_HARDWARE_MONITOR_H + +//# Common Includes +#include <Common/lofar_string.h> +#include <Common/lofar_vector.h> + +//# GCF Includes +#include <GCF/RTDB/RTDB_PropertySet.h> +#include <GCF/TM/GCF_TCPPort.h> +#include <GCF/TM/GCF_TimerPort.h> +#include <GCF/TM/GCF_Task.h> +#include <GCF/TM/GCF_Event.h> + +// forward declaration + +namespace LOFAR { + namespace StationCU { + +using GCF::TM::GCFTimerPort; +using GCF::TM::GCFTCPPort; +using GCF::TM::GCFEvent; +using GCF::TM::GCFPortInterface; +using GCF::TM::GCFTask; +using GCF::RTDB::RTDBPropertySet; + + +class HardwareMonitor : public GCFTask +{ +public: + explicit HardwareMonitor(const string& cntlrName); + ~HardwareMonitor(); + + // Interrupthandler for switching to finishingstate when exiting the program. + static void sigintHandler (int signum); + void finish(); + +private: + // During the initial state all connections with the other programs are made. + GCFEvent::TResult initial_state (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult connect2RSP (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult askConfiguration (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult createPropertySets (GCFEvent& e, GCFPortInterface& p); + + GCFEvent::TResult askVersion (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult askRSPinfo (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult askRCUinfo (GCFEvent& e, GCFPortInterface& p); + GCFEvent::TResult waitForNextCycle (GCFEvent& e, GCFPortInterface& p); + + GCFEvent::TResult finishing_state (GCFEvent& e, GCFPortInterface& p); + + // avoid defaultconstruction and copying + HardwareMonitor(); + HardwareMonitor(const HardwareMonitor&); + HardwareMonitor& operator=(const HardwareMonitor&); + + void _disconnectedHandler(GCFPortInterface& port); + + // Data members + RTDBPropertySet* itsOwnPropertySet; + + GCFTimerPort* itsTimerPort; + + GCFTCPPort* itsRSPDriver; + + uint32 itsPollInterval; + + uint32 itsNrRCUs; + uint32 itsNrRSPboards; + uint32 itsNrSubracks; + uint32 itsNrCabinets; + + vector<RTDBPropertySet*> itsCabinets; + vector<RTDBPropertySet*> itsSubracks; + vector<RTDBPropertySet*> itsRSPs; + vector<RTDBPropertySet*> itsRCUs; +}; + + };//StationCU +};//LOFAR +#endif diff --git a/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitor.log_prop b/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitor.log_prop new file mode 100644 index 0000000000000000000000000000000000000000..4c7ba3e0c839bf7fdc6ca2422db60650aec1fd85 --- /dev/null +++ b/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitor.log_prop @@ -0,0 +1,20 @@ +# add your custom loggers and appenders here +# + +log4cplus.rootLogger=DEBUG, STDOUT, FILE + +log4cplus.logger.TRC=TRACE2 +log4cplus.additivity.TRC=FALSE + +log4cplus.appender.STDOUT=log4cplus::ConsoleAppender +log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout +log4cplus.appender.STDOUT.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{9} - %m [%.25l]%n +log4cplus.appender.STDOUT.logToStdErr=true + +log4cplus.appender.FILE=log4cplus::RollingFileAppender +log4cplus.appender.FILE.File=../log/HardwareMonitor.log +log4cplus.appender.FILE.MaxFileSize=5MB +log4cplus.appender.FILE.MaxBackupIndex=5 +log4cplus.appender.FILE.layout=log4cplus::PatternLayout +log4cplus.appender.FILE.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%.25l]%n + diff --git a/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitorMain.cc b/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitorMain.cc new file mode 100644 index 0000000000000000000000000000000000000000..073986df76bd20ad5c75123c5b11784b5d412acd --- /dev/null +++ b/MAC/APL/StationCU/src/HardwareMonitor/HardwareMonitorMain.cc @@ -0,0 +1,43 @@ +//# HardwareMonitor.cc: Main entry for the HardwareMonitor. +//# +//# Copyright (C) 2006 +//# 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 "HardwareMonitor.h" + +using namespace LOFAR::GCF::TM; +using namespace LOFAR::StationCU; + +int main(int argc, char* argv[]) +{ + // args: cntlrname, parentHost, parentService + GCFTask::init(argc, argv); + + HardwareMonitor hm(argv[1]); + hm.start(); // make initial transition + + GCFTask::run(); + + return 0; +} + diff --git a/MAC/APL/StationCU/src/HardwareMonitor/Makefile.am b/MAC/APL/StationCU/src/HardwareMonitor/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..2b9fda4fedbbe44d4df07b88e138dacaea36eb7a --- /dev/null +++ b/MAC/APL/StationCU/src/HardwareMonitor/Makefile.am @@ -0,0 +1,28 @@ +bin_PROGRAMS = HardwareMonitor + +HardwareMonitor_CPPFLAGS = -Wno-deprecated \ + -fmessage-length=0 \ + -fdiagnostics-show-location=once + +HardwareMonitor_SOURCES = HardwareMonitor.cc \ + HardwareMonitorMain.cc + +HardwareMonitor_LDADD = $(LOFAR_DEPEND) +HardwareMonitor_DEPENDENCIES= $(LOFAR_DEPEND) + +NOINSTHDRS = HardwareMonitor.h \ + RCUConstants.h \ + StationPermDatapointDefs.h + +INSTHDRS = + +pkginclude_HEADERS = $(NOINSTHDRS) $(INSTHDRS) + +DOCHDRS = $(pkginclude_HEADERS) $(BUILT_SOURCES) + +EXTRA_DIST = $(configfiles_DATA) $(sysconf_DATA) + +sysconf_DATA = HardwareMonitor.conf \ + HardwareMonitor.log_prop + +include $(top_srcdir)/Makefile.common diff --git a/MAC/APL/StationCU/src/HardwareMonitor/RCUConstants.h b/MAC/APL/StationCU/src/HardwareMonitor/RCUConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..b3c9ea92c6df0a55911e8643dd97e2a84a00a114 --- /dev/null +++ b/MAC/APL/StationCU/src/HardwareMonitor/RCUConstants.h @@ -0,0 +1,68 @@ +//# RCUConstants.h: Mask and offset for decomposing the raw RCUsetting value +//# +//# Copyright (C) 2007 +//# 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 STATIONCU_RCUCONSTANTS_H +#define STATIONCU_RCUCONSTANTS_H + +namespace LOFAR { + namespace StationCU { + +// NOTE: these constants should match the real mapping that is defined in RCUSettings.h +// in the PIC/RSP_Protocol directory. +static const uint32 DELAY_MASK = 0x0000007F; +static const uint32 INPUT_ENABLE_MASK = 0x00000080; +static const uint32 LBL_ANT_POWER_MASK = 0x00000100; +static const uint32 LBH_ANT_POWER_MASK = 0x00000200; +static const uint32 HBA_ANT_POWER_MASK = 0x00000400; +static const uint32 USE_LB_MASK = 0x00000800; +static const uint32 HB_FILTER_MASK = 0x00003000; +static const uint32 HB_FILTER_OFFSET = 12; +static const uint32 LB_POWER_MASK = 0x00004000; +static const uint32 HB_POWER_MASK = 0x00008000; +static const uint32 ADC_POWER_MASK = 0x00010000; +static const uint32 USE_LBH_MASK = 0x00020000; +static const uint32 LB_FILTER_MASK = 0x00060000; +static const uint32 LB_FILTER_OFFSET = 17; +static const uint32 ATT_MASK = 0x00F80000; +static const uint32 ATT_OFFSET = 19; + + +// NOTE: THESE CONSTANTS SHOULD BE SOMEWHERE AT A GLOBAL PLACE +static const uint32 NR_SUBRACKS_PER_CABINET = 2; +static const uint32 NR_RSPBOARDS_PER_SUBRACK= 4; +static const uint32 NR_RCUS_PER_RSPBOARD = 8; +static const uint32 NR_RCUS_PER_SUBRACK = (NR_RCUS_PER_RSPBOARD * NR_RSPBOARDS_PER_SUBRACK); +static const uint32 NR_RCUS_PER_CABINET = (NR_RCUS_PER_SUBRACK * NR_SUBRACKS_PER_CABINET); + +#define PN_RSP_AP_VERSION_MASK "AP%d.version" + +// next lines should be defined somewhere in Common. +#define PVSSNAME_FSM_CURACT "currentAction" +#define PVSSNAME_FSM_ERROR "error" +#define PVSSNAME_FSM_LOGMSG "logMsg" +#define PVSSNAME_FSM_STATE "state" +#define PVSSNAME_FSM_CHILDSTATE "childState" + + } // namespace StationCU +} // namespace LOFAR + +#endif diff --git a/MAC/APL/StationCU/src/HardwareMonitor/StationPermDatapointDefs.h b/MAC/APL/StationCU/src/HardwareMonitor/StationPermDatapointDefs.h new file mode 100644 index 0000000000000000000000000000000000000000..3f29a922dc9a2e48f94493d7743ef9263f507ed1 --- /dev/null +++ b/MAC/APL/StationCU/src/HardwareMonitor/StationPermDatapointDefs.h @@ -0,0 +1,116 @@ +// This file was generated by create_db_files v1.0 on Thu Aug 23 21:49:42 UTC 2007 + +// Cabinet +#define PSN_CABINET "LOFAR_PIC_@cabinet@" +#define PST_CABINET "Cabinet" +#define PN_CAB_FRONT_DOOR "front.door" +#define PN_CAB_FRONT_FAN "front.fan" +#define PN_CAB_FRONT_TEMPERATURE "front.temperature" +#define PN_CAB_BACK_DOOR "back.door" +#define PN_CAB_BACK_FAN "back.fan" +#define PN_CAB_BACK_TEMPERATURE "back.temperature" + +// SubRack +#define PSN_SUB_RACK "LOFAR_PIC_@cabinet@_@subrack@" +#define PST_SUB_RACK "SubRack" +#define PN_SRCK_SPU_STATE "SPU.state" +#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_STATE "clockBoard.state" +#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_STATE "Ethernet.state" +#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_STATE "BP.state" +#define PN_RSP_BP_TEMPERATURE "BP.temperature" +#define PN_RSP_BP_VERSION "BP.version" +#define PN_RSP_BP_SYNC_SAMPLE_COUNT "BP.SYNC.sampleCount" +#define PN_RSP_BP_SYNC_SYNC_COUNT "BP.SYNC.syncCount" +#define PN_RSP_BP_SYNC_ERROR_COUNT "BP.SYNC.errorCount" +#define PN_RSP_AP0_STATE "AP0.state" +#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_STATE "AP1.state" +#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_STATE "AP2.state" +#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_STATE "AP3.state" +#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_SELLBA_HBA "bandSelLBA_HBA" +#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_SELLBL_LBH "bandSelLBL_LBH" +#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_LBL_STATE "LBL.state" +#define PN_RCU_LBH_STATE "LBH.state" +#define PN_RCU_HBA_STATE "HBA.state" + +// StationClock +#define PSN_STATION_CLOCK "LOFAR_PIC_StationClock" +#define PST_STATION_CLOCK "StationClock" +#define PN_SCK_CLOCK "clock" + +// 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" + +// StationCtrl +#define PSN_STATION_CTRL "LOFAR_PermSW_StationCtrl" +#define PST_STATION_CTRL "StationCtrl" + +// HardwareMonitor +#define PSN_HARDWARE_MONITOR "LOFAR_PermSW_HardwareMonitor" +#define PST_HARDWARE_MONITOR "HardwareMonitor" +#define PN_HWM_RSP_CONNECTED "RSPConnected" +