PSUSensors: Move to GetSensorConfiguration

GetSensorConfiguration has improved to have retries
and avoid more expensive GetManagedOjects calls. Use
it.

Tested
PSU sensors are created consistently ac_cycle test

Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
Change-Id: Id6b374ff415cc7c6c0d83b55f12551556838f2b7
diff --git a/src/PSUSensorMain.cpp b/src/PSUSensorMain.cpp
index 1a1cb3c..d55d3a0 100644
--- a/src/PSUSensorMain.cpp
+++ b/src/PSUSensorMain.cpp
@@ -216,27 +216,15 @@
     }
 }
 
-void createSensors(boost::asio::io_service& io,
-                   sdbusplus::asio::object_server& objectServer,
-                   std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
+static void createSensorsCallback(
+    boost::asio::io_service& io, sdbusplus::asio::object_server& objectServer,
+    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+    const ManagedObjectType& sensorConfigs,
+    const std::shared_ptr<boost::container::flat_set<std::string>>&
+        sensorsChanged)
 {
-
-    ManagedObjectType sensorConfigs;
     int numCreated = 0;
-    bool useCache = false;
-
-    // TODO may need only modify the ones that need to be changed.
-    sensors.clear();
-    for (const char* type : sensorTypes)
-    {
-        if (!getSensorConfiguration(type, dbusConnection, sensorConfigs,
-                                    useCache))
-        {
-            std::cerr << "error get sensor config from entity manager\n";
-            return;
-        }
-        useCache = true;
-    }
+    bool firstScan = sensorsChanged == nullptr;
 
     std::vector<fs::path> pmbusPaths;
     if (!findFiles(fs::path("/sys/class/hwmon"), "name", pmbusPaths))
@@ -400,6 +388,23 @@
             std::cerr << "Cannot find psu name, invalid configuration\n";
             continue;
         }
+
+        // on rescans, only update sensors we were signaled by
+        if (!firstScan)
+        {
+            std::string psuNameStr = "/" + *psuName;
+            auto it =
+                std::find_if(sensorsChanged->begin(), sensorsChanged->end(),
+                             [psuNameStr](std::string& s) {
+                                 return boost::ends_with(s, psuNameStr);
+                             });
+
+            if (it == sensorsChanged->end())
+            {
+                continue;
+            }
+            sensorsChanged->erase(it);
+        }
         checkEvent(directory.string(), eventMatch, eventPathList);
         checkGroupEvent(directory.string(), groupEventMatch,
                         groupEventPathList);
@@ -779,7 +784,8 @@
                           << sensorPathStr << "\" type \"" << sensorType
                           << "\"\n";
             }
-
+            // destruct existing one first if already created
+            sensors[sensorName] = nullptr;
             sensors[sensorName] = std::make_shared<PSUSensor>(
                 sensorPathStr, sensorType, objectServer, dbusConnection, io,
                 sensorName, std::move(sensorThresholds), *interfacePath,
@@ -808,6 +814,22 @@
     return;
 }
 
+void createSensors(
+    boost::asio::io_service& io, sdbusplus::asio::object_server& objectServer,
+    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+    const std::shared_ptr<boost::container::flat_set<std::string>>&
+        sensorsChanged)
+{
+    auto getter = std::make_shared<GetSensorConfiguration>(
+        dbusConnection, [&io, &objectServer, &dbusConnection, sensorsChanged](
+                            const ManagedObjectType& sensorConfigs) {
+            createSensorsCallback(io, objectServer, dbusConnection,
+                                  sensorConfigs, sensorsChanged);
+        });
+    getter->getConfiguration(
+        std::vector<std::string>(sensorTypes.begin(), sensorTypes.end()));
+}
+
 void propertyInitialize(void)
 {
     sensorTable = {{"power", "power/"},
@@ -907,10 +929,12 @@
     systemBus->request_name("xyz.openbmc_project.PSUSensor");
     sdbusplus::asio::object_server objectServer(systemBus);
     std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
+    auto sensorsChanged =
+        std::make_shared<boost::container::flat_set<std::string>>();
 
     propertyInitialize();
 
-    io.post([&]() { createSensors(io, objectServer, systemBus); });
+    io.post([&]() { createSensors(io, objectServer, systemBus, nullptr); });
     boost::asio::deadline_timer filterTimer(io);
     std::function<void(sdbusplus::message::message&)> eventHandler =
         [&](sdbusplus::message::message& message) {
@@ -919,6 +943,7 @@
                 std::cerr << "callback method error\n";
                 return;
             }
+            sensorsChanged->insert(message.get_path());
             filterTimer.expires_from_now(boost::posix_time::seconds(3));
             filterTimer.async_wait([&](const boost::system::error_code& ec) {
                 if (ec == boost::asio::error::operation_aborted)
@@ -929,7 +954,7 @@
                 {
                     std::cerr << "timer error\n";
                 }
-                createSensors(io, objectServer, systemBus);
+                createSensors(io, objectServer, systemBus, sensorsChanged);
             });
         };