Support more PSU Sensors

Base on PSU power sensors, support all other PSU sensors.

Tested By:
After run psusensor in BMC console, in xyz.openbmc_project.PSUSensor
PSU power, current, temperature, voltage and fan dbus interface has
been created with correct Thresholds and value.
Run ipmitool -I lanplus -H xxx -U root -P xxx sensor list, bellow
sensors can show as:
PSU2 Input Curre | 0.546      | Amps       | ok    | na        | na        | na        | 8.190     | na        | na
PSU2 Output Curr | 9.000      | Amps       | ok    | na        | na        | na        | 100.000   | 125.000   | na
PSU2 Fan Speed 1 | 3332.000   | RPM        | ok    | na        | na        | na        | na        | na        | na
PSU2 Input Power | 117.000    | Watts      | ok    | na        | na        | na        | 1357.200  | 1509.300  | na
PSU2 Output Powe | 105.300    | Watts      | ok    | na        | na        | na        | na        | na        | na
PSU2 Temperature | 26.000     | degrees C  | ok    | na        | na        | na        | 62.000    | 65.000    | na
PSU2 Input Volta | 235.000    | Volts      | ok    | na        | na        | na        | na        | na        | na

Change-Id: I2167594a8f369c8ed95b3dc3948f8f5b0bd8bdbb
Signed-off-by: Cheng C Yang <cheng.c.yang@linux.intel.com>
diff --git a/include/PSUSensor.hpp b/include/PSUSensor.hpp
index 8de480f..0c4edb1 100644
--- a/include/PSUSensor.hpp
+++ b/include/PSUSensor.hpp
@@ -4,14 +4,6 @@
 #include <sdbusplus/asio/object_server.hpp>
 #include <sensor.hpp>
 
-enum class SensorType
-{
-    tempSensor,
-    currSensor,
-    powerSensor,
-    voltSensor
-};
-
 class PSUSensor : public Sensor
 {
   public:
@@ -44,13 +36,13 @@
 {
   public:
     PSUProperty(std::string name, double max, double min, unsigned int factor) :
-        sensorTypeName(name), maxReading(max), minReading(min),
+        labelTypeName(name), maxReading(max), minReading(min),
         sensorScaleFactor(factor)
     {
     }
     ~PSUProperty() = default;
 
-    std::string sensorTypeName;
+    std::string labelTypeName;
     double maxReading;
     double minReading;
     unsigned int sensorScaleFactor;
diff --git a/src/PSUSensorMain.cpp b/src/PSUSensorMain.cpp
index c752cc6..bcbb5a5 100644
--- a/src/PSUSensorMain.cpp
+++ b/src/PSUSensorMain.cpp
@@ -36,9 +36,8 @@
     std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
     boost::container::flat_map<std::string, std::unique_ptr<PSUSensor>>&
         sensors,
-    boost::container::flat_map<SensorType, std::unique_ptr<PSUProperty>>&
-        sensorTable,
-    boost::container::flat_map<std::string, std::string>& labelMatch)
+    boost::container::flat_map<std::string, std::string>& sensorTable,
+    boost::container::flat_map<std::string, PSUProperty>& labelMatch)
 {
 
     ManagedObjectType sensorConfigs;
@@ -166,93 +165,127 @@
             continue;
         }
 
-        auto findSensorName = baseConfig->second.find("Name");
-        if (findSensorName == baseConfig->second.end())
+        auto findPSUName = baseConfig->second.find("Name");
+        if (findPSUName == baseConfig->second.end())
         {
             std::cerr << "could not determine configuration name for "
                       << deviceName << "\n";
             continue;
         }
 
-        std::vector<fs::path> powerPaths;
-        if (!findFiles(fs::path(directory), R"(power\d+_input$)", powerPaths,
-                       0))
+        std::vector<fs::path> sensorPaths;
+        if (!findFiles(fs::path(directory), R"(\w\d+_input$)", sensorPaths, 0))
         {
-            std::cerr << "No power sensor in PSU\n";
+            std::cerr << "No PSU non-label sensor in PSU\n";
             continue;
         }
 
