Support threshold hysteresis

Add support for a hysteresis value on the warning high/low and critical
high/low sensor thresholds.  On the high thresholds, this requires the
sensor value to dip below the (threshold - hysteresis) value before the
alarm clears, and on the low thresholds it has to go above (threshold +
hysteresis).

These are optional fields in the configuration JSON and will default to
zero if not present, which results in the previous behavior of not
having a hysteresis at all.

Tested: with IBM's Ambient_Virtual_Temp sensor. When changing the value
above a high threshold and then back below the threshold, we only see
the alarm deasserted when the temp is below (threshold - hysteresis).

Change-Id: Ied1d40def94e1b66cf4ec8826799bada4e6236ab
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
diff --git a/thresholds.hpp b/thresholds.hpp
index aa77f7f..96486d3 100644
--- a/thresholds.hpp
+++ b/thresholds.hpp
@@ -23,8 +23,33 @@
 template <typename T>
 struct Threshold;
 
+struct Hysteresis
+{
+    double highHysteresis;
+    double lowHysteresis;
+    auto getHighHysteresis()
+    {
+        return this->highHysteresis;
+    }
+
+    auto getLowHysteresis()
+    {
+        return this->lowHysteresis;
+    }
+
+    auto setHighHysteresis(double value)
+    {
+        this->highHysteresis = value;
+    }
+
+    auto setLowHysteresis(double value)
+    {
+        this->lowHysteresis = value;
+    }
+};
+
 template <>
-struct Threshold<WarningObject> : public WarningObject
+struct Threshold<WarningObject> : public WarningObject, public Hysteresis
 {
     static constexpr auto name = "Warning";
     using WarningObject::WarningObject;
@@ -76,7 +101,7 @@
 };
 
 template <>
-struct Threshold<CriticalObject> : public CriticalObject
+struct Threshold<CriticalObject> : public CriticalObject, public Hysteresis
 {
     static constexpr auto name = "Critical";
     using CriticalObject::CriticalObject;
@@ -128,7 +153,9 @@
 };
 
 template <>
-struct Threshold<SoftShutdownObject> : public SoftShutdownObject
+struct Threshold<SoftShutdownObject> :
+    public SoftShutdownObject,
+    public Hysteresis
 {
     static constexpr auto name = "SoftShutdown";
     using SoftShutdownObject::SoftShutdownObject;
@@ -180,7 +207,9 @@
 };
 
 template <>
-struct Threshold<HardShutdownObject> : public HardShutdownObject
+struct Threshold<HardShutdownObject> :
+    public HardShutdownObject,
+    public Hysteresis
 {
     static constexpr auto name = "HardShutdown";
     using HardShutdownObject::HardShutdownObject;
@@ -232,10 +261,14 @@
 };
 
 template <>
-struct Threshold<PerformanceLossObject> : public PerformanceLossObject
+struct Threshold<PerformanceLossObject> :
+    public PerformanceLossObject,
+    public Hysteresis
 {
     static constexpr auto name = "PerformanceLoss";
     using PerformanceLossObject::PerformanceLossObject;
+    double performanceLossHighHysteresis;
+    double performanceLossLowHysteresis;
 
     auto high()
     {