monitor: Add up/down count fault detection

Create an up/down count fault determination algorithm that
could be used in place of the current timer based outOfRange()
function.
The up/down count is a different method for determining when
a fan is faulted by counting up each iteration a rotor is
out of spec and removing those counts when the rotor
returns within spec.

Tested:
    1. Remove a fan and run Mihawk, the counter add 1 when sensor
       is out of spec, and replaced the fan back before hit the
       threshold, the counter decrement back to 0.
    2. Remove a fan, counter add 1 and mark the removed fan as
       nonfunctional when counter reaches the threshold, and
       Replaced the fan back, counter will decrement back to 0
       and fan back to functional.

Change-Id: I632dd2c7553b007beb7ae6bb694a590d2cfc2a1c
Signed-off-by: Jolie Ku <jolie_ku@wistron.com>
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/monitor/tach_sensor.cpp b/monitor/tach_sensor.cpp
index 637ff68..ed00a9b 100644
--- a/monitor/tach_sensor.cpp
+++ b/monitor/tach_sensor.cpp
@@ -70,15 +70,15 @@
 TachSensor::TachSensor(Mode mode, sdbusplus::bus::bus& bus, Fan& fan,
                        const std::string& id, bool hasTarget, size_t funcDelay,
                        const std::string& interface, double factor,
-                       int64_t offset, size_t timeout,
-                       const std::optional<size_t>& errorDelay,
+                       int64_t offset, size_t method, size_t threshold,
+                       size_t timeout, const std::optional<size_t>& errorDelay,
                        const sdeventplus::Event& event) :
     _bus(bus),
     _fan(fan), _name(FAN_SENSOR_PATH + id), _invName(path(fan.getName()) / id),
     _hasTarget(hasTarget), _funcDelay(funcDelay), _interface(interface),
-    _factor(factor), _offset(offset), _timeout(timeout),
-    _timerMode(TimerMode::func),
-    _timer(event, std::bind(&Fan::timerExpired, &fan, std::ref(*this))),
+    _factor(factor), _offset(offset), _method(method), _threshold(threshold),
+    _timeout(timeout), _timerMode(TimerMode::func),
+    _timer(event, std::bind(&Fan::updateState, &fan, std::ref(*this))),
     _errorDelay(errorDelay)
 {
     // Start from a known state of functional
@@ -251,6 +251,24 @@
     }
 }
 
+void TachSensor::setCounter(bool count)
+{
+    if (count)
+    {
+        if (_counter < _threshold)
+        {
+            ++_counter;
+        }
+    }
+    else
+    {
+        if (_counter > 0)
+        {
+            --_counter;
+        }
+    }
+}
+
 void TachSensor::updateInventory(bool functional)
 {
     auto objectMap =