Index: /trunk/FACT++/scripts/Main.js
===================================================================
--- /trunk/FACT++/scripts/Main.js	(revision 18084)
+++ /trunk/FACT++/scripts/Main.js	(revision 18085)
@@ -195,4 +195,18 @@
 
 // ================================================================
+//  Interrupt data taking in case of high currents
+// ================================================================
+dim.onchange['FEEDBACK'] = function(state)
+{
+    if ((state.name=="Critical" || state.name=="OnStandby") &&
+        (this.prev!="Critical"  && this.prev!="OnStandby"))
+    {
+        console.out("Feedback state changed from "+this.prev+" to "+state.name+" [Main.js]");
+        irq = "RESCHEDULE";
+    }
+    this.prev=state.name;
+}
+
+// ================================================================
 //  Code related to switching bias voltage on and off
 // ================================================================
@@ -203,4 +217,7 @@
 {
     if (!evt.data)
+        return;
+
+    if (this.ok==undefined)
         return;
 
@@ -223,8 +240,4 @@
     }
     avg /= 320;
-
-    if (this.ok==undefined)
-        return;
-
 
     this.ok = cnt<3;// || (this.last!=undefined && Math.abs(this.last-avg)<0.002);
@@ -306,5 +319,5 @@
         ov = 1.1;
 
-    if (this.ov!=ov && dim.state("FEEDBACK").name=="InProgress")
+    if (this.ov!=ov && dim.state("FEEDBACK").name=="InProgress") // FIXME: Warning, OnStandby, Critical if (ov<this.ov)
     {
         dim.log("Stoping feedback.");
@@ -328,4 +341,7 @@
 
         dim.send("FEEDBACK/START", ov);
+
+        // FIXME: We could miss "InProgress" if it immediately changes to "Warning"
+        //        Maybe a dim.timeout state>8 ?
         dim.wait("FEEDBACK", "InProgress", 45000);
 
@@ -365,5 +381,5 @@
 // ================================================================
 
-function Shutdown()
+function Shutdown(singlepe)
 {
     dim.log("Starting shutdown.");
@@ -419,13 +435,16 @@
     }*/
 
-    dim.log("Taking single-pe run.");
-
-    // The voltage must be on
-    service_feedback.voltageOn();
-    service_feedback.waitForVoltageOn();
-
-    // Before we can switch to 3000 we have to make the right DRS calibration
-    dim.log("Taking single p.e. run.");
-    while (!irq && !takeRun("single-pe", 10000));
+    if (singlepe)
+    {
+        dim.log("Taking single-pe run.");
+
+        // The voltage must be on
+        service_feedback.voltageOn();
+        service_feedback.waitForVoltageOn();
+
+        // Before we can switch to 3000 we have to make the right DRS calibration
+        dim.log("Taking single p.e. run.");
+        while (!irq && !takeRun("single-pe", 10000));
+    }
 
     // It is unclear what comes next, so we better switch off the voltage
@@ -528,4 +547,5 @@
          "FTM_CONTROL/TRIGGER_RATES",
          "GPS_CONTROL/NEMA",
+         "SQM_CONTROL/DATA",
          "LID_CONTROL/DATA",
          "MAGIC_LIDAR/DATA",
@@ -554,5 +574,5 @@
 
     var list = obj.data.split('\n').map(map);
-
+//     [A
     function check(name)
     {
@@ -613,6 +633,4 @@
 //console.out("Feedback init: start.");
 service_feedback.get(5000);
-
-//v8.timeout(3000, function() { var n = dim.state("FEEDBACK").name; if (n=="CurrentCtrlIdle" || n=="CurrentControl") return true; });
 
 // ----------------------------------------------------------------
@@ -708,5 +726,8 @@
 
     if (irq.toUpperCase()=="RESCHEDULE")
-        return true;
+    {
+        irq = undefined;
+        return false;
+    }
 
     if (irq.toUpperCase()=="OFF")
@@ -716,4 +737,12 @@
         return true;
     }
+
+    /*
+    if (irq.toUpperCase()=="STOP")
+    {
+        dim.send("FAD_CONTROL/CLOSE_OPEN_FILES");
+        dim.send("MCP/STOP");
+        return true;
+    }*/
 
     if (irq.toUpperCase()=="SHUTDOWN")
@@ -786,4 +815,5 @@
     }
 
