Index: fact/Evidence/Alarm.cc
===================================================================
--- fact/Evidence/Alarm.cc	(revision 10128)
+++ fact/Evidence/Alarm.cc	(revision 10143)
@@ -8,5 +8,4 @@
   - Maximum severity may be reset by a command 'Alarm/ResetAlarm' for a server.
   - A text describing the current state of all servers is published as DIM service.
-    The states are described in LevelStr[].
   - A master alarm (indicating most severe of individual alarms) is published. 
   - The server can be switched on/off with the command 'Alarm/Switch'.
@@ -15,5 +14,5 @@
   from main thread.
 
-  Oliver Grimm, June 2010
+  Oliver Grimm, February 2011
 
 \********************************************************************/
@@ -26,6 +25,6 @@
 using namespace std;
 
-const char* LevelStr[] = {"OK", "WARN", "ERROR", "FATAL", "UNAVAILABLE"};
-const int MIN_PERIOD = 5;  // Minimum period in seconds for checking servers are alive 
+const int MIN_PERIOD = 5;	// Minimum period in seconds for checking servers are alive 
+const int UNAVA = 255;		// Alarm level to use if server unavailable
 
 //
@@ -135,8 +134,8 @@
   for (int i=0; i<List.size(); i++) if (getInfo() == List[i].Subscription) {
 	// Update level: unavailable or current severity of status (safely extracted)  
-	if (!ServiceOK(getInfo())) List[i].Level = 4;
+	if (!ServiceOK(getInfo())) List[i].Level = UNAVA;
 	else {
 	  int Severity = atoi(ToString(getInfo()->getFormat(), getInfo()->getData(), getInfo()->getSize()).c_str());
-	  if ((Severity>List[i].Level) || (List[i].Level==4 && Severity==0)) List[i].Level = Severity;
+	  if ((Severity>List[i].Level) || (List[i].Level==UNAVA && Severity==0)) List[i].Level = Severity;
 	}
   }
@@ -177,4 +176,5 @@
 
   ostringstream Buf;
+  string Desc;
   int Alarm = -1, Ret;  
 
