Add func for Maximum when sensor from DBus

Add function to calculate the maximum value.

Tested:
in entity-manager/baseboard.json:
add virtual sensor use Type=Maximum:
```
    {
        "Exposes": [
            {
                "Name": "NVMe MAX Temp",
                "Sensors": [
                    "NVMe 0 Temp",
                    "NVMe 1 Temp",
                    "NVMe 2 Temp",
                    "NVMe 3 Temp",
                    "NVMe 4 Temp"
                ],
                "Thresholds": [
                    {
                        "Direction": "greater than",
                        "Name": "upper critical",
                        "Severity": 1,
                        "Value": 116
                    },
                    {
                        "Direction": "less than",
                        "Name": "lower critical",
                        "Severity": 1,
                        "Value": 1
                    }
                ],
                "Type": "Maximum",
                "Units": "DegreesC"
            }
        ],
        "Logging": "Off",
        "Name": "NVMe MAX",
        "Probe": "TRUE",
        "Type": "NVMe",
        "xyz.openbmc_project.Inventory.Item.Chassis": {}
    }
```

in phosphor-virtual-sensor/virtual_sensor_config.json
```
{
	"Desc": {
		"Config": "D-Bus",
		"Type": "Maximum"
	}
}
```

root@NULL:~# busctl  tree xyz.openbmc_project.VirtualSensor
`-/xyz
  `-/xyz/openbmc_project
      `-/xyz/openbmc_project/sensors/temperature
        |-/xyz/openbmc_project/sensors/temperature/NVMe_MAX_Temp
root@NULL:~# ipmitool sensor list | grep -i NVMe
NVMe_MAX_Temp |70| degrees C |na| na|1.000|6.000|111.000|116.000|na
root@NULL:~#

Signed-off-by: Tao Lin <lintao.lc@inspur.com>
Change-Id: I620a0ee3c3cc4dbae6485c77fe4e47c62a04a804
diff --git a/virtualSensor.cpp b/virtualSensor.cpp
index 063fb0f..d130200 100644
--- a/virtualSensor.cpp
+++ b/virtualSensor.cpp
@@ -10,8 +10,9 @@
 static constexpr auto busName = "xyz.openbmc_project.VirtualSensor";
 static constexpr auto sensorDbusPath = "/xyz/openbmc_project/sensors/";
 static constexpr auto vsThresholdsIfaceSuffix = ".Thresholds";
-static constexpr std::array<const char*, 1> calculationIfaces = {
-    "xyz.openbmc_project.Configuration.ModifiedMedian"};
+static constexpr std::array<const char*, 2> calculationIfaces = {
+    "xyz.openbmc_project.Configuration.ModifiedMedian",
+    "xyz.openbmc_project.Configuration.Maximum"};
 static constexpr auto defaultHysteresis = 0;
 
 PHOSPHOR_LOG2_USING_WITH_FLAGS;
@@ -461,6 +462,10 @@
     {
         return calculateModifiedMedianValue(paramMap);
     }
+    else if (calculation == "xyz.openbmc_project.Configuration.Maximum")
+    {
+        return calculateMaximumValue(paramMap);
+    }
     return std::numeric_limits<double>::quiet_NaN();
 }
 
@@ -552,6 +557,31 @@
     }
 }
 
+double VirtualSensor::calculateMaximumValue(
+    const VirtualSensor::ParamMap& paramMap)
+{
+    std::vector<double> values;
+
+    for (auto& param : paramMap)
+    {
+        auto& name = param.first;
+        if (auto var = symbols.get_variable(name))
+        {
+            if (!sensorInRange(var->ref()))
+            {
+                continue;
+            }
+            values.push_back(var->ref());
+        }
+    }
+    auto maxIt = std::max_element(values.begin(), values.end());
+    if (maxIt == values.end())
+    {
+        return std::numeric_limits<double>::quiet_NaN();
+    }
+    return *maxIt;
+}
+
 void VirtualSensor::createThresholds(const Json& threshold,
                                      const std::string& objPath)
 {
diff --git a/virtualSensor.hpp b/virtualSensor.hpp
index 286bca3..d85303a 100644
--- a/virtualSensor.hpp
+++ b/virtualSensor.hpp
@@ -190,6 +190,8 @@
     /** @brief Calculate median value from sensors */
     double
         calculateModifiedMedianValue(const VirtualSensor::ParamMap& paramMap);
+    /** @brief Calculate maximum value from sensors */
+    double calculateMaximumValue(const VirtualSensor::ParamMap& paramMap);
     /** @brief create threshold objects from json config */
     void createThresholds(const Json& threshold, const std::string& objPath);
     /** @brief parse config from entity manager **/