Add new PID Class types "power" and "powersum"

Implements this feature:
https://github.com/openbmc/phosphor-pid-control/issues/24

In addition to the existing "temp" and "margin" classes, adding
new "power" and "powersum" Class types.

The "power" class is the same as "temp", but expects D-Bus power
sensors, instead of D-Bus temperature sensors.

The "powersum" class is the same as "power", but sums together all of
the given inputs, instead of finding the maximum.

Signed-off-by: Josh Lehan <krellan@google.com>
Change-Id: I11d8ad8385632658ed061671134be87a560cd02a
diff --git a/pid/thermalcontroller.cpp b/pid/thermalcontroller.cpp
index 8778719..db4763f 100644
--- a/pid/thermalcontroller.cpp
+++ b/pid/thermalcontroller.cpp
@@ -30,13 +30,26 @@
 
 ThermalType getThermalType(const std::string& typeString)
 {
-    /* Currently it only supports the two types. */
-    return (typeString == "temp") ? ThermalType::absolute : ThermalType::margin;
+    if (typeString == "margin")
+    {
+        return ThermalType::margin;
+    }
+    if ((typeString == "temp") || (typeString == "power"))
+    {
+        return ThermalType::absolute;
+    }
+    if (typeString == "powersum")
+    {
+        return ThermalType::summation;
+    }
+
+    throw ControllerBuildException("Unrecognized PID Type/Class string");
 }
 
 bool isThermalType(const std::string& typeString)
 {
-    static const std::vector<std::string> thermalTypes = {"temp", "margin"};
+    static const std::vector<std::string> thermalTypes = {"temp", "margin",
+                                                          "power", "powersum"};
     return std::count(thermalTypes.begin(), thermalTypes.end(), typeString);
 }
 
@@ -49,7 +62,6 @@
     if (inputs.empty())
     {
         throw ControllerBuildException("Thermal controller missing inputs");
-        return nullptr;
     }
 
     auto thermal = std::make_unique<ThermalController>(id, inputs, type, owner);
@@ -67,16 +79,27 @@
 {
     double value;
     const double& (*compare)(const double&, const double&);
+    bool doSummation = false;
+
     if (type == ThermalType::margin)
     {
         value = std::numeric_limits<double>::max();
         compare = std::min<double>;
     }
-    else
+    else if (type == ThermalType::absolute)
     {
         value = std::numeric_limits<double>::lowest();
         compare = std::max<double>;
     }
+    else if (type == ThermalType::summation)
+    {
+        doSummation = true;
+        value = 0.0;
+    }
+    else
+    {
+        throw ControllerBuildException("Unrecognized ThermalType");
+    }
 
     bool acceptable = false;
     for (const auto& in : _inputs)
@@ -89,7 +112,15 @@
             continue;
         }
 
-        value = compare(value, cachedValue);
+        if (doSummation)
+        {
+            value += cachedValue;
+        }
+        else
+        {
+            value = compare(value, cachedValue);
+        }
+
         acceptable = true;
     }