Index: /trunk/FACT++/src/smartfact.cc
===================================================================
--- /trunk/FACT++/src/smartfact.cc	(revision 18407)
+++ /trunk/FACT++/src/smartfact.cc	(revision 18408)
@@ -8,4 +8,5 @@
 
 #include <sys/stat.h> //for file stats
+#include <sys/statvfs.h> //for file statvfs
 
 #include "Dim.h"
@@ -33,4 +34,5 @@
 #include "HeadersDrive.h"
 #include "HeadersPower.h"
+#include "HeadersPFmini.h"
 #include "HeadersAgilent.h"
 #include "HeadersFeedback.h"
@@ -552,4 +554,7 @@
 
     float fFscControlHumidityAvg;
+
+    deque<float> fPfMiniHumidityHist;
+    deque<float> fPfMiniTemperatureHist;
 
     deque<float> fTemperatureControlHist;
@@ -631,4 +636,5 @@
     DimDescribedState fDimFadControl;
     DimDescribedState fDimFscControl;
+    DimDescribedState fDimPfMiniControl;
     DimDescribedState fDimGpsControl;
     DimDescribedState fDimSqmControl;
@@ -1903,4 +1909,38 @@
 
         fFscControlHumidityAvg = num>0 ? avg/num : 0;
+
+        return GetCurrentState();
+    }
+
+    int HandlePfMiniData(const EventImp &d)
+    {
+        if (!CheckDataSize(d, "PfMini:Data", sizeof(PFmini::Data)))
+            return GetCurrentState();
+
+        const PFmini::Data &data = d.Ref<PFmini::Data>();
+
+        ostringstream out;
+
+        out << fixed << setprecision(1);
+        out << d.GetJavaDate() << '\n';
+
+        out << HTML::kGreen << '\t' << data.temp << '\n';
+        out << HTML::kGreen << '\t' << data.hum  << '\n';
+
+        ofstream(fPath+"/pfmini.data") << out.str();
+
+        fPfMiniTemperatureHist.push_back(data.temp);
+        if (fPfMiniTemperatureHist.size()>60*4) // 1h
+            fPfMiniTemperatureHist.pop_front();
+
+        fPfMiniHumidityHist.push_back(data.hum);
+        if (fPfMiniHumidityHist.size()>60*4) // 1h
+            fPfMiniHumidityHist.pop_front();
+
+        WriteHist(d, "hist-pfmini-temp",
+                  fPfMiniTemperatureHist, 45, 0);
+
+        WriteHist(d, "hist-pfmini-hum",
+                  fPfMiniHumidityHist, 100, 0);
 
         return GetCurrentState();
@@ -2569,4 +2609,32 @@
         // ==============================================================
 
+        bool reqscript = false;
+
+#ifdef HAVE_SQL
+        try
+        {
+            const string query = Tools::Form("SELECT COUNT(*) FROM calendar.Data WHERE NOT u LIKE 'moon' AND y=%d AND m=%d AND d=%d",
+                                             now.NightAsInt()/10000, (now.NightAsInt()/100)%100-1, now.NightAsInt()%100);
+
+            const mysqlpp::StoreQueryResult res = Database(fDatabase).query(query).store();
+
+            const uint32_t cnt = res[0][0];
+
+            reqscript = cnt>0 && fSun.state>=2 && fSun.state<=6;
+        }
+        catch (const exception &e)
+        {
+            Out() << e.what() << endl;
+        }
+#endif
+        // ==============================================================
+
+        struct statvfs vfs;
+        statvfs("/daq", &vfs);
+
+        const uint64_t freedaq = vfs.f_bsize*vfs.f_bavail;
+
+        // ==============================================================
+
         const bool data_taking =
             fDimMcp.state()==MCP::State::kTriggerOn ||
@@ -2596,4 +2664,7 @@
                            "<b>datalogger not ready</b>");
 
+        newerr |= SetError(fDimControl.state()!=3 && reqscript,
+                           "<b>No script running during datataking time.</b>");
+
         //newerr |= SetError(fDimDriveControl.state()==Drive::State::kLocked,
         //                   "<b><#darkred>Drive in LOCKED state, drive was automatically parked</#></b>");
@@ -2622,4 +2693,9 @@
                            "Average camera humidity exceed 60%");
 
+        newerr |= SetError(!fPfMiniHumidityHist.empty() && fPfMiniHumidityHist.back()>40,
+                           "Camera humidity inside camera exceeds 40% (PFmini)");
+        newerr |= SetError(!fTemperatureControlHist.empty() && (fTemperatureControlHist.back()<26.5 || fTemperatureControlHist.back()>29),
+                           "Container temperature outside [26.5;29]&deg;C");
+
         newerr |= SetError(!fMagicWeatherHist[kHum].empty() && fMagicWeatherHist[kHum].back()>98 && fDimLidControl.state()==Lid::State::kOpen,
                            "Outside humidity exceeds 98% while lid is open");
@@ -2650,5 +2726,8 @@
 
         newerr |= SetError(fFreeSpace<50000000000,
-                           "Less than 50GB disk space left.");
+                           "Less than 50GB disk space left on newdaq.");
+
+        newerr |= SetError(freedaq<80000000000,
+                           "Less than 80GB disk space left on daq.");
 
         newerr |= SetError(fDimPwrControl.state()==Power::State::kCoolingFailure,
@@ -3055,4 +3134,5 @@
             out << GetStateHtml(fDimRateControl,    RateControl::State::kConnected);
             out << GetStateHtml(fDimFscControl,     FSC::State::kConnected);
+            out << GetStateHtml(fDimPfMiniControl,  PFmini::State::kConnected);
             out << GetStateHtml(fDimGpsControl,     GPS::State::kConnected);
             out << GetStateHtml(fDimSqmControl,     SQM::State::kConnected);
@@ -3079,4 +3159,14 @@
 
             out << col << '\t' << Tools::Scientific(fFreeSpace) << "B\n";
+
+            col = HTML::kRed;
+            if (freedaq>uint64_t(199999999999))
+                col = HTML::kYellow;
+            if (freedaq>uint64_t(999999999999))
+                col = HTML::kGreen;
+            if (freedaq==UINT64_MAX)
+                col = HTML::kWhite;
+
+            out << col << '\t' << Tools::Scientific(freedaq) << "B\n";
 
             out << HTML::kGreen << '\t' << dt.str().substr(0, dt.str().length()-7) << '\n';
@@ -3130,4 +3220,5 @@
         fDimFadControl    ("FAD_CONTROL"),
         fDimFscControl    ("FSC_CONTROL"),
+        fDimPfMiniControl ("PFMINI_CONTROL"),
         fDimGpsControl    ("GPS_CONTROL"),
         fDimSqmControl    ("SQM_CONTROL"),
@@ -3157,4 +3248,5 @@
         fDimFadControl.Subscribe(*this);
         fDimFscControl.Subscribe(*this);
+        fDimPfMiniControl.Subscribe(*this);
         fDimGpsControl.Subscribe(*this);
         fDimSqmControl.Subscribe(*this);
@@ -3194,4 +3286,7 @@
         Subscribe("FSC_CONTROL/BIAS_TEMP")
             (bind(&StateMachineSmartFACT::HandleFscBiasTemp,         this, placeholders::_1));
+
+        Subscribe("PFMINI_CONTROL/DATA")
+            (bind(&StateMachineSmartFACT::HandlePfMiniData,          this, placeholders::_1));
 
         Subscribe("GPS_CONTROL/NEMA")
