Fixed issue with wrong timestamp

Telemetry service used steady_clock for generating timestamps, but it
produced incorrect time. This change makes telemetry service use
steady_clock for intervals and system_clock for timestamps.

Changed readings timestamp to display current timestamp instead of a
time when reading was received.

Tested:
- correct timestamp is visible on dbus
- other telemetry service features are still working

Change-Id: Ic49f45640532cfffaeff5e0bd5591e6d99e5def5
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/src/details/collection_function.cpp b/src/details/collection_function.cpp
index d92fdf3..360f082 100644
--- a/src/details/collection_function.cpp
+++ b/src/details/collection_function.cpp
@@ -8,101 +8,105 @@
 class FunctionSingle : public CollectionFunction
 {
   public:
-    ReadingItem calculate(const std::vector<ReadingItem>& readings,
-                          uint64_t) const override
+    double calculate(const std::vector<ReadingItem>& readings,
+                     Milliseconds) const override
     {
-        return readings.back();
+        return readings.back().second;
     }
 
-    ReadingItem calculateForStartupInterval(std::vector<ReadingItem>& readings,
-                                            uint64_t timestamp) const override
+    double calculateForStartupInterval(std::vector<ReadingItem>& readings,
+                                       Milliseconds) const override
     {
         readings.assign({readings.back()});
-        return readings.back();
+        return readings.back().second;
     }
 };
 
 class FunctionMinimum : public CollectionFunction
 {
   public:
-    ReadingItem calculate(const std::vector<ReadingItem>& readings,
-                          uint64_t) const override
+    double calculate(const std::vector<ReadingItem>& readings,
+                     Milliseconds) const override
     {
-        return *std::min_element(
-            readings.begin(), readings.end(),
-            [](const auto& left, const auto& right) {
-                return std::make_tuple(!std::isfinite(left.second),
-                                       left.second) <
-                       std::make_tuple(!std::isfinite(right.second),
-                                       right.second);
-            });
+        return std::min_element(
+                   readings.begin(), readings.end(),
+                   [](const auto& left, const auto& right) {
+                       return std::make_tuple(!std::isfinite(left.second),
+                                              left.second) <
+                              std::make_tuple(!std::isfinite(right.second),
+                                              right.second);
+                   })
+            ->second;
     }
 
-    ReadingItem calculateForStartupInterval(std::vector<ReadingItem>& readings,
-                                            uint64_t timestamp) const override
+    double calculateForStartupInterval(std::vector<ReadingItem>& readings,
+                                       Milliseconds timestamp) const override
     {
-        readings.assign({ReadingItem(calculate(readings, timestamp))});
-        return readings.back();
+        readings.assign(
+            {ReadingItem(timestamp, calculate(readings, timestamp))});
+        return readings.back().second;
     }
 };
 
 class FunctionMaximum : public CollectionFunction
 {
   public:
-    ReadingItem calculate(const std::vector<ReadingItem>& readings,
-                          uint64_t) const override
+    double calculate(const std::vector<ReadingItem>& readings,
+                     Milliseconds) const override
     {
-        return *std::max_element(
-            readings.begin(), readings.end(),
-            [](const auto& left, const auto& right) {
-                return std::make_tuple(std::isfinite(left.second),
-                                       left.second) <
-                       std::make_tuple(std::isfinite(right.second),
-                                       right.second);
-            });
+        return std::max_element(
+                   readings.begin(), readings.end(),
+                   [](const auto& left, const auto& right) {
+                       return std::make_tuple(std::isfinite(left.second),
+                                              left.second) <
+                              std::make_tuple(std::isfinite(right.second),
+                                              right.second);
+                   })
+            ->second;
     }
 
-    ReadingItem calculateForStartupInterval(std::vector<ReadingItem>& readings,
-                                            uint64_t timestamp) const override
+    double calculateForStartupInterval(std::vector<ReadingItem>& readings,
+                                       Milliseconds timestamp) const override
     {
-        readings.assign({ReadingItem(calculate(readings, timestamp))});
-        return readings.back();
+        readings.assign(
+            {ReadingItem(timestamp, calculate(readings, timestamp))});
+        return readings.back().second;
     }
 };
 
 class FunctionAverage : public CollectionFunction
 {
   public:
-    ReadingItem calculate(const std::vector<ReadingItem>& readings,
-                          uint64_t timestamp) const override
+    double calculate(const std::vector<ReadingItem>& readings,
+                     Milliseconds timestamp) const override
     {
         auto valueSum = 0.0;
-        auto timeSum = uint64_t{0};
+        auto timeSum = Milliseconds{0};
         for (auto it = readings.begin(); it != std::prev(readings.end()); ++it)
         {
             if (std::isfinite(it->second))
             {
                 const auto kt = std::next(it);
                 const auto duration = kt->first - it->first;
-                valueSum += it->second * duration;
+                valueSum += it->second * duration.count();
                 timeSum += duration;
             }
         }
 
         const auto duration = timestamp - readings.back().first;
-        valueSum += readings.back().second * duration;
+        valueSum += readings.back().second * duration.count();
         timeSum += duration;
 
-        return ReadingItem{timestamp, valueSum / timeSum};
+        return valueSum / std::max(timeSum.count(), uint64_t{1u});
     }
 
-    ReadingItem calculateForStartupInterval(std::vector<ReadingItem>& readings,
-                                            uint64_t timestamp) const override
+    double calculateForStartupInterval(std::vector<ReadingItem>& readings,
+                                       Milliseconds timestamp) const override
     {
         auto result = calculate(readings, timestamp);
-        if (std::isfinite(result.second))
+        if (std::isfinite(result))
         {
-            readings.assign({ReadingItem(readings.front().first, result.second),
+            readings.assign({ReadingItem(readings.front().first, result),
                              ReadingItem(timestamp, readings.back().second)});
         }
         return result;
@@ -111,9 +115,11 @@
 
 class FunctionSummation : public CollectionFunction
 {
+    using Multiplier = std::chrono::duration<double>;
+
   public:
-    ReadingItem calculate(const std::vector<ReadingItem>& readings,
-                          uint64_t timestamp) const override
+    double calculate(const std::vector<ReadingItem>& readings,
+                     const Milliseconds timestamp) const override
     {
         auto valueSum = 0.0;
         for (auto it = readings.begin(); it != std::prev(readings.end()); ++it)
@@ -121,28 +127,45 @@
             if (std::isfinite(it->second))
             {
                 const auto kt = std::next(it);
-                const auto duration = kt->first - it->first;
-                valueSum += it->second * duration;
+                const auto multiplier =
+                    calculateMultiplier(kt->first - it->first);
+                valueSum += it->second * multiplier.count();
             }
         }
 
-        const auto duration = timestamp - readings.back().first;
-        valueSum += readings.back().second * duration;
+        const auto multiplier =
+            calculateMultiplier(timestamp - readings.back().first);
+        valueSum += readings.back().second * multiplier.count();
 
-        return ReadingItem{timestamp, valueSum};
+        return valueSum;
     }
 
-    ReadingItem calculateForStartupInterval(std::vector<ReadingItem>& readings,
-                                            uint64_t timestamp) const override
+    double
+        calculateForStartupInterval(std::vector<ReadingItem>& readings,
+                                    const Milliseconds timestamp) const override
     {
-        auto result = calculate(readings, timestamp);
-        if (std::isfinite(result.second) && timestamp > 0u)
+        const auto result = calculate(readings, timestamp);
+        if (readings.size() > 2 && std::isfinite(result))
         {
-            readings.assign({ReadingItem(timestamp - 1u, result.second),
-                             ReadingItem(timestamp, readings.back().second)});
+            const auto multiplier =
+                calculateMultiplier(timestamp - readings.front().first).count();
+            if (multiplier > 0.)
+            {
+                const auto prevValue = result / multiplier;
+                readings.assign(
+                    {ReadingItem(readings.front().first, prevValue),
+                     ReadingItem(timestamp, readings.back().second)});
+            }
         }
         return result;
     }
+
+  private:
+    static constexpr Multiplier calculateMultiplier(Milliseconds duration)
+    {
+        constexpr auto m = Multiplier{Seconds{1}};
+        return Multiplier{duration / m};
+    }
 };
 
 std::shared_ptr<CollectionFunction>
diff --git a/src/details/collection_function.hpp b/src/details/collection_function.hpp
index a8708e7..ca653a1 100644
--- a/src/details/collection_function.hpp
+++ b/src/details/collection_function.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "types/duration_types.hpp"
 #include "types/operation_type.hpp"
 
 #include <cstdint>
@@ -10,18 +11,18 @@
 namespace details
 {
 
-using ReadingItem = std::pair<uint64_t, double>;
+using ReadingItem = std::pair<Milliseconds, double>;
 
 class CollectionFunction
 {
   public:
     virtual ~CollectionFunction() = default;
 
-    virtual ReadingItem calculate(const std::vector<ReadingItem>& readings,
-                                  uint64_t timestamp) const = 0;
-    virtual ReadingItem
+    virtual double calculate(const std::vector<ReadingItem>& readings,
+                             Milliseconds timestamp) const = 0;
+    virtual double
         calculateForStartupInterval(std::vector<ReadingItem>& readings,
-                                    uint64_t timestamp) const = 0;
+                                    Milliseconds timestamp) const = 0;
 };
 
 std::shared_ptr<CollectionFunction> makeCollectionFunction(OperationType);
diff --git a/src/discrete_threshold.cpp b/src/discrete_threshold.cpp
index 89a1b7c..25cc46f 100644
--- a/src/discrete_threshold.cpp
+++ b/src/discrete_threshold.cpp
@@ -37,11 +37,11 @@
 }
 
 void DiscreteThreshold::sensorUpdated(interfaces::Sensor& sensor,
-                                      uint64_t timestamp)
+                                      Milliseconds timestamp)
 {}
 
 void DiscreteThreshold::sensorUpdated(interfaces::Sensor& sensor,
-                                      uint64_t timestamp, double value)
+                                      Milliseconds timestamp, double value)
 {
     auto& [sensorName, dwell, timer] = getDetails(sensor);
 
@@ -60,7 +60,7 @@
 }
 
 void DiscreteThreshold::startTimer(interfaces::Sensor& sensor,
-                                   uint64_t timestamp, double value)
+                                   Milliseconds timestamp, double value)
 {
     auto& [sensorName, dwell, timer] = getDetails(sensor);
     if (dwellTime == Milliseconds::zero())
@@ -87,7 +87,7 @@
 }
 
 void DiscreteThreshold::commit(const std::string& sensorName,
-                               uint64_t timestamp, double value)
+                               Milliseconds timestamp, double value)
 {
     for (const auto& action : actions)
     {
diff --git a/src/discrete_threshold.hpp b/src/discrete_threshold.hpp
index 8dc2eeb..636a4f5 100644
--- a/src/discrete_threshold.hpp
+++ b/src/discrete_threshold.hpp
@@ -4,7 +4,7 @@
 #include "interfaces/sensor_listener.hpp"
 #include "interfaces/threshold.hpp"
 #include "interfaces/trigger_action.hpp"
-#include "types/milliseconds.hpp"
+#include "types/duration_types.hpp"
 #include "types/trigger_types.hpp"
 
 #include <boost/asio/steady_timer.hpp>
@@ -30,8 +30,8 @@
     {}
 
     void initialize() override;
-    void sensorUpdated(interfaces::Sensor&, uint64_t) override;
-    void sensorUpdated(interfaces::Sensor&, uint64_t, double) override;
+    void sensorUpdated(interfaces::Sensor&, Milliseconds) override;
+    void sensorUpdated(interfaces::Sensor&, Milliseconds, double) override;
 
   private:
     boost::asio::io_context& ioc;
@@ -55,7 +55,7 @@
     };
     std::vector<ThresholdDetail> details;
 
-    void startTimer(interfaces::Sensor&, uint64_t, double);
-    void commit(const std::string&, uint64_t, double);
+    void startTimer(interfaces::Sensor&, Milliseconds, double);
+    void commit(const std::string&, Milliseconds, double);
     ThresholdDetail& getDetails(interfaces::Sensor& sensor);
 };
