Index: branches/fscctrl_safety_limits/src/fscctrl.cc
===================================================================
--- branches/fscctrl_safety_limits/src/fscctrl.cc	(revision 18340)
+++ branches/fscctrl_safety_limits/src/fscctrl.cc	(revision 18341)
@@ -41,4 +41,6 @@
     vector<Interpolator2D::vec> fPositionsSensors;
     vector<Interpolator2D::vec> fPositionsBias;
+    FSC::SecurityCurrentLimits fSecurityCurrentLimits;
+    bool fSecurityLimitsExceeded;
 
     virtual void UpdateTemp(float, const vector<float> &)
@@ -437,6 +439,8 @@
          */
 
+        CheckCurrentLimits(currents);
         if (fIsVerbose)
         {
+            /*
             for (size_t i=0; i<resist.size(); i++)
                 //if (resist[i]>800 && resist[i]<2000)
@@ -446,4 +450,8 @@
                 else
                     Out() << setw(2) << i << " - " << setw(4) << (int)resist[i] << ": " << "----" << endl;
+                */
+            PrintTemperaturesNicely(temperatures);
+            PrintVoltagesNicely(voltages, currents);
+            Out() << "\n" << "fSecurityLimitsExceeded:" << fSecurityLimitsExceeded << endl;
         }
 
@@ -456,6 +464,235 @@
         fNumConsecutiveMessages++;
 
+        
         return true;
     }
