Index: /trunk/FACT++/src/smartfact.cc
===================================================================
--- /trunk/FACT++/src/smartfact.cc	(revision 14978)
+++ /trunk/FACT++/src/smartfact.cc	(revision 14979)
@@ -190,5 +190,5 @@
         };
 
-        description = state[name];
+        description = name[state];
 
         const string arr = isday ?
@@ -592,5 +592,5 @@
 
     template<class T>
-        void WriteBinaryVec(const Time &tm, const string &fname, const vector<T> &vec, double scale, double offset=0, const string &title="")
+        void WriteBinaryVec(const Time &tm, const string &fname, const vector<T> &vec, double scale, double offset=0, const string &title="", const string &col="")
     {
         if (vec.size()==0)
@@ -611,4 +611,6 @@
             out << stat.max << '\x7f';
         }
+        if (!col.empty())
+            out << col;
         for (auto it=vec.begin(); it!=vec.end(); it++)
         {
@@ -633,5 +635,5 @@
         ofstream(fPath+"/"+fname+".bin") << out.str();
     }
-
+    /*
     template<class T>
         void WriteBinaryVec(const EventImp &d, const string &fname, const vector<T> &vec, double scale, double offset=0, const string &title="")
@@ -650,5 +652,18 @@
     {
         WriteBinaryVec(d.GetTime(), fname, vector<T>(&t, &t+1), scale, offset);
-    }
+    }*/
+
+    template<class T>
+        void WriteHist(const EventImp &d, const string &fname, const T &t, double scale, double offset=0)
+    {
+        WriteBinaryVec(d.GetTime(), fname, vector<T>(&t, &t+1), scale, offset, "", "000");
+    }
+
+    template<class T>
+        void WriteCam(const EventImp &d, const string &fname, const T &t, double scale, double offset=0)
+    {
+        WriteBinaryVec(d.GetTime(), fname, vector<T>(&t, &t+1), scale, offset, "", "");
+    }
+
 
     // -------------------------------------------------------------------
@@ -741,7 +756,8 @@
 #endif
 
-        // [0] DimControl::kReady (Idle)
-        // [1] DimControl::kLoad
-        // [2] DimControl::kStarted
+        // [0] DimControl::kIdle
+        // [1] DimControl::kLoading
+        // [2] DimControl::kCompiling
+        // [3] DimControl::kRinning
         if (d.GetQoS()==1)
         {
@@ -754,5 +770,5 @@
             HandleControlMessageImp(Event(d, file.data(), file.length()+1));
 
-        // Not that this will also "ding" just after program startup
+        // Note that this will also "ding" just after program startup
         // if the dimctrl is still in state -3
         if (d.GetQoS()==0)
@@ -875,5 +891,5 @@
         ofstream(fPath+"/"+name+".data") << out.str();
 
-        WriteBinary(d, "hist-magicweather-"+name, fMagicWeatherHist[i], max-min, min);
+        WriteHist(d, "hist-magicweather-"+name, fMagicWeatherHist[i], max-min, min);
     }
 
@@ -938,5 +954,5 @@
         const double scale = stat.max>0 ? pow(10, ceil(log10(stat.max))) : 0;
 
-        WriteBinary(d, "hist-tng-dust", fTngWeatherDustHist, scale);
+        WriteHist(d, "hist-tng-dust", fTngWeatherDustHist, scale);
 
         ostringstream out;
@@ -1004,5 +1020,5 @@
             fDriveControlTrackingDevHist.pop_front();
 
-        WriteBinary(d, "hist-control-deviation", fDriveControlTrackingDevHist, 120);
+        WriteHist(d, "hist-control-deviation", fDriveControlTrackingDevHist, 120);
 
         ostringstream out;
@@ -1094,5 +1110,5 @@
 
         // Write the 160 patch values to a file
-        WriteBinary(d, "cam-feedback-deviation", dev, 1);
+        WriteCam(d, "cam-feedback-deviation", dev, 1);
 
         const Statistics stat(dev, 3);
@@ -1134,7 +1150,7 @@
 
         if (fDimBiasControl.state()==BIAS::State::kVoltageOn)
-            WriteBinary(d, "cam-biascontrol-voltage", val, 10, 65);
+            WriteCam(d, "cam-biascontrol-voltage", val, 10, 65);
         else
-            WriteBinary(d, "cam-biascontrol-voltage", val, 75);
+            WriteCam(d, "cam-biascontrol-voltage", val, 75);
 
         ostringstream out;
@@ -1210,5 +1226,5 @@
 
         // Write the 160 patch values to a file
-        WriteBinary(d, "cam-biascontrol-current", val, 100);
+        WriteCam(d, "cam-biascontrol-current", val, 100);
 
         const Statistics stat(v, 0, 3);
@@ -1224,5 +1240,5 @@
 
         // write the history to a file
-        WriteBinary(d, "hist-biascontrol-current", fBiasControlCurrentHist, 100);
+        WriteHist(d, "hist-biascontrol-current", fBiasControlCurrentHist, 100);
 
         const string col0 = cal ? HTML::kGreen : HTML::kWhite;
