use ZoneInterface pointers where Dbus aspect not important

The implementation of the ZoneInterface used is the DbusPidZone, however
using the ZoneInterface when the Dbus aspect is unimportant provides for
trivial support of other implementations.

Signed-off-by: Patrick Venture <venture@google.com>
Change-Id: I0ed87322904e7f87e5b5c8a50c01144f3d843a10
diff --git a/pid/builder.cpp b/pid/builder.cpp
index a5f0ef1..c6b8eaf 100644
--- a/pid/builder.cpp
+++ b/pid/builder.cpp
@@ -21,6 +21,8 @@
 #include "pid/fancontroller.hpp"
 #include "pid/stepwisecontroller.hpp"
 #include "pid/thermalcontroller.hpp"
+#include "pid/zone.hpp"
+#include "pid/zone_interface.hpp"
 
 #include <sdbusplus/bus.hpp>
 
@@ -39,12 +41,12 @@
     return std::string(objectPath) + std::to_string(zone);
 }
 
-std::unordered_map<int64_t, std::unique_ptr<DbusPidZone>>
+std::unordered_map<int64_t, std::unique_ptr<ZoneInterface>>
     buildZones(const std::map<int64_t, conf::PIDConf>& zonePids,
                std::map<int64_t, struct conf::ZoneConfig>& zoneConfigs,
                SensorManager& mgr, sdbusplus::bus::bus& modeControlBus)
 {
-    std::unordered_map<int64_t, std::unique_ptr<DbusPidZone>> zones;
+    std::unordered_map<int64_t, std::unique_ptr<ZoneInterface>> zones;
 
     for (const auto& zi : zonePids)
     {
diff --git a/pid/builder.hpp b/pid/builder.hpp
index 4db7447..ff2f682 100644
--- a/pid/builder.hpp
+++ b/pid/builder.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
-#include "pid/zone.hpp"
+#include "conf.hpp"
+#include "pid/zone_interface.hpp"
 #include "sensors/manager.hpp"
 
 #include <sdbusplus/bus.hpp>
@@ -11,7 +12,7 @@
 namespace pid_control
 {
 
-std::unordered_map<int64_t, std::unique_ptr<DbusPidZone>>
+std::unordered_map<int64_t, std::unique_ptr<ZoneInterface>>
     buildZones(const std::map<int64_t, conf::PIDConf>& zonePids,
                std::map<int64_t, struct conf::ZoneConfig>& zoneConfigs,
                SensorManager& mgr, sdbusplus::bus::bus& modeControlBus);
diff --git a/pid/pidloop.cpp b/pid/pidloop.cpp
index fe6c9b7..1cdf019 100644
--- a/pid/pidloop.cpp
+++ b/pid/pidloop.cpp
@@ -18,6 +18,7 @@
 
 #include "pid/pidcontroller.hpp"
 #include "pid/tuning.hpp"
+#include "pid/zone_interface.hpp"
 #include "sensors/sensor.hpp"
 
 #include <boost/asio/steady_timer.hpp>
@@ -25,13 +26,14 @@
 #include <chrono>
 #include <map>
 #include <memory>
+#include <sstream>
 #include <thread>
 #include <vector>
 
 namespace pid_control
 {
 
-static void processThermals(DbusPidZone* zone)
+static void processThermals(ZoneInterface* zone)
 {
     // Get the latest margins.
     zone->updateSensors();
@@ -44,7 +46,7 @@
     zone->determineMaxSetPointRequest();
 }
 
-void pidControlLoop(DbusPidZone* zone, boost::asio::steady_timer& timer,
+void pidControlLoop(ZoneInterface* zone, boost::asio::steady_timer& timer,
                     bool first, int ms100cnt)
 {
     if (first)
@@ -115,8 +117,9 @@
 
             if (loggingEnabled)
             {
-                zone->getLogHandle() << "," << zone->getFailSafeMode();
-                zone->getLogHandle() << std::endl;
+                std::ostringstream out;
+                out << "," << zone->getFailSafeMode() << std::endl;
+                zone->writeLog(out.str());
             }
 
             ms100cnt += 1;
diff --git a/pid/pidloop.hpp b/pid/pidloop.hpp
index c8365e3..0b8690b 100644
--- a/pid/pidloop.hpp
+++ b/pid/pidloop.hpp
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "pid/zone.hpp"
+#include "pid/zone_interface.hpp"
 
 #include <boost/asio/steady_timer.hpp>
 
@@ -12,12 +12,12 @@
  * This function calls itself indefinitely in an async loop to calculate
  * fan outputs based on thermal inputs.
  *
- * @param[in] zone - ptr to the DbusPidZone for this loop.
+ * @param[in] zone - ptr to the ZoneInterface implementation for this loop.
  * @param[in] timer - boost timer used for async callback.
  * @param[in] first - boolean to denote if initialization needs to be run.
  * @param[in] ms100cnt - loop timer counter.
  */
-void pidControlLoop(DbusPidZone* zone, boost::asio::steady_timer& timer,
+void pidControlLoop(ZoneInterface* zone, boost::asio::steady_timer& timer,
                     bool first = true, int ms100cnt = 0);
 
 } // namespace pid_control
diff --git a/pid/zone.cpp b/pid/zone.cpp
index ca0f67f..9621993 100644
--- a/pid/zone.cpp
+++ b/pid/zone.cpp
@@ -31,6 +31,7 @@
 #include <fstream>
 #include <iostream>
 #include <memory>
+#include <string>
 
 namespace pid_control
 {
@@ -196,9 +197,10 @@
     return;
 }
 
-std::ofstream& DbusPidZone::getLogHandle(void)
+void DbusPidZone::writeLog(const std::string& value)
 {
-    return _log;
+    _log << value;
+    return;
 }
 
 /*
diff --git a/pid/zone.hpp b/pid/zone.hpp
index 254ea42..3bea9c2 100644
--- a/pid/zone.hpp
+++ b/pid/zone.hpp
@@ -49,30 +49,30 @@
         }
     }
 
-    double getMaxSetPointRequest(void) const override;
-    bool getManualMode(void) const;
-
+    bool getManualMode(void) const override;
     /* Could put lock around this since it's accessed from two threads, but
      * only one reader/one writer.
      */
     void setManualMode(bool mode);
     bool getFailSafeMode(void) const override;
+
     int64_t getZoneID(void) const;
     void addSetPoint(double setpoint) override;
+    double getMaxSetPointRequest(void) const override;
     void addRPMCeiling(double ceiling) override;
-    void clearSetPoints(void);
-    void clearRPMCeilings(void);
+    void clearSetPoints(void) override;
+    void clearRPMCeilings(void) override;
     double getFailSafePercent(void) const override;
     double getMinThermalSetpoint(void) const;
 
     Sensor* getSensor(const std::string& name) override;
-    void determineMaxSetPointRequest(void);
-    void updateFanTelemetry(void);
-    void updateSensors(void);
-    void initializeCache(void);
+    void determineMaxSetPointRequest(void) override;
+    void updateFanTelemetry(void) override;
+    void updateSensors(void) override;
+    void initializeCache(void) override;
     void dumpCache(void);
-    void processFans(void);
-    void processThermals(void);
+    void processFans(void) override;
+    void processThermals(void) override;
 
     void addFanPID(std::unique_ptr<Controller> pid);
     void addThermalPID(std::unique_ptr<Controller> pid);
@@ -80,8 +80,8 @@
     void addFanInput(const std::string& fan);
     void addThermalInput(const std::string& therm);
 
-    void initializeLog(void);
-    std::ofstream& getLogHandle(void);
+    void initializeLog(void) override;
+    void writeLog(const std::string& value) override;
 
     /* Method for setting the manual mode over dbus */
     bool manual(bool value) override;
diff --git a/pid/zone_interface.hpp b/pid/zone_interface.hpp
index f701064..a024c0e 100644
--- a/pid/zone_interface.hpp
+++ b/pid/zone_interface.hpp
@@ -7,18 +7,79 @@
 namespace pid_control
 {
 
+/**
+ * In a Zone you have a set of PIDs which feed each other.  Fan PIDs are fed set
+ * points from Thermal PIDs.
+ */
 class ZoneInterface
 {
   public:
     virtual ~ZoneInterface() = default;
 
-    virtual double getCachedValue(const std::string& name) = 0;
-    virtual void addSetPoint(double setpoint) = 0;
-    virtual void addRPMCeiling(double ceiling) = 0;
-    virtual double getMaxSetPointRequest() const = 0;
-    virtual bool getFailSafeMode() const = 0;
-    virtual double getFailSafePercent() const = 0;
+    /** If the zone implementation supports logging, initialize the log. */
+    virtual void initializeLog(void) = 0;
+    /** If the zone implementation supports logging, write string to log. */
+    virtual void writeLog(const std::string& value) = 0;
+
+    /** Return a pointer to the sensor specified by name. */
     virtual Sensor* getSensor(const std::string& name) = 0;
+
+    /* updateFanTelemetry() and updateSensors() both clear the failsafe state
+     * for a sensor if it's no longer in that state.
+     */
+    /** For each fan input in the zone, read each to update the cachedValue and
+     * check if the fan is beyond its timeout to trigger a failsafe condition.
+     */
+    virtual void updateFanTelemetry(void) = 0;
+    /** For each thermal input in the zone, read each to update the cachedValue
+     * and check if the sensor is beyond its timeout to trigger a failsafe
+     * condition.
+     */
+    virtual void updateSensors(void) = 0;
+    /** For each fan and thermal input in the zone, set the cachedValue to 0 and
+     * set the input as failsafe - to default the zone to failsafe before it
+     * starts processing values to control fans.
+     */
+    virtual void initializeCache(void) = 0;
+    /** Return cached value for sensor by name. */
+    virtual double getCachedValue(const std::string& name) = 0;
+
+    /** Add a set point value for the Max Set Point computation. */
+    virtual void addSetPoint(double setpoint) = 0;
+    /** Clear all set points specified via addSetPoint */
+    virtual void clearSetPoints(void) = 0;
+
+    /** Add maximum RPM value to drive fan pids. */
+    virtual void addRPMCeiling(double ceiling) = 0;
+    /** Clear any RPM value set with addRPMCeiling. */
+    virtual void clearRPMCeilings(void) = 0;
+
+    /** Compute the value returned by getMaxSetPointRequest - called from the
+     * looping mechanism before triggering any Fan PIDs. The value computed is
+     * used by each fan PID.
+     */
+    virtual void determineMaxSetPointRequest(void) = 0;
+    /** Given the set points added via addSetPoint, return the maximum value -
+     * called from the PID loop that uses that value to drive the fans.
+     */
+    virtual double getMaxSetPointRequest() const = 0;
+
+    /** Return if the zone has any sensors in fail safe mode. */
+    virtual bool getFailSafeMode() const = 0;
+    /** Return the rpm or pwm percent value to drive fan pids when zone is in
+     * fail safe.
+     */
+    virtual double getFailSafePercent() const = 0;
+
+    /** Return if the zone is set to manual mode.  false equates to automatic
+     * mode (the default).
+     */
+    virtual bool getManualMode(void) const = 0;
+
+    /** For each fan pid, do processing. */
+    virtual void processFans(void) = 0;
+    /** For each thermal pid, do processing. */
+    virtual void processThermals(void) = 0;
 };
 
 } // namespace pid_control