Index: /trunk/FACT++/src/HeadersDrive.h
===================================================================
--- /trunk/FACT++/src/HeadersDrive.h	(revision 14017)
+++ /trunk/FACT++/src/HeadersDrive.h	(revision 14018)
@@ -10,4 +10,5 @@
             kDisconnected = 1,
             kConnected,
+            kLocked,
             kNotReady,
             kReady,
Index: /trunk/FACT++/src/drivectrl.cc
===================================================================
--- /trunk/FACT++/src/drivectrl.cc	(revision 14017)
+++ /trunk/FACT++/src/drivectrl.cc	(revision 14018)
@@ -1,4 +1,9 @@
 #include <boost/bind.hpp>
 #include <boost/regex.hpp>
+
+#ifdef HAVE_LIBNOVA
+#include <libnova/solar.h>
+#include <libnova/rise_set.h>
+#endif
 
 #include "FACT.h"
@@ -920,4 +925,9 @@
     }
 
+    int Unlock()
+    {
+        return Drive::State::kNotReady;
+    }
+
     int Print()
     {
@@ -977,4 +987,39 @@
 
         return T::GetCurrentState();
+    }
+
+    Time fSunRise;
+
+    Time GetSunRise(const Time &time=Time())
+    {
+#ifdef HAVE_LIBNOVA
+        const double lon = -(17.+53./60+26.525/3600);
+        const double lat =   28.+45./60+42.462/3600;
+
+        ln_lnlat_posn observer;
+        observer.lng = lon;
+        observer.lat = lat;
+
+        // This caluclates the sun-rise of the next day after 12:00 noon
+        ln_rst_time sun_day;
+        if (ln_get_solar_rst(time.JD(), &observer, &sun_day)==1)
+        {
+            T::Fatal("GetSunRise reported the sun to be circumpolar!");
+            return Time(Time::none);
+        }
+
+        if (Time(sun_day.rise)>=time)
+            return Time(sun_day.rise);
+
+        if (ln_get_solar_rst(time.JD()+0.5, &observer, &sun_day)==1)
+        {
+            T::Fatal("GetSunRise reported the sun to be circumpolar!");
+            return Time(Time::none);
+        }
+
+        return Time(sun_day.rise);
+#else
+        return Time(boost::date_time::pos_infin);
+#endif
     }
 
@@ -988,4 +1033,27 @@
         poll_one();
 
+        if (T::GetCurrentState()==Drive::State::kLocked)
+            return Drive::State::kLocked;
+
+
+        if (T::GetCurrentState()>Drive::State::kLocked)
+        {
+            Time now;
+            if (now>fSunRise)
+            {
+                SendCommand("PREPS Park", false);
+
+                fSunRise = GetSunRise(now);
+                if (!fSunRise)
+                    return T::kSM_FatalError;
+
+                ostringstream msg;
+                msg << "Next sun-rise will be at " << fSunRise;
+                T::Info(msg);
+
+                return Drive::State::kLocked;
+            }
+        }
+
         return fDrive.GetState();
     }
@@ -995,5 +1063,5 @@
     StateMachineDrive(ostream &out=cout) :
         T(out, "DRIVE_CONTROL"), ba::io_service::work(static_cast<ba::io_service&>(*this)),
-        fDrive(*this, *this)
+        fDrive(*this, *this), fSunRise(GetSunRise())
     {
         // State names
@@ -1119,4 +1187,8 @@
 //            ("");
 
+        T::AddEvent("UNLOCK", Drive::State::kLocked)
+            (bind(&StateMachineDrive::Unlock, this))
+            ("Stop any kind of movement.");
+
 
         // Verbosity commands
@@ -1227,4 +1299,7 @@
     int EvalOptions(Configuration &conf)
     {
+        if (!fSunRise)
+            return 1;
+
         fDrive.SetVerbose(!conf.Get<bool>("quiet"));
 
@@ -1272,4 +1347,11 @@
             fDatabase = conf.Get<string>("source-database");
             ReadDatabase();
+        }
+
+        if (fSunRise.IsValid())
+        {
+            ostringstream msg;
+            msg << "Next sun-rise will be at " << fSunRise;
+            T::Message(msg);
         }
 