diff --git a/src/interfaces/clock.hpp b/src/interfaces/clock.hpp
index 0c355b7..b37ff3a 100644
--- a/src/interfaces/clock.hpp
+++ b/src/interfaces/clock.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "types/duration_types.hpp"
+
 #include <chrono>
 
 namespace interfaces
@@ -8,15 +10,10 @@
 class Clock
 {
   public:
-    using duration = std::chrono::steady_clock::time_point::duration;
-    using rep = std::chrono::steady_clock::time_point::rep;
-    using period = std::chrono::steady_clock::time_point::period;
-    using time_point = std::chrono::steady_clock::time_point;
-
     virtual ~Clock() = default;
 
-    virtual time_point now() const noexcept = 0;
-    virtual uint64_t timestamp() const noexcept = 0;
+    virtual Milliseconds steadyTimestamp() const noexcept = 0;
+    virtual Milliseconds systemTimestamp() const noexcept = 0;
 };
 
 } // namespace interfaces
diff --git a/src/interfaces/sensor_listener.hpp b/src/interfaces/sensor_listener.hpp
index 9406da6..a47c8d4 100644
--- a/src/interfaces/sensor_listener.hpp
+++ b/src/interfaces/sensor_listener.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "types/duration_types.hpp"
+
 #include <cstdint>
 #include <optional>
 
