Index: /trunk/FACT++/scripts/Main.js
===================================================================
--- /trunk/FACT++/scripts/Main.js	(revision 16840)
+++ /trunk/FACT++/scripts/Main.js	(revision 16841)
@@ -90,4 +90,6 @@
 // ================================================================
 
+var irq;
+
 function doDrsCalibration(where)
 {
@@ -98,14 +100,14 @@
     var tm = new Date();
 
-    while (1)
+    while (!irq)
     {
         dim.send("FAD_CONTROL/START_DRS_CALIBRATION");
-        if (!takeRun("drs-pedestal", 1000))     // 40 / 20s     (50Hz)
+        if (irq || !takeRun("drs-pedestal", 1000))     // 40 / 20s     (50Hz)
             continue;
 
-        if (!takeRun("drs-gain",     1000))     // 40 / 20s     (50Hz)
+        if (irq || !takeRun("drs-gain",     1000))     // 40 / 20s     (50Hz)
             continue;
 
-        if (!takeRun("drs-pedestal", 1000))     // 40 / 20s     (50Hz)
+        if (irq || !takeRun("drs-pedestal", 1000))     // 40 / 20s     (50Hz)
             continue;
 
@@ -115,11 +117,11 @@
     dim.send("FAD_CONTROL/SET_FILE_FORMAT", 2);
 
-    while (!takeRun("drs-pedestal", 1000));     // 40 / 20s     (50Hz)
-    while (!takeRun("drs-time",     1000));     // 40 / 20s     (50Hz)
-
-    while (1)
+    while (!irq && !takeRun("drs-pedestal", 1000));     // 40 / 20s     (50Hz)
+    while (!irq && !takeRun("drs-time",     1000));     // 40 / 20s     (50Hz)
+
+    while (!irq)
     {
         dim.send("FAD_CONTROL/RESET_SECONDARY_DRS_BASELINE");
-        if (takeRun("pedestal",     1000))      // 40 / 10s     (80Hz)
+        if (takeRun("pedestal",     1000))              // 40 / 10s     (80Hz)
             break;
     }
@@ -127,10 +129,12 @@
     dim.send("FAD_CONTROL/SET_FILE_FORMAT", 2);
 
-    while (!takeRun("pedestal",     1000));     // 40 / 10s     (80Hz)
-
-        //                                       -----------
-        //                                       4'40 / 2'00
-
-    console.out("  "+new Date().toUTCString()+": DRS calibration done [%.1f]".$((new Date()-tm)/1000));
+    while (!irq && !takeRun("pedestal",     1000));     // 40 / 10s     (80Hz)
+    //                                                   -----------
+    //                                                   4'40 / 2'00
+
+    if (irq)
+        console.out("  "+new Date().toUTCString()+": DRS calibration interrupted [%.1fs]".$((new Date()-tm)/1000));
+    else
+        console.out("  "+new Date().toUTCString()+": DRS calibration done [%.1fs]".$((new Date()-tm)/1000));
 }
 
@@ -348,5 +352,6 @@
     function func()
     {
-        if ((this.cnt!=undefined && this.get().counter>this.cnt+10) ||
+        if (irq ||
+            (this.cnt!=undefined && this.get().counter>this.cnt+10) ||
             (this.voltageStep && this.voltageStep<0.02))
             return true;
@@ -357,5 +362,8 @@
     v8.timeout(4*60000, func, this);
 
-    console.out("  "+new Date().toUTCString()+": Voltage stable within limits [dV=%.3f, cnt=%d, %.2fs]".$(this.voltageStep, this.get().counter, (new Date()-now)/1000));
+    if (irq)
+        console.out("  "+new Date().toUTCString()+": Waiting for stable voltage interrupted [dU=%.3fV, cnt=%d, %.2fs]".$(this.voltageStep, this.get().counter, (new Date()-now)/1000));
+    else
+        console.out("  "+new Date().toUTCString()+": Voltage stable within limits [dV=%.3f, cnt=%d, %.2fs]".$(this.voltageStep, this.get().counter, (new Date()-now)/1000));
 }
 
@@ -592,10 +600,33 @@
 
     if (valid)
-        console.out("  "+new Date().toUTCString()+": Last DRS calib: %.1fmin ago".$(diff));
+        console.out("  "+new Date().toUTCString()+": Last DRS calibration was %.1fmin ago".$(diff));
     else
-        console.out("  "+new Date().toUTCString()+": No valid drs calibration available.");
+        console.out("  "+new Date().toUTCString()+": No valid DRS calibration available.");
 
     return valid ? diff : null;
 }
+
+// ----------------------------------------------------------------
+// Install interrupt handler
+// ----------------------------------------------------------------
+function handleIrq(cmd, args, time, user)
+{
+    console.out("Interrupt received:");
+    console.out("  IRQ:  "+cmd);
+    console.out("  Time: "+time);
+    console.out("  User: "+user);
+
+    irq = cmd ? cmd : "stop";
+
+    // This will end a run in progress as if it where correctly stopped
+    if (dim.state("MCP").name=="TakingData")
+        dim.send("MCP/STOP");
+
+    // This will stop a rate scan in progress
+    if (dim.state("RATE_SCAN").name=="InProgress")
+        dim.send("RATE_SCAN/STOP");
+}
+
+dimctrl.setInterruptHandler(handleIrq);
 
 // ----------------------------------------------------------------
@@ -613,11 +644,11 @@
     var n = new Date();
     if (observations.length>0 && test==-1)
-        console.out(n.toUTCString()+": First observation scheduled for "+observations[0].start.toUTCString());
+        console.out("  "+n.toUTCString()+": First observation scheduled for "+observations[0].start.toUTCString());
     if (test>=0 && test<observations.length)
-        console.out(n.toUTCString()+": First observation should start immediately.");
+        console.out("  "+n.toUTCString()+": First observation should start immediately.");
     if (observations.length>0 && observations[0].start>n+12*3600*1000)
-        console.out(n.toUTCString()+": No observations scheduled for the next 12 hours!");
+        console.out("  "+n.toUTCString()+": No observations scheduled for the next 12 hours!");
     if (observations.length==0)
-        console.out(n.toUTCString()+": No observations scheduled!");
+        console.out("  "+n.toUTCString()+": No observations scheduled!");
 }
 
