diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index 5f5ef6e..829ce00 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -20,6 +20,7 @@
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/date_time.hpp>
 #include <dbus_utility.hpp>
+#include <memory>
 #include <sstream>
 #include <utils/systemd_utils.hpp>
 #include <variant>
@@ -118,15 +119,20 @@
     "xyz.openbmc_project.Configuration.Pid.Zone";
 static constexpr const char* stepwiseConfigurationIface =
     "xyz.openbmc_project.Configuration.Stepwise";
+static constexpr const char* thermalModeIface =
+    "xyz.openbmc_project.Control.ThermalMode";
 
 static void asyncPopulatePid(const std::string& connection,
                              const std::string& path,
+                             const std::string& currentProfile,
+                             const std::vector<std::string>& supportedProfiles,
                              std::shared_ptr<AsyncResp> asyncResp)
 {
 
     crow::connections::systemBus->async_method_call(
-        [asyncResp](const boost::system::error_code ec,
-                    const dbus::utility::ManagedObjectType& managedObj) {
+        [asyncResp, currentProfile, supportedProfiles](
+            const boost::system::error_code ec,
+            const dbus::utility::ManagedObjectType& managedObj) {
             if (ec)
             {
                 BMCWEB_LOG_ERROR << ec;
@@ -168,6 +174,13 @@
             configRoot["@odata.type"] = "#OemManager.Fan";
             configRoot["@odata.context"] =
                 "/redfish/v1/$metadata#OemManager.Fan";
+            configRoot["Profile@Redfish.AllowableValues"] = supportedProfiles;
+
+            if (!currentProfile.empty())
+            {
+                configRoot["Profile"] = currentProfile;
+            }
+            BMCWEB_LOG_ERROR << "profile = " << currentProfile << " !";
 
             for (const auto& pathPair : managedObj)
             {
@@ -186,6 +199,7 @@
                         messages::internalError(asyncResp->res);
                         return;
                     }
+
                     const std::string* namePtr =
                         std::get_if<std::string>(&findName->second);
                     if (namePtr == nullptr)
@@ -194,9 +208,29 @@
                         messages::internalError(asyncResp->res);
                         return;
                     }
-
                     std::string name = *namePtr;
                     dbus::utility::escapePathForDbus(name);
+
+                    auto findProfiles = intfPair.second.find("Profiles");
+                    if (findProfiles != intfPair.second.end())
+                    {
+                        const std::vector<std::string>* profiles =
+                            std::get_if<std::vector<std::string>>(
+                                &findProfiles->second);
+                        if (profiles == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR << "Pid Profiles Field illegal";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        if (std::find(profiles->begin(), profiles->end(),
+                                      currentProfile) == profiles->end())
+                        {
+                            BMCWEB_LOG_INFO
+                                << name << " not supported in current profile";
+                            continue;
+                        }
+                    }
                     nlohmann::json* config = nullptr;
 
                     const std::string* classPtr = nullptr;
@@ -522,8 +556,9 @@
     return true;
 }
 
-static bool findChassis(const dbus::utility::ManagedObjectType& managedObj,
-                        const std::string& value, std::string& chassis)
+static const dbus::utility::ManagedItem*
+    findChassis(const dbus::utility::ManagedObjectType& managedObj,
+                const std::string& value, std::string& chassis)
 {
     BMCWEB_LOG_DEBUG << "Find Chassis: " << value << "\n";
 
@@ -541,11 +576,16 @@
 
     if (it == managedObj.end())
     {
-        return false;
+        return nullptr;
     }
     // 5 comes from <chassis-name> being the 5th element
     // /xyz/openbmc_project/inventory/system/chassis/<chassis-name>
-    return dbus::utility::getNthStringFromPath(it->first.str, 5, chassis);
+    if (dbus::utility::getNthStringFromPath(it->first.str, 5, chassis))
+    {
+        return &(*it);
+    }
+
+    return nullptr;
 }
 
 static CreatePIDRet createPidInterface(
@@ -554,7 +594,7 @@
     const dbus::utility::ManagedObjectType& managedObj, bool createNewObject,
     boost::container::flat_map<std::string, dbus::utility::DbusVariantType>&
         output,
-    std::string& chassis)
+    std::string& chassis, const std::string& profile)
 {
 
     // common deleter
@@ -595,11 +635,13 @@
         return CreatePIDRet::del;
     }
 
+    const dbus::utility::ManagedItem* managedItem = nullptr;
     if (!createNewObject)
     {
         // if we aren't creating a new object, we should be able to find it on
         // d-bus
-        if (!findChassis(managedObj, it.key(), chassis))
+        managedItem = findChassis(managedObj, it.key(), chassis);
+        if (managedItem == nullptr)
         {
             BMCWEB_LOG_ERROR << "Failed to get chassis from config patch";
             messages::invalidObject(response->res, it.key());
@@ -607,6 +649,56 @@
         }
     }
 
+    if (profile.size() &&
+        (type == "PidControllers" || type == "FanControllers" ||
+         type == "StepwiseControllers"))
+    {
+        if (managedItem == nullptr)
+        {
+            output["Profiles"] = std::vector<std::string>{profile};
+        }
+        else
+        {
+            std::string interface;
+            if (type == "StepwiseControllers")
+            {
+                interface = stepwiseConfigurationIface;
+            }
+            else
+            {
+                interface = pidConfigurationIface;
+            }
+            auto findConfig = managedItem->second.find(interface);
+            if (findConfig == managedItem->second.end())
+            {
+                BMCWEB_LOG_ERROR
+                    << "Failed to find interface in managed object";
+                messages::internalError(response->res);
+                return CreatePIDRet::fail;
+            }
+            auto findProfiles = findConfig->second.find("Profiles");
+            if (findProfiles != findConfig->second.end())
+            {
+                const std::vector<std::string>* curProfiles =
+                    std::get_if<std::vector<std::string>>(
+                        &(findProfiles->second));
+                if (curProfiles == nullptr)
+                {
+                    BMCWEB_LOG_ERROR << "Illegal profiles in managed object";
+                    messages::internalError(response->res);
+                    return CreatePIDRet::fail;
+                }
+                if (std::find(curProfiles->begin(), curProfiles->end(),
+                              profile) == curProfiles->end())
+                {
+                    std::vector<std::string> newProfiles = *curProfiles;
+                    newProfiles.push_back(profile);
+                    output["Profiles"] = newProfiles;
+                }
+            }
+        }
+    }
+
     if (type == "PidControllers" || type == "FanControllers")
     {
         if (createNewObject)
@@ -846,6 +938,510 @@
     }
     return CreatePIDRet::patch;
 }
+struct GetPIDValues : std::enable_shared_from_this<GetPIDValues>
+{
+
+    GetPIDValues(const std::shared_ptr<AsyncResp>& asyncResp) :
+        asyncResp(asyncResp)
+
+    {
+    }
+
+    void run()
+    {
+        std::shared_ptr<GetPIDValues> self = shared_from_this();
+
+        // get all configurations
+        crow::connections::systemBus->async_method_call(
+            [self](const boost::system::error_code ec,
+                   const crow::openbmc_mapper::GetSubTreeType& subtree) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << ec;
+                    messages::internalError(self->asyncResp->res);
+                    return;
+                }
+                self->subtree = subtree;
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", 0,
+            std::array<const char*, 4>{
+                pidConfigurationIface, pidZoneConfigurationIface,
+                objectManagerIface, stepwiseConfigurationIface});
+
+        // at the same time get the selected profile
+        crow::connections::systemBus->async_method_call(
+            [self](const boost::system::error_code ec,
+                   const crow::openbmc_mapper::GetSubTreeType& subtree) {
+                if (ec || subtree.empty())
+                {
+                    return;
+                }
+                if (subtree[0].second.size() != 1)
+                {
+                    // invalid mapper response, should never happen
+                    BMCWEB_LOG_ERROR << "GetPIDValues: Mapper Error";
+                    messages::internalError(self->asyncResp->res);
+                    return;
+                }
+
+                const std::string& path = subtree[0].first;
+                const std::string& owner = subtree[0].second[0].first;
+                crow::connections::systemBus->async_method_call(
+                    [path, owner, self](
+                        const boost::system::error_code ec,
+                        const boost::container::flat_map<
+                            std::string, std::variant<std::vector<std::string>,
+                                                      std::string>>& resp) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "GetPIDValues: Can't get "
+                                                "thermalModeIface "
+                                             << path;
+                            messages::internalError(self->asyncResp->res);
+                            return;
+                        }
+                        const std::string* current;
+                        const std::vector<std::string>* supported;
+                        for (auto& [key, value] : resp)
+                        {
+                            if (key == "Current")
+                            {
+                                current = std::get_if<std::string>(&value);
+                                if (current == nullptr)
+                                {
+                                    BMCWEB_LOG_ERROR
+                                        << "GetPIDValues: thermal mode "
+                                           "iface invalid "
+                                        << path;
+                                    messages::internalError(
+                                        self->asyncResp->res);
+                                    return;
+                                }
+                            }
+                            if (key == "Supported")
+                            {
+                                supported =
+                                    std::get_if<std::vector<std::string>>(
+                                        &value);
+                                if (supported == nullptr)
+                                {
+                                    BMCWEB_LOG_ERROR
+                                        << "GetPIDValues: thermal mode "
+                                           "iface invalid"
+                                        << path;
+                                    messages::internalError(
+                                        self->asyncResp->res);
+                                    return;
+                                }
+                            }
+                        }
+                        if (current == nullptr || supported == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR << "GetPIDValues: thermal mode "
+                                                "iface invalid "
+                                             << path;
+                            messages::internalError(self->asyncResp->res);
+                            return;
+                        }
+                        self->currentProfile = *current;
+                        self->supportedProfiles = *supported;
+                    },
+                    owner, path, "org.freedesktop.DBus.Properties", "GetAll",
+                    thermalModeIface);
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", 0,
+            std::array<const char*, 1>{thermalModeIface});
+    }
+
+    ~GetPIDValues()
+    {
+        if (asyncResp->res.result() != boost::beast::http::status::ok)
+        {
+            return;
+        }
+        // create map of <connection, path to objMgr>>
+        boost::container::flat_map<std::string, std::string> objectMgrPaths;
+        boost::container::flat_set<std::string> calledConnections;
+        for (const auto& pathGroup : subtree)
+        {
+            for (const auto& connectionGroup : pathGroup.second)
+            {
+                auto findConnection =
+                    calledConnections.find(connectionGroup.first);
+                if (findConnection != calledConnections.end())
+                {
+                    break;
+                }
+                for (const std::string& interface : connectionGroup.second)
+                {
+                    if (interface == objectManagerIface)
+                    {
+                        objectMgrPaths[connectionGroup.first] = pathGroup.first;
+                    }
+                    // this list is alphabetical, so we
+                    // should have found the objMgr by now
+                    if (interface == pidConfigurationIface ||
+                        interface == pidZoneConfigurationIface ||
+                        interface == stepwiseConfigurationIface)
+                    {
+                        auto findObjMgr =
+                            objectMgrPaths.find(connectionGroup.first);
+                        if (findObjMgr == objectMgrPaths.end())
+                        {
+                            BMCWEB_LOG_DEBUG << connectionGroup.first
+                                             << "Has no Object Manager";
+                            continue;
+                        }
+
+                        calledConnections.insert(connectionGroup.first);
+
+                        asyncPopulatePid(findObjMgr->first, findObjMgr->second,
+                                         currentProfile, supportedProfiles,
+                                         asyncResp);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    std::vector<std::string> supportedProfiles;
+    std::string currentProfile;
+    crow::openbmc_mapper::GetSubTreeType subtree;
+    std::shared_ptr<AsyncResp> asyncResp;
+};
+
+struct SetPIDValues : std::enable_shared_from_this<SetPIDValues>
+{
+
+    SetPIDValues(const std::shared_ptr<AsyncResp>& asyncResp,
+                 nlohmann::json& data) :
+        asyncResp(asyncResp)
+    {
+
+        std::optional<nlohmann::json> pidControllers;
+        std::optional<nlohmann::json> fanControllers;
+        std::optional<nlohmann::json> fanZones;
+        std::optional<nlohmann::json> stepwiseControllers;
+
+        if (!redfish::json_util::readJson(
+                data, asyncResp->res, "PidControllers", pidControllers,
+                "FanControllers", fanControllers, "FanZones", fanZones,
+                "StepwiseControllers", stepwiseControllers, "Profile", profile))
+        {
+            BMCWEB_LOG_ERROR << "Line:" << __LINE__ << ", Illegal Property "
+                             << data.dump();
+            return;
+        }
+        configuration.emplace_back("PidControllers", std::move(pidControllers));
+        configuration.emplace_back("FanControllers", std::move(fanControllers));
+        configuration.emplace_back("FanZones", std::move(fanZones));
+        configuration.emplace_back("StepwiseControllers",
+                                   std::move(stepwiseControllers));
+    }
+    void run()
+    {
+        if (asyncResp->res.result() != boost::beast::http::status::ok)
+        {
+            return;
+        }
+
+        std::shared_ptr<SetPIDValues> self = shared_from_this();
+
+        // todo(james): might make sense to do a mapper call here if this
+        // interface gets more traction
+        crow::connections::systemBus->async_method_call(
+            [self](const boost::system::error_code ec,
+                   dbus::utility::ManagedObjectType& managedObj) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error communicating to Entity Manager";
+                    messages::internalError(self->asyncResp->res);
+                    return;
+                }
+                self->managedObj = std::move(managedObj);
+            },
+            "xyz.openbmc_project.EntityManager", "/", objectManagerIface,
+            "GetManagedObjects");
+
+        // at the same time get the profile information
+        crow::connections::systemBus->async_method_call(
+            [self](const boost::system::error_code ec,
+                   const crow::openbmc_mapper::GetSubTreeType& subtree) {
+                if (ec || subtree.empty())
+                {
+                    return;
+                }
+                if (subtree[0].second.empty())
+                {
+                    // invalid mapper response, should never happen
+                    BMCWEB_LOG_ERROR << "SetPIDValues: Mapper Error";
+                    messages::internalError(self->asyncResp->res);
+                    return;
+                }
+
+                const std::string& path = subtree[0].first;
+                const std::string& owner = subtree[0].second[0].first;
+                crow::connections::systemBus->async_method_call(
+                    [self, path, owner](
+                        const boost::system::error_code ec,
+                        const boost::container::flat_map<
+                            std::string, std::variant<std::vector<std::string>,
+                                                      std::string>>& resp) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "SetPIDValues: Can't get "
+                                                "thermalModeIface "
+                                             << path;
+                            messages::internalError(self->asyncResp->res);
+                            return;
+                        }
+                        const std::string* current;
+                        const std::vector<std::string>* supported;
+                        for (auto& [key, value] : resp)
+                        {
+                            if (key == "Current")
+                            {
+                                current = std::get_if<std::string>(&value);
+                                if (current == nullptr)
+                                {
+                                    BMCWEB_LOG_ERROR
+                                        << "SetPIDValues: thermal mode "
+                                           "iface invalid "
+                                        << path;
+                                    messages::internalError(
+                                        self->asyncResp->res);
+                                    return;
+                                }
+                            }
+                            if (key == "Supported")
+                            {
+                                supported =
+                                    std::get_if<std::vector<std::string>>(
+                                        &value);
+                                if (supported == nullptr)
+                                {
+                                    BMCWEB_LOG_ERROR
+                                        << "SetPIDValues: thermal mode "
+                                           "iface invalid"
+                                        << path;
+                                    messages::internalError(
+                                        self->asyncResp->res);
+                                    return;
+                                }
+                            }
+                        }
+                        if (current == nullptr || supported == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR << "SetPIDValues: thermal mode "
+                                                "iface invalid "
+                                             << path;
+                            messages::internalError(self->asyncResp->res);
+                            return;
+                        }
+                        self->currentProfile = *current;
+                        self->supportedProfiles = *supported;
+                        self->profileConnection = owner;
+                        self->profilePath = path;
+                    },
+                    owner, path, "org.freedesktop.DBus.Properties", "GetAll",
+                    thermalModeIface);
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", 0,
+            std::array<const char*, 1>{thermalModeIface});
+    }
+    ~SetPIDValues()
+    {
+        if (asyncResp->res.result() != boost::beast::http::status::ok)
+        {
+            return;
+        }
+
+        std::shared_ptr<AsyncResp> response = asyncResp;
+
+        if (profile)
+        {
+            if (std::find(supportedProfiles.begin(), supportedProfiles.end(),
+                          *profile) == supportedProfiles.end())
+            {
+                messages::actionParameterUnknown(response->res, "Profile",
+                                                 *profile);
+                return;
+            }
+            currentProfile = *profile;
+            crow::connections::systemBus->async_method_call(
+                [response](const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_ERROR << "Error patching profile" << ec;
+                        messages::internalError(response->res);
+                    }
+                },
+                profileConnection, profilePath,
+                "org.freedesktop.DBus.Properties", "Set", thermalModeIface,
+                "Current", std::variant<std::string>(*profile));
+        }
+
+        for (auto& containerPair : configuration)
+        {
+            auto& container = containerPair.second;
+            if (!container)
+            {
+                continue;
+            }
+            std::string& type = containerPair.first;
+
+            for (nlohmann::json::iterator it = container->begin();
+                 it != container->end(); it++)
+            {
+                const auto& name = it.key();
+                auto pathItr =
+                    std::find_if(managedObj.begin(), managedObj.end(),
+                                 [&name](const auto& obj) {
+                                     return boost::algorithm::ends_with(
+                                         obj.first.str, "/" + name);
+                                 });
+                boost::container::flat_map<std::string,
+                                           dbus::utility::DbusVariantType>
+                    output;
+
+                output.reserve(16); // The pid interface length
+
+                // determines if we're patching entity-manager or
+                // creating a new object
+                bool createNewObject = (pathItr == managedObj.end());
+                std::string iface;
+                if (type == "PidControllers" || type == "FanControllers")
+                {
+                    iface = pidConfigurationIface;
+                    if (!createNewObject &&
+                        pathItr->second.find(pidConfigurationIface) ==
+                            pathItr->second.end())
+                    {
+                        createNewObject = true;
+                    }
+                }
+                else if (type == "FanZones")
+                {
+                    iface = pidZoneConfigurationIface;
+                    if (!createNewObject &&
+                        pathItr->second.find(pidZoneConfigurationIface) ==
+                            pathItr->second.end())
+                    {
+
+                        createNewObject = true;
+                    }
+                }
+                else if (type == "StepwiseControllers")
+                {
+                    iface = stepwiseConfigurationIface;
+                    if (!createNewObject &&
+                        pathItr->second.find(stepwiseConfigurationIface) ==
+                            pathItr->second.end())
+                    {
+                        createNewObject = true;
+                    }
+                }
+                BMCWEB_LOG_DEBUG << "Create new = " << createNewObject << "\n";
+                output["Name"] = boost::replace_all_copy(name, "_", " ");
+
+                std::string chassis;
+                CreatePIDRet ret = createPidInterface(
+                    response, type, it, pathItr->first.str, managedObj,
+                    createNewObject, output, chassis, currentProfile);
+                if (ret == CreatePIDRet::fail)
+                {
+                    return;
+                }
+                else if (ret == CreatePIDRet::del)
+                {
+                    continue;
+                }
+
+                if (!createNewObject)
+                {
+                    for (const auto& property : output)
+                    {
+                        crow::connections::systemBus->async_method_call(
+                            [response,
+                             propertyName{std::string(property.first)}](
+                                const boost::system::error_code ec) {
+                                if (ec)
+                                {
+                                    BMCWEB_LOG_ERROR << "Error patching "
+                                                     << propertyName << ": "
+                                                     << ec;
+                                    messages::internalError(response->res);
+                                    return;
+                                }
+                                messages::success(response->res);
+                            },
+                            "xyz.openbmc_project.EntityManager",
+                            pathItr->first.str,
+                            "org.freedesktop.DBus.Properties", "Set", iface,
+                            property.first, property.second);
+                    }
+                }
+                else
+                {
+                    if (chassis.empty())
+                    {
+                        BMCWEB_LOG_ERROR << "Failed to get chassis from config";
+                        messages::invalidObject(response->res, name);
+                        return;
+                    }
+
+                    bool foundChassis = false;
+                    for (const auto& obj : managedObj)
+                    {
+                        if (boost::algorithm::ends_with(obj.first.str, chassis))
+                        {
+                            chassis = obj.first.str;
+                            foundChassis = true;
+                            break;
+                        }
+                    }
+                    if (!foundChassis)
+                    {
+                        BMCWEB_LOG_ERROR << "Failed to find chassis on dbus";
+                        messages::resourceMissingAtURI(
+                            response->res, "/redfish/v1/Chassis/" + chassis);
+                        return;
+                    }
+
+                    crow::connections::systemBus->async_method_call(
+                        [response](const boost::system::error_code ec) {
+                            if (ec)
+                            {
+                                BMCWEB_LOG_ERROR << "Error Adding Pid Object "
+                                                 << ec;
+                                messages::internalError(response->res);
+                                return;
+                            }
+                            messages::success(response->res);
+                        },
+                        "xyz.openbmc_project.EntityManager", chassis,
+                        "xyz.openbmc_project.AddObject", "AddObject", output);
+                }
+            }
+        }
+    }
+    std::shared_ptr<AsyncResp> asyncResp;
+    std::vector<std::pair<std::string, std::optional<nlohmann::json>>>
+        configuration;
+    std::optional<std::string> profile;
+    dbus::utility::ManagedObjectType managedObj;
+    std::vector<std::string> supportedProfiles;
+    std::string currentProfile;
+    std::string profileConnection;
+    std::string profilePath;
+};
 
 class Manager : public Node
 {
@@ -864,73 +1460,6 @@
     }
 
   private:
-    void getPidValues(std::shared_ptr<AsyncResp> asyncResp)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
-                        const crow::openbmc_mapper::GetSubTreeType& subtree) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                // create map of <connection, path to objMgr>>
-                boost::container::flat_map<std::string, std::string>
-                    objectMgrPaths;
-                boost::container::flat_set<std::string> calledConnections;
-                for (const auto& pathGroup : subtree)
-                {
-                    for (const auto& connectionGroup : pathGroup.second)
-                    {
-                        auto findConnection =
-                            calledConnections.find(connectionGroup.first);
-                        if (findConnection != calledConnections.end())
-                        {
-                            break;
-                        }
-                        for (const std::string& interface :
-                             connectionGroup.second)
-                        {
-                            if (interface == objectManagerIface)
-                            {
-                                objectMgrPaths[connectionGroup.first] =
-                                    pathGroup.first;
-                            }
-                            // this list is alphabetical, so we
-                            // should have found the objMgr by now
-                            if (interface == pidConfigurationIface ||
-                                interface == pidZoneConfigurationIface ||
-                                interface == stepwiseConfigurationIface)
-                            {
-                                auto findObjMgr =
-                                    objectMgrPaths.find(connectionGroup.first);
-                                if (findObjMgr == objectMgrPaths.end())
-                                {
-                                    BMCWEB_LOG_DEBUG << connectionGroup.first
-                                                     << "Has no Object Manager";
-                                    continue;
-                                }
-
-                                calledConnections.insert(connectionGroup.first);
-
-                                asyncPopulatePid(findObjMgr->first,
-                                                 findObjMgr->second, asyncResp);
-                                break;
-                            }
-                        }
-                    }
-                }
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", 0,
-            std::array<const char*, 4>{
-                pidConfigurationIface, pidZoneConfigurationIface,
-                objectManagerIface, stepwiseConfigurationIface});
-    }
-
     void doGet(crow::Response& res, const crow::Request& req,
                const std::vector<std::string>& params) override
     {
@@ -1035,208 +1564,8 @@
             "xyz.openbmc_project.Software.BMC.Updater",
             "/xyz/openbmc_project/software",
             "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-        getPidValues(asyncResp);
-    }
-    void setPidValues(std::shared_ptr<AsyncResp> response, nlohmann::json& data)
-    {
-
-        // todo(james): might make sense to do a mapper call here if this
-        // interface gets more traction
-        crow::connections::systemBus->async_method_call(
-            [response,
-             data](const boost::system::error_code ec,
-                   const dbus::utility::ManagedObjectType& managedObj) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "Error communicating to Entity Manager";
-                    messages::internalError(response->res);
-                    return;
-                }
-
-                // todo(james) mutable doesn't work with asio bindings
-                nlohmann::json jsonData = data;
-
-                std::optional<nlohmann::json> pidControllers;
-                std::optional<nlohmann::json> fanControllers;
-                std::optional<nlohmann::json> fanZones;
-                std::optional<nlohmann::json> stepwiseControllers;
-                if (!redfish::json_util::readJson(
-                        jsonData, response->res, "PidControllers",
-                        pidControllers, "FanControllers", fanControllers,
-                        "FanZones", fanZones, "StepwiseControllers",
-                        stepwiseControllers))
-                {
-                    BMCWEB_LOG_ERROR << "Line:" << __LINE__
-                                     << ", Illegal Property "
-                                     << jsonData.dump();
-                    return;
-                }
-                std::array<
-                    std::pair<std::string, std::optional<nlohmann::json>*>, 4>
-                    sections = {
-                        std::make_pair("PidControllers", &pidControllers),
-                        std::make_pair("FanControllers", &fanControllers),
-                        std::make_pair("FanZones", &fanZones),
-                        std::make_pair("StepwiseControllers",
-                                       &stepwiseControllers)};
-
-                for (auto& containerPair : sections)
-                {
-                    auto& container = *(containerPair.second);
-                    if (!container)
-                    {
-                        continue;
-                    }
-                    std::string& type = containerPair.first;
-
-                    for (nlohmann::json::iterator it = container->begin();
-                         it != container->end(); it++)
-                    {
-                        const auto& name = it.key();
-                        auto pathItr =
-                            std::find_if(managedObj.begin(), managedObj.end(),
-                                         [&name](const auto& obj) {
-                                             return boost::algorithm::ends_with(
-                                                 obj.first.str, "/" + name);
-                                         });
-                        boost::container::flat_map<
-                            std::string, dbus::utility::DbusVariantType>
-                            output;
-
-                        output.reserve(16); // The pid interface length
-
-                        // determines if we're patching entity-manager or
-                        // creating a new object
-                        bool createNewObject = (pathItr == managedObj.end());
-                        std::string iface;
-                        if (type == "PidControllers" ||
-                            type == "FanControllers")
-                        {
-                            iface = pidConfigurationIface;
-                            if (!createNewObject &&
-                                pathItr->second.find(pidConfigurationIface) ==
-                                    pathItr->second.end())
-                            {
-                                createNewObject = true;
-                            }
-                        }
-                        else if (type == "FanZones")
-                        {
-                            iface = pidZoneConfigurationIface;
-                            if (!createNewObject &&
-                                pathItr->second.find(
-                                    pidZoneConfigurationIface) ==
-                                    pathItr->second.end())
-                            {
-
-                                createNewObject = true;
-                            }
-                        }
-                        else if (type == "StepwiseControllers")
-                        {
-                            iface = stepwiseConfigurationIface;
-                            if (!createNewObject &&
-                                pathItr->second.find(
-                                    stepwiseConfigurationIface) ==
-                                    pathItr->second.end())
-                            {
-                                createNewObject = true;
-                            }
-                        }
-                        BMCWEB_LOG_DEBUG << "Create new = " << createNewObject
-                                         << "\n";
-                        output["Name"] =
-                            boost::replace_all_copy(name, "_", " ");
-
-                        std::string chassis;
-                        CreatePIDRet ret = createPidInterface(
-                            response, type, it, pathItr->first.str, managedObj,
-                            createNewObject, output, chassis);
-                        if (ret == CreatePIDRet::fail)
-                        {
-                            return;
-                        }
-                        else if (ret == CreatePIDRet::del)
-                        {
-                            continue;
-                        }
-
-                        if (!createNewObject)
-                        {
-                            for (const auto& property : output)
-                            {
-                                crow::connections::systemBus->async_method_call(
-                                    [response,
-                                     propertyName{std::string(property.first)}](
-                                        const boost::system::error_code ec) {
-                                        if (ec)
-                                        {
-                                            BMCWEB_LOG_ERROR
-                                                << "Error patching "
-                                                << propertyName << ": " << ec;
-                                            messages::internalError(
-                                                response->res);
-                                            return;
-                                        }
-                                        messages::success(response->res);
-                                    },
-                                    "xyz.openbmc_project.EntityManager",
-                                    pathItr->first.str,
-                                    "org.freedesktop.DBus.Properties", "Set",
-                                    iface, property.first, property.second);
-                            }
-                        }
-                        else
-                        {
-                            if (chassis.empty())
-                            {
-                                BMCWEB_LOG_ERROR
-                                    << "Failed to get chassis from config";
-                                messages::invalidObject(response->res, name);
-                                return;
-                            }
-
-                            bool foundChassis = false;
-                            for (const auto& obj : managedObj)
-                            {
-                                if (boost::algorithm::ends_with(obj.first.str,
-                                                                chassis))
-                                {
-                                    chassis = obj.first.str;
-                                    foundChassis = true;
-                                    break;
-                                }
-                            }
-                            if (!foundChassis)
-                            {
-                                BMCWEB_LOG_ERROR
-                                    << "Failed to find chassis on dbus";
-                                messages::resourceMissingAtURI(
-                                    response->res,
-                                    "/redfish/v1/Chassis/" + chassis);
-                                return;
-                            }
-
-                            crow::connections::systemBus->async_method_call(
-                                [response](const boost::system::error_code ec) {
-                                    if (ec)
-                                    {
-                                        BMCWEB_LOG_ERROR
-                                            << "Error Adding Pid Object " << ec;
-                                        messages::internalError(response->res);
-                                        return;
-                                    }
-                                    messages::success(response->res);
-                                },
-                                "xyz.openbmc_project.EntityManager", chassis,
-                                "xyz.openbmc_project.AddObject", "AddObject",
-                                output);
-                        }
-                    }
-                }
-            },
-            "xyz.openbmc_project.EntityManager", "/", objectManagerIface,
-            "GetManagedObjects");
+        auto pids = std::make_shared<GetPIDValues>(asyncResp);
+        pids->run();
     }
 
     void doPatch(crow::Response& res, const crow::Request& req,
@@ -1273,7 +1602,8 @@
                 }
                 if (fan)
                 {
-                    setPidValues(response, *fan);
+                    auto pid = std::make_shared<SetPIDValues>(response, *fan);
+                    pid->run();
                 }
             }
         }
