Index: /trunk/FACT++/src/smartfact.cc
===================================================================
--- /trunk/FACT++/src/smartfact.cc	(revision 18365)
+++ /trunk/FACT++/src/smartfact.cc	(revision 18366)
@@ -86,13 +86,14 @@
     Time time;
 
-    Time fRiseDayTime;
-    Time fRiseCivil;
-    Time fRiseAstronomical;
-    Time fRiseDarkTime;
-
-    Time fSetDayTime;
-    Time fSetCivil;
-    Time fSetAstronomical;
-    Time fSetDarkTime;
+    // This is always the time of the next...
+    Time fSunRise00;
+    Time fSunRise06;
+    Time fSunRise12;
+    Time fSunRise18;
+
+    Time fSunSet00;
+    Time fSunSet06;
+    Time fSunSet12;
+    Time fSunSet18;
 
     int state;
@@ -103,4 +104,18 @@
     bool visible;
 
+    Nova::RstTime Rst(double jd, double hrz=LN_SOLAR_STANDART_HORIZON)
+    {
+        Nova::RstTime rs = Nova::GetSolarRst(jd-0.5, hrz);
+        if (jd>rs.rise || jd>rs.set)
+        {
+            const Nova::RstTime rs2 = Nova::GetSolarRst(jd+0.5, hrz);
+            if (jd>rs.rise)
+                rs.rise = rs2.rise;
+            if (jd>rs.set)
+                rs.set = rs2.set;
+        }
+        return rs;
+    }
+
 public:
     Sun() : time(Time::none)
@@ -116,5 +131,74 @@
         const double JD = time.JD();
 
