phosphor-pid-control: reuse the code for sensor

https://gerrit.openbmc.org/c/openbmc/phosphor-pid-control/+/58664 has been
merged. This commit is just cherry-pick'ed to use the change in advance.

Google-Bug-Id: 269669082
Signed-off-by: Tom Tung <tomtung@google.com>
Change-Id: I361a958f072c6fd40099e5af43245e3a3ee1cb17
(cherry picked from commit 0d41bee12a1c7c52a8ff346c13cd754014d6e7b8)
Signed-off-by: Josh Lehan <krellan@google.com>
diff --git a/recipes-phosphor/fans/phosphor-pid-control/0001-pid-reuse-the-code-for-processing-sensors-input.patch b/recipes-phosphor/fans/phosphor-pid-control/0001-pid-reuse-the-code-for-processing-sensors-input.patch
new file mode 100644
index 0000000..c01ba60
--- /dev/null
+++ b/recipes-phosphor/fans/phosphor-pid-control/0001-pid-reuse-the-code-for-processing-sensors-input.patch
@@ -0,0 +1,266 @@
+From df1f183fb4c850c71abb6ea940a9ed2e9c7b9d23 Mon Sep 17 00:00:00 2001
+From: Tom Tung <shes050117@gmail.com>
+Date: Mon, 14 Nov 2022 19:26:52 +0800
+Subject: [PATCH] pid: reuse the code for processing sensors input
+
+The code for processing sensors' inputs are the same in updateFanTelemetry() and
+updateSensors(). This patch extract the similar code out as a private
+function and make it be called in these two functions.
+
+Tested:
+- Can still build phosphor-pid-control.
+- Copy built image to the system and it works fine.
+
+Change-Id: I6249053e788bfa14bb7bdf2a880be5403c20029b
+Signed-off-by: Tom Tung <shes050117@gmail.com>
+
+Patch Tracking Bug: b/269669082
+Upstream info / review:
+https://gerrit.openbmc.org/c/openbmc/phosphor-pid-control/+/58664
+Upstream-Status: Accepted.
+Justification: cherry-pick the patch before the next rebase gets pulled
+in.
+
+---
+ pid/zone.cpp | 119 ++-------------------------------------------------
+ pid/zone.hpp |  73 +++++++++++++++++++++++++++++++
+ 2 files changed, 77 insertions(+), 115 deletions(-)
+
+diff --git a/pid/zone.cpp b/pid/zone.cpp
+index e9aaafc..c88f41b 100644
+--- a/pid/zone.cpp
++++ b/pid/zone.cpp
+@@ -348,7 +348,7 @@ void DbusPidZone::updateFanTelemetry(void)
+      * is disabled?  I think it's a waste to try and log things even if the
+      * data is just being dropped though.
+      */
+-    tstamp now = std::chrono::high_resolution_clock::now();
++    const auto now = std::chrono::high_resolution_clock::now();
+     if (loggingEnabled)
+     {
+         _log << std::chrono::duration_cast<std::chrono::milliseconds>(
+@@ -358,67 +358,7 @@ void DbusPidZone::updateFanTelemetry(void)
+         _log << "," << _maximumSetPointName;
+     }
+ 
+-    for (const auto& f : _fanInputs)
+-    {
+-        auto sensor = _mgr.getSensor(f);
+-        ReadReturn r = sensor->read();
+-        _cachedValuesByName[f] = {r.value, r.unscaled};
+-        int64_t timeout = sensor->getTimeout();
+-        tstamp then = r.updated;
+-
+-        auto duration =
+-            std::chrono::duration_cast<std::chrono::seconds>(now - then)
+-                .count();
+-        auto period = std::chrono::seconds(timeout).count();
+-        /*
+-         * TODO(venture): We should check when these were last read.
+-         * However, these are the fans, so if I'm not getting updated values
+-         * for them... what should I do?
+-         */
+-        if (loggingEnabled)
+-        {
+-            const auto& v = _cachedValuesByName[f];
+-            _log << "," << v.scaled << "," << v.unscaled;
+-            const auto& p = _cachedFanOutputs[f];
+-            _log << "," << p.scaled << "," << p.unscaled;
+-        }
+-
+-        if (debugEnabled)
+-        {
+-            std::cerr << f << " fan sensor reading: " << r.value << "\n";
+-        }
+-
+-        // check if fan fail.
+-        if (sensor->getFailed())
+-        {
+-            _failSafeSensors.insert(f);
+-            if (debugEnabled)
+-            {
+-                std::cerr << f << " fan sensor get failed\n";
+-            }
+-        }
+-        else if (timeout != 0 && duration >= period)
+-        {
+-            _failSafeSensors.insert(f);
+-            if (debugEnabled)
+-            {
+-                std::cerr << f << " fan sensor timeout\n";
+-            }
+-        }
+-        else
+-        {
+-            // Check if it's in there: remove it.
+-            auto kt = _failSafeSensors.find(f);
+-            if (kt != _failSafeSensors.end())
+-            {
+-                if (debugEnabled)
+-                {
+-                    std::cerr << f << " is erased from failsafe sensor set\n";
+-                }
+-                _failSafeSensors.erase(kt);
+-            }
+-        }
+-    }
++    processSensorInputs</* fanSensorLogging */ true>(_fanInputs, now);
+ 
+     if (loggingEnabled)
+     {
+@@ -434,59 +374,8 @@ void DbusPidZone::updateFanTelemetry(void)
+ 
+ void DbusPidZone::updateSensors(void)
+ {
+-    using namespace std::chrono;
+-    /* margin and temp are stored as temp */
+-    tstamp now = high_resolution_clock::now();
+-
+-    for (const auto& t : _thermalInputs)
+-    {
+-        auto sensor = _mgr.getSensor(t);
+-        ReadReturn r = sensor->read();
+-        int64_t timeout = sensor->getTimeout();
+-
+-        _cachedValuesByName[t] = {r.value, r.unscaled};
+-        tstamp then = r.updated;
+-
+-        auto duration = duration_cast<std::chrono::seconds>(now - then).count();
+-        auto period = std::chrono::seconds(timeout).count();
+-
+-        if (debugEnabled)
+-        {
+-            std::cerr << t << " temperature sensor reading: " << r.value
+-                      << "\n";
+-        }
+-
+-        if (sensor->getFailed())
+-        {
+-            _failSafeSensors.insert(t);
+-            if (debugEnabled)
+-            {
+-                std::cerr << t << " temperature sensor get failed\n";
+-            }
+-        }
+-        else if (timeout != 0 && duration >= period)
+-        {
+-            // std::cerr << "Entering fail safe mode.\n";
+-            _failSafeSensors.insert(t);
+-            if (debugEnabled)
+-            {
+-                std::cerr << t << " temperature sensor get timeout\n";
+-            }
+-        }
+-        else
+-        {
+-            // Check if it's in there: remove it.
+-            auto kt = _failSafeSensors.find(t);
+-            if (kt != _failSafeSensors.end())
+-            {
+-                if (debugEnabled)
+-                {
+-                    std::cerr << t << " is erased from failsafe sensor set\n";
+-                }
+-                _failSafeSensors.erase(kt);
+-            }
+-        }
+-    }
++    processSensorInputs</* fanSensorLogging */ false>(
++        _thermalInputs, std::chrono::high_resolution_clock::now());
+ 
+     return;
+ }
+diff --git a/pid/zone.hpp b/pid/zone.hpp
+index 0504a6d..b985f5f 100644
+--- a/pid/zone.hpp
++++ b/pid/zone.hpp
+@@ -13,6 +13,7 @@
+ #include <xyz/openbmc_project/Control/Mode/server.hpp>
+ 
+ #include <fstream>
++#include <iostream>
+ #include <map>
+ #include <memory>
+ #include <set>
+@@ -99,6 +100,78 @@ class DbusPidZone : public ZoneInterface, public ModeObject
+     bool failSafe() const override;
+ 
+   private:
++    template <bool fanSensorLogging>
++    void processSensorInputs(const std::vector<std::string>& sensorInputs,
++                             std::chrono::high_resolution_clock::time_point now)
++    {
++        for (const auto& sensorInput : sensorInputs)
++        {
++            auto sensor = _mgr.getSensor(sensorInput);
++            ReadReturn r = sensor->read();
++            _cachedValuesByName[sensorInput] = {r.value, r.unscaled};
++            int64_t timeout = sensor->getTimeout();
++            std::chrono::high_resolution_clock::time_point then = r.updated;
++
++            auto duration =
++                std::chrono::duration_cast<std::chrono::seconds>(now - then)
++                    .count();
++            auto period = std::chrono::seconds(timeout).count();
++            /*
++             * TODO(venture): We should check when these were last read.
++             * However, these are the fans, so if I'm not getting updated values
++             * for them... what should I do?
++             */
++            if constexpr (fanSensorLogging)
++            {
++                if (loggingEnabled)
++                {
++                    const auto& v = _cachedValuesByName[sensorInput];
++                    _log << "," << v.scaled << "," << v.unscaled;
++                    const auto& p = _cachedFanOutputs[sensorInput];
++                    _log << "," << p.scaled << "," << p.unscaled;
++                }
++            }
++
++            if (debugEnabled)
++            {
++                std::cerr << sensorInput << " sensor reading: " << r.value
++                          << "\n";
++            }
++
++            // check if fan fail.
++            if (sensor->getFailed())
++            {
++                _failSafeSensors.insert(sensorInput);
++                if (debugEnabled)
++                {
++                    std::cerr << sensorInput << " sensor get failed\n";
++                }
++            }
++            else if (timeout != 0 && duration >= period)
++            {
++                _failSafeSensors.insert(sensorInput);
++                if (debugEnabled)
++                {
++                    std::cerr << sensorInput << " sensor timeout\n";
++                }
++            }
++            else
++            {
++                // Check if it's in there: remove it.
++                auto kt = _failSafeSensors.find(sensorInput);
++                if (kt != _failSafeSensors.end())
++                {
++                    if (debugEnabled)
++                    {
++                        std::cerr << sensorInput
++                                  << " is erased from failsafe sensor set\n";
++                    }
++                    _failSafeSensors.erase(kt);
++                }
++            }
++        }
++    }
++
+     std::ofstream _log;
+ 
+     const int64_t _zoneId;
+-- 
+2.39.1.581.gbfd45094c4-goog
+
diff --git a/recipes-phosphor/fans/phosphor-pid-control_%.bbappend b/recipes-phosphor/fans/phosphor-pid-control_%.bbappend
index 9cc66e5..0df0387 100644
--- a/recipes-phosphor/fans/phosphor-pid-control_%.bbappend
+++ b/recipes-phosphor/fans/phosphor-pid-control_%.bbappend
@@ -3,4 +3,5 @@
 SRC_URI:append:gbmc = " \
  file://0001-Implementing-the-TempToMargin-feature.patch \
  file://0001-Skipping-over-Association-Definitions-messages.patch \
+ file://0001-pid-reuse-the-code-for-processing-sensors-input.patch \
 "