Add base class to simplify threshold logic

Add base class for the default case check_thresholds
calls the thresholds.cpp function. This way for normal
things we can just pass sensors around as the base class.

Make it so that theshold alerts are only sent once.

Change-Id: Ic8e3ae1900aeb12b74c099f637f45bc038bd3c9a
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/sensors/src/Thresholds.cpp b/sensors/src/Thresholds.cpp
index d31f487..b792a9b 100644
--- a/sensors/src/Thresholds.cpp
+++ b/sensors/src/Thresholds.cpp
@@ -4,6 +4,7 @@
 #include <boost/lexical_cast.hpp>
 #include <fstream>
 #include <iostream>
+#include <sensor.hpp>
 
 static constexpr bool DEBUG = false;
 constexpr size_t MAX_THRESHOLDS = 4;
@@ -162,6 +163,91 @@
     }
 }
 
+void checkThresholds(Sensor *sensor)
+{
+
+    if (sensor->thresholds.empty())
+    {
+        return;
+    }
+    for (auto &threshold : sensor->thresholds)
+    {
+        if (threshold.direction == thresholds::Direction::HIGH)
+        {
+            if (sensor->value > threshold.value && !threshold.asserted)
+            {
+                assertThresholds(sensor, threshold.level, threshold.direction,
+                                 true);
+                threshold.asserted = true;
+            }
+            else if (sensor->value <= threshold.value && threshold.asserted)
+            {
+                assertThresholds(sensor, threshold.level, threshold.direction,
+                                 false);
+                threshold.asserted = false;
+            }
+        }
+        else
+        {
+            if (sensor->value < threshold.value && !threshold.asserted)
+            {
+                assertThresholds(sensor, threshold.level, threshold.direction,
+                                 true);
+                threshold.asserted = true;
+            }
+            else if (sensor->value >= threshold.value && threshold.asserted)
+            {
+                assertThresholds(sensor, threshold.level, threshold.direction,
+                                 false);
+                threshold.asserted = false;
+            }
+        }
+    }
+}
+
+void assertThresholds(Sensor *sensor, thresholds::Level level,
+                      thresholds::Direction direction, bool assert)
+{
+    std::string property;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> interface;
+    if (level == thresholds::Level::WARNING &&
+        direction == thresholds::Direction::HIGH)
+    {
+        property = "WarningAlarmHigh";
+        interface = sensor->thresholdInterfaceWarning;
+    }
+    else if (level == thresholds::Level::WARNING &&
+             direction == thresholds::Direction::LOW)
+    {
+        property = "WarningAlarmLow";
+        interface = sensor->thresholdInterfaceWarning;
+    }
+    else if (level == thresholds::Level::CRITICAL &&
+             direction == thresholds::Direction::HIGH)
+    {
+        property = "CriticalAlarmHigh";
+        interface = sensor->thresholdInterfaceCritical;
+    }
+    else if (level == thresholds::Level::CRITICAL &&
+             direction == thresholds::Direction::LOW)
+    {
+        property = "CriticalAlarmLow";
+        interface = sensor->thresholdInterfaceCritical;
+    }
+    else
+    {
+        std::cerr << "Unknown threshold, level " << level << "direction "
+                  << direction << "\n";
+        return;
+    }
+    if (!interface)
+    {
+        std::cout << "trying to set uninitialized interface\n";
+        return;
+    }
+    interface->set_property(property, assert);
+}
+
 static constexpr std::array<const char *, 4> ATTR_TYPES = {"lcrit", "min",
                                                            "max", "crit"};