@@ -184,6 +184,14 @@
   else for (int i=0; i<List.size(); i++) {
 	// Alarm level description
-	Buf << List[i].Server << ": " << (List[i].Level>=0 && List[i].Level<=4 ? LevelStr[List[i].Level] : "unknown");
-	Buf << " (" << List[i].Level << ")" << endl;
+	Buf << List[i].Server << ": ";
+	switch (List[i].Level) {
+	case INFO:	Desc = "OK"; break;
+	case WARN:	Desc = "WARN"; break;
+	case ERROR:	Desc = "ERROR"; break;
+	case FATAL:	Desc = "FATAL"; break;
+	case UNAVA:	Desc = "UNAVAILABLE"; break;
+	default:	Desc = "?"; break;
+	}
+	Buf << Desc << " (" << List[i].Level << ")" << endl;
 
 	// Adjust master alarm and update server alarm level
@@ -198,8 +206,7 @@
 	  char *Text;
 	  time_t Time = time(NULL);
-	  if (asprintf(&Text, "echo \"Server alarm level '%s' at %s\"|"
+	  if (asprintf(&Text, "echo \"Server alarm level '%s' (%d) at %s\"|"
 			"mail -s \"Evidence Alarm for '%s'\" %s",
-			List[i].Level>=0 && List[i].Level<=4 ? LevelStr[List[i].Level] : "unknown",
-	  		ctime(&Time), List[i].Server.c_str(), List[i].Email.c_str()) != -1) {
+			Desc.c_str(), List[i].Level, ctime(&Time), List[i].Server.c_str(), List[i].Email.c_str()) != -1) {
 		system(Text); // Return value depending on OS
 		free(Text);
@@ -245,5 +252,5 @@
         if (A.List[i].Server == Server) Exist = true;
       }
-	  if (!Exist) A.List[i].Level = 4;
+	  if (!Exist) A.List[i].Level = UNAVA;
 
 	  // Check if standard service available in case server not yet checked (Level is -1)
Index: fact/Evidence/Edd/Edd.cc
===================================================================
--- fact/Evidence/Edd/Edd.cc	(revision 10128)
+++ fact/Evidence/Edd/Edd.cc	(revision 10143)
@@ -1439,4 +1439,43 @@
 
 //
+// FADctrl page
+//
+TP_FADctrl::TP_FADctrl() {
+
+  QString Board;
+  
+  QGridLayout *Layout = new QGridLayout(this);
+  setAttribute(Qt::WA_DeleteOnClose);
+  EddLineDisplay *Line;
+  
+  Line = new EddLineDisplay("FADctrl/Message");
+  Line->setMaximumWidth(200);
+  Layout->addWidget(Line, 0, 0, 1, 3);      
+
+  EddCommand *Command = new EddCommand("FADctrl/Command");
+  Layout->addWidget(Command, 1, 0, 1, 4);    
+
+  EddText *Text = new EddText("FADctrl/ConsoleOut", true);
+  Text->setFixedWidth(400);
+  Layout->addWidget(Text, 2, 0, 4, 4);
+
+  for (int i=0; i<10; i++) {
+    Board = Board.sprintf("FADctrl/Board%.2d/", i);
+    Line = new EddLineDisplay(Board+"Server");
+    Layout->addWidget(Line, i+7, 0, 1, 1);
+    Line = new EddLineDisplay(Board+"BoardID");
+    Layout->addWidget(Line, i+7, 1, 1, 1);
+    Line = new EddLineDisplay(Board+"Temperature", 0);
+    Layout->addWidget(Line, i+7, 2, 1, 1);
+    Line = new EddLineDisplay(Board+"Temperature", 1);
+    Layout->addWidget(Line, i+7, 3, 1, 1);
+    Line = new EddLineDisplay(Board+"Temperature", 2);
+    Layout->addWidget(Line, i+7, 4, 1, 1);
+    Line = new EddLineDisplay(Board+"Temperature", 3);
+    Layout->addWidget(Line, i+7, 5, 1, 1);
+  }
+}
+
+//
 // Event scope page
 //
@@ -1750,4 +1789,5 @@
   connect(TabWidget, SIGNAL(tabCloseRequested(int)), SLOT(DetachTab(int)));
   TabWidget->addTab(new TP_DAQ, "Event scope " + DRSBoard);
+  TabWidget->addTab(new TP_FADctrl, "FADctrl");
   TabWidget->addTab(new TP_Bias, "Bias");
   TabWidget->addTab(new TP_Feedback, "Feedback");
Index: fact/Evidence/Edd/Edd.h
===================================================================
--- fact/Evidence/Edd/Edd.h	(revision 10128)
+++ fact/Evidence/Edd/Edd.h	(revision 10143)
@@ -322,4 +322,11 @@
 };
 
+class TP_FADctrl: public QWidget {
+  Q_OBJECT
+
+  public:
+    TP_FADctrl();
+};
+
 class TP_Feedback: public QWidget {
   Q_OBJECT
Index: fact/Evidence/Evidence.cc
===================================================================
--- fact/Evidence/Evidence.cc	(revision 10128)
+++ fact/Evidence/Evidence.cc	(revision 10143)
@@ -20,5 +20,5 @@
   - A terminate-handler is installed for catching unhandled C++ exceptions.
 
-  Oliver Grimm, June 2010
+  Oliver Grimm
  
 \********************************************************************/
@@ -59,5 +59,5 @@
 
   if (!ServiceOK(DimInfo::getInfo())) return;
-return;
+
   This->Lock();
   ConfigTimeStamp = getInfo()->getInt();
@@ -82,15 +82,4 @@
   // Clear to allow new rpc call
   CurrentItem.clear(); 
-  This->Unlock();
-}
-
-// Request configuration data possible only when answer to previous request received
-void EvidenceServer::Config::RequestNB(string Item) {
-
-  This->Lock();
-  if (CurrentItem.empty()) {
-	CurrentItem = Item;
-	setData(((char *) Item.c_str()));
-  }
   This->Unlock();
 }
@@ -163,5 +152,5 @@
 	Message(ERROR, "pthread_mutex_destroy() failed (%s)", strerror(Ret));
   }
-  
+
   delete MessageService;
   delete[] MessageData;
@@ -170,4 +159,5 @@
 
 // DIM exit handler
