Add collection of power history data

On every PowerSupply::analyze() call, read the most recent input
history record and pass it to the RecordManager instance.  If it
is one that RecordManager doesn't have yet, get the latest maximum
and average properties from RecordManager and update D-Bus.

Change-Id: I42d63e99c7223ba1b8a7f1138657cd505a68e66a
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/power-supply/power_supply.cpp b/power-supply/power_supply.cpp
index 00e3b8c..50d647a 100644
--- a/power-supply/power_supply.cpp
+++ b/power-supply/power_supply.cpp
@@ -61,6 +61,7 @@
 constexpr auto PART_NUMBER = "part_number";
 constexpr auto FW_VERSION = "fw_version";
 constexpr auto CCIN = "ccin";
+constexpr auto INPUT_HISTORY = "input_history";
 
 PowerSupply::PowerSupply(const std::string& name, size_t inst,
                          const std::string& objpath,
@@ -157,6 +158,8 @@
                 checkCurrentOutOverCurrentFault(statusWord);
                 checkPGOrUnitOffFault(statusWord);
             }
+
+            updateHistory();
         }
     }
     catch (ReadFailure& e)
@@ -768,6 +771,29 @@
     maximum = std::make_unique<history::Maximum>(bus, maxPath);
 }
 
+void PowerSupply::updateHistory()
+{
+    if (!recordManager)
+    {
+        //Not enabled
+        return;
+    }
+
+    //Read just the most recent average/max record
+    auto data = pmbusIntf.readBinary(
+            INPUT_HISTORY,
+            pmbus::Type::HwmonDeviceDebug,
+            history::RecordManager::RAW_RECORD_SIZE);
+
+    //Update D-Bus only if something changed (a new record ID, or cleared out)
+    auto changed = recordManager->add(data);
+    if (changed)
+    {
+        average->values(std::move(recordManager->getAverageRecords()));
+        maximum->values(std::move(recordManager->getMaximumRecords()));
+    }
+}
+
 }
 }
 }
diff --git a/power-supply/power_supply.hpp b/power-supply/power_supply.hpp
index f17be38..5eb96a9 100644
--- a/power-supply/power_supply.hpp
+++ b/power-supply/power_supply.hpp
@@ -388,6 +388,20 @@
          */
         void updateInventory();
 
+        /**
+         * @brief Reads the most recent input history record from the power
+         *        supply and updates the average and maximum properties in
+         *        D-Bus if there is a new reading available.
+         *
+         * This will still run every time analyze() is called so code can
+         * post new data as soon as possible and the timestamp will more
+         * accurately reflect the correct time.
+         *
+         * D-Bus is only updated if there is a change and the oldest record
+         * will be pruned if the property already contains the max number of
+         * records.
+         */
+        void updateHistory();
 };
 
 }