@@ -13,8 +15,8 @@
   public:
     virtual ~SensorListener() = default;
 
-    virtual void sensorUpdated(interfaces::Sensor&, uint64_t) = 0;
-    virtual void sensorUpdated(interfaces::Sensor&, uint64_t, double) = 0;
+    virtual void sensorUpdated(interfaces::Sensor&, Milliseconds) = 0;
+    virtual void sensorUpdated(interfaces::Sensor&, Milliseconds, double) = 0;
 };
 
 } // namespace interfaces
diff --git a/src/interfaces/trigger_action.hpp b/src/interfaces/trigger_action.hpp
index d21f238..437a79f 100644
--- a/src/interfaces/trigger_action.hpp
+++ b/src/interfaces/trigger_action.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "types/duration_types.hpp"
+
 #include <cstdint>
 #include <string>
 
@@ -11,7 +13,7 @@
   public:
     virtual ~TriggerAction() = default;
 
-    virtual void commit(const std::string& id, uint64_t timestamp,
+    virtual void commit(const std::string& id, Milliseconds timestamp,
                         double value) = 0;
 };
 } // namespace interfaces
diff --git a/src/metric.cpp b/src/metric.cpp
index ee12c74..d8241b9 100644
--- a/src/metric.cpp
+++ b/src/metric.cpp
@@ -16,28 +16,26 @@
 
     virtual ~CollectionData() = default;
 
