pid/fancontroller: Set failsafe PWM in destructor

Introduce a new feature that's guarded by a new meson option
'offline-failsafe-pwm':

After the FanController object was destroyed it can no longer regulate
the fans. To prevent system failure set all fans to the FailSafePercent
defined in the configuration.

In addition to rebuilding configuration it also allows to keep the fans
in FailSafe mode as long as the phosphor-pid-control.service is stopped
or the system reboots. However this change doesn't cover the case of
a program crash where the destructor won't be executed. Abnormal program
termination must be handled by systemd and it out of scope of this
change.

Tested: 'systemctl stop phosphor-pid-control.service' and see the fans
        ramp up to FailSafePercent.

Change-Id: I81262b07fd4c1212efc1a4ba4635bde8bc7b5215
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
diff --git a/pid/fancontroller.cpp b/pid/fancontroller.cpp
index 8bbe3f2..b0591b5 100644
--- a/pid/fancontroller.cpp
+++ b/pid/fancontroller.cpp
@@ -212,4 +212,34 @@
     return;
 }
 
+FanController::~FanController()
+{
+#ifdef OFFLINE_FAILSAFE_PWM
+    double percent = _owner->getFailSafePercent();
+    if (debugEnabled)
+    {
+        std::cerr << "Zone " << _owner->getZoneID()
+                  << " offline fans output pwm: " << percent << "\n";
+    }
+
+    // value and kFanFailSafeDutyCycle are 10 for 10% so let's fix that.
+    percent /= 100.0;
+
+    // PidSensorMap for writing.
+    for (const auto& it : _inputs)
+    {
+        auto sensor = _owner->getSensor(it);
+        auto redundantWrite = _owner->getRedundantWrite();
+        int64_t rawWritten;
+        sensor->write(percent, redundantWrite, &rawWritten);
+
+        // The outputCache will be used later,
+        // to store a record of the PWM commanded,
+        // so that this information can be included during logging.
+        auto unscaledWritten = static_cast<double>(rawWritten);
+        _owner->setOutputCache(sensor->getName(), {percent, unscaledWritten});
+    }
+#endif
+}
+
 } // namespace pid_control
diff --git a/pid/fancontroller.hpp b/pid/fancontroller.hpp
index 447ce7b..c2b76b9 100644
--- a/pid/fancontroller.hpp
+++ b/pid/fancontroller.hpp
@@ -29,7 +29,7 @@
         PIDController(id, owner),
         _inputs(inputs), _direction(FanSpeedDirection::NEUTRAL)
     {}
-
+    ~FanController();
     double inputProc(void) override;
     double setptProc(void) override;
     void outputProc(double value) override;