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/ADCSensor.cpp b/sensors/src/ADCSensor.cpp
index 1ac0988..b72f5c1 100644
--- a/sensors/src/ADCSensor.cpp
+++ b/sensors/src/ADCSensor.cpp
@@ -40,27 +40,27 @@
                      std::vector<thresholds::Threshold> &&_thresholds,
                      const double scale_factor,
                      const std::string &sensorConfiguration) :
-    path(path),
-    objServer(objectServer), configuration(sensorConfiguration),
+    Sensor(),
+    path(path), objServer(objectServer), configuration(sensorConfiguration),
     name(boost::replace_all_copy(sensor_name, " ", "_")),
-    thresholds(std::move(_thresholds)), scale_factor(scale_factor),
-    sensor_interface(objectServer.add_interface(
-        "/xyz/openbmc_project/sensors/voltage/" + name,
-        "xyz.openbmc_project.Sensor.Value")),
-    input_dev(io, open(path.c_str(), O_RDONLY)), wait_timer(io),
-    value(std::numeric_limits<double>::quiet_NaN()), err_count(0),
+    scale_factor(scale_factor), input_dev(io, open(path.c_str(), O_RDONLY)),
+    wait_timer(io), err_count(0),
     // todo, get these from config
     max_value(20), min_value(0)
 {
+    thresholds = std::move(_thresholds);
+    sensorInterface = objectServer.add_interface(
+        "/xyz/openbmc_project/sensors/voltage/" + name,
+        "xyz.openbmc_project.Sensor.Value");
     if (thresholds::HasWarningInterface(thresholds))
     {
-        threshold_interface_warning = objectServer.add_interface(
+        thresholdInterfaceWarning = objectServer.add_interface(
             "/xyz/openbmc_project/sensors/voltage/" + name,
             "xyz.openbmc_project.Sensor.Threshold.Warning");
     }
     if (thresholds::HasCriticalInterface(thresholds))
     {
-        threshold_interface_critical = objectServer.add_interface(
+        thresholdInterfaceCritical = objectServer.add_interface(
             "/xyz/openbmc_project/sensors/voltage/" + name,
             "xyz.openbmc_project.Sensor.Threshold.Critical");
     }
@@ -73,9 +73,9 @@
     // close the input dev to cancel async operations
     input_dev.close();
     wait_timer.cancel();
-    objServer.remove_interface(threshold_interface_warning);
-    objServer.remove_interface(threshold_interface_critical);
-    objServer.remove_interface(sensor_interface);
+    objServer.remove_interface(thresholdInterfaceWarning);
+    objServer.remove_interface(thresholdInterfaceCritical);
+    objServer.remove_interface(sensorInterface);
 }
 
 void ADCSensor::setup_read(void)
@@ -152,92 +152,23 @@
 
 void ADCSensor::check_thresholds(void)
 {
-    if (thresholds.empty())
-        return;
-    for (auto threshold : thresholds)
-    {
-        if (threshold.direction == thresholds::Direction::HIGH)
-        {
-            if (value > threshold.value)
-            {
-                assert_thresholds(threshold.level, threshold.direction, true);
-            }
-            else
-            {
-                assert_thresholds(threshold.level, threshold.direction, false);
-            }
-        }
-        else
-        {
-            if (value < threshold.value)
-            {
-                assert_thresholds(threshold.level, threshold.direction, true);
-            }
-            else
-            {
-                assert_thresholds(threshold.level, threshold.direction, false);
-            }
-        }
-    }
+    thresholds::checkThresholds(this);
 }
 
 void ADCSensor::update_value(const double &new_value)
 {
-    bool ret = sensor_interface->set_property("Value", new_value);
+    bool ret = sensorInterface->set_property("Value", new_value);
     value = new_value;
     check_thresholds();
 }
 
-void ADCSensor::assert_thresholds(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 = threshold_interface_warning;
-    }
-    else if (level == thresholds::Level::WARNING &&
-             direction == thresholds::Direction::LOW)
-    {
-        property = "WarningAlarmLow";
-        interface = threshold_interface_warning;
-    }
-    else if (level == thresholds::Level::CRITICAL &&
-             direction == thresholds::Direction::HIGH)
-    {
-        property = "CriticalAlarmHigh";
-        interface = threshold_interface_critical;
-    }
-    else if (level == thresholds::Level::CRITICAL &&
-             direction == thresholds::Direction::LOW)
-    {
-        property = "CriticalAlarmLow";
-        interface = threshold_interface_critical;
-    }
-    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);
-}
-
 void ADCSensor::set_initial_properties(
     std::shared_ptr<sdbusplus::asio::connection> &conn)
 {
     // todo, get max and min from configuration
-    sensor_interface->register_property("MaxValue", max_value);
-    sensor_interface->register_property("MinValue", min_value);
-    sensor_interface->register_property("Value", value);
+    sensorInterface->register_property("MaxValue", max_value);
+    sensorInterface->register_property("MinValue", min_value);
+    sensorInterface->register_property("Value", value);
 
     for (auto &threshold : thresholds)
     {
@@ -246,7 +177,7 @@
         std::string alarm;
         if (threshold.level == thresholds::Level::CRITICAL)
         {
-            iface = threshold_interface_critical;
+            iface = thresholdInterfaceCritical;
             if (threshold.direction == thresholds::Direction::HIGH)
             {
                 level = "CriticalHigh";
@@ -260,7 +191,7 @@
         }
         else if (threshold.level == thresholds::Level::WARNING)
         {
-            iface = threshold_interface_warning;
+            iface = thresholdInterfaceWarning;
             if (threshold.direction == thresholds::Direction::HIGH)
             {
                 level = "WarningHigh";
@@ -294,18 +225,16 @@
             });
         iface->register_property(alarm, false);
     }
-    if (!sensor_interface->initialize())
+    if (!sensorInterface->initialize())
     {
         std::cerr << "error initializing value interface\n";
     }
-    if (threshold_interface_warning &&
-        !threshold_interface_warning->initialize())
+    if (thresholdInterfaceWarning && !thresholdInterfaceWarning->initialize())
     {
         std::cerr << "error initializing warning threshold interface\n";
     }
 
-    if (threshold_interface_critical &&
-        !threshold_interface_critical->initialize())
+    if (thresholdInterfaceCritical && !thresholdInterfaceCritical->initialize())
     {
         std::cerr << "error initializing critical threshold interface\n";
     }
diff --git a/sensors/src/CPUSensor.cpp b/sensors/src/CPUSensor.cpp
index 66bca1f..ce9e60b 100644
--- a/sensors/src/CPUSensor.cpp
+++ b/sensors/src/CPUSensor.cpp
@@ -35,27 +35,28 @@
                      boost::asio::io_service &io, const std::string &sensorName,
                      std::vector<thresholds::Threshold> &&_thresholds,
                      const std::string &sensorConfiguration) :
-    path(path),
-    objectType(objectType), objServer(objectServer),
+    Sensor(),
+    path(path), objectType(objectType), objServer(objectServer),
     name(boost::replace_all_copy(sensorName, " ", "_")), dbusConnection(conn),
-    thresholds(std::move(_thresholds)), configuration(sensorConfiguration),
-    sensor_interface(objectServer.add_interface(
-        "/xyz/openbmc_project/sensors/temperature/" + name,
-        "xyz.openbmc_project.Sensor.Value")),
-    input_dev(io, open(path.c_str(), O_RDONLY)), wait_timer(io),
-    value(std::numeric_limits<double>::quiet_NaN()), err_count(0),
+    configuration(sensorConfiguration),
+
+    input_dev(io, open(path.c_str(), O_RDONLY)), wait_timer(io), err_count(0),
     // todo, get these from config
     max_value(127), min_value(-128)
 {
+    thresholds = std::move(_thresholds);
+    sensorInterface = objectServer.add_interface(
+        "/xyz/openbmc_project/sensors/temperature/" + name,
+        "xyz.openbmc_project.Sensor.Value");
     if (thresholds::HasWarningInterface(thresholds))
     {
-        threshold_interface_warning = objectServer.add_interface(
+        thresholdInterfaceWarning = objectServer.add_interface(
             "/xyz/openbmc_project/sensors/temperature/" + name,
             "xyz.openbmc_project.Sensor.Threshold.Warning");
     }
     if (thresholds::HasCriticalInterface(thresholds))
     {
-        threshold_interface_critical = objectServer.add_interface(
+        thresholdInterfaceCritical = objectServer.add_interface(
             "/xyz/openbmc_project/sensors/temperature/" + name,
             "xyz.openbmc_project.Sensor.Threshold.Critical");
     }
@@ -69,9 +70,9 @@
     // close the input dev to cancel async operations
     input_dev.close();
     wait_timer.cancel();
-    objServer.remove_interface(threshold_interface_warning);
-    objServer.remove_interface(threshold_interface_critical);
-    objServer.remove_interface(sensor_interface);
+    objServer.remove_interface(thresholdInterfaceWarning);
+    objServer.remove_interface(thresholdInterfaceCritical);
+    objServer.remove_interface(sensorInterface);
 }
 
 void CPUSensor::setup_read(void)
@@ -128,7 +129,7 @@
         else
         {
             err_count = 0; // check power again in 10 cycles
-            sensor_interface->set_property(
+            sensorInterface->set_property(
                 "Value", std::numeric_limits<double>::quiet_NaN());
         }
     }
@@ -154,92 +155,23 @@
 
 void CPUSensor::check_thresholds(void)
 {
-    if (thresholds.empty())
-        return;
-    for (auto threshold : thresholds)
-    {
-        if (threshold.direction == thresholds::Direction::HIGH)
-        {
-            if (value > threshold.value)
-            {
-                assert_thresholds(threshold.level, threshold.direction, true);
-            }
-            else
-            {
-                assert_thresholds(threshold.level, threshold.direction, false);
-            }
-        }
-        else
-        {
-            if (value < threshold.value)
-            {
-                assert_thresholds(threshold.level, threshold.direction, true);
-            }
-            else
-            {
-                assert_thresholds(threshold.level, threshold.direction, false);
-            }
-        }
-    }
+    thresholds::checkThresholds(this);
 }
 
 void CPUSensor::update_value(const double &new_value)
 {
-    sensor_interface->set_property("Value", new_value);
+    sensorInterface->set_property("Value", new_value);
     value = new_value;
     check_thresholds();
 }
 
-void CPUSensor::assert_thresholds(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 = threshold_interface_warning;
-    }
-    else if (level == thresholds::Level::WARNING &&
-             direction == thresholds::Direction::LOW)
-    {
-        property = "WarningAlarmLow";
-        interface = threshold_interface_warning;
-    }
-    else if (level == thresholds::Level::CRITICAL &&
-             direction == thresholds::Direction::HIGH)
-    {
-        property = "CriticalAlarmHigh";
-        interface = threshold_interface_critical;
-    }
-    else if (level == thresholds::Level::CRITICAL &&
-             direction == thresholds::Direction::LOW)
-    {
-        property = "CriticalAlarmLow";
-        interface = threshold_interface_critical;
-    }
-    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);
-}
-
 void CPUSensor::set_initial_properties(
     std::shared_ptr<sdbusplus::asio::connection> &conn)
 {
     // todo, get max and min from configuration
-    sensor_interface->register_property("MaxValue", max_value);
-    sensor_interface->register_property("MinValue", min_value);
-    sensor_interface->register_property("Value", value);
+    sensorInterface->register_property("MaxValue", max_value);
+    sensorInterface->register_property("MinValue", min_value);
+    sensorInterface->register_property("Value", value);
 
     for (auto &threshold : thresholds)
     {
@@ -248,7 +180,7 @@
         std::string alarm;
         if (threshold.level == thresholds::Level::CRITICAL)
         {
-            iface = threshold_interface_critical;
+            iface = thresholdInterfaceCritical;
             if (threshold.direction == thresholds::Direction::HIGH)
             {
                 level = "CriticalHigh";
@@ -262,7 +194,7 @@
         }
         else if (threshold.level == thresholds::Level::WARNING)
         {
-            iface = threshold_interface_warning;
+            iface = thresholdInterfaceWarning;
             if (threshold.direction == thresholds::Direction::HIGH)
             {
                 level = "WarningHigh";
@@ -302,18 +234,16 @@
         }
         iface->register_property(alarm, false);
     }
-    if (!sensor_interface->initialize())
+    if (!sensorInterface->initialize())
     {
         std::cerr << "error initializing value interface\n";
     }
-    if (threshold_interface_warning &&
-        !threshold_interface_warning->initialize())
+    if (thresholdInterfaceWarning && !thresholdInterfaceWarning->initialize())
     {
         std::cerr << "error initializing warning threshold interface\n";
     }
 
-    if (threshold_interface_critical &&
-        !threshold_interface_critical->initialize())
+    if (thresholdInterfaceCritical && !thresholdInterfaceCritical->initialize())
     {
         std::cerr << "error initializing critical threshold interface\n";
     }
diff --git a/sensors/src/HwmonTempSensor.cpp b/sensors/src/HwmonTempSensor.cpp
index c1db504..5d3251a 100644
--- a/sensors/src/HwmonTempSensor.cpp
+++ b/sensors/src/HwmonTempSensor.cpp
@@ -37,28 +37,28 @@
     boost::asio::io_service &io, const std::string &sensor_name,
     std::vector<thresholds::Threshold> &&_thresholds,
     const std::string &sensorConfiguration) :
-    path(path),
-    objectType(objectType), configuration(sensorConfiguration),
+    Sensor(),
+    path(path), objectType(objectType), configuration(sensorConfiguration),
     objServer(objectServer),
     name(boost::replace_all_copy(sensor_name, " ", "_")),
-    thresholds(std::move(_thresholds)),
-    sensor_interface(objectServer.add_interface(
-        "/xyz/openbmc_project/sensors/temperature/" + name,
-        "xyz.openbmc_project.Sensor.Value")),
-    input_dev(io, open(path.c_str(), O_RDONLY)), wait_timer(io),
-    value(std::numeric_limits<double>::quiet_NaN()), err_count(0),
+    input_dev(io, open(path.c_str(), O_RDONLY)), wait_timer(io), err_count(0),
     // todo, get these from config
     max_value(127), min_value(-128)
 {
+    thresholds = std::move(_thresholds);
+    sensorInterface = objectServer.add_interface(
+        "/xyz/openbmc_project/sensors/temperature/" + name,
+        "xyz.openbmc_project.Sensor.Value");
+
     if (thresholds::HasWarningInterface(thresholds))
     {
-        threshold_interface_warning = objectServer.add_interface(
+        thresholdInterfaceWarning = objectServer.add_interface(
             "/xyz/openbmc_project/sensors/temperature/" + name,
             "xyz.openbmc_project.Sensor.Threshold.Warning");
     }
     if (thresholds::HasCriticalInterface(thresholds))
     {
-        threshold_interface_critical = objectServer.add_interface(
+        thresholdInterfaceCritical = objectServer.add_interface(
             "/xyz/openbmc_project/sensors/temperature/" + name,
             "xyz.openbmc_project.Sensor.Threshold.Critical");
     }
@@ -71,9 +71,9 @@
     // close the input dev to cancel async operations
     input_dev.close();
     wait_timer.cancel();
-    objServer.remove_interface(threshold_interface_warning);
-    objServer.remove_interface(threshold_interface_critical);
-    objServer.remove_interface(sensor_interface);
+    objServer.remove_interface(thresholdInterfaceWarning);
+    objServer.remove_interface(thresholdInterfaceCritical);
+    objServer.remove_interface(sensorInterface);
 }
 
 void HwmonTempSensor::setup_read(void)
@@ -144,93 +144,23 @@
 
 void HwmonTempSensor::check_thresholds(void)
 {
-    if (thresholds.empty())
-        return;
-    for (auto threshold : thresholds)
-    {
-        if (threshold.direction == thresholds::Direction::HIGH)
-        {
-            if (value > threshold.value)
-            {
-                assert_thresholds(threshold.level, threshold.direction, true);
-            }
-            else
-            {
-                assert_thresholds(threshold.level, threshold.direction, false);
-            }
-        }
-        else
-        {
-            if (value < threshold.value)
-            {
-                assert_thresholds(threshold.level, threshold.direction, true);
-            }
-            else
-            {
-                assert_thresholds(threshold.level, threshold.direction, false);
-            }
-        }
-    }
+    thresholds::checkThresholds(this);
 }
 
 void HwmonTempSensor::update_value(const double &new_value)
 {
-    sensor_interface->set_property("Value", new_value);
+    sensorInterface->set_property("Value", new_value);
     value = new_value;
     check_thresholds();
 }
 
-void HwmonTempSensor::assert_thresholds(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 = threshold_interface_warning;
-    }
-    else if (level == thresholds::Level::WARNING &&
-             direction == thresholds::Direction::LOW)
-    {
-        property = "WarningAlarmLow";
-        interface = threshold_interface_warning;
-    }
-    else if (level == thresholds::Level::CRITICAL &&
-             direction == thresholds::Direction::HIGH)
-    {
-        property = "CriticalAlarmHigh";
-        interface = threshold_interface_critical;
-    }
-    else if (level == thresholds::Level::CRITICAL &&
-             direction == thresholds::Direction::LOW)
-    {
-        property = "CriticalAlarmLow";
-        interface = threshold_interface_critical;
-    }
-    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);
-}
-
 void HwmonTempSensor::set_initial_properties(
     std::shared_ptr<sdbusplus::asio::connection> &conn)
 {
     // todo, get max and min from configuration
-    sensor_interface->register_property("MaxValue", max_value);
-    sensor_interface->register_property("MinValue", min_value);
-    sensor_interface->register_property("Value", value);
+    sensorInterface->register_property("MaxValue", max_value);
+    sensorInterface->register_property("MinValue", min_value);
+    sensorInterface->register_property("Value", value);
 
     for (auto &threshold : thresholds)
     {
@@ -239,7 +169,7 @@
         std::string alarm;
         if (threshold.level == thresholds::Level::CRITICAL)
         {
-            iface = threshold_interface_critical;
+            iface = thresholdInterfaceCritical;
             if (threshold.direction == thresholds::Direction::HIGH)
             {
                 level = "CriticalHigh";
@@ -253,7 +183,7 @@
         }
         else if (threshold.level == thresholds::Level::WARNING)
         {
-            iface = threshold_interface_warning;
+            iface = thresholdInterfaceWarning;
             if (threshold.direction == thresholds::Direction::HIGH)
             {
                 level = "WarningHigh";
@@ -286,18 +216,16 @@
             });
         iface->register_property(alarm, false);
     }
-    if (!sensor_interface->initialize())
+    if (!sensorInterface->initialize())
     {
         std::cerr << "error initializing value interface\n";
     }
-    if (threshold_interface_warning &&
-        !threshold_interface_warning->initialize())
+    if (thresholdInterfaceWarning && !thresholdInterfaceWarning->initialize())
     {
         std::cerr << "error initializing warning threshold interface\n";
     }
 
-    if (threshold_interface_critical &&
-        !threshold_interface_critical->initialize())
+    if (thresholdInterfaceCritical && !thresholdInterfaceCritical->initialize())
     {
         std::cerr << "error initializing critical threshold interface\n";
     }
diff --git a/sensors/src/TachSensor.cpp b/sensors/src/TachSensor.cpp
index 91f0545..10d94f2 100644
--- a/sensors/src/TachSensor.cpp
+++ b/sensors/src/TachSensor.cpp
@@ -36,27 +36,28 @@
                        boost::asio::io_service &io, const std::string &fanName,
                        std::vector<thresholds::Threshold> &&_thresholds,
                        const std::string &sensorConfiguration) :
-    path(path),
-    objServer(objectServer), dbusConnection(conn),
+    Sensor(),
+    path(path), objServer(objectServer), dbusConnection(conn),
     name(boost::replace_all_copy(fanName, " ", "_")),
-    configuration(sensorConfiguration), thresholds(std::move(_thresholds)),
-    sensor_interface(objectServer.add_interface(
-        "/xyz/openbmc_project/sensors/fan_tach/" + name,
-        "xyz.openbmc_project.Sensor.Value")),
-    input_dev(io, open(path.c_str(), O_RDONLY)), wait_timer(io),
-    value(std::numeric_limits<double>::quiet_NaN()), err_count(0),
+    configuration(sensorConfiguration),
+    input_dev(io, open(path.c_str(), O_RDONLY)), wait_timer(io), err_count(0),
     // todo, get these from config
     max_value(25000), min_value(0)
 {
+    thresholds = std::move(_thresholds);
+    sensorInterface = objectServer.add_interface(
+        "/xyz/openbmc_project/sensors/fan_tach/" + name,
+        "xyz.openbmc_project.Sensor.Value");
+
     if (thresholds::HasWarningInterface(thresholds))
     {
-        threshold_interface_warning = objectServer.add_interface(
+        thresholdInterfaceWarning = objectServer.add_interface(
             "/xyz/openbmc_project/sensors/fan_tach/" + name,
             "xyz.openbmc_project.Sensor.Threshold.Warning");
     }
     if (thresholds::HasCriticalInterface(thresholds))
     {
-        threshold_interface_critical = objectServer.add_interface(
+        thresholdInterfaceCritical = objectServer.add_interface(
             "/xyz/openbmc_project/sensors/fan_tach/" + name,
             "xyz.openbmc_project.Sensor.Threshold.Critical");
     }
@@ -70,9 +71,9 @@
     // close the input dev to cancel async operations
     input_dev.close();
     wait_timer.cancel();
-    objServer.remove_interface(threshold_interface_warning);
-    objServer.remove_interface(threshold_interface_critical);
-    objServer.remove_interface(sensor_interface);
+    objServer.remove_interface(thresholdInterfaceWarning);
+    objServer.remove_interface(thresholdInterfaceCritical);
+    objServer.remove_interface(sensorInterface);
 }
 
 void TachSensor::setup_read(void)
@@ -127,7 +128,7 @@
         else
         {
             err_count = 0; // check power again in 10 cycles
-            sensor_interface->set_property(
+            sensorInterface->set_property(
                 "Value", std::numeric_limits<double>::quiet_NaN());
         }
     }
@@ -151,92 +152,23 @@
 
 void TachSensor::check_thresholds(void)
 {
-    if (thresholds.empty())
-        return;
-    for (auto &threshold : thresholds)
-    {
-        if (threshold.direction == thresholds::Direction::HIGH)
-        {
-            if (value > threshold.value)
-            {
-                assert_thresholds(threshold.level, threshold.direction, true);
-            }
-            else
-            {
-                assert_thresholds(threshold.level, threshold.direction, false);
-            }
-        }
-        else
-        {
-            if (value < threshold.value)
-            {
-                assert_thresholds(threshold.level, threshold.direction, true);
-            }
-            else
-            {
-                assert_thresholds(threshold.level, threshold.direction, false);
-            }
-        }
-    }
+    thresholds::checkThresholds(this);
 }
 
 void TachSensor::update_value(const double &new_value)
 {
-    sensor_interface->set_property("Value", new_value);
+    sensorInterface->set_property("Value", new_value);
     value = new_value;
     check_thresholds();
 }
 
-void TachSensor::assert_thresholds(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 = threshold_interface_warning;
-    }
-    else if (level == thresholds::Level::WARNING &&
-             direction == thresholds::Direction::LOW)
-    {
-        property = "WarningAlarmLow";
-        interface = threshold_interface_warning;
-    }
-    else if (level == thresholds::Level::CRITICAL &&
-             direction == thresholds::Direction::HIGH)
-    {
-        property = "CriticalAlarmHigh";
-        interface = threshold_interface_critical;
-    }
-    else if (level == thresholds::Level::CRITICAL &&
-             direction == thresholds::Direction::LOW)
-    {
-        property = "CriticalAlarmLow";
-        interface = threshold_interface_critical;
-    }
-    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);
-}
-
 void TachSensor::set_initial_properties(
     std::shared_ptr<sdbusplus::asio::connection> &conn)
 {
     // todo, get max and min from configuration
-    sensor_interface->register_property("MaxValue", max_value);
-    sensor_interface->register_property("MinValue", min_value);
-    sensor_interface->register_property("Value", value);
+    sensorInterface->register_property("MaxValue", max_value);
+    sensorInterface->register_property("MinValue", min_value);
+    sensorInterface->register_property("Value", value);
 
     for (auto &threshold : thresholds)
     {
@@ -245,7 +177,7 @@
         std::string alarm;
         if (threshold.level == thresholds::Level::CRITICAL)
         {
-            iface = threshold_interface_critical;
+            iface = thresholdInterfaceCritical;
             if (threshold.direction == thresholds::Direction::HIGH)
             {
                 level = "CriticalHigh";
@@ -259,7 +191,7 @@
         }
         else if (threshold.level == thresholds::Level::WARNING)
         {
-            iface = threshold_interface_warning;
+            iface = thresholdInterfaceWarning;
             if (threshold.direction == thresholds::Direction::HIGH)
             {
                 level = "WarningHigh";
@@ -294,18 +226,16 @@
             });
         iface->register_property(alarm, false);
     }
-    if (!sensor_interface->initialize())
+    if (!sensorInterface->initialize())
     {
         std::cerr << "error initializing value interface\n";
     }
-    if (threshold_interface_warning &&
-        !threshold_interface_warning->initialize())
+    if (thresholdInterfaceWarning && !thresholdInterfaceWarning->initialize())
     {
         std::cerr << "error initializing warning threshold interface\n";
     }
 
-    if (threshold_interface_critical &&
-        !threshold_interface_critical->initialize())
+    if (thresholdInterfaceCritical && !thresholdInterfaceCritical->initialize())
     {
         std::cerr << "error initializing critical threshold interface\n";
     }
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"};