-    virtual ReadingItem update(uint64_t timestamp) = 0;
-    virtual ReadingItem update(uint64_t timestamp, double value) = 0;
+    virtual std::optional<double> update(Milliseconds timestamp) = 0;
+    virtual double update(Milliseconds timestamp, double value) = 0;
 };
 
 class Metric::DataPoint : public Metric::CollectionData
 {
   public:
-    ReadingItem update(uint64_t timestamp) override
+    std::optional<double> update(Milliseconds) override
     {
-        return ReadingItem{lastTimestamp, lastReading};
+        return lastReading;
     }
 
-    ReadingItem update(uint64_t timestamp, double reading) override
+    double update(Milliseconds, double reading) override
     {
-        lastTimestamp = timestamp;
         lastReading = reading;
-        return update(timestamp);
+        return reading;
     }
 
   private:
-    uint64_t lastTimestamp = 0u;
-    double lastReading = 0.0;
+    std::optional<double> lastReading;
 };
 
 class Metric::DataInterval : public Metric::CollectionData
@@ -56,43 +54,51 @@
         }
     }
 
-    ReadingItem update(uint64_t timestamp) override
+    std::optional<double> update(Milliseconds timestamp) override
     {
-        if (readings.size() > 0)
+        if (readings.empty())
         {
-            auto it = readings.begin();
-            for (auto kt = std::next(readings.rbegin()); kt != readings.rend();
-                 ++kt)
-            {
-                const auto& [nextItemTimestamp, nextItemReading] =
-                    *std::prev(kt);
-                if (timestamp >= nextItemTimestamp &&
-                    static_cast<uint64_t>(timestamp - nextItemTimestamp) >
-                        duration.t.count())
-                {
-                    it = kt.base();
-                    break;
-                }
-            }
-            readings.erase(readings.begin(), it);
-
-            if (timestamp > duration.t.count())
-            {
-                readings.front().first = std::max(
-                    readings.front().first, timestamp - duration.t.count());
-            }
+            return std::nullopt;
         }
 
+        cleanup(timestamp);
+
         return function->calculate(readings, timestamp);
     }
 
-    ReadingItem update(uint64_t timestamp, double reading) override
+    double update(Milliseconds timestamp, double reading) override
     {
         readings.emplace_back(timestamp, reading);
-        return update(timestamp);
+
+        cleanup(timestamp);
+
+        return function->calculate(readings, timestamp);
     }
 
   private:
+    void cleanup(Milliseconds timestamp)
+    {
+        auto it = readings.begin();
+        for (auto kt = std::next(readings.rbegin()); kt != readings.rend();
+             ++kt)
+        {
+            const auto& [nextItemTimestamp, nextItemReading] = *std::prev(kt);
+            if (timestamp >= nextItemTimestamp &&
+                timestamp - nextItemTimestamp > duration.t)
+            {
+                it = kt.base();
+                break;
+            }
+        }
+        readings.erase(readings.begin(), it);
+
+        if (timestamp > duration.t)
+        {
+            readings.front().first =
+                std::max(readings.front().first, timestamp - duration.t);
+        }
+    }
+
     std::shared_ptr<details::CollectionFunction> function;
     std::vector<ReadingItem> readings;
     CollectionDuration duration;
@@ -105,12 +111,17 @@
         function(std::move(function))
     {}
 
-    ReadingItem update(uint64_t timestamp) override
+    std::optional<double> update(Milliseconds timestamp) override
     {
+        if (readings.empty())
+        {
+            return std::nullopt;
+        }
+
         return function->calculateForStartupInterval(readings, timestamp);
     }
 