+// Note handler runs in DIM thread, thus exit() will call destructors of static objects in this thread
 void EvidenceServer::exitHandler(int Code) {
 
@@ -184,8 +174,8 @@
 
 // Set server message (if Severity is FATAL, exit() will be invoked)
-void EvidenceServer::Message(MessageType Severity, const char *Format, ...) {
-
-  static const char* StateString[] = {"Info", "Warn", "Error", "Fatal"};
+void EvidenceServer::Message(int Severity, const char *Format, ...) {
+
   static char ErrorString[] = "vasprintf() failed in Message()";
+  char Buffer[10];
   char *Text;
   
@@ -206,6 +196,16 @@
   
   // Send message to console and log file
-  printf("%s (%s): %s\n", MessageService->getName(), StateString[Severity], NewMsg->Text);
-  SendToLog("%s (%s): %s", MessageService->getName(), StateString[Severity], NewMsg->Text);
+  const char *Desc;
+  switch (Severity) {
+	case INFO:	Desc = "Info"; break;
+	case WARN:	Desc = "Warn"; break;
+	case ERROR:	Desc = "Error"; break;
+	case FATAL:	Desc = "Fatal"; break;
+	default:	snprintf(Buffer, sizeof(Buffer),  "%d", Severity);
+				Desc = Buffer;
+  }
+  
+  printf("%s (%s): %s\n", MessageService->getName(), Desc, NewMsg->Text);
+  SendToLog("%s (%s): %s", MessageService->getName(), Desc, NewMsg->Text);
 
   // Update DIM message service
@@ -293,8 +293,13 @@
   if (!Blocking) {
  	Lock();
-	if (List.count(Item) > 0) {
-	  ConfClass->RequestNB(Name + " " + Item);
-	  Result = List[Item].Value;
+
+	// Make request if currently non is processed
+	if (ConfClass->CurrentItem.empty()) {
+	  ConfClass->CurrentItem = Item;
+	  ConfClass->setData(((char *) (Name + " " + Item).c_str()));
 	}
+
+	if (List.count(Item) > 0) Result = List[Item].Value;
+	else Result = Default;
 	Unlock();
   }
@@ -353,9 +358,8 @@
 void EvidenceServer::SignalHandler(int Signal) {
 
-  static bool Called = false;
+  static int Count = 0;
 
   // At first invocation just request exit
-  if (!Called) {
-	Called = true;
+  if (++Count == 1) {
 	This->ExitRequest = true;
 	return;
@@ -363,6 +367,12 @@
 
   // If invoked twice, call exit()
-  This->Message(WARN, "Signal handler called again, invoking exit() (signal %d)", Signal);
-  exit(EXIT_FAILURE);
+  if (Count == 2) {
+	This->Message(WARN, "Signal handler called twice, invoking exit() (signal %d)", Signal);
+	exit(EXIT_FAILURE);
+  }
+
+  // If invoked more than twice, call abort()
+  This->Message(WARN, "Signal handler called %d times, invoking abort(). Good bye. (signal %d)", Count, Signal);
+  abort();
 }
 
Index: fact/Evidence/Evidence.h
===================================================================
--- fact/Evidence/Evidence.h	(revision 10128)
+++ fact/Evidence/Evidence.h	(revision 10143)
@@ -30,5 +30,4 @@
 
 		DimInfo *Service;
-		std::string CurrentItem;
 
 		void rpcInfoHandler();
@@ -41,5 +40,5 @@
 
 		int ConfigTimeStamp;
-		void RequestNB(std::string);
+		std::string CurrentItem;
 	};
 
@@ -73,7 +72,7 @@
 	~EvidenceServer();
 
-	enum MessageType {INFO=0, WARN=1, ERROR=2, FATAL=3};
+	enum {INFO=0, WARN=10, ERROR=20, FATAL=30};
 
-	void Message(MessageType, const char *, ...);
+	void Message(int, const char *, ...);
 	static void SendToLog(const char *, ...);
 	std::string GetConfig(std::string, std::string = std::string());
Index: fact/Evidence/readme.txt
===================================================================
--- fact/Evidence/readme.txt	(revision 10128)
+++ fact/Evidence/readme.txt	(revision 10143)
@@ -47,2 +47,5 @@
 12/8/2010	Added command to switch alarm server on/off (command 'Alarm/Switch').
 9/12/2010	Minimum period for checking server status in Alarm set to 5 seconds.
+2/2/2011	Changed encoding of WARN, ERROR and FATAL to 10,20,30 to allow intermediate values.
+			Non-blocking configuration request with default value was not working.
+			Signal handler calls abort() if invoked three times or more.
