Index: trunk/FACT++/src/smartfact.cc
===================================================================
--- trunk/FACT++/src/smartfact.cc	(revision 14212)
+++ trunk/FACT++/src/smartfact.cc	(revision 14213)
@@ -449,4 +449,6 @@
     set<string>   fErrorList;
     deque<string> fErrorHist;
+    deque<string> fChatHist;
+    Time          fChatLastTime;
 
     Sun   fSun;
@@ -707,5 +709,5 @@
     }
 
-    void HandleFscControlStateChange()
+    void HandleFscControlStateChange(const EventImp &d)
     {
         const int32_t &last  = fDimFscControl.last.second;
@@ -716,8 +718,32 @@
 
         if (last<FSC::State::kConnected && state==FSC::State::kConnected)
+        {
+            AddMcpConfigurationHist(d, "<B>Camera swiched on</B>");
             SetAudio("startup");
+        }
 
         if (last==FSC::State::kConnected && state<FSC::State::kConnected)
+        {
+            AddMcpConfigurationHist(d, "<B>Camera swiched off</B>");
             SetAudio("shutdown");
+        }
+    }
+
+    void AddMcpConfigurationHist(const EventImp &d, const string &msg)
+    {
+        if (d.GetTime()>fMcpConfigurationLastTime+boost::posix_time::hours(12))
+            fMcpConfigurationHist.clear();
+
+        fMcpConfigurationLastTime  = d.GetTime();
+        fMcpConfigurationHist.push_back(d.GetTimeAsStr("%H:%M:%S ")+msg+"<br/>");
+
+        ostringstream out;
+        out << d.GetJavaDate() << '\n';
+        out << HTML::kWhite << '\t';
+        for (auto it=fMcpConfigurationHist.rbegin(); it!=fMcpConfigurationHist.rend(); it++)
+            out << *it;
+        out << '\n';
+
+        ofstream(fPath+"/observations.data") << out.str();
     }
 
@@ -734,7 +760,4 @@
         }
 
-        if (d.GetTime()>fMcpConfigurationLastTime+boost::posix_time::hours(12))
-            fMcpConfigurationHist.clear();
-
         // If a run ends...
         if (fMcpConfigurationState==MCP::State::kTakingData && d.GetQoS()==MCP::State::kIdle)
@@ -747,13 +770,14 @@
                 SetAudio("losticks");
 
+            fLastRunFinishedWithZeroEvents = fFadControlNumEvents==0;
+
             ostringstream out;
-            out << d.GetTimeAsStr("%H:%M:%S") << " <#darkred>" << d.Ptr<char>(16);
+            out << "<#darkred>" << d.Ptr<char>(16);
             if (!fDriveControlSourceName.empty())
                 out << " [" << fDriveControlSourceName << ']';
             out << " (N=" << fFadControlNumEvents << ')';
-            out << "</#><br/>";
-            fMcpConfigurationHist.push_back(out.str());
-
-            fLastRunFinishedWithZeroEvents = fFadControlNumEvents==0;
+            out << "</#>";
+
+            AddMcpConfigurationHist(d, out.str());
         }
 
@@ -764,11 +788,12 @@
 
             ostringstream out;
-            out << d.GetTimeAsStr("%H:%M:%S") << " <#darkgreen>" << fMcpConfigurationName;
+            out << "<#darkgreen>" << fMcpConfigurationName;
             if (!fDriveControlSourceName.empty())
                 out << " [" << fDriveControlSourceName << ']';
             if (fFadControlStartRun>0)
                 out << " (Run " << fFadControlStartRun << ')';
-            out << "</#><br/>";
-            fMcpConfigurationHist.push_back(out.str());
+            out << "</#>";
+
+            AddMcpConfigurationHist(d, out.str());
         }
 
@@ -777,14 +802,4 @@
         fMcpConfigurationMaxEvents = d.Get<uint64_t>(8);
         fMcpConfigurationName      = d.Ptr<char>(16);
-        fMcpConfigurationLastTime  = d.GetTime();
-
-        ostringstream out;
-        out << d.GetJavaDate() << '\n';
-        out << HTML::kWhite << '\t';
-        for (auto it=fMcpConfigurationHist.rbegin(); it!=fMcpConfigurationHist.rend(); it++)
-            out << *it;
-        out << '\n';
-
-        ofstream(fPath+"/observations.data") << out.str();
 
         return GetCurrentState();
@@ -1659,4 +1674,42 @@
     }
 
+    int HandleChatMsg(const EventImp &d)
+    {
+        if (d.GetSize()==0 || d.GetQoS()!=MessageImp::kMessage)
+            return GetCurrentState();
+
+        if (d.GetTime()>fChatLastTime+boost::posix_time::hours(12))
+            fChatHist.clear();
+
+        if (Time()<d.GetTime()+boost::posix_time::minutes(1))
+            SetAudio("message");
+
+        fChatLastTime = d.GetTime();
+
+        string msg;
+        msg += d.GetTimeAsStr("%H:%M:%S ");
+        msg += d.Ptr<char>();
+
+        fChatHist.push_front(msg);
+        if (fChatHist.size()>80)
+            fChatHist.pop_back();
+
+        ostringstream out;
+        out << setprecision(3);
+        out << Header(d) << '\n';
+        out << HTML::kWhite << '\t';
+
+        out << "<->";
+        for (auto it=fChatHist.begin(); it!=fChatHist.end(); it++)
+            out << *it << "<br/>";
+        out << "</->";
+
+        out << '\n';
+
+        ofstream(fPath+"/chat.data") << out.str();
+
+        return GetCurrentState();
+    }
+
     // -------------------------------------------------------------------
 
