psu-ng: Don't log brownout error if all PSUs are missing

During a BMC reboot at runtime, the PSUs may not exist yet on D-Bus.
Therefore, add a check to ignore if all PSUs are marked as not present,
or the total of PSUs is 0, and not log a brownout error. Therefore to
log a brownout error, at least one PSU must report a AC loss VIN fault.

Tested: Verified a brownout error is not logged on a reboot at runtime
even though the number of PSUs was 0. Also a brownout error was not
logged when all PSUs were manually set to not present.

Change-Id: Ic96ccb2609a4a4d8f07c3a63106ec43619dc341b
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/phosphor-power-supply/psu_manager.cpp b/phosphor-power-supply/psu_manager.cpp
index 198e87f..a1b9476 100644
--- a/phosphor-power-supply/psu_manager.cpp
+++ b/phosphor-power-supply/psu_manager.cpp
@@ -426,19 +426,42 @@
     if (powerOn)
     {
         std::map<std::string, std::string> additionalData;
-        auto hasVINUVFaultCount = decltype(psus.size())(0);
+
+        auto notPresentCount = decltype(psus.size())(
+            std::count_if(psus.begin(), psus.end(),
+                          [](const auto& psu) { return !psu->isPresent(); }));
+
+        auto hasVINUVFaultCount = decltype(psus.size())(
+            std::count_if(psus.begin(), psus.end(), [](const auto& psu) {
+                return psu->hasVINUVFault();
+            }));
+
+        // The PSU D-Bus objects may not be available yet, so ignore if all
+        // PSUs are not present or the number of PSUs is still 0.
+        if ((psus.size() == (notPresentCount + hasVINUVFaultCount)) &&
+            (psus.size() != notPresentCount) && (psus.size() != 0))
+        {
+            // Brownout: All PSUs report an AC failure: At least one PSU reports
+            // AC loss VIN fault and the rest either report AC loss VIN fault as
+            // well or are not present.
+            if (!brownoutLogged)
+            {
+                createError(
+                    "xyz.openbmc_project.State.Shutdown.Power.Error.Blackout",
+                    additionalData);
+                brownoutLogged = true;
+            }
+        }
+        else
+        {
+            // Brownout condition is not present or has been cleared
+            brownoutLogged = false;
+        }
 
         for (auto& psu : psus)
         {
             additionalData.clear();
 
-            // Check for brownout condition: PSU reports AC loss VIN fault or is
-            // not present.
-            if (!psu->isPresent() || psu->hasVINUVFault())
-            {
-                hasVINUVFaultCount++;
-            }
-
             if (!psu->isFaultLogged() && !psu->isPresent())
             {
                 std::map<std::string, std::string> requiredPSUsData;
@@ -621,23 +644,6 @@
                 }
             }
         }
-
-        if (hasVINUVFaultCount == psus.size())
-        {
-            // Brownout: All PSUs report AC loss VIN fault or are not present
-            if (!brownoutLogged)
-            {
-                createError(
-                    "xyz.openbmc_project.State.Shutdown.Power.Error.Blackout",
-                    additionalData);
-                brownoutLogged = true;
-            }
-        }
-        else
-        {
-            // Brownout condition is not present or has been cleared
-            brownoutLogged = false;
-        }
     }
 }