Index: /trunk/FACT++/src/smartfact.cc
===================================================================
--- /trunk/FACT++/src/smartfact.cc	(revision 17358)
+++ /trunk/FACT++/src/smartfact.cc	(revision 17359)
@@ -27,4 +27,5 @@
 #include "HeadersFTM.h"
 #include "HeadersFSC.h"
+#include "HeadersGPS.h"
 #include "HeadersMCP.h"
 #include "HeadersLid.h"
@@ -436,5 +437,4 @@
     Time      fMcpConfigurationRunStart;
     EventHist fMcpConfigurationHist;
-
     bool fLastRunFinishedWithZeroEvents;
 
@@ -456,4 +456,6 @@
 
     float fFscControlHumidityAvg;
+
+    deque<float> fTemperatureControlHist;
 
     float  fDriveControlPointingZd;
@@ -533,4 +535,5 @@
     DimDescribedState fDimFadControl;
     DimDescribedState fDimFscControl;
+    DimDescribedState fDimGpsControl;
     DimDescribedState fDimAgilentControl;
     DimDescribedState fDimPwrControl;
@@ -1146,5 +1149,5 @@
 
         // write the history to a file
-        WriteHist(d, "hist-biascontrol-current", fBiasControlCurrentHist, 100);
+        WriteHist(d, "hist-biascontrol-current", fBiasControlCurrentHist, 125);
 
         // --------------------------------------------------------
@@ -1787,4 +1790,100 @@
 
         fFscControlHumidityAvg = num>0 ? avg/num : 0;
+
+        return GetCurrentState();
+    }
+
+    int HandleGpsNema(const EventImp &d)
+    {
+        if (!CheckDataSize(d, "GpsControl:Nema", sizeof(GPS::NEMA)))
+            return GetCurrentState();
+
+        const GPS::NEMA &nema = d.Ref<GPS::NEMA>();
+
+        ostringstream out;
+
+        out << fixed;
+        out << d.GetJavaDate() << '\n';
+
+        switch (nema.qos)
+        {
+        case 1:  out << HTML::kGreen << "\tGPS fix [1]\n"; break;
+        case 2:  out << HTML::kGreen << "\tDifferential fix [2]\n"; break;
+        default: out << HTML::kRed << "\tinvalid [" << nema.qos << "]\n"; break;
+        }
+
+        out << HTML::kWhite << '\t' << nema.count << '\n';
+        out << HTML::kWhite << '\t' << Time(nema.time).GetAsStr("%H:%M:%S") << '\n';
+        out << HTML::kWhite << '\t' << setprecision(4) << nema.lat    << '\n';
+        out << HTML::kWhite << '\t' << setprecision(4) << nema.lng    << '\n';
+        out << HTML::kWhite << '\t' << setprecision(1) << nema.height << "\n";
+        out << HTML::kWhite << '\t' << setprecision(1) << nema.hdop   << "\n";
+        out << HTML::kWhite << '\t' << setprecision(1) << nema.geosep << "\n";
+
+        ofstream(fPath+"/gps.data") << out.str();
+
+        return GetCurrentState();
+    }
+
+    string GetTempColor(float t)
+    {
+        if (t>25 && t<30)
+            return HTML::kGreen;
+
+        if (t<20 || t>35)
+            return HTML::kRed;
+
+        return HTML::kYellow;
+    }
+
+    int HandleTemperatureData(const EventImp &d)
+    {
+        if (!CheckDataSize(d, "Temperature:Data", 3*sizeof(float)))
+            return GetCurrentState();
+
+        const float *temp = d.Ptr<float>();
+
+        ostringstream out;
+
+        out << fixed << setprecision(1);
+        out << d.GetJavaDate() << '\n';
+
+        out << GetTempColor(temp[1]) << '\t' << temp[1] << '\n';
+        out << GetTempColor(temp[0]) << '\t' << temp[0] << '\n';
+        out << GetTempColor(temp[2]) << '\t' << temp[2] << '\n';
+
+        ofstream(fPath+"/temperature.data") << out.str();
+
+        if (!fTemperatureControlHist.empty())
+        {
+            fTemperatureControlHist.push_back(temp[0]);
+            if (fTemperatureControlHist.size()>60) // 1h
+                fTemperatureControlHist.pop_front();
+        }
+
+        WriteHist(d, "hist-temperaturecontrol",
+                  fTemperatureControlHist, 45, 0);
+
+        return GetCurrentState();
+    }
+
+    int HandleAgilentData(const EventImp &d)
+    {
+        if (!CheckDataSize(d, "Agilent:Data", 4*sizeof(float)))
+            return GetCurrentState();
+
+        const float *data = d.Ptr<float>();
+
+        ostringstream out;
+
+        out << fixed << setprecision(1);
+        out << d.GetJavaDate() << '\n';
+
+        out << HTML::kWhite << '\t' << data[0] << '\n';
+        out << HTML::kWhite << '\t' << data[1] << '\n';
+        out << HTML::kWhite << '\t' << data[2] << '\n';
+        out << HTML::kWhite << '\t' << data[3] << '\n';
+
+        ofstream(fPath+"/agilent.data") << out.str();
 
         return GetCurrentState();
@@ -2220,5 +2319,5 @@
         {
             const mysqlpp::StoreQueryResult res =
-                Database(fDatabase).query("SELECT fSourceName, fRightAscension, fDeclination FROM source WHERE fSourceTypeKEY=1").store();
+                Database(fDatabase).query("SELECT fSourceName, fRightAscension, fDeclination FROM Source WHERE fSourceTypeKEY=1").store();
 
             out  << HTML::kWhite << '\t';
@@ -2837,4 +2936,5 @@
             out << GetStateHtml(fDimRateControl,    RateControl::State::kConnected);
             out << GetStateHtml(fDimFscControl,     FSC::State::kConnected);
+            out << GetStateHtml(fDimGpsControl,     GPS::State::kConnected);
             out << GetStateHtml(fDimAgilentControl, Agilent::State::kVoltageOff);
             out << GetStateHtml(fDimPwrControl,     Power::State::kSystemOff);
@@ -2908,4 +3008,5 @@
         fDimFadControl    ("FAD_CONTROL"),
         fDimFscControl    ("FSC_CONTROL"),
+        fDimGpsControl    ("GPS_CONTROL"),
         fDimAgilentControl("AGILENT_CONTROL"),
         fDimPwrControl    ("PWR_CONTROL"),
@@ -2931,4 +3032,5 @@
         fDimFadControl.Subscribe(*this);
         fDimFscControl.Subscribe(*this);
+        fDimGpsControl.Subscribe(*this);
         fDimAgilentControl.Subscribe(*this);
         fDimPwrControl.Subscribe(*this);
@@ -2964,4 +3066,13 @@
         Subscribe("FSC_CONTROL/BIAS_TEMP")
             (bind(&StateMachineSmartFACT::HandleFscBiasTemp,         this, placeholders::_1));
+
+        Subscribe("GPS_CONTROL/NEMA")
+            (bind(&StateMachineSmartFACT::HandleGpsNema,             this, placeholders::_1));
+
+        Subscribe("TEMPERATURE/DATA")
+            (bind(&StateMachineSmartFACT::HandleTemperatureData,    this, placeholders::_1));
+
+        Subscribe("AGILENT_CONTROL/DATA")
+            (bind(&StateMachineSmartFACT::HandleAgilentData,        this, placeholders::_1));
 
         Subscribe("MAGIC_WEATHER/DATA")