+    //dim.log("DEBUG: Next observation scheduled for "+nextObs.start.toUTCString()+" [id="+nextObs.id+"]");
     if (nextObs && nextId!=nextObs.id)
     {
@@ -817,6 +847,6 @@
     }
 
-    // Check if sun is still up... only DATA and RATESCAN must be suppressed
-    if ((obs[sub].task=="DATA" || obs[sub].task=="RATESCAN") && sun.isUp)
+    // Check if sun is still up... only DATA and */
+    if ((obs[sub].task=="DATA" || obs[sub].task=="RATESCAN" || obs[sub].task=="RATESCAN2" ) && sun.isUp)
     {
         var now = new Date();
@@ -836,5 +866,5 @@
     // otherwise it is difficult to allow e.g. the STARTUP at the beginning of the night
     var power_states = sun.isUp || !system_on ? [ "DriveOff", "SystemOn" ] : [ "SystemOn" ];
-    var drive_states = sun.isUp || !system_on ?   undefined    : [ "Armed", "Tracking", "OnTrack" ];
+    var drive_states = sun.isUp || !system_on ? undefined : [ "Armed", "Tracking", "OnTrack" ];
 
     // A scheduled task was found, lets check if all servers are
@@ -858,5 +888,5 @@
          [ "AGILENT_CONTROL_80V", [ "VoltageOn"                ] ],
          [ "BIAS_CONTROL",        [ "VoltageOff", "VoltageOn", "Ramping" ] ],
-         [ "FEEDBACK",            [ "Calibrated", "InProgress" ] ],
+         [ "FEEDBACK",            [ "Calibrated", "InProgress", "OnStandby", "Warning", "Critical" ] ],
          [ "LID_CONTROL",         [ "Open", "Closed"           ] ],
          [ "DRIVE_CONTROL",       drive_states/*[ "Armed", "Tracking", "OnTrack" ]*/ ],
@@ -866,4 +896,5 @@
          [ "RATE_CONTROL",        [ "Connected", "GlobalThresholdSet", "InProgress"  ] ],
          [ "GPS_CONTROL",         [ "Locked"  ] ],
+         [ "SQM_CONTROL",         [ "Disconnected", "Connected", "Valid" ] ],
         ];
 
@@ -872,9 +903,23 @@
     {
         throw new Error("Something unexpected has happened. One of the servers "+
-                        "is in a state in which it should not be. Please,"+
+                        "is in a state in which it should not be. Please,"+ 
                         "try to find out what happened...");
     }
 
-    datalogger_subscriptions.check();
+    datalogger_subscriptions.check();                                         
+                                                                                
+    // If this is an observation which needs the voltage to be swicthed on
+    // skip that if the voltage is not stable                                    
+    /*
+    if (obs[sub].task=="DATA" || obs[sub].task=="RATESCAN")
+    {
+        var state = dim.state("FEEDBACK").name;
+        if (state=="Warning" || state=="Critical" || state=="OnStandby")
+        {
+            v8.sleep(1000);
+            continue;
+        }
+    }*/
+
 
     // Check if obs.task is one of the one-time-tasks
@@ -909,5 +954,5 @@
 
     case "SHUTDOWN":
-        Shutdown();
+        Shutdown(true);
         system_on = false;
 
@@ -1019,7 +1064,7 @@
         service_feedback.voltageOn(0);
 
