PSUSensor: Add Offset attribute

The value of "Offset" is measured by power team and is considered as the
correctest calibration value for making the sensor reading value much
more precise on the platform.

Add the customizable attribute "Offset" to be able to adjust the raw
data and than update to the "Value" property on dbus.

Tested: Add the following configuration to entity-manager
        {
            "Address": "0x68",
            "Bus": "32",
            "Labels": [
                "vout1",
                "iout1",
                "pout1",
                "temp1"
            ],
            "Name": "onboard_p12v",
            "Thresholds": [
                ...
            ],
            "Type": "RAA228000",
            "iout1_Max": 108.0,
            "iout1_Offset": -0.25,
            "pout1_Max": 900.0,
            "pout1_Offset": -5.0,
            "vout1_Max": 13.0
        },
    - Check the reading value on dbus of this sensor is equal to the
      value we expected.

Signed-off-by: Jeff Lin <JeffLin2@quantatw.com>
Change-Id: Ia741c668e1d1939d2366f2b02553a465cd3c616b
diff --git a/include/PSUSensor.hpp b/include/PSUSensor.hpp
index 9bc2e83..2c56c64 100644
--- a/include/PSUSensor.hpp
+++ b/include/PSUSensor.hpp
@@ -20,7 +20,7 @@
               std::vector<thresholds::Threshold>&& thresholds,
               const std::string& sensorConfiguration,
               const std::string& sensorUnits, unsigned int factor, double max,
-              double min, const std::string& label, size_t tSize,
+              double min, double offset, const std::string& label, size_t tSize,
               double pollRate);
     ~PSUSensor() override;
     void setupRead(void);
@@ -34,6 +34,7 @@
     std::string pathRatedMin;
     unsigned int sensorFactor;
     uint8_t minMaxReadCounter;
+    double sensorOffset;
     void handleResponse(const boost::system::error_code& err);
     void checkThresholds(void) override;
     void updateMinMaxValues(void);
@@ -51,9 +52,11 @@
 class PSUProperty
 {
   public:
-    PSUProperty(std::string name, double max, double min, unsigned int factor) :
-        labelTypeName(std::move(name)), maxReading(max), minReading(min),
-        sensorScaleFactor(factor)
+    PSUProperty(std::string name, double max, double min, unsigned int factor,
+                double offset) :
+        labelTypeName(std::move(name)),
+        maxReading(max), minReading(min), sensorScaleFactor(factor),
+        sensorOffset(offset)
     {}
     ~PSUProperty() = default;
 
@@ -61,4 +64,5 @@
     double maxReading;
     double minReading;
     unsigned int sensorScaleFactor;
+    double sensorOffset;
 };
diff --git a/src/PSUSensor.cpp b/src/PSUSensor.cpp
index d323b4d..9ceda7f 100644
--- a/src/PSUSensor.cpp
+++ b/src/PSUSensor.cpp
@@ -42,14 +42,14 @@
                      std::vector<thresholds::Threshold>&& thresholdsIn,
                      const std::string& sensorConfiguration,
                      const std::string& sensorUnits, unsigned int factor,
-                     double max, double min, const std::string& label,
-                     size_t tSize, double pollRate) :
+                     double max, double min, double offset,
+                     const std::string& label, size_t tSize, double pollRate) :
     Sensor(boost::replace_all_copy(sensorName, " ", "_"),
            std::move(thresholdsIn), sensorConfiguration, objectType, false, max,
            min, conn),
     std::enable_shared_from_this<PSUSensor>(), objServer(objectServer),
     inputDev(io), waitTimer(io), path(path), pathRatedMax(""), pathRatedMin(""),