-    ReadingItem update(uint64_t timestamp, double reading) override
+    double update(Milliseconds timestamp, double reading) override
     {
         readings.emplace_back(timestamp, reading);
         return function->calculateForStartupInterval(readings, timestamp);
@@ -158,24 +169,31 @@
 
 std::vector<MetricValue> Metric::getReadings() const
 {
-    const auto timestamp = clock->timestamp();
+    const auto steadyTimestamp = clock->steadyTimestamp();
+    const auto systemTimestamp = clock->systemTimestamp();
+
     auto resultReadings = readings;
 
     for (size_t i = 0; i < resultReadings.size(); ++i)
     {
-        std::tie(resultReadings[i].timestamp, resultReadings[i].value) =
-            collectionAlgorithms[i]->update(timestamp);
+        if (const auto value = collectionAlgorithms[i]->update(steadyTimestamp))
+        {
+            resultReadings[i].timestamp =
+                std::chrono::duration_cast<Milliseconds>(systemTimestamp)
+                    .count();
+            resultReadings[i].value = *value;
+        }
     }
 
     return resultReadings;
 }
 
-void Metric::sensorUpdated(interfaces::Sensor& notifier, uint64_t timestamp)
+void Metric::sensorUpdated(interfaces::Sensor& notifier, Milliseconds timestamp)
 {
     findAssociatedData(notifier).update(timestamp);
 }
 
-void Metric::sensorUpdated(interfaces::Sensor& notifier, uint64_t timestamp,
+void Metric::sensorUpdated(interfaces::Sensor& notifier, Milliseconds timestamp,
                            double value)
 {
     findAssociatedData(notifier).update(timestamp, value);
diff --git a/src/metric.hpp b/src/metric.hpp
index 1ff5bc2..859315e 100644
--- a/src/metric.hpp
+++ b/src/metric.hpp
@@ -19,8 +19,9 @@
     void initialize() override;
     void deinitialize() override;
     std::vector<MetricValue> getReadings() const override;
-    void sensorUpdated(interfaces::Sensor&, uint64_t) override;
-    void sensorUpdated(interfaces::Sensor&, uint64_t, double value) override;
+    void sensorUpdated(interfaces::Sensor&, Milliseconds) override;
+    void sensorUpdated(interfaces::Sensor&, Milliseconds,
+                       double value) override;
     LabeledMetricParameters dumpConfiguration() const override;
     uint64_t sensorCount() const override;
 
diff --git a/src/numeric_threshold.cpp b/src/numeric_threshold.cpp
index ebb7826..3bec427 100644
--- a/src/numeric_threshold.cpp
+++ b/src/numeric_threshold.cpp
@@ -42,11 +42,11 @@
 }
 
 void NumericThreshold::sensorUpdated(interfaces::Sensor& sensor,
-                                     uint64_t timestamp)
+                                     Milliseconds timestamp)
 {}
 
 void NumericThreshold::sensorUpdated(interfaces::Sensor& sensor,
-                                     uint64_t timestamp, double value)
+                                     Milliseconds timestamp, double value)
 {
     auto& [sensorName, prevValue, dwell, timer] = getDetails(sensor);
     bool decreasing = thresholdValue < prevValue && thresholdValue > value;
@@ -68,8 +68,8 @@
 }
 
 void NumericThreshold::startTimer(const std::string& sensorName,
-                                  uint64_t timestamp, double value, bool& dwell,
-                                  boost::asio::steady_timer& timer)
+                                  Milliseconds timestamp, double value,
+                                  bool& dwell, boost::asio::steady_timer& timer)
 {
     if (dwellTime == Milliseconds::zero())
     {
@@ -93,8 +93,8 @@
     }
 }
 
-void NumericThreshold::commit(const std::string& sensorName, uint64_t timestamp,
-                              double value)
+void NumericThreshold::commit(const std::string& sensorName,
+                              Milliseconds timestamp, double value)
 {
     for (const auto& action : actions)
     {
diff --git a/src/numeric_threshold.hpp b/src/numeric_threshold.hpp
index 338d00b..2aff15c 100644
--- a/src/numeric_threshold.hpp
+++ b/src/numeric_threshold.hpp
@@ -4,7 +4,7 @@
 #include "interfaces/sensor_listener.hpp"
 #include "interfaces/threshold.hpp"
 #include "interfaces/trigger_action.hpp"
-#include "types/milliseconds.hpp"
+#include "types/duration_types.hpp"
 #include "types/trigger_types.hpp"
 
 #include <boost/asio/steady_timer.hpp>
@@ -28,8 +28,8 @@
     ~NumericThreshold();
 
     void initialize() override;
-    void sensorUpdated(interfaces::Sensor&, uint64_t) override;
-    void sensorUpdated(interfaces::Sensor&, uint64_t, double) override;
+    void sensorUpdated(interfaces::Sensor&, Milliseconds) override;
+    void sensorUpdated(interfaces::Sensor&, Milliseconds, double) override;
 
   private:
     boost::asio::io_context& ioc;
@@ -54,8 +54,8 @@
     };
     std::vector<ThresholdDetail> details;
 
-    void startTimer(const std::string&, uint64_t, double, bool&,
+    void startTimer(const std::string&, Milliseconds, double, bool&,
                     boost::asio::steady_timer&);
-    void commit(const std::string&, uint64_t, double);
+    void commit(const std::string&, Milliseconds, double);
     ThresholdDetail& getDetails(interfaces::Sensor& sensor);
 };
diff --git a/src/on_change_threshold.cpp b/src/on_change_threshold.cpp
index 5285ee3..e278c7f 100644
--- a/src/on_change_threshold.cpp
+++ b/src/on_change_threshold.cpp
@@ -18,11 +18,11 @@
 }
 
 void OnChangeThreshold::sensorUpdated(interfaces::Sensor& sensor,
-                                      uint64_t timestamp)
+                                      Milliseconds timestamp)
 {}
 
 void OnChangeThreshold::sensorUpdated(interfaces::Sensor& sensor,
-                                      uint64_t timestamp, double value)
+                                      Milliseconds timestamp, double value)
 {
     auto it =
         std::find_if(sensors.begin(), sensors.end(),
@@ -32,7 +32,7 @@
 }
 
 void OnChangeThreshold::commit(const std::string& sensorName,
-                               uint64_t timestamp, double value)
+                               Milliseconds timestamp, double value)
 {
     for (const auto& action : actions)
     {
diff --git a/src/on_change_threshold.hpp b/src/on_change_threshold.hpp
index 7eb1f6d..61c75d5 100644
--- a/src/on_change_threshold.hpp
+++ b/src/on_change_threshold.hpp
@@ -25,13 +25,13 @@
     {}
 
     void initialize() override;
-    void sensorUpdated(interfaces::Sensor&, uint64_t) override;
-    void sensorUpdated(interfaces::Sensor&, uint64_t, double) override;
+    void sensorUpdated(interfaces::Sensor&, Milliseconds) override;
+    void sensorUpdated(interfaces::Sensor&, Milliseconds, double) override;
 
   private:
     const Sensors sensors;
     const std::vector<std::string> sensorNames;
     const std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
 
-    void commit(const std::string&, uint64_t, double);
+    void commit(const std::string&, Milliseconds, double);
 };
diff --git a/src/report.cpp b/src/report.cpp
index 54189e3..170f50d 100644
--- a/src/report.cpp
+++ b/src/report.cpp
@@ -21,7 +21,7 @@
                interfaces::ReportManager& reportManager,
                interfaces::JsonStorage& reportStorageIn,
                std::vector<std::shared_ptr<interfaces::Metric>> metricsIn,
-               const bool enabledIn) :
+               const bool enabledIn, std::unique_ptr<interfaces::Clock> clock) :
     id(reportId),
     name(reportName), reportingType(reportingTypeIn), interval(intervalIn),
     reportActions(std::move(reportActionsIn)),