-        if (obs.source != undefined)
-        {
-            dim.log("Pointing telescope to '"+obs[cub].source+"'.");
+        if (obs[sub].source != undefined)
+        {
+            dim.log("Pointing telescope to '"+obs[sub].source+"'.");
             dim.send("DRIVE_CONTROL/TRACK_ON", obs[sub].source);
         }
@@ -1037,26 +1082,144 @@
         service_feedback.waitForVoltageOn();
 
-        var tm2 = new Date();
-
-        dim.log("Starting ratescan.");
-
-        // Start rate scan
-        dim.send("RATE_SCAN/START_THRESHOLD_SCAN", 50, 1000, -10);
-
-        // Lets wait if the ratescan really starts... this might take a few
-        // seconds because RATE_SCAN configures the ftm and is waiting for
-        // it to be configured.
-        dim.wait("RATE_SCAN", "InProgress", 10000);
-        dim.wait("RATE_SCAN", "Connected", 2700000);
-
-        // this line is actually some kind of hack. 
-        // after the Ratescan, no data is written to disk. I don't know why, but it happens all the time
-        // So I decided to put this line here as a kind of patchwork....
-        //dim.send("FAD_CONTROL/SET_FILE_FORMAT", 6);
-
-        dim.log("Ratescan done [%.1fs, %.1fs]".$((tm2-tm1)/1000, (new Date()-tm2)/1000));
+        if (!irq)
+        {
+            var tm2 = new Date();
+
+            dim.log("Starting ratescan.");
+
+            // Start rate scan
+            dim.send("RATE_SCAN/START_THRESHOLD_SCAN", 50, 1000, -10, "default");
+
+            // Lets wait if the ratescan really starts... this might take a few
+            // seconds because RATE_SCAN configures the ftm and is waiting for
+            // it to be configured.
+            dim.wait("RATE_SCAN", "InProgress", 10000);
+            dim.wait("RATE_SCAN", "Connected", 2700000);
+
+            // Here one could implement a watchdog for the feedback as well, but what is the difference
+            // whether finally one has to find out if the feedback was in the correct state
+            // or the ratescan was interrupted?
+
+            // this line is actually some kind of hack.
+            // after the Ratescan, no data is written to disk. I don't know why, but it happens all the time
+            // So I decided to put this line here as a kind of patchwork....
+            //dim.send("FAD_CONTROL/SET_FILE_FORMAT", 6);
+
+            dim.log("Ratescan done [%.1fs, %.1fs]".$((tm2-tm1)/1000, (new Date()-tm2)/1000));
+        }
+
         dim.log("Task finished [RATESCAN]");
         console.out("");
         break; // case "RATESCAN"
+
+    case "RATESCAN2":
+        var tm1 = new Date();
+
+        // This is a workaround to make sure that we really catch
+        // the new OnTrack state later and not the old one
+        dim.send("DRIVE_CONTROL/STOP");
+        dim.wait("DRIVE_CONTROL", "Armed", 15000);
+
+        // Open the lid if required
+        if (!obs[sub].lidclosed)
+            OpenLid();
+        else
+            CloseLid();
+
+        // Switch the voltage to a reduced level (Ubd)
+        service_feedback.voltageOn(0);
+
+        // track source/position or move to position
+        if (obs[sub].lidclosed)
+        {
+            dim.log("Moving telescope to zd="+obs[sub].zd+" az="+obs[sub].az);
+            dim.send("DRIVE_CONTROL/MOVE_TO", obs[sub].zd, obs[sub].az);
+            v8.sleep(1000);
+            dim.wait("DRIVE_CONTROL", "Armed", 150000); // 110s for turning and 30s for stabilizing
+        }
+        else
+        {
+            if (obs[sub].source != undefined)
+            {
+                dim.log("Pointing telescope to '"+obs[sub].source+"'.");
+                dim.send("DRIVE_CONTROL/TRACK_ON", obs[sub].source);
+            }
+            else
+            {
+                dim.log("Pointing telescope to ra="+obs[sub].ra+" dec="+obs[sub].dec);
+                dim.send("DRIVE_CONTROL/TRACK", obs[sub].ra, obs[sub].dec);
+            }
+
+            dim.wait("DRIVE_CONTROL", "OnTrack", 150000); // 110s for turning and 30s for stabilizing
+        }
+
+        // Now tracking stable, switch voltage to nominal level and wait
+        // for stability.
+        if (obs[sub].rstype=="dark-bias-off")
+            service_feedback.voltageOff();
+        else
+        {
+            service_feedback.voltageOn();
+            service_feedback.waitForVoltageOn();
+        }
+        dim.log("rs-type: "+obs[sub].rstype);
+
+        if (!irq)
+        {
+            var tm2 = new Date();
+
+            dim.log("Starting ratescan 2/1");
+
+            // Start rate scan
+            dim.send("RATE_SCAN/START_THRESHOLD_SCAN", 50, 300, 20, obs[sub].rstype);
+
+            // Lets wait if the ratescan really starts... this might take a few
+            // seconds because RATE_SCAN configures the ftm and is waiting for
+            // it to be configured.
+            dim.wait("RATE_SCAN", "InProgress", 10000);
+            dim.wait("RATE_SCAN", "Connected", 2700000);
+
+            // Here one could implement a watchdog for the feedback as well, but what is the difference
+            // whether finally one has to find out if the feedback was in the correct state
+            // or the ratescan was interrupted?
+
+            // this line is actually some kind of hack.
+            // after the Ratescan, no data is written to disk. I don't know why, but it happens all the time
+            // So I decided to put this line here as a kind of patchwork....
+            //dim.send("FAD_CONTROL/SET_FILE_FORMAT", 6);
+
+            dim.log("Ratescan 2/1 done [%.1fs, %.1fs]".$((tm2-tm1)/1000, (new Date()-tm2)/1000));
+        }
+
+        if (!irq)
+        {
+            var tm2 = new Date();
+
+            dim.log("Starting ratescan 2/2");
+
+            // Start rate scan
+            dim.send("RATE_SCAN/START_THRESHOLD_SCAN", 300, 1000, 100, obs[sub].rstype);
+
+            // Lets wait if the ratescan really starts... this might take a few
+            // seconds because RATE_SCAN configures the ftm and is waiting for
+            // it to be configured.
+            dim.wait("RATE_SCAN", "InProgress", 10000);
+            dim.wait("RATE_SCAN", "Connected", 2700000);
+
+            // Here one could implement a watchdog for the feedback as well, but what is the difference
+            // whether finally one has to find out if the feedback was in the correct state
+            // or the ratescan was interrupted?
+
+            // this line is actually some kind of hack.
+            // after the Ratescan, no data is written to disk. I don't know why, but it happens all the time
+            // So I decided to put this line here as a kind of patchwork....
+            //dim.send("FAD_CONTROL/SET_FILE_FORMAT", 6);
+
+            dim.log("Ratescan 2/2 done [%.1fs, %.1fs]".$((tm2-tm1)/1000, (new Date()-tm2)/1000));
+        }
+
+        dim.log("Task finished [RATESCAN2]");
+        console.out("");
+        break; // case "RATESCAN2"
 
     case "DATA":
@@ -1072,6 +1235,8 @@
         }
     */