@@ -1414,10 +1430,10 @@
         // FIXME: Add statistics for all kind of rates
 
-        WriteBinary(d, "hist-ftmcontrol-triggerrate",
-                    fFtmControlTriggerRateHist, 100);
-        WriteBinary(d, "cam-ftmcontrol-boardrates",
-                    vector<float>(brates, brates+40), 10);
-        WriteBinary(d, "cam-ftmcontrol-patchrates",
-                    vector<float>(prates, prates+160), 10);
+        WriteHist(d, "hist-ftmcontrol-triggerrate",
+                  fFtmControlTriggerRateHist, 100);
+        WriteCam(d, "cam-ftmcontrol-boardrates",
+                 vector<float>(brates, brates+40), 10);
+        WriteCam(d, "cam-ftmcontrol-patchrates",
+                 vector<float>(prates, prates+160), 10);
 
         ostringstream out;
@@ -1462,6 +1478,6 @@
         vector<uint16_t> vecb(dat.fMultiplicity, dat.fMultiplicity+40);
 
-        WriteBinary(d, "cam-ftmcontrol-thresholds-patch", vecp, 1000);
-        WriteBinary(d, "cam-ftmcontrol-thresholds-board", vecb,  100);
+        WriteCam(d, "cam-ftmcontrol-thresholds-patch", vecp, 1000);
+        WriteCam(d, "cam-ftmcontrol-thresholds-board", vecb,  100);
 
         const Statistics statp(vecp);
@@ -1597,7 +1613,7 @@
         switch (fFadControlDrsStep)
         {
-        case 0:  WriteBinary(d, "cam-fadcontrol-eventdata", max, 2,   -1); break;
-        case 1:  WriteBinary(d, "cam-fadcontrol-eventdata", max, 2,    0); break;
-        default: WriteBinary(d, "cam-fadcontrol-eventdata", max, 0.25, 0); break;
+        case 0:  WriteCam(d, "cam-fadcontrol-eventdata", max, 2,   -1); break;
+        case 1:  WriteCam(d, "cam-fadcontrol-eventdata", max, 2,    0); break;
+        default: WriteCam(d, "cam-fadcontrol-eventdata", max, 0.25, 0); break;
         }
 
@@ -1674,6 +1690,6 @@
         ofstream(fPath+"/fsc.data") << out.str();
 
-        WriteBinary(d, "hist-fsccontrol-temperature",
-                    fFscControlTemperatureHist, 10);
+        WriteHist(d, "hist-fsccontrol-temperature",
+                  fFscControlTemperatureHist, 10);
 
         return GetCurrentState();
@@ -1730,6 +1746,6 @@
         fRateScanBoard %= 40;
 
-        WriteBinary(d, "hist-ratescan",      fRateScanDataHist[0],                10, -2);
-        WriteBinary(d, "cam-ratescan-board", fRateScanDataHist[fRateScanBoard+1], 10, -4);
+        WriteHist(d, "hist-ratescan",      fRateScanDataHist[0],                10, -2);
+        WriteCam(d,  "cam-ratescan-board", fRateScanDataHist[fRateScanBoard+1], 10, -4);
 
         ostringstream out;
@@ -1764,5 +1780,5 @@
             fRateControlThreshold.pop_front();
 
-        WriteBinary(d, "hist-ratecontrol-threshold", fRateControlThreshold, 1000);
+        WriteHist(d, "hist-ratecontrol-threshold", fRateControlThreshold, 1000);
 
         return GetCurrentState();
@@ -1997,7 +2013,10 @@
                 const double angle = m.Angle(src->ra, src->dec);
 
-                const double lc = angle*hrz.alt*pow(disk, 6)/360/360;
-
-                cur = 7.7+4942*lc;
+                // Current prediction
+                const double cang = sin(angle  *M_PI/180);
+                const double calt = sin(hrz.alt*M_PI/180);
+
+                const double lc = calt>0 ? cang*sqrt(calt)*pow(disk, 3) : -1;
+                cur = lc>0 ? 8+104.5*lc : -1;
 
                 vec.push_back(cur); // Covert LC to pixel current in uA
@@ -2087,6 +2106,31 @@
         out4 << now.JavaDate() << '\n';
 
-        multimap<Time, pair<string, float>> culmination;
-        multimap<Time, pair<string, float>> lightcond;
+        struct Entry
+        {
+            string name;
+            float value;
+            int color;
+            Entry(const string &n, float v, int c) : name(n), value(v), color(c%8) { }
+
+            const string &Col() const
+            {
+                // If this list is updatd the number count in the constructor needs
+                // to be updated, too
+                static const string hcol[] = { "888", "8cf", "c8f", "bbb", "8fc", "cf8", "f8c", "fc8" };
+                return hcol[color];
+            }
+
+            vector<float> GetColor(double scale, double offset=0) const
+            {
+                vector<float> rc(3);
+                rc[0] = double(Col()[0])*scale/126+offset;
+                rc[1] = double(Col()[1])*scale/126+offset;
+                rc[2] = double(Col()[2])*scale/126+offset;
+                return rc;
+            }
+        };
+
+        multimap<Time, Entry> culmination;
+        multimap<Time, Entry> lightcond;
         vector<vector<float>> alt;
         vector<vector<float>> cur;