@@ -30,7 +30,7 @@
     reportUpdates(reportUpdatesIn),
     readingsBuffer(deduceBufferSize(reportUpdates, reportingType)),
     objServer(objServer), metrics(std::move(metricsIn)), timer(ioc),
-    reportStorage(reportStorageIn), enabled(enabledIn)
+    reportStorage(reportStorageIn), enabled(enabledIn), clock(std::move(clock))
 {
     readingParameters =
         toReadingParameters(utils::transform(metrics, [](const auto& metric) {
@@ -318,7 +318,8 @@
     }
 
     readings = {
-        Clock().timestamp(),
+        std::chrono::duration_cast<Milliseconds>(clock->systemTimestamp())
+            .count(),
         std::vector<ReadingData>(readingsBuffer.begin(), readingsBuffer.end())};
 
     reportIface->signal_property("Readings");
diff --git a/src/report.hpp b/src/report.hpp
index 72563f5..e2f422d 100644
--- a/src/report.hpp
+++ b/src/report.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "interfaces/clock.hpp"
 #include "interfaces/json_storage.hpp"
 #include "interfaces/metric.hpp"
 #include "interfaces/report.hpp"
@@ -29,7 +30,7 @@
            interfaces::ReportManager& reportManager,
            interfaces::JsonStorage& reportStorage,
            std::vector<std::shared_ptr<interfaces::Metric>> metrics,
-           const bool enabled);
+           const bool enabled, std::unique_ptr<interfaces::Clock> clock);
     ~Report() = default;
 
     Report(const Report&) = delete;
@@ -83,6 +84,7 @@
 
     interfaces::JsonStorage& reportStorage;
     bool enabled;
+    std::unique_ptr<interfaces::Clock> clock;
 
   public:
     static constexpr const char* reportIfaceName =
diff --git a/src/report_factory.cpp b/src/report_factory.cpp
index f72a3f7..278b9f1 100644
--- a/src/report_factory.cpp
+++ b/src/report_factory.cpp
@@ -40,10 +40,10 @@
                 std::make_unique<Clock>());
         });
 