+
+    void PrintTemperaturesNicely(const vector<float> &t)
+    {
+        /*
+        "FSC_CONTROL/TEMPERATURE", "F:1;F:31;F:8;F:8;F:4;F:4;F:4",
+                    "|t[s]:FSC uptime"
+                    "|T_sens[deg C]:Sensor compartment temperatures"
+                    "|T_crate[deg C]:Temperatures crate 0 (back/front), 1 (b/f), 2 (b/f), 3 (b/f)"
+                    "|T_ps[deg C]:Temp power supplies crate 0 (back/front), 1, 2, 3"
+                    "|T_aux[deg C]:Auxiliary power supply temperatures FTM (top/bottom), FSC (t/b)"
+                    "|T_back[deg C]:FTM backpanel temperatures FTM (top/bottom), FSC (top/bottom)"
+                    "|T_eth[deg C]:Ethernet switches temperatures top (front/back), bottom (f/b)"),
+        // sensor compartment temperatures
+            0,  1,  2,  3,  4,  5,  6, 56, 57, 58, 59, 60,
+            61, 62, 32, 33, 34, 35, 36, 63, 37, 38, 39, 24,
+            25, 26, 27, 28, 29, 30, 31,
+            // crate temperatures (0-3, back/front)
+            12, 13, 52, 53, 44, 46, 20, 21,
+            //crate power supply temperatures (0-3)
+            8, 9, 48, 49, 40, 41, 16, 17,
+            // aux power supplies (FTM-side top/bot, FSC-side top/bot)
+            45, 50, 19, 42,
+            // backpanel (FTM-side top/bot, FSC-side top/bot)
+            11, 51, 18, 43,
+            // switch boxes (top front/back, bottom front/back)
+            15, 14, 47, 10,
+        */
+        //Out() << "0         1         2         3         4         5         6         7         " << endl;
+        //Out() << "01234567890123456789012345678901234567890123456789012345678901234567890123456789" << endl;
+        Out() << ". - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . -." << endl;
+        Out() << "T_sens:";
+        for (int i=0; i<31; i++){
+            if (i%16==0){
+                Out() << "\n";
+            }
+            Out() << setw(4) << setprecision(1) << fixed << t[i] << " ";
+        }
+        Out() << endl;
+        Out() << ". - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . -." << endl;
+
+        Out() << "T_crate: (B:back, F:front)" << endl;
+        Out() << "0: B|   F|1: B|   F|2: B|   F|3: B|   F|" << endl;
+        for (int i=31; i<31+8; i++){
+            Out() << setw(4) << setprecision(1) << fixed << t[i] << "|";
+        }
+        Out() << endl;
+        Out() << ". - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . -." << endl;
+        
+        Out() << "T_ps: crate power supplies (B:back, F:front)" << endl;
+        Out() << "0: B|   F|1: B|   F|2: B|   F|3: B|   F|" << endl;
+        for (int i=31+8; i<31+8+8; i++){
+            Out() << setw(4) << setprecision(1) << fixed << t[i] << "|";
+        }
+        Out() << endl;
+        Out() << ". - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . -." << endl;
+        Out() << "T_aux: auxiliary power supplies" << endl;
+        Out() << "FTM top|    bot|FSC top|    bot|" << endl;
+        for (int i=31+8+8; i<31+8+8+4; i++){
+            Out() << setw(7) << setprecision(1) << fixed << t[i] << "|";
+        }
+        Out() << endl;
+        Out() << ". - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . -." << endl;
+        Out() << "T_back: backpanel temperatures" << endl;
+        Out() << "FTM top|    bot|FSC top|    bot|" << endl;
+        for (int i=31+8+8+4; i<31+8+8+4+4; i++){
+            Out() << setw(7) << setprecision(1) << fixed << t[i] << "|";
+        }
+        Out() << endl;
+        Out() << ". - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . -." << endl;
+        Out() << "T_ethernet: switch boxes" << endl;
+        Out() << "top front|     back|bot front|     back|" << endl;
+        for (int i=31+8+8+4; i<31+8+8+4+4; i++){
+            Out() << setw(9) << setprecision(1) << fixed << t[i] << "|";
+        }
+        Out() << endl;
+        Out() << ". - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . -." << endl;
+    }
+
+    void PrintVoltagesNicely(const vector<float> &v, const vector<float> &c)
+    {
+        /*
+            
+            F:4;F:4;F:4;F:4;F:4;F:4;F:2;F:2;F:1;F:1",
+            
+            "|FAD_Ud[V]:FAD digital (crate 0-3)"
+            "|FAD_Up[V]:FAD positive (crate 0-3)"
+            "|FAD_Un[V]:FAD negative (crate 0-3)"
+            "|FPA_Ud[V]:FPA digital (crate 0-3)"
+            "|FPA_Up[V]:FPA positive (crate 0-3)"
+            "|FPA_Un[V]:FPA negative (crate 0-3)"
+            
+            "|ETH_U[V]:Ethernet switch (pos/neg)"
+            "|FTM_U[V]:FTM - trigger master (pos/neg)"
+            "|FFC_U[V]:FFC"
+            "|FLP_U[V]:FLP - light pulser"),
+        */
+        const char* const voltage_names[] = {
+                 "FAD_d  | ", 
+                 "FAD_p  | ", 
+                 "FAD_n  | ", 
+                 "FPA_d  | ",
+                 "FPA_p  | ", 
+                 "FPA_n  | ",
+                 "Etherne| ",
+                 "FTM    | ",
+                 "FFC    | ",
+                 "FLP    | ",
+             };
+        const int length_per_group[] = {
+            4, 4,  4,  4, 4,  4, 2, 2, 1, 1,
+        };
+
+        Out() << ". - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . -." << endl;
+
+        Out() << "       | Voltages                        | Currents" << endl;
+        Out() << "-------| 0     | 1     | 2     | 3     | | 0     | 1     | 2     | 3     |" << endl;
+
+        int pos=0;
+        for (int i=0; i<10; i++)
+        {
+            Out() << voltage_names[i];
+            for (int j=0; j<length_per_group[i]; j++)
+            {   
+                Out() << setw(6) << setprecision(2) << fixed << v[pos++] << "| ";
+            }
+            pos -= length_per_group[i];
+            for (int j=0; j<4-length_per_group[i]; j++)
+            {
+                Out() << "        ";
+            }
+            Out() << "|";
+            for (int j=0; j<length_per_group[i]; j++)
+            {
+                Out() << setw(6) << setprecision(2) << fixed << c[pos++] << "| ";
+            }
+            Out() << endl;
+        }
+        
+        Out() << ". - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . -." << endl;
+        
+
+    }
+
+    bool CheckCurrentLimits(const vector<float> &currents)
+    {
+        /*
+            F:4;F:4;F:4;F:4;F:4;F:4;F:2;F:2;F:1;F:1",
+            "|FAD_Id[A]:FAD digital (crate 0-3)"
+            "|FAD_Ip[A]:FAD positive (crate 0-3)"
+            "|FAD_In[A]:FAD negative (crate 0-3)"
+            "|FPA_Id[A]:FPA digital (crate 0-3)"
+            "|FPA_Ip[A]:FPA positive (crate 0-3)"
+            "|FPA_In[A]:FPA negative (crate 0-3)"
+            "|ETH_I[A]:Ethernet switch (pos/neg)"
+            "|FTM_I[A]:FTM - trigger master (pos/neg)"
+            "|FFC_I[A]:FFC"
+            "|FLP_I[A]:FLP - light pulser")
+        */
+        fSecurityLimitsExceeded = false;
+        
+        const double current_limits[] = {
+            fSecurityCurrentLimits.FAD_digital, 
+            fSecurityCurrentLimits.FAD_positive, 
+            fSecurityCurrentLimits.FAD_negative, 
+            fSecurityCurrentLimits.FPA_digital, 
+            fSecurityCurrentLimits.FPA_positive, 
+            fSecurityCurrentLimits.FPA_negative,
+            fSecurityCurrentLimits.ethernet_switch,
+            INFINITY,
+            fSecurityCurrentLimits.FFC,
+            fSecurityCurrentLimits.FLP,
+            };
+        
+        const int channels_per_group[] = {
+            4, 4,  4,  4, 4,  4, 2, 2, 1, 1,
+        };
+        
+        const int groups = 10;
+        
+        const char* const group_names[] = {
+            "FAD_digital",
+            "FAD_positive",
+            "FAD_negative",
+            "FPA_digital",
+            "FPA_positive",
+            "FPA_negative",
+            "ethernet_switch",
+            "",
+            "FFC",
+            "FLP",
+            };
+
+        const char* const channel_names[][4] = {
+            {"crate 0", "crate 1", "crate 2", "crate 3"},
+            {"crate 0", "crate 1", "crate 2", "crate 3"},
+            {"crate 0", "crate 1", "crate 2", "crate 3"},
+            {"crate 0", "crate 1", "crate 2", "crate 3"},
+            {"crate 0", "crate 1", "crate 2", "crate 3"},
+            {"crate 0", "crate 1", "crate 2", "crate 3"},
+            {"FTM side", "FSC side"},
+            {""},
+            {"-"},
+            {"-"},
+            };
+        
+
+        int offset=0;
+        for (int g=0; g<groups; g++){
+            for (int c=0; c<channels_per_group[g]; c++)
+            {
+                int id = offset+c;
+                if (abs(currents[id]) > abs(current_limits[g])){
+                    Out() << "current limit exeeded!! ";
+                    Out() << "group: "<< group_names[g];
+                    Out() << " channel: "<< channel_names[g][c];
+                    Out() << " value: "<< currents[id];
+                    Out() << " limit: "<< current_limits[g];
+                    Out() << endl;
+                    fSecurityLimitsExceeded = true;
+                }
+                
+            }
+            offset += channels_per_group[g];
+        }
+        return fSecurityLimitsExceeded;
+    }
+
+
 
     void StartRead()