-    sensorFactor(factor), minMaxReadCounter(0)
+    sensorFactor(factor), minMaxReadCounter(0), sensorOffset(offset)
 {
     std::string unitPath = sensor_paths::getPathForUnits(sensorUnits);
     if constexpr (debug)
@@ -57,8 +57,8 @@
         std::cerr << "Constructed sensor: path " << path << " type "
                   << objectType << " config " << sensorConfiguration
                   << " typename " << unitPath << " factor " << factor << " min "
-                  << min << " max " << max << " name \"" << sensorName
-                  << "\"\n";
+                  << min << " max " << max << " offset " << offset << " name \""
+                  << sensorName << "\"\n";
     }
     if (pollRate > 0.0)
     {
@@ -181,7 +181,7 @@
         try
         {
             rawValue = std::stod(buffer);
-            updateValue(rawValue / sensorFactor);
+            updateValue((rawValue / sensorFactor) + sensorOffset);
             if (minMaxReadCounter++ % 8 == 0)
             {
                 updateMinMaxValues();
diff --git a/src/PSUSensorMain.cpp b/src/PSUSensorMain.cpp
index 01ae6d8..e31eb1b 100644
--- a/src/PSUSensorMain.cpp
+++ b/src/PSUSensorMain.cpp
@@ -620,6 +620,7 @@
             std::string keyScale = labelHead + "_Scale";
             std::string keyMin = labelHead + "_Min";
             std::string keyMax = labelHead + "_Max";
+            std::string keyOffset = labelHead + "_Offset";
 
             bool customizedName = false;
             auto findCustomName = baseConfig->second.find(keyName);
@@ -697,6 +698,21 @@
                 }
             }
 
+            auto findCustomOffset = baseConfig->second.find(keyOffset);
+            if (findCustomOffset != baseConfig->second.end())
+            {
+                try
+                {
+                    psuProperty->sensorOffset = std::visit(
+                        VariantToDoubleVisitor(), findCustomOffset->second);
+                }
+                catch (std::invalid_argument&)
+                {
+                    std::cerr << "Unable to parse " << keyOffset << "\n";
+                    continue;
+                }
+            }
+
             if (!(psuProperty->minReading < psuProperty->maxReading))
             {
                 std::cerr << "Min must be less than Max\n";
@@ -802,7 +818,8 @@
                           << psuProperty->labelTypeName << "\" Scale "
                           << psuProperty->sensorScaleFactor << " Min "
                           << psuProperty->minReading << " Max "
-                          << psuProperty->maxReading << "\n";
+                          << psuProperty->maxReading << " Offset "
+                          << psuProperty->sensorOffset << "\n";
             }
 
             std::string sensorName = psuProperty->labelTypeName;
@@ -836,8 +853,8 @@
                 sensorPathStr, sensorType, objectServer, dbusConnection, io,
                 sensorName, std::move(sensorThresholds), *interfacePath,
                 findSensorUnit->second, factor, psuProperty->maxReading,
-                psuProperty->minReading, labelHead, thresholdConfSize,
-                pollRate);
+                psuProperty->minReading, psuProperty->sensorOffset, labelHead,
+                thresholdConfSize, pollRate);
             sensors[sensorName]->setupRead();
             ++numCreated;
             if constexpr (debug)
@@ -885,74 +902,75 @@
                    {"in", sensor_paths::unitVolts},
                    {"fan", sensor_paths::unitRPMs}};
 