@@ -1785,6 +1838,7 @@
 
         double max   = 0;
-        double maxjd = jd0;
-
+        double maxjd = 0;
+
+        int cnt = 0;
 
         vector<float> alt;
@@ -1797,5 +1851,5 @@
             ln_get_hrz_from_equ(pos, observer, jd+h, &hrz);
 
-            if (h>jd0 && h<jd1 && hrz.alt>15)
+            if (h>jd0 && h<jd1)
                 alt.push_back(hrz.alt);
 
@@ -1805,10 +1859,13 @@
                 maxjd = jd+h;
             }
-        }
-
-        if (max<15)
+
+            if (h>jd0 && h<jd1 && hrz.alt>15)
+                cnt++;
+        }
+
+        if (max<=15 || cnt==0)
             return make_pair(vector<float>(), make_pair(Time(), 0));
 
-        return make_pair(alt, make_pair(maxjd, maxjd>jd0+jd&&maxjd<jd1+jd?max:0));
+        return make_pair(alt, make_pair(maxjd, maxjd>jd+jd0&&maxjd<jd+jd1?max:0));
     }
 #endif
@@ -2268,5 +2325,5 @@
                 if (dev>60)   // ~1.5mm
                     col = HTML::kYellow;
-                if (dev>100)  // ~1/4 of a pixel ~ 2.5mm
+                if (dev>120)  // ~1/4 of a pixel ~ 2.5mm
                     col = HTML::kRed;
             }
@@ -2315,5 +2372,11 @@
         if (fDimDNS.online() && fDimFscControl.state()>FSC::State::kDisconnected && fFscControlTemperatureHist.size()>0)
         {
-            out << HTML::kGreen << '\t' << fFscControlTemperatureHist.back() << '\n';
+            string col = HTML::kGreen;
+            if (fFscControlTemperatureHist.back()>5)
+                col = HTML::kYellow;
+            if (fFscControlTemperatureHist.back()>8)
+                col = HTML::kRed;
+
+            out << col << '\t' << fFscControlTemperatureHist.back() << '\n';
         }
         else
@@ -2462,7 +2525,7 @@
             out << GetStateHtml(fDimRateControl,  4);
             out << GetStateHtml(fDimFscControl,   2);
+            out << GetStateHtml(fDimRateScan,     4);
             out << GetStateHtml(fDimMagicWeather, 2);
             out << GetStateHtml(fDimTngWeather,   2);
-            out << GetStateHtml(fDimRateScan,     4);
             out << GetStateHtml(fDimChat,         0);
             out << GetStateHtml(fDimSkypeClient,  1);
@@ -2537,5 +2600,5 @@
         fDimSkypeClient.Subscribe(*this);
 
-        fDimFscControl.SetCallback(bind(&StateMachineSmartFACT::HandleFscControlStateChange, this));
+        fDimFscControl.SetCallback(bind(&StateMachineSmartFACT::HandleFscControlStateChange, this, placeholders::_1));
         fDimControl.SetCallback(bind(&StateMachineSmartFACT::HandleControlStateChange, this, placeholders::_1));
         fDimControl.AddCallback("dotest.dim", bind(&StateMachineSmartFACT::HandleDoTest, this, placeholders::_1));
@@ -2582,4 +2645,6 @@
         Subscribe("FAD_CONTROL/DRS_RUNS")
             (bind(&StateMachineSmartFACT::HandleFadDrsRuns,          this, placeholders::_1));
+        Subscribe("FAD_CONTROL/EVENT_DATA")
+            (bind(&StateMachineSmartFACT::HandleFadEventData,        this, placeholders::_1));
 
         Subscribe("FTM_CONTROL/TRIGGER_RATES")
@@ -2596,6 +2661,7 @@
             (bind(&StateMachineSmartFACT::HandleRateScanData,        this, placeholders::_1));
 
-        Subscribe("FAD_CONTROL/EVENT_DATA")
-            (bind(&StateMachineSmartFACT::HandleFadEventData,        this, placeholders::_1));
+        Subscribe("CHAT/MESSAGE")
+            (bind(&StateMachineSmartFACT::HandleChatMsg,             this, placeholders::_1));
+
 
         // =================================================================
@@ -2653,6 +2719,5 @@
         out << Time().JavaDate() << '\n';
 
-        ofstream(fPath+"/errorhist.data")    << out.str();
-        ofstream(fPath+"/error.data")        << out.str();
+        ofstream(fPath+"/error.data") << out.str();
 
         return -1;