@@ -569,7 +806,17 @@
     }
 
+    void SetSecurityCurrentLimits(const FSC::SecurityCurrentLimits &lim)
+    {
+        fSecurityCurrentLimits = lim;
+    }
+
     void SetPositionsBias(const vector<Interpolator2D::vec> &vec)
     {
         fPositionsBias = vec;
+    }
+
+    bool IsSecurityLimitExceeded() const
+    {
+        return fSecurityLimitsExceeded;
     }
 
@@ -788,5 +1035,18 @@
     int Execute()
     {
-        return fFSC.IsOpen() ? State::kConnected : State::kDisconnected;
+        if (fFSC.IsSecurityLimitExceeded())
+        {
+            return State::kOverCurrent;
+        }
+        else if(fFSC.IsOpen())
+        {
+            return State::kConnected;
+        }
+        else
+        {
+            return State::kDisconnected;
+        }
+
+        //return fFSC.IsOpen() ? State::kConnected : State::kDisconnected;
     }
 
@@ -822,4 +1082,10 @@
         T::AddStateName(State::kConnected, "Connected",
                      "Ethernet connection to FSC established.");
+
+        T::AddStateName(State::kHighCurrent, "HighPowerConsumption",
+                     "FSC board measures high power consumption, c.f. FSC current limits in config-file or config-DB.");
+
+        T::AddStateName(State::kOverCurrent, "OverCurrent",
+                     "FSC board measures *too* power consumption, c.f. FSC current limits in config-file or config-DB.");
 
         // Verbosity commands
@@ -869,4 +1135,16 @@
         fFSC.SetPositionsSensors(v1);
         fFSC.SetPositionsBias(v2);
+
+        FSC::SecurityCurrentLimits lim;
+        lim.ethernet_switch = conf.Get<double>("ethernet_switch");
+        lim.FFC = conf.Get<double>("FFC");
+        lim.FLP = conf.Get<double>("FLP");
+        lim.FAD_digital = conf.Get<double>("FAD_digital");
+        lim.FAD_negative = conf.Get<double>("FAD_negative");
+        lim.FAD_positive = conf.Get<double>("FAD_positive");
+        lim.FPA_digital = conf.Get<double>("FPA_digital");
+        lim.FPA_negative = conf.Get<double>("FPA_negative");
+        lim.FPA_positive = conf.Get<double>("FPA_positive");
+        fFSC.SetSecurityCurrentLimits(lim);
 
         SetEndpoint(conf.Get<string>("addr"));
@@ -896,6 +1174,20 @@
         ("quiet,q",       po_bool(true),  "Disable printing contents of all received messages (except dynamic data) in clear text.")
         ;
+    
+    po::options_description current_limits("Security current limits");
+    current_limits.add_options()
+        ("ethernet_switch", var<double>()->required(), "(signed) floating point number, the max/min current, for pos/neg currents in A.")
+        ("FFC", var<double>()->required(), "(signed) floating point number, the max/min current, for pos/neg currents in A.")
+        ("FLP", var<double>()->required(), "(signed) floating point number, the max/min current, for pos/neg currents in A.")
+        ("FAD_digital", var<double>()->required(), "(signed) floating point number, the max/min current, for pos/neg currents in A.")
+        ("FAD_negative", var<double>()->required(), "(signed) floating point number, the max/min current, for pos/neg currents in A.")
+        ("FAD_positive", var<double>()->required(), "(signed) floating point number, the max/min current, for pos/neg currents in A.")
+        ("FPA_digital", var<double>()->required(), "(signed) floating point number, the max/min current, for pos/neg currents in A.")
+        ("FPA_negative", var<double>()->required(), "(signed) floating point number, the max/min current, for pos/neg currents in A.")
+        ("FPA_positive", var<double>()->required(), "(signed) floating point number, the max/min current, for pos/neg currents in A.")
+        ;
 
     conf.AddOptions(control);
+    conf.AddOptions(current_limits);
 }
 