-        for (const auto& powerPath : powerPaths)
+        for (const auto& sensorPath : sensorPaths)
         {
-            auto powerPathStr = powerPath.string();
-            auto labelPath =
-                boost::replace_all_copy(powerPathStr, "input", "label");
-            std::ifstream labelFile(labelPath);
-            if (!labelFile.good())
-            {
-                std::cerr << "Failure reading " << powerPath << "\n";
-                continue;
-            }
-            std::string label;
-            std::getline(labelFile, label);
-            labelFile.close();
 
-            auto findSensor = sensors.find(label);
-            if (findSensor != sensors.end())
+            std::string labelHead;
+            std::string sensorPathStr = sensorPath.string();
+            std::string sensorNameStr = sensorPath.filename();
+            std::string sensorNameSubStr =
+                sensorNameStr.substr(0, sensorNameStr.find("_") - 1);
+
+            std::string labelPathStr =
+                boost::replace_all_copy(sensorNameStr, "input", "label");
+            std::vector<fs::path> labelPaths;
+            if (!findFiles(fs::path(directory), labelPathStr, labelPaths, 0))
             {
+                std::cerr << "No PSU non-label sensor in PSU\n";
                 continue;
             }
 
-            std::vector<thresholds::Threshold> sensorThresholds;
-            std::string labelHead = label.substr(0, label.find(" "));
-            parseThresholdsFromConfig(*sensorData, sensorThresholds,
-                                      &labelHead);
-            if (sensorThresholds.empty())
+            if (labelPaths.empty())
             {
-                continue;
-            }
-
-            std::string labelName;
-            auto findLabel = labelMatch.find(label);
-            if (findLabel != labelMatch.end())
-            {
-                labelName = findLabel->second;
+                labelHead = sensorNameStr.substr(0, sensorNameStr.find("_"));
             }
             else
             {
-                labelName = label;
-            }
-            std::string sensorName =
-                std::get<std::string>(findSensorName->second) + " " + labelName;
+                auto labelPath =
+                    boost::replace_all_copy(sensorPathStr, "input", "label");
+                std::ifstream labelFile(labelPath);
+                if (!labelFile.good())
+                {
+                    std::cerr << "Failure reading " << sensorPath << "\n";
+                    continue;
+                }
+                std::string label;
+                std::getline(labelFile, label);
+                labelFile.close();
 
-            auto findProperty = sensorTable.find(SensorType::powerSensor);
-            if (findProperty == sensorTable.end())
+                auto findSensor = sensors.find(label);
+                if (findSensor != sensors.end())
+                {
+                    continue;
+                }
+
+                labelHead = label.substr(0, label.find(" "));
+            }
+
+            std::vector<thresholds::Threshold> sensorThresholds;
+
+            parseThresholdsFromConfig(*sensorData, sensorThresholds,
+                                      &labelHead);
+
+            auto findProperty = labelMatch.find(labelHead);
+            if (findProperty == labelMatch.end())
             {
-                std::cerr << "Cannot find PSU sensorType " << sensorType
-                          << "\n";
                 continue;
             }
 
+            unsigned int factor =
+                std::pow(10, findProperty->second.sensorScaleFactor);
+            if (sensorThresholds.empty())
+            {
+                if (!parseThresholdsFromAttr(sensorThresholds, sensorPathStr,
+                                             factor))
+                {
+                    std::cerr << "error populating thresholds\n";
+                }
+            }
+
+            auto findSensorType = sensorTable.find(sensorNameSubStr);
+            if (findSensorType == sensorTable.end())
+            {
+                std::cerr << "Cannot find PSU sensorType\n";
+                continue;
+            }
+
+            std::string sensorName =
+                std::get<std::string>(findPSUName->second) + " " +
+                findProperty->second.labelTypeName;
+
             sensors[sensorName] = std::make_unique<PSUSensor>(
-                powerPathStr, sensorType, objectServer, dbusConnection, io,
+                sensorPathStr, sensorType, objectServer, dbusConnection, io,
                 sensorName, std::move(sensorThresholds), *interfacePath,
-                findProperty->second->sensorTypeName,
-                findProperty->second->sensorScaleFactor,
-                findProperty->second->maxReading,
-                findProperty->second->minReading);
+                findSensorType->second, factor, findProperty->second.maxReading,
+                findProperty->second.minReading);
         }
     }
     return;
 }
 
 void propertyInitialize(
-    boost::container::flat_map<SensorType, std::unique_ptr<PSUProperty>>&
-        sensorTable,
-    boost::container::flat_map<std::string, std::string>& labelMatch)
+    boost::container::flat_map<std::string, std::string>& sensorTable,
+    boost::container::flat_map<std::string, PSUProperty>& labelMatch)
 {
-    sensorTable[SensorType::powerSensor] =
-        std::make_unique<PSUProperty>("power/", 65535, 0, 100000);
-    labelMatch["pin"] = "Input Power";
+    sensorTable = {{"power", "power/"},
+                   {"curr", "current/"},
+                   {"temp", "temperature/"},
+                   {"in", "voltage/"},
+                   {"fan", "fan_tach/"}};
+
+    labelMatch = {{"pin", PSUProperty("Input Power", 3000, 0, 6)},
+                  {"pout1", PSUProperty("Output Power", 3000, 0, 6)},
+                  {"vin", PSUProperty("Input Voltage", 255, 0, 3)},
+                  {"iin", PSUProperty("Input Current", 20, 0, 3)},
+                  {"iout1", PSUProperty("Output Current", 255, 0, 3)},
+                  {"temp1", PSUProperty("Temperature", 127, -128, 3)},
+                  {"fan1", PSUProperty("Fan Speed 1", 10000, 0, 0)},
+                  {"fan2", PSUProperty("Fan Speed 2", 10000, 0, 0)}};
 }
 
 int main(int argc, char** argv)
@@ -263,10 +296,9 @@
     systemBus->request_name("xyz.openbmc_project.PSUSensor");
     sdbusplus::asio::object_server objectServer(systemBus);
     boost::container::flat_map<std::string, std::unique_ptr<PSUSensor>> sensors;
-    boost::container::flat_map<SensorType, std::unique_ptr<PSUProperty>>
-        sensorTable;
+    boost::container::flat_map<std::string, std::string> sensorTable;
     std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
-    boost::container::flat_map<std::string, std::string> labelMatch;
+    boost::container::flat_map<std::string, PSUProperty> labelMatch;
 
     propertyInitialize(sensorTable, labelMatch);