psu-ng: Set the PowerSystemInputs status on Brownout condition

When a brownout condition is detected, set the PowerSystemInputs status
property to Fault to avoid an autorestart, reference design doc:
https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/48015

Add a Before=xyz.openbmc_project.State.Chassis.service to the psu
monitor service file since the chassis service is the one that will be
reading the property.

Add additional data to the Blackout error log.

Tested: On simulation:

1. Clear brownout at runtime:
- At power on, inject a power fault to all PSUs to trigger a brownout
  and verify the CurrentPowerStatus is set to Fault:

Mar 20 19:49:14 p10bmc phosphor-log-manager[318]: Created PEL 0x5000000d
(BMC ID 13) with SRC 110000AC
Mar 20 19:49:14 p10bmc phosphor-power-control[307]:
callbackSetPowerSupplyError:
xyz.openbmc_project.State.Shutdown.Power.Error.Blackout

‣ Type=signal  Endian=l  Flags=1  Version=1 Cookie=94  Timestamp="Sun
2022-03-20 19:49:14.241856 UTC"
  Sender=:1.1296
Path=/xyz/openbmc_project/power/power_supplies/chassis0/psus
Interface=org.freedesktop.DBus.Properties  Member=PropertiesChanged
...
          STRING
"xyz.openbmc_project.State.Decorator.PowerSystemInputs";
...
                                  STRING
"xyz.openbmc_project.State.Decorator.PowerSystemInputs.Status.Fault";

- Additional data on the error log:

"User Data 1": {
    "Section Version": "1",
    "Sub-section type": "1",
    "Created by": "0x2000",
    "NOT_PRESENT_COUNT": "2",
    "VIN_FAULT_COUNT": "2",
    "_PID": "10244"
}

- Clear the brownout condition and verify the status is set to Good.

Change-Id: I29695b641fb81515680a478e872bac29a6de560a
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 e6a3225..03ee9e4 100644
--- a/phosphor-power-supply/psu_manager.cpp
+++ b/phosphor-power-supply/psu_manager.cpp
@@ -363,7 +363,6 @@
         {
             powerOn = false;
             runValidateConfig = true;
-            brownoutLogged = false;
         }
     }
 }
@@ -459,41 +458,36 @@
         psu->analyze();
     }
 
+    std::map<std::string, std::string> additionalData;
+
+    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.
+        additionalData["NOT_PRESENT_COUNT"] = std::to_string(notPresentCount);
+        additionalData["VIN_FAULT_COUNT"] = std::to_string(hasVINUVFaultCount);
+        setBrownout(additionalData);
+    }
+    else
+    {
+        // Brownout condition is not present or has been cleared
+        clearBrownout();
+    }
+
     if (powerOn)
     {
-        std::map<std::string, std::string> additionalData;
-
-        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();
@@ -869,4 +863,27 @@
     }
 }
 
+void PSUManager::setBrownout(std::map<std::string, std::string>& additionalData)
+{
+    powerSystemInputs.status(sdbusplus::xyz::openbmc_project::State::Decorator::
+                                 server::PowerSystemInputs::Status::Fault);
+    if (!brownoutLogged)
+    {
+        if (powerOn)
+        {
+            createError(
+                "xyz.openbmc_project.State.Shutdown.Power.Error.Blackout",
+                additionalData);
+            brownoutLogged = true;
+        }
+    }
+}
+
+void PSUManager::clearBrownout()
+{
+    powerSystemInputs.status(sdbusplus::xyz::openbmc_project::State::Decorator::
+                                 server::PowerSystemInputs::Status::Good);
+    brownoutLogged = false;
+}
+
 } // namespace phosphor::power::manager