@@ -633,5 +664,5 @@
 var system_on;  // undefined
 
-while (1)
+while (!irq)
 {
     // Check if observation position is still valid
@@ -669,9 +700,12 @@
     if (lastId!=obs.id) // !Object.isEqual(obs, nextObs)
     {
-        console.out("--- "+obs.id+" ---");
-        console.out("Current time:        "+new Date().toUTCString());
-        console.out("Current observation: "+obs.start.toUTCString());
+        console.out("");
+        console.out("  "+new Date().toUTCString()+": Starting new observation [id="+obs.id+"]");
+
+        //console.out("--- "+obs.id+" ---");
+        //console.out("Current time:        "+new Date().toUTCString());
+        //console.out("Current observation: "+obs.start.toUTCString());
         if (nextObs!=undefined)
-            console.out("Next    observation: "+nextObs.start.toUTCString());
+            console.out("  "+new Date().toUTCString()+": Next observation scheduled for "+nextObs.start.toUTCString());
         console.out("");
 
@@ -723,5 +757,7 @@
     }
 
-    console.out("\n"+(new Date()).toUTCString()+": Current measurement: "+obs[sub]);
+
+    if (obs[sub].task!="IDLE" && obs[sub].task!="DATA")
+        console.out("  "+new Date().toUTCString()+": New task ["+obs[sub]+"]");
 
     // FIXME: Maybe print a warning if Drive is on during day time!
@@ -772,9 +808,16 @@
     switch (obs[sub].task)
     {
+    case "IDLE":
+        v8.sleep(5000);
+        continue;
+
     case "STARTUP":
-        console.out("  "+new Date().toUTCString()+": New task [STARTUP]", "");
+        //console.out("", "  "+new Date().toUTCString()+": New task [STARTUP]");
         CloseLid();
 
         doDrsCalibration("startup");  // will switch the voltage off
+
+        if (irq)
+            break;
 
         service_feedback.voltageOn();
@@ -783,5 +826,5 @@
         // Before we can switch to 3000 we have to make the right DRS calibration
         console.out("  "+new Date().toUTCString()+": Taking single p.e. run.");
-        while (!takeRun("pedestal", 5000));
+        while (!irq && !takeRun("pedestal", 5000));
 
         // It is unclear what comes next, so we better switch off the voltage
@@ -792,5 +835,5 @@
 
     case "SHUTDOWN":
-        console.out("  "+new Date().toUTCString()+": New task [SHUTDOWN]", "");
+        //console.out("  "+new Date().toUTCString()+": New task [SHUTDOWN]", "");
         Shutdown();
         system_on = false;
@@ -803,16 +846,12 @@
         continue;
 
-    case "IDLE":
-        v8.sleep(1000);
-        continue;
-
     case "DRSCALIB":
-        console.out("  "+new Date().toUTCString()+": New task [DRSCALIB]", "");
+        //console.out("  "+new Date().toUTCString()+": New task [DRSCALIB]", "");
         doDrsCalibration("drscalib");  // will switch the voltage off
-       console.out("  "+new Date().toUTCString()+": Task finished [DRSCALIB]", "");
+        console.out("  "+new Date().toUTCString()+": Task finished [DRSCALIB]", "");
         break;
 
     case "SINGLEPE":
-        console.out("  "+new Date().toUTCString()+": New task [SINGLE-PE]", "");
+        //console.out("  "+new Date().toUTCString()+": New task [SINGLE-PE]", "");
 
         // The lid must be closes
@@ -822,5 +861,9 @@
         var diff = getTimeSinceLastDrsCalib();
         if (diff>30 || diff==null)
+        {
             doDrsCalibration("singlepe");  // will turn voltage off
+            if (irq)
+                break;
+        }
 
         // The voltage must be on
@@ -830,20 +873,20 @@
         // Before we can switch to 3000 we have to make the right DRS calibration
         console.out("  "+new Date().toUTCString()+": Taking single p.e. run.");
-        while (!takeRun("pedestal", 5000));
+        while (!irq && !takeRun("pedestal", 5000));
 
         // It is unclear what comes next, so we better switch off the voltage
         service_feedback.voltageOff();
-       console.out("  "+new Date().toUTCString()+": Task finished [SINGLE-PE]", "");
+        console.out("  "+new Date().toUTCString()+": Task finished [SINGLE-PE]", "");
         break;
 
     case "RATESCAN":
-        console.out("  "+new Date().toUTCString()+": New task [RATESCAN]", "");
+        //console.out("  "+new Date().toUTCString()+": New task [RATESCAN]", "");
 
         var tm1 = new Date();
 
         // This is a workaround to make sure that we really catch
-        // the new state and not the old one
+        // the new OnTrack state later and not the old one
         dim.send("DRIVE_CONTROL/STOP");
-        dim.wait("DRIVE_CONTROL", "Armed", 5000);
+        dim.wait("DRIVE_CONTROL", "Armed", 15000);
 
         // The lid must be open
@@ -907,5 +950,5 @@
         // ------------------------------------------------------------
 
-        console.out("  "+new Date().toUTCString()+": Run #"+run+"  (remaining "+parseInt(remaining)+"min)");
+        console.out("  "+new Date().toUTCString()+": Run count "+run+" [remaining "+parseInt(remaining)+"min]");
 
         // ----- Time since last DRS Calibration [min] ------
@@ -935,8 +978,8 @@
             console.out("  "+new Date().toUTCString()+": Moving telescope to '"+obs[sub].source+"' [wobble="+wobble+"]");
 
-            //var offset = observations[obs][2];
-            //var wobble = observations[obs][3 + parseInt(run/4)%2];
-
-            //dim.send("DRIVE_CONTROL/TRACK_SOURCE", offset, wobble, source);
+            // 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);
 
             dim.send("DRIVE_CONTROL/TRACK_WOBBLE", wobble, obs[sub].source);
@@ -947,7 +990,25 @@
 
         if (drscal)
+        {
             doDrsCalibration("data");  // will turn voltage off
 
+            // Now we switch on the voltage and a significant amount of
+            // time has been passed, so do the check again.
+            sun = Sun.horizon(-12);
+            if (!was_up && sun.isUp)
+            {
+                console.out("", "  "+new Date().toUTCString()+": Sun rise detected.... automatic shutdown initiated!");
+                // FIXME: State check?
+                Shutdown();
+                system_on = false;
+                continue;
+            }
+        }
+
+        if (irq)
+            break;
+
         OpenLid();
+
 
         // voltage must be switched on after the lid is open for the
@@ -969,9 +1030,9 @@
 
             // Calibration (2% of 20')
-            while (1)
+            while (!irq)
             {
-                if (!takeRun("pedestal",         1000))  // 80 Hz  -> 10s
+                if (irq || !takeRun("pedestal",         1000))  // 80 Hz  -> 10s
                     continue;
-                if (!takeRun("light-pulser-ext", 1000))  // 80 Hz  -> 10s
+                if (irq || !takeRun("light-pulser-ext", 1000))  // 80 Hz  -> 10s
                     continue;
                 break;
@@ -1001,5 +1062,5 @@
 
     if (nextObs!=undefined && sub==obs.length-1)
-        console.out("  "+new Date().toUTCString()+": Waiting for next observation scheduled at "+nextObs.start.toUTCString(),"");
+        console.out("  "+new Date().toUTCString()+": Next observation will start at "+nextObs.start.toUTCString(),"");
 
     sub++;
@@ -1007,4 +1068,9 @@
 
 sub_drsruns.close();
+
+console.out("  "+new Date().toUTCString()+": Left main loop [irq="+irq+"]");
+
+if (irq.toUpperCase()=="SHUTDOWN")
+    Shutdown();
 
 // ================================================================
@@ -1014,5 +1080,2 @@
 // error handline : http://www.sitepoint.com/exceptional-exception-handling-in-javascript/
 // classes: http://www.phpied.com/3-ways-to-define-a-javascript-class/
-//
-// Arguments: TakeFirstDrsCalib
-// To be determined: How to stop the script without foreceful interruption?
