psu-ng: Handle health rollup based on availability

When a PSU is set to not available, create an association between the
power supply and its chassis as a way to 'roll up' the health status to
that chassis.  It looks like:

    <chassis>/critical
        endpoints: <power supply>
    <power supply>/health_rollup
        endpoints: <chassis>

There is Redfish code that look at the endpoints in that chassis
association object to determine if the chassis health is OK or not.

Note that some systems, such as IBM's, have other code that will fill
in that association when it is called out in an event log, which is why
this code doesn't have to do it for every single fault.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I262dd738ebadb72aa207011941066fc282bfe4df
diff --git a/phosphor-power-supply/power_supply.cpp b/phosphor-power-supply/power_supply.cpp
index e5fa9c8..bdfc6bb 100644
--- a/phosphor-power-supply/power_supply.cpp
+++ b/phosphor-power-supply/power_supply.cpp
@@ -168,6 +168,16 @@
         log<level::DEBUG>(
             fmt::format("presentOld: {} present: {}", presentOld, present)
                 .c_str());
+
+        auto invpath = inventoryPath.substr(strlen(INVENTORY_OBJ_PATH));
+        auto const lastSlashPos = invpath.find_last_of('/');
+        std::string prettyName = invpath.substr(lastSlashPos + 1);
+        setPresence(bus, invpath, present, prettyName);
+        updateInventory();
+
+        // Need Functional to already be correct before calling this
+        checkAvailability();
+
         if (present)
         {
             std::this_thread::sleep_for(std::chrono::milliseconds(bindDelay));
@@ -180,13 +190,6 @@
         {
             bindOrUnbindDriver(present);
         }
-
-        auto invpath = inventoryPath.substr(strlen(INVENTORY_OBJ_PATH));
-        auto const lastSlashPos = invpath.find_last_of('/');
-        std::string prettyName = invpath.substr(lastSlashPos + 1);
-        setPresence(bus, invpath, present, prettyName);
-        updateInventory();
-        checkAvailability();
     }
 }
 
@@ -921,6 +924,11 @@
     {
         auto invpath = inventoryPath.substr(strlen(INVENTORY_OBJ_PATH));
         phosphor::power::psu::setAvailable(bus, invpath, available);
+
+        // Check if the health rollup needs to change based on the
+        // new availability value.
+        phosphor::power::psu::handleChassisHealthRollup(bus, inventoryPath,
+                                                        !available);
     }
 }