-        // Warning: return code of 1 means circumpolar and is not checked!
+        // >0deg           : day
+        //  -6deg -   0deg : civil        twilight
+        // -12deg -  -6deg : nautical     twilight
+        // -18deg - -12deg : astronomical twilight
+        // <-18deg         : night
+
+        const Nova::RstTime sun00 = Rst(JD);
+        const Nova::RstTime sun06 = Rst(JD,  -6);
+        const Nova::RstTime sun12 = Rst(JD, -12);
+        const Nova::RstTime sun18 = Rst(JD, -18);
+
+        fSunRise00 = sun00.rise;
+        fSunRise06 = sun06.rise;
+        fSunRise12 = sun12.rise;
+        fSunRise18 = sun18.rise;
+
+        fSunSet00  = sun00.set;
+        fSunSet06  = sun06.set;
+        fSunSet12  = sun12.set;
+        fSunSet18  = sun18.set;
+
+        array<double,8> arr =
+        {{
+            sun00.set,
+            sun06.set,
+            sun12.set,
+            sun18.set,
+            sun18.rise,
+            sun12.rise,
+            sun06.rise,
+            sun00.rise,
+        }};
+
+
+        state = std::min_element(arr.begin(), arr.end())-arr.begin();
+
+        string name[] =
+        {
+            "day time",
+            "civil twilight",
+            "nautical twilight",
+            "astron. twilight",
+            "dark time",
+            "astron. twilight",
+            "nautical twilight",
+            "civil twilight"
+        };
+
+        description = name[state];
+
+        const string txt = fSunRise18<fSunSet18 ?
+            time.MinutesTo(fSunRise18)+"&uarr;" :
+            time.MinutesTo(fSunSet18)+"&darr;";
+
+        description += " ["+txt+"]";
+
+        isday = state==0;
+
+        switch (state)
+        {
+        case 0:                  color = HTML::kRed;     break;
+        case 1: case 2:          color = HTML::kYellow;  break;
+        case 3: case 4:  case 5: color = HTML::kGreen;   break;
+        case 6: case 7:          color = HTML::kYellow;  break;
+        }
+
+        visible = state==0;
+
+        /*
+         // Warning: return code of 1 means circumpolar and is not checked!
         Nova::RstTime sun_day          = Nova::GetSolarRst(JD-0.5);
         Nova::RstTime sun_civil        = Nova::GetSolarRst(JD-0.5,  -6);
@@ -156,32 +240,42 @@
         }
 
-        // case 0: midnight to sun-rise | !is_day && !is_night | rise/set
-        // case 1: sun-rise to sun-set  |  is_day && !is_night | set /rise
-        // case 2: sun-set  to midnight |  is_day &&  is_night | rise/set
+        // case 0: midnight to sun-rise | !is_day && !is_night | rise/set  | -> isday=0
+        // case 1: sun-rise to sun-set  |  is_day && !is_night | set /rise | -> isday=1
+        // case 2: sun-set  to midnight |  is_day &&  is_night | rise/set  | -> isday=0
 
         isday = is_day^is_night;
 
-        state = isday ? 4 : 0;
-        if (time>fSetDayTime)       state++;
-        if (time>fSetCivil)         state++;
-        if (time>fSetAstronomical)  state++;
-        if (time>fSetDarkTime)      state++;
-
-        if (time>fRiseDarkTime)     state++;
-        if (time>fRiseAstronomical) state++;
-        if (time>fRiseCivil)        state++;
-        if (time>fRiseDayTime)      state++;
+        Time fRiseDayTime;      //   0: Start of day time (=end of civil twilight)
+        Time fRiseCivil;        //  -6: End of nautical twilight
+        Time fRiseAstronomical; // -12: End of astron. twilight
+        Time fRiseDarkTime;     // -18: End of dark time
+
+        Time fSetDayTime;       //   0: End of day time (=start of civil twilight)
+        Time fSetCivil;         //  -6: Start of nautical twilight
+        Time fSetAstronomical;  // -12: Start of astron. twilight
+        Time fSetDarkTime;      // -18: Start of dark time
+
+        state = isday ? 4 : 0;               // 0 [-> Day time       ]
+        if (time>fSetDayTime)       state++; // 1 [-> Civil  twilight]
+        if (time>fSetCivil)         state++; // 2 [-> Naut.  twilight]
+        if (time>fSetAstronomical)  state++; // 3 [-> Astro. twilight]
+        if (time>fSetDarkTime)      state++; // 4 [-> Dark time      ]
+
+        if (time>fRiseDarkTime)     state++; // 5 [-> Astro. twilight]
+        if (time>fRiseAstronomical) state++; // 6 [-> Naut.  twilight]
+        if (time>fRiseCivil)        state++; // 7 [-> Civil  twilight]
+        if (time>fRiseDayTime)      state++; // 8 [-> Day time       ]
 
         string name[] =
         {
-            "dark time",
-            "astron. twilight",
-            "civil twilight",
-            "sunrise",
-            "day time",
-            "sunset",
-            "civil twilight",
-            "astron. twilight",
-            "dark time"
+            "dark time",          // 0
+            "astron. twilight",   // 1
+            "civil twilight",     // 2
+            "sunrise",            // 3
+            "day time",           // 4
+            "sunset",             // 5
+            "civil twilight",     // 6
+            "astron. twilight",   // 7
+            "dark time"           // 8
         };
 
@@ -204,4 +298,5 @@
 
         visible = state>=3 && state<=5;
+        */
 #endif
     }
@@ -1200,5 +1295,5 @@
         vector<float> Uov(ptr+416+6, ptr+416+6+320);
 
-        WriteCam(d, "cam-feedback-overvoltage", Uov, 0.2, 1.0);
+        WriteCam(d, "cam-feedback-overvoltage", Uov, 0.2, -0.1);
 
         const Statistics stat2(Uov);
