ipmbsensor fix errors / thresholds

Make the sensor set the lowest possible value when
multiple read errors occur. Also fix the sensor threshold
settings based on the spec:

A high-going threshold has its assertion events become set when the
reading is >= the threshold, while for a low-going event the assertion
becomes set when the reading is <= the threshold.

Tested: fans boosted after putting me in recovery

Change-Id: I0fc9edafb57afa61cf68124eec5d124cdbb51983
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/include/IpmbSensor.hpp b/include/IpmbSensor.hpp
index f226483..2185b68 100644
--- a/include/IpmbSensor.hpp
+++ b/include/IpmbSensor.hpp
@@ -42,6 +42,7 @@
     void init(void);
     void loadDefaults(void);
     void runInitCmd(void);
+    void processError(void);
 
     IpmbType type;
     IpmbSubType subType;
@@ -51,6 +52,7 @@
     uint8_t netfn;
     uint8_t command;
     uint8_t deviceAddress;
+    uint8_t errorCount;
     std::vector<uint8_t> commandData;
     std::optional<uint8_t> initCommand;
     std::vector<uint8_t> initData;
diff --git a/src/IpmbSensor.cpp b/src/IpmbSensor.cpp
index b0b20de..9f591ac 100644
--- a/src/IpmbSensor.cpp
+++ b/src/IpmbSensor.cpp
@@ -218,6 +218,24 @@
     thresholds::checkThresholds(this);
 }
 
+void IpmbSensor::processError(void)
+{
+    static constexpr size_t errorFilter = 2;
+
+    if (!errorCount)
+    {
+        std::cerr << "Invalid data from device: " << name << "\n";
+    }
+    else if (errorCount > errorFilter)
+    {
+        updateValue(0);
+    }
+    if (errorCount < std::numeric_limits<uint8_t>::max())
+    {
+        errorCount++;
+    }
+}
+
 void IpmbSensor::read(void)
 {
     static constexpr size_t pollTime = 1; // in seconds
@@ -238,15 +256,9 @@
             [this](boost::system::error_code ec,
                    const IpmbMethodType& response) {
                 const int& status = std::get<0>(response);
-                static bool firstError = true; // don't print too much
                 if (ec || status)
                 {
-                    if (firstError)
-                    {
-                        std::cerr << "Error reading from device: " << name
-                                  << "\n";
-                        firstError = false;
-                    }
+                    processError();
                     updateValue(0);
                     read();
                     return;
@@ -272,12 +284,7 @@
                 {
                     if (data.empty())
                     {
-                        if (firstError)
-                        {
-                            std::cerr << "Invalid data from device: " << name
-                                      << "\n";
-                            firstError = false;
-                        }
+                        processError();
                         read();
                         return;
                     }
@@ -288,12 +295,7 @@
                 {
                     if (data.size() < 5)
                     {
-                        if (firstError)
-                        {
-                            std::cerr << "Invalid data from device: " << name
-                                      << "\n";
-                            firstError = false;
-                        }
+                        processError();
                         read();
                         return;
                     }
@@ -304,12 +306,7 @@
                 {
                     if (data.empty())
                     {
-                        if (firstError)
-                        {
-                            std::cerr << "Invalid data from device: " << name
-                                      << "\n";
-                            firstError = false;
-                        }
+                        processError();
                         read();
                         return;
                     }
@@ -330,12 +327,7 @@
                 {
                     if (data.size() < 4)
                     {
-                        if (firstError)
-                        {
-                            std::cerr << "Invalid data from device: " << name
-                                      << "\n";
-                            firstError = false;
-                        }
+                        processError();
                         read();
                         return;
                     }
@@ -350,7 +342,7 @@
                 value = (value * scaleVal) + offsetVal;
                 updateValue(value);
                 read();
-                firstError = true; // success
+                errorCount = 0; // success
             },
             "xyz.openbmc_project.Ipmi.Channel.Ipmb",
             "/xyz/openbmc_project/Ipmi/Channel/Ipmb", "org.openbmc.Ipmb",
diff --git a/src/Thresholds.cpp b/src/Thresholds.cpp
index fe5537f..2bd62a0 100644
--- a/src/Thresholds.cpp
+++ b/src/Thresholds.cpp
@@ -231,7 +231,7 @@
     {
         if (threshold.direction == thresholds::Direction::HIGH)
         {
-            if (value > threshold.value)
+            if (value >= threshold.value)
             {
                 thresholdChanges.push_back(std::make_pair(threshold, true));
             }
@@ -242,7 +242,7 @@
         }
         else
         {
-            if (value < threshold.value)
+            if (value <= threshold.value)
             {
                 thresholdChanges.push_back(std::make_pair(threshold, true));
             }