-    return std::make_unique<Report>(bus->get_io_context(), objServer, id, name,
-                                    reportingType, reportActions, period,
-                                    appendLimit, reportUpdates, reportManager,
-                                    reportStorage, std::move(metrics), enabled);
+    return std::make_unique<Report>(
+        bus->get_io_context(), objServer, id, name, reportingType,
+        reportActions, period, appendLimit, reportUpdates, reportManager,
+        reportStorage, std::move(metrics), enabled, std::make_unique<Clock>());
 }
 
 Sensors ReportFactory::getSensors(
diff --git a/src/sensor.cpp b/src/sensor.cpp
index 5c71910..d81e1a1 100644
--- a/src/sensor.cpp
+++ b/src/sensor.cpp
@@ -100,7 +100,7 @@
 
 void Sensor::updateValue(double newValue)
 {
-    timestamp = Clock().timestamp();
+    timestamp = Clock().steadyTimestamp();
 
     if (value == newValue)
     {
diff --git a/src/sensor.hpp b/src/sensor.hpp
index 3c9c746..d2c3ec2 100644
--- a/src/sensor.hpp
+++ b/src/sensor.hpp
@@ -2,7 +2,7 @@
 
 #include "interfaces/sensor.hpp"
 #include "interfaces/sensor_listener.hpp"
-#include "types/milliseconds.hpp"
+#include "types/duration_types.hpp"
 #include "utils/unique_call.hpp"
 
 #include <boost/asio/high_resolution_timer.hpp>
@@ -53,7 +53,7 @@
 
     utils::UniqueCall uniqueCall;
     std::vector<std::weak_ptr<interfaces::SensorListener>> listeners;
-    uint64_t timestamp = 0;
+    Milliseconds timestamp = Milliseconds{0u};
     std::optional<double> value;
     std::unique_ptr<sdbusplus::bus::match_t> signalMonitor;
 };
diff --git a/src/trigger_actions.cpp b/src/trigger_actions.cpp
index e159cb1..22c81a3 100644
--- a/src/trigger_actions.cpp
+++ b/src/trigger_actions.cpp
@@ -9,9 +9,9 @@
 
 namespace
 {
-std::string timestampToString(uint64_t timestamp)
+std::string timestampToString(Milliseconds timestamp)
 {
-    std::time_t t = static_cast<time_t>(timestamp);
+    std::time_t t = static_cast<time_t>(timestamp.count());
     std::array<char, sizeof("YYYY-MM-DDThh:mm:ssZ")> buf = {};
     size_t size =
         std::strftime(buf.data(), buf.size(), "%FT%TZ", std::gmtime(&t));
@@ -55,7 +55,7 @@
     throw std::runtime_error("Invalid type");
 }
 
-void LogToJournal::commit(const std::string& sensorName, uint64_t timestamp,
+void LogToJournal::commit(const std::string& sensorName, Milliseconds timestamp,
                           double value)
 {
     std::string msg = std::string(getType()) +
@@ -84,14 +84,14 @@
     throw std::runtime_error("Invalid type");
 }
 
-void LogToRedfish::commit(const std::string& sensorName, uint64_t timestamp,
+void LogToRedfish::commit(const std::string& sensorName, Milliseconds timestamp,
                           double value)
 {
     phosphor::logging::log<phosphor::logging::level::INFO>(
         "Threshold value is exceeded",
         phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", getMessageId()),
         phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%llu,%s",
-                                 sensorName.c_str(), value, timestamp,
+                                 sensorName.c_str(), value, timestamp.count(),
                                  getDirection(value, threshold)));
 }
 
@@ -146,7 +146,7 @@
     throw std::runtime_error("Invalid severity");
 }
 
-void LogToJournal::commit(const std::string& sensorName, uint64_t timestamp,
+void LogToJournal::commit(const std::string& sensorName, Milliseconds timestamp,
                           double value)
 {
     std::string msg = std::string(getSeverity()) +
@@ -171,14 +171,14 @@
     throw std::runtime_error("Invalid severity");
 }
 
-void LogToRedfish::commit(const std::string& sensorName, uint64_t timestamp,
+void LogToRedfish::commit(const std::string& sensorName, Milliseconds timestamp,
                           double value)
 {
     phosphor::logging::log<phosphor::logging::level::INFO>(
         "Discrete treshold condition is met",
         phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", getMessageId()),
         phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%llu",
-                                 sensorName.c_str(), value, timestamp));
+                                 sensorName.c_str(), value, timestamp.count()));
 }
 
 void fillActions(
@@ -216,7 +216,7 @@
 
 namespace onChange
 {
-void LogToJournal::commit(const std::string& sensorName, uint64_t timestamp,
+void LogToJournal::commit(const std::string& sensorName, Milliseconds timestamp,
                           double value)
 {
     std::string msg = "Value changed on sensor " + sensorName +
@@ -226,7 +226,7 @@
     phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
 }
 
-void LogToRedfish::commit(const std::string& sensorName, uint64_t timestamp,
+void LogToRedfish::commit(const std::string& sensorName, Milliseconds timestamp,
                           double value)
 {
     const char* messageId = "OpenBMC.0.1.0.DiscreteThresholdOnChange";
@@ -234,7 +234,7 @@
         "Uncondtional discrete threshold triggered",
         phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageId),
         phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%llu",
-                                 sensorName.c_str(), value, timestamp));
+                                 sensorName.c_str(), value, timestamp.count()));
 }
 
 void fillActions(
@@ -270,7 +270,7 @@
 } // namespace onChange
 } // namespace discrete
 
