control: Add fan configuration class framework

The fan class will contain the configuration for each fan to be
controlled within the system. A minimum of 1 fan is required to be
configured.

Tested:
    Fan JSON configuration able to be loaded
    Fan objects created, each with a name as configured

Change-Id: I5f90377453cf7d5d85e1c7c570325c2d97a6060b
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json/Makefile.am b/control/json/Makefile.am
index b87b0db..7d16d6f 100644
--- a/control/json/Makefile.am
+++ b/control/json/Makefile.am
@@ -13,4 +13,5 @@
 
 libfan_control_json_la_SOURCES = \
 	manager.cpp \
-	profile.cpp
+	profile.cpp \
+	fan.cpp
diff --git a/control/json/fan.cpp b/control/json/fan.cpp
new file mode 100644
index 0000000..b2f152c
--- /dev/null
+++ b/control/json/fan.cpp
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2020 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "fan.hpp"
+
+#include <nlohmann/json.hpp>
+#include <sdbusplus/bus.hpp>
+
+namespace phosphor::fan::control::json
+{
+
+using json = nlohmann::json;
+
+Fan::Fan(sdbusplus::bus::bus& bus, const json& jsonObj) :
+    ConfigBase(jsonObj), _bus(bus)
+{}
+
+} // namespace phosphor::fan::control::json
diff --git a/control/json/fan.hpp b/control/json/fan.hpp
new file mode 100644
index 0000000..bd95160
--- /dev/null
+++ b/control/json/fan.hpp
@@ -0,0 +1,130 @@
+/**
+ * Copyright © 2020 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "config_base.hpp"
+
+#include <nlohmann/json.hpp>
+#include <sdbusplus/bus.hpp>
+
+namespace phosphor::fan::control::json
+{
+
+using json = nlohmann::json;
+
+/**
+ * @class Fan - Represents a configured fan control fan object
+ *
+ * A fan object contains the configured attributes for a fan within the system
+ * that will be controlled by the fan control application. These configuration
+ * attributes include, but are not limited to, the cooling zone in which the
+ * fan is included, what sensors make up the fan, the target interface to be
+ * used in setting a speed, and any profiles(OPTIONAL) the fan should be
+ * included in.
+ *
+ * (When no profile for a fan is given, the fan defaults to always be included)
+ *
+ */
+class Fan : public ConfigBase
+{
+  public:
+    /* JSON file name for fans */
+    static constexpr auto confFileName = "fans.json";
+
+    Fan() = delete;
+    Fan(const Fan&) = delete;
+    Fan(Fan&&) = delete;
+    Fan& operator=(const Fan&) = delete;
+    Fan& operator=(Fan&&) = delete;
+    ~Fan() = default;
+
+    /**
+     * Constructor
+     * Parses and populates a zone fan from JSON object data
+     *
+     * @param[in] bus - sdbusplus bus object
+     * @param[in] jsonObj - JSON object
+     */
+    Fan(sdbusplus::bus::bus& bus, const json& jsonObj);
+
+    /**
+     * @brief Get the list of profiles
+     *
+     * @return List of profiles this fan belongs to
+     */
+    inline const auto& getProfiles() const
+    {
+        return _profiles;
+    }
+
+    /**
+     * @brief Get the zone
+     *
+     * @return Zone this fan belongs in
+     */
+    inline const auto& getZone() const
+    {
+        return _zone;
+    }
+
+    /**
+     * @brief Get the list of sensors
+     *
+     * @return List of sensors with `Target` property
+     */
+    inline const auto& getSensors() const
+    {
+        return _sensors;
+    }
+
+    /**
+     * @brief Get the sensors' interface
+     *
+     * @return Interface containing `Target` to use on sensors
+     */
+    inline const auto& getInterface() const
+    {
+        return _interface;
+    }
+
+  private:
+    /* The sdbusplus bus object */
+    sdbusplus::bus::bus& _bus;
+
+    /**
+     * Profiles this fan belongs to (OPTIONAL).
+     * Otherwise always include this fan in the zone
+     * it belongs to when no profiles given
+     */
+    std::vector<std::string> _profiles;
+
+    /* The zone this fan belongs to */
+    std::string _zone;
+
+    /**
+     * Sensors containing the `Target` property on
+     * dbus that make up the fan
+     */
+    std::vector<std::string> _sensors;
+
+    /**
+     * Interface containing the `Target` property
+     * to use in controlling the fan's speed
+     */
+    std::string _interface;
+};
+
+} // namespace phosphor::fan::control::json
diff --git a/control/json_parser.cpp b/control/json_parser.cpp
index 9b80706..5e43de0 100644
--- a/control/json_parser.cpp
+++ b/control/json_parser.cpp
@@ -15,6 +15,7 @@
  */
 #include "json_parser.hpp"
 
+#include "json/fan.hpp"
 #include "json/manager.hpp"
 #include "json/profile.hpp"
 #include "types.hpp"
@@ -30,6 +31,8 @@
 
     // Profiles are optional
     auto profiles = getConfig<json::Profile>(bus, true);
+    // Fans to be controlled
+    auto fans = getConfig<json::Fan>(bus);
 
     // TODO Create zone groups after loading all JSON config files