Add Deassert Event to PSU

Tested:
Plug out AC cable and plug in it again, below redfish log is created
{
    "@odata.context": "/redfish/v1/$metadata#LogEntry.LogEntry",
    "@odata.id": "/redfish/v1/Systems/system/LogServices/EventLog/Entries/
1566427243",
    "@odata.type": "#LogEntry.v1_4_0.LogEntry",
    "Created": "2019-08-21T22:40:43+00:00",
    "EntryType": "Event",
    "Id": "1566427243",
    "Message": "Power supply PSU2 AC power regained.",
    "MessageArgs": [
        "PSU2"
    ],
    "MessageId": "OpenBMC.0.1.PowerSupplyACInserted",
    "Name": "System Event Log Entry",
    "Severity": "OK"
},

Signed-off-by: Cheng C Yang <cheng.c.yang@linux.intel.com>
Change-Id: Ic2626c99f06962dafabb580fe498fb558480f61e
diff --git a/include/PSUEvent.hpp b/include/PSUEvent.hpp
index 104b910..165ac92 100644
--- a/include/PSUEvent.hpp
+++ b/include/PSUEvent.hpp
@@ -49,7 +49,8 @@
     static constexpr size_t warnAfterErrorCount = 10;
     std::string psuName;
     std::string fanName;
-    std::string messageID = "";
+    std::string assertMessage;
+    std::string deassertMessage;
 };
 
 class PSUCombineEvent
diff --git a/src/PSUEvent.cpp b/src/PSUEvent.cpp
index 7c6fbea..b7cd3ae 100644
--- a/src/PSUEvent.cpp
+++ b/src/PSUEvent.cpp
@@ -66,12 +66,21 @@
     objServer.remove_interface(eventInterface);
 }
 
-static boost::container::flat_map<std::string, std::string> logID = {
-    {"PredictiveFailure", "OpenBMC.0.1.PowerSupplyFailurePredicted"},
-    {"Failure", "OpenBMC.0.1.PowerSupplyFailed"},
-    {"ACLost", "OpenBMC.0.1.PowerSupplyACLost"},
-    {"FanFault", "OpenBMC.0.1.PowerSupplyFanFailed"},
-    {"ConfigureError", "OpenBMC.0.1.PowerSupplyConfigurationError"}};
+static boost::container::flat_map<std::string,
+                                  std::pair<std::string, std::string>>
+    logID = {
+        {"PredictiveFailure",
+         {"OpenBMC.0.1.PowerSupplyFailurePredicted",
+          "OpenBMC.0.1.PowerSupplyPredictedFailureRecovered"}},
+        {"Failure",
+         {"OpenBMC.0.1.PowerSupplyFailed", "OpenBMC.0.1.PowerSupplyRecovered"}},
+        {"ACLost",
+         {"OpenBMC.0.1.PowerSupplyACLost",
+          "OpenBMC.0.1.PowerSupplyACInserted"}},
+        {"FanFault",
+         {"OpenBMC.0.1.PowerSupplyFanFailed",
+          "OpenBMC.0.1.PowerSupplyFanRecovered"}},
+        {"ConfigureError", {"OpenBMC.0.1.PowerSupplyConfigurationError", ""}}};
 
 PSUSubEvent::PSUSubEvent(
     std::shared_ptr<sdbusplus::asio::dbus_interface> eventInterface,
@@ -88,17 +97,24 @@
     auto found = logID.find(eventName);
     if (found == logID.end())
     {
-        messageID.clear();
+        assertMessage.clear();
+        deassertMessage.clear();
     }
     else
     {
-        messageID = found->second;
+        assertMessage = found->second.first;
+        deassertMessage = found->second.second;
     }
 
     auto fanPos = path.find("fan");
     if (fanPos != std::string::npos)
     {
         fanName = path.substr(fanPos);
+        auto fanNamePos = fanName.find("_");
+        if (fanNamePos != std::string::npos)
+        {
+            fanName = fanName.substr(0, fanNamePos);
+        }
     }
     setupRead();
 }
@@ -186,7 +202,7 @@
         {
             return;
         }
-        (*asserts).erase(found);
+        (*asserts).erase(path);
 
         if (!(*asserts).empty())
         {
@@ -196,11 +212,33 @@
         {
             *assertState = false;
             auto foundCombine = (*combineEvent).find(eventName);
-            if (foundCombine != (*combineEvent).end())
+            if (foundCombine == (*combineEvent).end())
             {
                 return;
             }
             (*combineEvent).erase(eventName);
+            if (!deassertMessage.empty())
+            {
+                // Fan Failed has two args
+                std::string sendMessage = eventName + " deassert";
+                if (deassertMessage == "OpenBMC.0.1.PowerSupplyFanRecovered")
+                {
+                    sd_journal_send(
+                        "MESSAGE=%s", sendMessage.c_str(), "PRIORITY=%i",
+                        LOG_ERR, "REDFISH_MESSAGE_ID=%s",
+                        deassertMessage.c_str(), "REDFISH_MESSAGE_ARGS=%s,%s",
+                        psuName.c_str(), fanName.c_str(), NULL);
+                }
+                else
+                {
+                    sd_journal_send(
+                        "MESSAGE=%s", sendMessage.c_str(), "PRIORITY=%i",
+                        LOG_ERR, "REDFISH_MESSAGE_ID=%s",
+                        deassertMessage.c_str(), "REDFISH_MESSAGE_ARGS=%s",
+                        psuName.c_str(), NULL);
+                }
+            }
+
             if ((*combineEvent).empty())
             {
                 eventInterface->set_property("functional", true);
@@ -213,23 +251,23 @@
         if (*assertState == false)
         {
             *assertState = true;
-            if (!messageID.empty())
+            if (!assertMessage.empty())
             {
                 // Fan Failed has two args
                 std::string sendMessage = eventName + " assert";
-                if (messageID == "OpenBMC.0.1.PowerSupplyFanFailed")
+                if (assertMessage == "OpenBMC.0.1.PowerSupplyFanFailed")
                 {
-                    sd_journal_send("MESSAGE=%s", sendMessage.c_str(),
-                                    "PRIORITY=%i", LOG_ERR,
-                                    "REDFISH_MESSAGE_ID=%s", messageID.c_str(),
-                                    "REDFISH_MESSAGE_ARGS=%s,%s",
-                                    psuName.c_str(), fanName.c_str(), NULL);
+                    sd_journal_send(
+                        "MESSAGE=%s", sendMessage.c_str(), "PRIORITY=%i",
+                        LOG_ERR, "REDFISH_MESSAGE_ID=%s", assertMessage.c_str(),
+                        "REDFISH_MESSAGE_ARGS=%s,%s", psuName.c_str(),
+                        fanName.c_str(), NULL);
                 }
                 else
                 {
                     sd_journal_send(
                         "MESSAGE=%s", sendMessage.c_str(), "PRIORITY=%i",
-                        LOG_ERR, "REDFISH_MESSAGE_ID=%s", messageID.c_str(),
+                        LOG_ERR, "REDFISH_MESSAGE_ID=%s", assertMessage.c_str(),
                         "REDFISH_MESSAGE_ARGS=%s", psuName.c_str(), NULL);
                 }
             }