Persist current mode property framework

Add the ability to save the current  mode property value to
persisted storage.

Change-Id: I354fce7c11a61871a49c9b205dc79ee598f8b1c8
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/configure.ac b/configure.ac
index 8ffda9b..0421801 100644
--- a/configure.ac
+++ b/configure.ac
@@ -109,6 +109,12 @@
        AC_DEFINE_UNQUOTED([CONTROL_OBJPATH], ["$CONTROL_OBJPATH"],
                           [The fan control root object path])
 
+       AC_ARG_VAR(CONTROL_PERSIST_ROOT_PATH, [Root path for persisting zone property states])
+       AS_IF([test "x$CONTROL_PERSIST_ROOT_PATH" == "x"],
+             [CONTROL_PERSIST_ROOT_PATH="/var/lib/phosphor-fan-presence/control"])
+       AC_DEFINE_UNQUOTED([CONTROL_PERSIST_ROOT_PATH], ["$CONTROL_PERSIST_ROOT_PATH"],
+                          [Root path for persisting zone property states])
+
        # Add optional yaml file arguments
        AC_ARG_VAR(FAN_DEF_YAML_FILE,
                   [The fan definition file to use])
diff --git a/control/zone.cpp b/control/zone.cpp
index 9333daa..7d836ba 100644
--- a/control/zone.cpp
+++ b/control/zone.cpp
@@ -15,11 +15,16 @@
  */
 #include <chrono>
 #include <functional>
+#include <fstream>
+#include <cereal/cereal.hpp>
+#include <cereal/archives/json.hpp>
+#include <experimental/filesystem>
 #include <phosphor-logging/log.hpp>
 #include <phosphor-logging/elog.hpp>
 #include <phosphor-logging/elog-errors.hpp>
 #include <stdexcept>
 #include <xyz/openbmc_project/Common/error.hpp>
+#include "config.h"
 #include "zone.hpp"
 #include "utility.hpp"
 #include "sdbusplus.hpp"
@@ -34,6 +39,7 @@
 using namespace std::chrono;
 using namespace phosphor::fan;
 using namespace phosphor::logging;
+namespace fs = std::experimental::filesystem;
 using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
                              Error::InternalFailure;
 
@@ -597,6 +603,17 @@
     return empty;
 }
 
+void Zone::saveCurrentMode()
+{
+    fs::path path{CONTROL_PERSIST_ROOT_PATH};
+    // Append zone and property description
+    path /= std::to_string(_zoneNum);
+    path /= "CurrentMode";
+    std::ofstream ofs(path.c_str(), std::ios::binary);
+    cereal::JSONOutputArchive oArch(ofs);
+    oArch(ThermalObject::current());
+}
+
 }
 }
 }
diff --git a/control/zone.hpp b/control/zone.hpp
index ad4d4b4..feaa8c8 100644
--- a/control/zone.hpp
+++ b/control/zone.hpp
@@ -616,6 +616,12 @@
         std::vector<TimerEvent> _timerEvents;
 
         /**
+         * @brief Save the thermal control current mode property
+         * to persisted storage
+         */
+        void saveCurrentMode();
+
+        /**
          * @brief Get the request speed base if defined, otherwise the
          * the current target speed is returned
          *