Index: trunk/FACT++/src/smartfact.cc
===================================================================
--- trunk/FACT++/src/smartfact.cc	(revision 13496)
+++ trunk/FACT++/src/smartfact.cc	(revision 13497)
@@ -62,4 +62,5 @@
     DimStampedInfo fDimMagicWeatherData;
 
+    DimStampedInfo fDimFeedback;
     DimStampedInfo fDimFeedbackCalibration;
 
@@ -75,4 +76,7 @@
     enum weather_t { kTemp = 0, kDew, kHum, kPress, kWind, kGusts, kDir };
     float fMagicWeatherData[7];
+
+    vector<float> fFeedbackCalibration;
+    vector<float> fBiasControlVoltageVec;
 
     float  fBiasControlVoltageMed;
@@ -231,8 +235,25 @@
     void HandleFeedbackCalibration(const DimData &d)
     {
+        if (!CheckDataSize(d, "Feedback:Calibration", 3*4*416))
+        {
+            fFeedbackCalibration.clear();
+            return;
+        }
+
+        const float *ptr = d.ptr<float>();
+        fFeedbackCalibration.assign(ptr+2*416, ptr+3*416);
+    }
+
+    void HandleBiasControlVoltage(const DimData &d)
+    {
         if (!CheckDataSize(d, "BiasControl:Voltage", 1664))
-            return;
-
-        vector<float> v(d.ptr<float>(), d.ptr<float>()+320);
+        {
+            fBiasControlVoltageVec.clear();
+            return;
+        }
+
+        fBiasControlVoltageVec.assign(d.ptr<float>(), d.ptr<float>()+320);
+
+        vector<float> v(fBiasControlVoltageVec);
         sort(v.begin(), v.end());
 
@@ -245,20 +266,4 @@
     }
 
-    void HandleBiasControlVoltage(const DimData &d)
-    {
-        if (!CheckDataSize(d, "BiasControl:Voltage", 1664))
-            return;
-
-        vector<float> v(d.ptr<float>(), d.ptr<float>()+320);
-        sort(v.begin(), v.end());
-
-        fBiasControlVoltageMed = (v[159]+v[160])/2;
-
-        const char *ptr = d.ptr<char>();
-
-        ofstream fout("www/biascontrol-voltage.bin");
-        fout.write(ptr, 320*sizeof(float));
-    }
-
     void HandleBiasControlCurrent(const DimData &d)
     {
@@ -266,5 +271,25 @@
             return;
 
-        vector<uint16_t> v(d.ptr<uint16_t>(), d.ptr<uint16_t>()+320);
+        vector<float> v(320);
+        for (int i=0; i<320; i++)
+            v[i] = d.ptr<uint16_t>()[i];
+
+        if (fFeedbackCalibration.size()>0 && fBiasControlVoltageVec.size()>0)
+            for (int i=0; i<320; i++)
+                v[i] -= fBiasControlVoltageVec[i]/fFeedbackCalibration[i]*1e6;
+
+        vector<uint8_t> val(160, 0);
+        for (int i=0; i<160; i++)
+        {
+            const float I = max(v[i*2], v[i*2+1]);
+
+            float range = nearbyint(128*I/1000); // [0, 1000uA]
+            if (range>127)
+                range=127;
+            if (range<0)
+                range=0;
+            val[i] = (uint8_t)range;
+        }
+
         sort(v.begin(), v.end());
 
@@ -273,8 +298,8 @@
         fBiasControlCurrentMax = v[316]            * 5000./4096;
 
-        const char *ptr = d.ptr<char>();
+        const char *ptr = reinterpret_cast<char*>(val.data());
 
         ofstream fout("www/biascontrol-current.bin");
-        fout.write(ptr, 320*sizeof(uint16_t));
+        fout.write(ptr, 160*sizeof(uint8_t));
     }
 
@@ -425,9 +450,15 @@
         out << "n/a\n";
 
+        const static string kWhite  = "#ffffff";
+        const static string kYellow = "#fffff0";
+        const static string kRed    = "#fff8f0";
+        const static string kGreen  = "#f0fff0";
+        const static string kBlue   = "#f0f0ff";
+
         // ------------------ Drive -----------------
         if (fStatusDriveControl.second>=5)   // Armed, Moving, Tracking
         {
             const State rc = fNetwork.GetState("DRIVE_CONTROL", fStatusDriveControl.second);
-            out << "#ffffff\t";
+            out << kWhite << "\t";
             out << rc.name << '\t';
             out << fDriveControlPointingZd  << '\t';
@@ -437,5 +468,5 @@
         }
         else
-            out << "#ffffff\t\t\t\t\t\n";
+            out << kWhite << "\t\t\t\t\t\n";
 
         // --------------- MagicWeather -------------
@@ -443,16 +474,16 @@
         {
             const float diff = fMagicWeatherData[kTemp]-fMagicWeatherData[kDew];
-            string col1 = "#fff8f0";
+            string col1 = kRed;
             if (diff>0.3)
-                col1="#fffff0";
+                col1 = kYellow;
             if (diff>0.7)
-                col1="#f0fff0";
+                col1 = kGreen;
 
             const float wind = fMagicWeatherData[kGusts];
-            string col2 = "#f0fff0";
+            string col2 = kGreen;
             if (wind>35)
-                col2="#fffff0";
+                col2 = kYellow;
             if (wind>50)
-                col2="#fff8f0";
+                col2 = kRed;
 
             out << col1 << "\t";
@@ -463,5 +494,5 @@
         }
         else
-            out << "#ffffff\t\t\n\n";
+            out << kWhite << "\t\t\n\n";
 
         // --------------- BiasControl -------------
@@ -470,9 +501,12 @@
             fStatusBiasControl.second==9)   // Off
         {
-            string col = fBiasControlVoltageMed>3?"#fff8f0":"#ffffff";
+            string col = fBiasControlVoltageMed>3?kGreen:kWhite;
             if (fBiasControlCurrentMax>280)
-                col = "#fffff0";
+                col = kYellow;
             if (fBiasControlCurrentMax>350)
-                col = "#fff8f0";
+                col = kRed;
+
+            if (fFeedbackCalibration.size()==0)
+                col = kBlue;
 
             out << col << "\t";
@@ -482,5 +516,5 @@
         }
         else
-            out << "#ffffff\t\t\t\n";
+            out << kWhite << "\t\t\t\n";
 
 