+
         // Calculate remaining time for this observation in minutes
         var remaining = nextObs==undefined ? 0 : (nextObs.start-new Date())/60000;
+        //dim.log("DEBUG: remaining: "+remaining+" nextObs="+nextObs+" start="+nextObs.start);
 
         // ------------------------------------------------------------
@@ -1095,5 +1260,5 @@
         //  ...no drs calibration was done yet
         var drscal = (run%4==0 && (remaining>15 && diff>70)) || diff==null;
-
+    
         if (point)
         {
@@ -1134,5 +1299,5 @@
 
         if (irq)
-            break;
+            continue;
 
         OpenLid();
@@ -1140,4 +1305,12 @@
         // This is now th right time to wait for th drive to be stable
         dim.wait("DRIVE_CONTROL", "OnTrack", 150000); // 110s for turning and 30s for stabilizing
+
+        // Now check the voltage... (do not start a lot of stuff just to do nothing)
+        var state = dim.state("FEEDBACK").name;
+        if (state=="Warning" || state=="Critical" || state=="OnStandby")
+        {
+            v8.sleep(60000);
+            continue;
+        }
 
         // Now we are 'OnTrack', so we can ramp to nominal voltage
@@ -1147,5 +1320,5 @@
 
         // If pointing had changed, do calibration
-        if (point)
+        if (!irq && point)
         {
             dim.log("Starting calibration.");
@@ -1177,5 +1350,5 @@
         {
             var len = 300;
-            while (len>15)
+            while (!irq && len>15)
             {
                 var time = new Date();