-void UpdateReport::commit(const std::string&, uint64_t, double)
+void UpdateReport::commit(const std::string&, Milliseconds, double)
 {
     for (const auto& name : reportIds)
     {
diff --git a/src/trigger_actions.hpp b/src/trigger_actions.hpp
index d86acb8..2871256 100644
--- a/src/trigger_actions.hpp
+++ b/src/trigger_actions.hpp
@@ -15,7 +15,7 @@
     LogToJournal(::numeric::Type type, double val) : type(type), threshold(val)
     {}
 
-    void commit(const std::string& id, uint64_t timestamp,
+    void commit(const std::string& id, Milliseconds timestamp,
                 double value) override;
 
   private:
@@ -31,7 +31,7 @@
     LogToRedfish(::numeric::Type type, double val) : type(type), threshold(val)
     {}
 
-    void commit(const std::string& id, uint64_t timestamp,
+    void commit(const std::string& id, Milliseconds timestamp,
                 double value) override;
 
   private:
@@ -56,7 +56,7 @@
     LogToJournal(::discrete::Severity severity) : severity(severity)
     {}
 
-    void commit(const std::string& id, uint64_t timestamp,
+    void commit(const std::string& id, Milliseconds timestamp,
                 double value) override;
 
   private:
@@ -71,7 +71,7 @@
     LogToRedfish(::discrete::Severity severity) : severity(severity)
     {}
 
-    void commit(const std::string& id, uint64_t timestamp,
+    void commit(const std::string& id, Milliseconds timestamp,
                 double value) override;
 
   private:
@@ -94,7 +94,7 @@
     LogToJournal()
     {}
 
-    void commit(const std::string& id, uint64_t timestamp,
+    void commit(const std::string& id, Milliseconds timestamp,
                 double value) override;
 };
 
@@ -104,7 +104,7 @@
     LogToRedfish()
     {}
 
-    void commit(const std::string& id, uint64_t timestamp,
+    void commit(const std::string& id, Milliseconds timestamp,
                 double value) override;
 };
 
@@ -126,7 +126,7 @@
         reportIds(std::move(ids))
     {}
 
-    void commit(const std::string& id, uint64_t timestamp,
+    void commit(const std::string& id, Milliseconds timestamp,
                 double value) override;
 
   private:
diff --git a/src/types/collection_duration.hpp b/src/types/collection_duration.hpp
index 2db8278..cdb9ff9 100644
--- a/src/types/collection_duration.hpp
+++ b/src/types/collection_duration.hpp
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "types/milliseconds.hpp"
+#include "types/duration_types.hpp"
 
 #include <boost/serialization/strong_typedef.hpp>
 #include <nlohmann/json.hpp>
diff --git a/src/types/duration_type.hpp b/src/types/duration_type.hpp
deleted file mode 100644
index 69d3862..0000000
--- a/src/types/duration_type.hpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include <chrono>
-#include <cstdint>
-
-using Milliseconds = std::chrono::duration<uint64_t, std::milli>;
diff --git a/src/types/milliseconds.hpp b/src/types/duration_types.hpp
similarity index 66%
rename from src/types/milliseconds.hpp
rename to src/types/duration_types.hpp
index 6de2c2b..b65f779 100644
--- a/src/types/milliseconds.hpp
+++ b/src/types/duration_types.hpp
@@ -2,4 +2,5 @@
 
 #include <chrono>
 
+using Seconds = std::chrono::duration<uint64_t>;
 using Milliseconds = std::chrono::duration<uint64_t, std::milli>;
diff --git a/src/utils/clock.hpp b/src/utils/clock.hpp
index 00fd8d0..4e17952 100644
--- a/src/utils/clock.hpp
+++ b/src/utils/clock.hpp
@@ -1,22 +1,24 @@
 #pragma once
 
 #include "interfaces/clock.hpp"
-#include "types/duration_type.hpp"
+#include "types/duration_types.hpp"
 
 #include <chrono>
 
 class Clock : public interfaces::Clock
 {
   public:
-    time_point now() const noexcept override
+    Milliseconds steadyTimestamp() const noexcept override
     {
-        return std::chrono::steady_clock::now();
+        return std::chrono::time_point_cast<Milliseconds>(
+                   std::chrono::steady_clock::now())
+            .time_since_epoch();
     }
 
-    uint64_t timestamp() const noexcept override
+    Milliseconds systemTimestamp() const noexcept override
     {
-        return std::chrono::time_point_cast<Milliseconds>(now())
-            .time_since_epoch()
-            .count();
+        return std::chrono::time_point_cast<Milliseconds>(
+                   std::chrono::system_clock::now())
+            .time_since_epoch();
     }
 };
diff --git a/src/utils/detached_timer.hpp b/src/utils/detached_timer.hpp
index 636949c..ae97fab 100644
--- a/src/utils/detached_timer.hpp
+++ b/src/utils/detached_timer.hpp
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "types/milliseconds.hpp"
+#include "types/duration_types.hpp"
 
 #include <boost/asio/io_context.hpp>
 #include <boost/asio/steady_timer.hpp>