@@ -2097,9 +2141,17 @@
         observer.lat = lat;
 
-        const pair<vector<float>, pair<Time, float>> vism = GetVisibility(0, &observer, now.JD());
+        int ccol = 0;
+        int lcol = 0;
+
+        /*const*/ pair<vector<float>, pair<Time, float>> vism = GetVisibility(0, &observer, now.JD());
         if (vism.first.size()>0)
         {
+            const Entry entry("Moon", vism.second.second, ccol);
+            culmination.insert(make_pair(vism.second.first, entry));
+            const vector<float> col = entry.GetColor(75, 15);
+            vism.first.insert(vism.first.begin(), col.begin(), col.end());
             alt.push_back(vism.first);
-            culmination.insert(make_pair(vism.second.first, make_pair("Moon", vism.second.second)));
+
+            ccol++;
         }
 #endif
@@ -2129,15 +2181,25 @@
                 ln_get_hrz_from_equ(&pos, &observer, now.JD(), &hrz);
 
-                const pair<vector<float>, pair<Time, float>> vis = GetVisibility(&pos, &observer, now.JD());
+                /*const*/ pair<vector<float>, pair<Time, float>> vis = GetVisibility(&pos, &observer, now.JD());
                 if (vis.first.size()>0)
                 {
+                    const Entry entry(name, vis.second.second, ccol);
+                    culmination.insert(make_pair(vis.second.first, entry));
+                    const vector<float> col = entry.GetColor(75, 15);
+                    vis.first.insert(vis.first.begin(), col.begin(), col.end());
                     alt.push_back(vis.first);
-                    culmination.insert(make_pair(vis.second.first, make_pair(name, vis.second.second)));
-
-                    const pair<vector<float>, pair<Time, float>> lc = GetLightCondition(&pos, &observer, now.JD());
+
+                    ccol++;
+
+                    /*const*/ pair<vector<float>, pair<Time, float>> lc = GetLightCondition(&pos, &observer, now.JD());
                     if (lc.first.size()>0)
                     {
+                        const Entry entry2(name, lc.second.second, lcol);
+                        lightcond.insert(make_pair(lc.second.first, entry2));
+                        const vector<float> col2 = entry2.GetColor(100);
+                        lc.first.insert(lc.first.begin(), col2.begin(), col2.end());
                         cur.push_back(lc.first);
-                        lightcond.insert(make_pair(lc.second.first, make_pair(name, lc.second.second)));
+
+                        lcol++;
                     }
                 }
@@ -2172,19 +2234,22 @@
             for (auto it=culmination.begin(); it!=culmination.end(); it++)
             {
+                const Entry &e = it->second;
                 if (it!=culmination.begin())
                     out3 << ", ";
-                out3 << "<B>" << it->second.first << "</B>";
-                if (it->second.second>0)
-                    out3 << " [" << nearbyint(90-it->second.second) << "&deg;]";
+                out3 << "<B#" << e.Col() << ">" << e.name << "</B>";
+                if (e.value>0)
+                    out3 << " [" << nearbyint(90-e.value) << "&deg;]";
             }
 
             out4 << setprecision(3);
+
             for (auto it=lightcond.begin(); it!=lightcond.end(); it++)
             {
+                const Entry &e = it->second;
                 if (it!=lightcond.begin())
                     out4 << ", ";
-                out4 << "<B>" << it->second.first << "</B>";
-                if (it->second.second>0)
-                    out4 << " [" << nearbyint(it->second.second) << "]";
+                out4 << "<B#" << e.Col() << ">" << e.name << "</B>";
+                if (e.value>0)
+                    out4 << " [" << nearbyint(e.value) << "]";
             }
 
Index: /trunk/FACT++/www/smartfact/index.js
===================================================================
--- /trunk/FACT++/www/smartfact/index.js	(revision 14978)
+++ /trunk/FACT++/www/smartfact/index.js	(revision 14979)
@@ -1091,4 +1091,5 @@
             form = "&mdash;";
 
+        form = form.replace(/<B#(.*?)>/g, "<b style='background:#$1'>");
         form = form.replace(/<#(.*?)>/g, "<font color='$1'>");
         form = form.replace(/<([\+-])>/g, "<font size='$11'>");
@@ -1430,4 +1431,5 @@
 
     ctx.strokeStyle = "#666";
+    ctx.fillStyle = "#"+color(100);
 
     // --- data ---
@@ -1435,6 +1437,9 @@
     for (var j=1; j<data.length; j++)
     {
-        if (data[j].length<2)
+        if (data[j].length<5)
             continue;
+
+        ctx.strokeStyle = "#"+data[j].substr(0, 3);
+        data[j] = data[j].substr(3);
 
         ctx.beginPath();
@@ -1446,5 +1451,4 @@
         ctx.lineTo(cw-mr, ch-mb);
         ctx.lineTo(ml,    ch-mb);
-        ctx.fillStyle = "#"+color(100);
         ctx.stroke();
 
