Only update inventory when presence state changes

When the presence state of a fan enclosure, determined from all the
sensors part of that fan enclosure, changes then update inventory.

Change-Id: Ie80e83fa7d0200239ced7b9d2ef84664e599e8ca
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/fan_enclosure.cpp b/fan_enclosure.cpp
index 998bd50..aaf415d 100644
--- a/fan_enclosure.cpp
+++ b/fan_enclosure.cpp
@@ -21,17 +21,24 @@
 constexpr auto INVENTORY_PATH = "/xyz/openbmc_project/inventory";
 constexpr auto INVENTORY_INTF = "xyz.openbmc_project.Inventory.Manager";
 
-FanEnclosure::ObjectMap FanEnclosure::getObjectMap()
+presenceState FanEnclosure::getCurPresState()
 {
-    ObjectMap invObj;
-    InterfaceMap invIntf;
-    PropertyMap invProp;
     auto presPred = [](auto const& s) {return s->isPresent();};
     // Determine if all sensors show fan is not present
     auto isPresent = std::any_of(sensors.begin(),
                                  sensors.end(),
                                  presPred);
-    invProp.emplace("Present", isPresent);
+
+    return (isPresent) ? PRESENT : NOT_PRESENT;
+}
+
+FanEnclosure::ObjectMap FanEnclosure::getObjectMap(const bool curPresState)
+{
+    ObjectMap invObj;
+    InterfaceMap invIntf;
+    PropertyMap invProp;
+
+    invProp.emplace("Present", curPresState);
     invProp.emplace("PrettyName", fanDesc);
     invIntf.emplace("xyz.openbmc_project.Inventory.Item", std::move(invProp));
     Object fanInvPath = invPath;
@@ -71,31 +78,38 @@
 
 void FanEnclosure::updInventory()
 {
-    //Get inventory object for this fan
-    ObjectMap invObj = getObjectMap();
-    //Get inventory manager service name from mapper
-    std::string invService;
-    try
+    auto curPresState = getCurPresState();
+    // Only update inventory when presence state changed
+    if (presState != curPresState)
     {
-        invService = getInvService();
-    }
-    catch (const std::runtime_error& err)
-    {
-        log<level::ERR>(err.what());
-        return;
-    }
-    // Update inventory for this fan
-    auto invMsg = bus.new_method_call(invService.c_str(),
-                                      INVENTORY_PATH,
-                                      INVENTORY_INTF,
-                                      "Notify");
-    invMsg.append(std::move(invObj));
-    auto invMgrResponseMsg = bus.call(invMsg);
-    if (invMgrResponseMsg.is_method_error())
-    {
-        log<level::ERR>(
-            "Error in inventory manager call to update inventory");
-        return;
+        // Get inventory object for this fan
+        ObjectMap invObj = getObjectMap(curPresState);
+        // Get inventory manager service name from mapper
+        std::string invService;
+        try
+        {
+            invService = getInvService();
+        }
+        catch (const std::runtime_error& err)
+        {
+            log<level::ERR>(err.what());
+            return;
+        }
+        // Update inventory for this fan
+        auto invMsg = bus.new_method_call(invService.c_str(),
+                                          INVENTORY_PATH,
+                                          INVENTORY_INTF,
+                                          "Notify");
+        invMsg.append(std::move(invObj));
+        auto invMgrResponseMsg = bus.call(invMsg);
+        if (invMgrResponseMsg.is_method_error())
+        {
+            log<level::ERR>(
+                "Error in inventory manager call to update inventory");
+            return;
+        }
+        // Inventory updated, set presence state to current
+        presState = curPresState;
     }
 }
 
diff --git a/fan_enclosure.hpp b/fan_enclosure.hpp
index cd9f689..da6f7e5 100644
--- a/fan_enclosure.hpp
+++ b/fan_enclosure.hpp
@@ -12,6 +12,13 @@
 namespace presence
 {
 
+typedef enum presenceState
+{
+    NOT_PRESENT,
+    PRESENT,
+    UNKNOWN
+} presenceState;
+
 class FanEnclosure
 {
     using Property = std::string;
@@ -52,10 +59,12 @@
         const std::string invPath;
         const std::string fanDesc;
         std::vector<std::unique_ptr<Sensor>> sensors;
+        presenceState presState = UNKNOWN;
 
+        presenceState getCurPresState();
         //TODO openbmc/openbmc#1299 - Move getInvService() to a utility file
         std::string getInvService();
-        ObjectMap getObjectMap();
+        ObjectMap getObjectMap(bool curPresState);
 
 };