psu: Updates for power supply presence

Update the JSON file to indicate the minimum and maximum number of power
supplies this system can have.

Update the JSON file to have an array of power supply objects, each with
their various own properties. Each power supply will have:
1) An associated D-Bus path for the inventory. This will have the
   Present property.
2) An associated I2C bus number.
3) An associated I2C bus adddress.

Update PowerSupply class to have a present member variable, an
isPresent() accessor function, and two functions for updating the
presence. One function will be the call back function for either
inventory change events or interface added events, which will use
associated match member variables. The second function being one that
attempts to read the inventory Present property on startup. If reading
the Present property on startup fails, the property changed or interface
added events should work to get the value when that property is
available.

Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
Change-Id: Ib34510a6da66ba1b8f1e927093b3d10b09beb410
diff --git a/phosphor-power-supply/power_supply.cpp b/phosphor-power-supply/power_supply.cpp
new file mode 100644
index 0000000..a6be9f5
--- /dev/null
+++ b/phosphor-power-supply/power_supply.cpp
@@ -0,0 +1,58 @@
+#include "power_supply.hpp"
+
+#include "types.hpp"
+#include "utility.hpp"
+
+namespace phosphor
+{
+namespace power
+{
+namespace psu
+{
+
+using namespace phosphor::logging;
+
+void PowerSupply::updatePresence()
+{
+    try
+    {
+        // Use getProperty utility function to get presence status.
+        util::getProperty(INVENTORY_IFACE, PRESENT_PROP, inventoryPath,
+                          INVENTORY_MGR_IFACE, bus, this->present);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        // Relying on property change or interface added to retry.
+        // Log an informational trace to the journal.
+        log<level::INFO>("D-Bus property access failure exception");
+    }
+}
+
+void PowerSupply::inventoryChanged(sdbusplus::message::message& msg)
+{
+    std::string msgSensor;
+    std::map<std::string, sdbusplus::message::variant<uint32_t, bool>> msgData;
+    msg.read(msgSensor, msgData);
+
+    // Check if it was the Present property that changed.
+    auto valPropMap = msgData.find(PRESENT_PROP);
+    if (valPropMap != msgData.end())
+    {
+        if (std::get<bool>(valPropMap->second))
+        {
+            present = true;
+            clearFaults();
+        }
+        else
+        {
+            present = false;
+
+            // Clear out the now outdated inventory properties
+            updateInventory();
+        }
+    }
+}
+
+} // namespace psu
+} // namespace power
+} // namespace phosphor