Index: trunk/FACT++/src/ftmctrl.cc
===================================================================
--- trunk/FACT++/src/ftmctrl.cc	(revision 15183)
+++ trunk/FACT++/src/ftmctrl.cc	(revision 15184)
@@ -1207,4 +1207,5 @@
     uint64_t fTimeStampOn;
     uint32_t fTriggerCounter;
+    uint64_t fPrevState;
 
     void UpdateFirstHeader()
@@ -1253,19 +1254,35 @@
         fDimDynamicData.Update(data);
 
-        float    rate = -1;
-        uint64_t tdiff = 0;
-        uint64_t odiff = 0;
-        if (fHeader.fTimeStamp>=fTimeStamp && fHeader.fTriggerCounter>=fTriggerCounter)
-        {
-            tdiff = fHeader.fTimeStamp          -fTimeStamp;
-            odiff = fDynamicData.fOnTimeCounter -fTimeStampOn;
-
-            const uint32_t cdiff = fHeader.fTriggerCounter-fTriggerCounter;
-            rate = tdiff==0 ? 0 : 1000000*float(cdiff)/tdiff;
-        }
+        uint64_t odiff = fDynamicData.fOnTimeCounter;
+        uint32_t cdiff = fHeader.fTriggerCounter;
+
+        // When the state changes (trigger on or trigger off)
+        // The counters will be resetted, thus in the next report
+        // the correct counters are the counters itself, or the correct
+        // offset is 0. For the first call, fPrevState is 0 (which is not
+        // a valid state, so it will be considered as 'changed') and
+        // fTimeStamp, fTimeStampOn and fTriggerCounter are also 0.
+        // The checks on the on-time counter and the trigger counter
+        // are just for the very unlikely case that we miss the state
+        // change because we get no updated reports in between.
+        const uint8_t state = fHeader.fState & FTM::States::kFtmStates;
+
+        if (state == fPrevState && fHeader.fTriggerCounter>=fTriggerCounter &&
+            fDynamicData.fOnTimeCounter>=fTimeStampOn)
+        {
+            odiff -= fTimeStampOn;
+            cdiff -= fTriggerCounter;
+        }
+
+        // The observation time calculated in the first report is most likely
+        // too large because the previous report is taken as reference,
+        // but this is the best what could be done.
+        const uint64_t tdiff = fHeader.fTimeStamp - fTimeStamp;
+        const float    rate  = fHeader.fTimeStamp>fTimeStamp ? 0 : 1000000*float(cdiff)/tdiff;
 
         fTimeStamp      = fHeader.fTimeStamp;
         fTimeStampOn    = fDynamicData.fOnTimeCounter;
         fTriggerCounter = fHeader.fTriggerCounter;
+        fPrevState      = state;
 
         const FTM::DimTriggerRates rates(fHeader, fDynamicData, fStaticData,
@@ -1317,6 +1334,6 @@
                                                           "|BoardRate[Hz]:Trigger rate of individual FTUs"
                                                           "|PatchRate[Hz]:Trigger rate of individual patches"
-                                                          "|ElapsedTime[sec]:Time elapsed since previous report"
-                                                          "|OnTime[sec]:OnTime elapsed since previous report"),
+                                                          "|ElapsedTime[s]:Time elapsed since previous report"
+                                                          "|OnTime[s]:OnTime elapsed since previous report"),
         fDimError         ("FTM_CONTROL/ERROR",           "X:1;S:1;S:28", ""),
         fDimFtuList       ("FTM_CONTROL/FTU_LIST",        "X:1;X:1;S:1;C:4;X:40;C:40;C:40",
@@ -1369,6 +1386,5 @@
                                                           "|NumErrors[int]:Num. of error messages"
                                                           "|NumRegister[int]:Num. of answers from a single register accesess"),
-        fTimeStamp(UINT64_MAX),
-        fTriggerCounter(UINT32_MAX)
+        fTimeStamp(0), fTimeStampOn(0), fTriggerCounter(0), fPrevState(0)
     {
     }
@@ -1988,4 +2004,5 @@
             fCounterStat = fFTM.GetCounter(FTM::kStaticData);
 
+            // T::Info(" ==> TODO: Update run in database!");
             T::Message("Sending new configuration was successfull.");
 
