IpmbSensor : Add PollRate property.

In existing IpmbSensor code, pollrate value is fixed as 1 sec.

We have OCP YosemiteV2 target which has 4 removable host, each host
has 70(x4) sensors. More number of sensor will leads to CPU usage.

Also IPMB Version does not require to read the version for every second.

Therefore, pollRate property can be added in the EM file and based on
those values each sensor/version can be read and updated. Hence CPU
utilization also reduces.

CPU load - pollRate is 1 sec.
PID  PPID  USER  STAT  VSZ   %VSZ  %CPU     COMMAND
323   1    root   R    8200   2%    16%  /usr/bin/ipmbsensor

CPU load - pollRate is 5 sec.
PID  PPID  USER  STAT  VSZ   %VSZ  %CPU     COMMAND
294   1    root   S    8124   2%    6%   /usr/bin/ipmbsensor

TESTED: Tested in yosemitev2 by giving different PollRate
to each sensor and verified.

Signed-off-by: Jayashree Dhanapal <jayashree-d@hcl.com>
Change-Id: I1f80d426699b11a1ac8c33137d12319df429620e
diff --git a/include/IpmbSensor.hpp b/include/IpmbSensor.hpp
index 4effd18..18d10c1 100644
--- a/include/IpmbSensor.hpp
+++ b/include/IpmbSensor.hpp
@@ -81,7 +81,7 @@
                sdbusplus::asio::object_server& objectServer,
                std::vector<thresholds::Threshold>&& thresholds,
                uint8_t deviceAddress, uint8_t hostSMbusIndex,
-               std::string& sensorTypeName);
+               const float pollRate, std::string& sensorTypeName);
     ~IpmbSensor() override;
 
     void checkThresholds(void) override;
@@ -105,6 +105,7 @@
     std::vector<uint8_t> commandData;
     std::optional<uint8_t> initCommand;
     std::vector<uint8_t> initData;
+    int sensorPollMs;
 
     ReadingFormat readingFormat;
 
diff --git a/src/IpmbSensor.cpp b/src/IpmbSensor.cpp
index f52f95e..c7a9f33 100644
--- a/src/IpmbSensor.cpp
+++ b/src/IpmbSensor.cpp
@@ -46,6 +46,7 @@
 static constexpr uint8_t meAddress = 1;
 static constexpr uint8_t lun = 0;
 static constexpr uint8_t hostSMbusIndexDefault = 0x03;
+static constexpr float pollRateDefault = 1; // in seconds
 
 static constexpr const char* sensorPathPrefix = "/xyz/openbmc_project/sensors/";
 
@@ -63,13 +64,14 @@
                        sdbusplus::asio::object_server& objectServer,
                        std::vector<thresholds::Threshold>&& thresholdData,
                        uint8_t deviceAddress, uint8_t hostSMbusIndex,
-                       std::string& sensorTypeName) :
+                       const float pollRate, std::string& sensorTypeName) :
     Sensor(boost::replace_all_copy(sensorName, " ", "_"),
            std::move(thresholdData), sensorConfiguration,
            "xyz.openbmc_project.Configuration.ExitAirTemp", false,
            ipmbMaxReading, ipmbMinReading, conn, PowerState::on),
     deviceAddress(deviceAddress), hostSMbusIndex(hostSMbusIndex),
-    objectServer(objectServer), waitTimer(io)
+    sensorPollMs(static_cast<int>(pollRate * 1000)), objectServer(objectServer),
+    waitTimer(io)
 {
     std::string dbusPath = sensorPathPrefix + sensorTypeName + "/" + name;
 
@@ -340,9 +342,7 @@
 
 void IpmbSensor::read(void)
 {
-    static constexpr size_t pollTime = 1; // in seconds
-
-    waitTimer.expires_from_now(boost::posix_time::seconds(pollTime));
+    waitTimer.expires_from_now(boost::posix_time::milliseconds(sensorPollMs));
     waitTimer.async_wait([this](const boost::system::error_code& ec) {
         if (ec == boost::asio::error::operation_aborted)
         {
@@ -451,6 +451,7 @@
 
                     std::string sensorClass =
                         loadVariant<std::string>(entry.second, "Class");
+
                     uint8_t hostSMbusIndex = hostSMbusIndexDefault;
                     auto findSmType = entry.second.find("HostSMbusIndex");
                     if (findSmType != entry.second.end())
@@ -459,6 +460,18 @@
                             VariantToUnsignedIntVisitor(), findSmType->second);
                     }
 
+                    float pollRate = pollRateDefault;
+                    auto findPollRate = entry.second.find("PollRate");
+                    if (findPollRate != entry.second.end())
+                    {
+                        pollRate = std::visit(VariantToFloatVisitor(),
+                                              findPollRate->second);
+                        if (pollRate <= 0.0f)
+                        {
+                            pollRate = pollRateDefault;
+                        }
+                    }
+
                     /* Default sensor type is "temperature" */
                     std::string sensorTypeName = "temperature";
                     auto findType = entry.second.find("SensorType");
@@ -472,7 +485,7 @@
                     sensor = std::make_unique<IpmbSensor>(
                         dbusConnection, io, name, pathPair.first, objectServer,
                         std::move(sensorThresholds), deviceAddress,
-                        hostSMbusIndex, sensorTypeName);
+                        hostSMbusIndex, pollRate, sensorTypeName);
 
                     /* Initialize scale and offset value */
                     sensor->scaleVal = 1;