@@ -2142,6 +2237,6 @@
     pair<vector<float>, pair<Time, float>> GetVisibility(Nova::EquPosn *src=0)
     {
-        const double sunset  = fSun.fSetAstronomical.JD();
-        const double sunrise = fSun.fRiseAstronomical.JD();
+        const double sunset  = fSun.fSunSet12.JD()-1;
+        const double sunrise = fSun.fSunRise12.JD();
 
         Nova::EquPosn  moon;
@@ -2182,6 +2277,6 @@
     pair<vector<float>, pair<Time, float>> GetLightCondition(const Nova::EquPosn &src_pos)
     {
-        const double sunset  = fSun.fSetAstronomical.JD();
-        const double sunrise = fSun.fRiseAstronomical.JD();
+        const double sunset  = fSun.fSunSet12.JD()-1;
+        const double sunrise = fSun.fSunRise12.JD();
 
         double max   = -1;
@@ -2228,18 +2323,18 @@
 
         vector<string> color(8, HTML::kWhite);
-        color[fSun.state%8] = HTML::kBlue;
+        color[fSun.state] = HTML::kBlue;
 
         ostringstream out;
         out << setprecision(3);
         out << now.JavaDate() << '\n';
-        out << color[0] << '\t' << fSun.fRiseDarkTime.GetAsStr("%H:%M") << '\n';
-        out << color[1] << '\t' << fSun.fRiseAstronomical.GetAsStr("%H:%M") << '\n';
-        out << color[2] << '\t' << fSun.fRiseCivil.GetAsStr("%H:%M") << '\n';
-        out << color[3] << '\t' << fSun.fRiseDayTime.GetAsStr("%H:%M") << '\n';
-
-        out << color[4] << '\t' << fSun.fSetDayTime.GetAsStr("%H:%M") << '\n';
-        out << color[5] << '\t' << fSun.fSetCivil.GetAsStr("%H:%M") << '\n';
-        out << color[6] << '\t' << fSun.fSetAstronomical.GetAsStr("%H:%M") << '\n';
-        out << color[7] << '\t' << fSun.fSetDarkTime.GetAsStr("%H:%M") << '\n';
+        out << color[4] << '\t' << fSun.fSunRise18.GetAsStr("%H:%M") << '\n';
+        out << color[5] << '\t' << fSun.fSunRise12.GetAsStr("%H:%M") << '\n';
+        out << color[6] << '\t' << fSun.fSunRise06.GetAsStr("%H:%M") << '\n';
+        out << color[7] << '\t' << fSun.fSunRise00.GetAsStr("%H:%M") << '\n';
+
+        out << color[0] << '\t' << fSun.fSunSet00.GetAsStr("%H:%M") << '\n';
+        out << color[1] << '\t' << fSun.fSunSet06.GetAsStr("%H:%M") << '\n';
+        out << color[2] << '\t' << fSun.fSunSet12.GetAsStr("%H:%M") << '\n';
+        out << color[3] << '\t' << fSun.fSunSet18.GetAsStr("%H:%M") << '\n';
 
         ofstream(fPath+"/sun.data") << out.str();
@@ -2424,13 +2519,13 @@
             }
 
-            if (fSun.fSetAstronomical>fSun.fRiseAstronomical)
-                fSun.fSetAstronomical += boost::posix_time::hours(24);
+            const Time st = fSun.fSunSet12;;
+            const Time rs = fSun.fSunRise12;
 
             ostringstream title;
-            title << fSun.fSetAstronomical.GetAsStr("%H:%M");
+            title << st.GetAsStr("%H:%M");
             title << " / ";
-            title << ((fSun.fRiseAstronomical-fSun.fSetAstronomical)/20).minutes();
+            title << ((rs>st?rs-st:st-rs)/20).minutes();
             title << "' / ";
-            title << fSun.fRiseAstronomical.GetAsStr("%H:%M");
+            title << rs.GetAsStr("%H:%M");
 
             out  << '\n';
@@ -2787,5 +2882,5 @@
                 out << " &#9788;";
                 if (fDimDriveControl.state()<Drive::State::kInitialized)
-                    out << " [" << fSun.fSetCivil.MinutesTo() << "&darr;]";
+                    out << " [" << fSun.fSunSet12.MinutesTo() << "&darr;]";
             }
             else
