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/psu_manager.hpp b/phosphor-power-supply/psu_manager.hpp
index b3877b7..a4628c4 100644
--- a/phosphor-power-supply/psu_manager.hpp
+++ b/phosphor-power-supply/psu_manager.hpp
@@ -9,6 +9,13 @@
 #include <sdeventplus/event.hpp>
 #include <sdeventplus/utility/timer.hpp>
 
+struct sys_properties
+{
+    int pollInterval;
+    int minPowerSupplies;
+    int maxPowerSupplies;
+};
+
 using namespace phosphor::power::psu;
 using namespace phosphor::logging;
 
@@ -19,11 +26,6 @@
 namespace manager
 {
 
-struct json_properties
-{
-    int pollInterval;
-};
-
 /**
  * @class PSUManager
  *
@@ -48,45 +50,11 @@
      * @param[in] configfile - string path to the configuration file
      */
     PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e,
-               const std::string& configfile) :
-        bus(bus)
-    {
-        // Parse out the JSON properties
-        json_properties properties = {0};
-        getJSONProperties(configfile, properties);
+               const std::string& configfile);
 
-        using namespace sdeventplus;
-        auto pollInterval = std::chrono::milliseconds(properties.pollInterval);
-        timer = std::make_unique<utility::Timer<ClockId::Monotonic>>(
-            e, std::bind(&PSUManager::analyze, this), pollInterval);
-
-        // Subscribe to power state changes
-        powerService = util::getService(POWER_OBJ_PATH, POWER_IFACE, bus);
-        powerOnMatch = std::make_unique<sdbusplus::bus::match_t>(
-            bus,
-            sdbusplus::bus::match::rules::propertiesChanged(POWER_OBJ_PATH,
-                                                            POWER_IFACE),
-            [this](auto& msg) { this->powerStateChanged(msg); });
-
-        initialize();
-    }
-
-    void getJSONProperties(const std::string& path, json_properties& p)
-    {
-        nlohmann::json configFileJSON = util::loadJSONFromFile(path.c_str());
-
-        if (configFileJSON == nullptr)
-        {
-            throw std::runtime_error("Failed to load JSON configuration file");
-        }
-
-        if (!configFileJSON.contains("pollInterval"))
-        {
-            throw std::runtime_error("Missing required pollInterval property");
-        }
-
-        p.pollInterval = configFileJSON.at("pollInterval");
-    }
+    void getJSONProperties(const std::string& path, sdbusplus::bus::bus& bus,
+                           sys_properties& p,
+                           std::vector<std::unique_ptr<PowerSupply>>& psus);
 
     /**
      * Initializes the manager.
@@ -141,7 +109,7 @@
     {
         for (auto& psu : psus)
         {
-            psu.clearFaults();
+            psu->clearFaults();
         }
     }
 
@@ -165,7 +133,7 @@
     {
         for (auto& psu : psus)
         {
-            psu.analyze();
+            psu->analyze();
         }
     }
 
@@ -200,14 +168,24 @@
     {
         for (auto& psu : psus)
         {
-            psu.updateInventory();
+            psu->updateInventory();
         }
     }
 
     /**
+     * @brief Minimum number of power supplies to operate.
+     */
+    int minPSUs = 1;
+
+    /**
+     * @brief Maximum number of power supplies possible.
+     */
+    int maxPSUs = 1;
+
+    /**
      * @brief The vector for power supplies.
      */
-    std::vector<PowerSupply> psus;
+    std::vector<std::unique_ptr<PowerSupply>> psus;
 };
 
 } // namespace manager