-    labelMatch = {{"pin", PSUProperty("Input Power", 3000, 0, 6)},
-                  {"pout1", PSUProperty("Output Power", 3000, 0, 6)},
-                  {"pout2", PSUProperty("Output Power", 3000, 0, 6)},
-                  {"pout3", PSUProperty("Output Power", 3000, 0, 6)},
-                  {"power1", PSUProperty("Output Power", 3000, 0, 6)},
-                  {"maxpin", PSUProperty("Max Input Power", 3000, 0, 6)},
-                  {"vin", PSUProperty("Input Voltage", 300, 0, 3)},
-                  {"maxvin", PSUProperty("Max Input Voltage", 300, 0, 3)},
-                  {"vout1", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout2", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout3", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout4", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout5", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout6", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout7", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout8", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout9", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout10", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout11", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout12", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout13", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout14", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout15", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout16", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout17", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout18", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout19", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout20", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout21", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout22", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout23", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout24", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout25", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout26", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout27", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout28", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout29", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout30", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout31", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vout32", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"vmon", PSUProperty("Auxiliary Input Voltage", 255, 0, 3)},
-                  {"in1", PSUProperty("Output Voltage", 255, 0, 3)},
-                  {"iin", PSUProperty("Input Current", 20, 0, 3)},
-                  {"iout1", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout2", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout3", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout4", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout5", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout6", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout7", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout8", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout9", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout10", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout11", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout12", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout13", PSUProperty("Output Current", 255, 0, 3)},
-                  {"iout14", PSUProperty("Output Current", 255, 0, 3)},
-                  {"curr1", PSUProperty("Output Current", 255, 0, 3)},
-                  {"maxiout1", PSUProperty("Max Output Current", 255, 0, 3)},
-                  {"temp1", PSUProperty("Temperature", 127, -128, 3)},
-                  {"temp2", PSUProperty("Temperature", 127, -128, 3)},
-                  {"temp3", PSUProperty("Temperature", 127, -128, 3)},
-                  {"temp4", PSUProperty("Temperature", 127, -128, 3)},
-                  {"temp5", PSUProperty("Temperature", 127, -128, 3)},
-                  {"temp6", PSUProperty("Temperature", 127, -128, 3)},
-                  {"maxtemp1", PSUProperty("Max Temperature", 127, -128, 3)},
-                  {"fan1", PSUProperty("Fan Speed 1", 30000, 0, 0)},
-                  {"fan2", PSUProperty("Fan Speed 2", 30000, 0, 0)}};
+    labelMatch = {
+        {"pin", PSUProperty("Input Power", 3000, 0, 6, 0)},
+        {"pout1", PSUProperty("Output Power", 3000, 0, 6, 0)},
+        {"pout2", PSUProperty("Output Power", 3000, 0, 6, 0)},
+        {"pout3", PSUProperty("Output Power", 3000, 0, 6, 0)},
+        {"power1", PSUProperty("Output Power", 3000, 0, 6, 0)},
+        {"maxpin", PSUProperty("Max Input Power", 3000, 0, 6, 0)},
+        {"vin", PSUProperty("Input Voltage", 300, 0, 3, 0)},
+        {"maxvin", PSUProperty("Max Input Voltage", 300, 0, 3, 0)},
+        {"vout1", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout2", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout3", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout4", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout5", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout6", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout7", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout8", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout9", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout10", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout11", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout12", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout13", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout14", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout15", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout16", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout17", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout18", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout19", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout20", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout21", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout22", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout23", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout24", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout25", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout26", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout27", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout28", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout29", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout30", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout31", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vout32", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"vmon", PSUProperty("Auxiliary Input Voltage", 255, 0, 3, 0)},
+        {"in1", PSUProperty("Output Voltage", 255, 0, 3, 0)},
+        {"iin", PSUProperty("Input Current", 20, 0, 3, 0)},
+        {"iout1", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout2", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout3", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout4", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout5", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout6", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout7", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout8", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout9", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout10", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout11", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout12", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout13", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"iout14", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"curr1", PSUProperty("Output Current", 255, 0, 3, 0)},
+        {"maxiout1", PSUProperty("Max Output Current", 255, 0, 3, 0)},
+        {"temp1", PSUProperty("Temperature", 127, -128, 3, 0)},
+        {"temp2", PSUProperty("Temperature", 127, -128, 3, 0)},
+        {"temp3", PSUProperty("Temperature", 127, -128, 3, 0)},
+        {"temp4", PSUProperty("Temperature", 127, -128, 3, 0)},
+        {"temp5", PSUProperty("Temperature", 127, -128, 3, 0)},
+        {"temp6", PSUProperty("Temperature", 127, -128, 3, 0)},
+        {"maxtemp1", PSUProperty("Max Temperature", 127, -128, 3, 0)},
+        {"fan1", PSUProperty("Fan Speed 1", 30000, 0, 0, 0)},
+        {"fan2", PSUProperty("Fan Speed 2", 30000, 0, 0, 0)}};
 
     pwmTable = {{"fan1", "Fan_1"}, {"fan2", "Fan_2"}};