diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index ce21406..1fb2f69 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -17,31 +17,280 @@
 
 #include "node.hpp"
 
+#include <boost/algorithm/string/replace.hpp>
+#include <dbus_utility.hpp>
+
 namespace redfish
 {
+static constexpr const char* objectManagerIface =
+    "org.freedesktop.DBus.ObjectManager";
+static constexpr const char* pidConfigurationIface =
+    "xyz.openbmc_project.Configuration.Pid";
+static constexpr const char* pidZoneConfigurationIface =
+    "xyz.openbmc_project.Configuration.Pid.Zone";
 
-/**
- * DBus types primitives for several generic DBus interfaces
- * TODO consider move this to separate file into boost::dbus
- */
-using GetManagedObjectsType = boost::container::flat_map<
-    sdbusplus::message::object_path,
-    boost::container::flat_map<
-        std::string,
-        boost::container::flat_map<
-            std::string, sdbusplus::message::variant<
-                             std::string, bool, uint8_t, int16_t, uint16_t,
-                             int32_t, uint32_t, int64_t, uint64_t, double>>>>;
+static void asyncPopulatePid(const std::string& connection,
+                             const std::string& path,
+                             std::shared_ptr<AsyncResp> asyncResp)
+{
+
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec,
+                    const dbus::utility::ManagedObjectType& managedObj) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << ec;
+                asyncResp->res.result(
+                    boost::beast::http::status::internal_server_error);
+                asyncResp->res.jsonValue.clear();
+                return;
+            }
+            nlohmann::json& configRoot =
+                asyncResp->res.jsonValue["Oem"]["OpenBmc"]["Fan"];
+            nlohmann::json& fans = configRoot["FanControllers"];
+            fans["@odata.type"] = "#OemManager.FanControllers";
+            fans["@odata.context"] =
+                "/redfish/v1/$metadata#OemManager.FanControllers";
+            fans["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem/OpenBmc/"
+                                "Fan/FanControllers";
+
+            nlohmann::json& pids = configRoot["PidControllers"];
+            pids["@odata.type"] = "#OemManager.PidControllers";
+            pids["@odata.context"] =
+                "/redfish/v1/$metadata#OemManager.PidControllers";
+            pids["@odata.id"] =
+                "/redfish/v1/Managers/bmc#/Oem/OpenBmc/Fan/PidControllers";
+
+            nlohmann::json& zones = configRoot["FanZones"];
+            zones["@odata.id"] =
+                "/redfish/v1/Managers/bmc#/Oem/OpenBmc/Fan/FanZones";
+            zones["@odata.type"] = "#OemManager.FanZones";
+            zones["@odata.context"] =
+                "/redfish/v1/$metadata#OemManager.FanZones";
+            configRoot["@odata.id"] =
+                "/redfish/v1/Managers/bmc#/Oem/OpenBmc/Fan";
+            configRoot["@odata.type"] = "#OemManager.Fan";
+            configRoot["@odata.context"] =
+                "/redfish/v1/$metadata#OemManager.Fan";
+
+            bool propertyError = false;
+            for (const auto& pathPair : managedObj)
+            {
+                for (const auto& intfPair : pathPair.second)
+                {
+                    if (intfPair.first != pidConfigurationIface &&
+                        intfPair.first != pidZoneConfigurationIface)
+                    {
+                        continue;
+                    }
+                    auto findName = intfPair.second.find("Name");
+                    if (findName == intfPair.second.end())
+                    {
+                        BMCWEB_LOG_ERROR << "Pid Field missing Name";
+                        asyncResp->res.result(
+                            boost::beast::http::status::internal_server_error);
+                        return;
+                    }
+                    const std::string* namePtr =
+                        mapbox::getPtr<const std::string>(findName->second);
+                    if (namePtr == nullptr)
+                    {
+                        BMCWEB_LOG_ERROR << "Pid Name Field illegal";
+                        return;
+                    }
+
+                    std::string name = *namePtr;
+                    dbus::utility::escapePathForDbus(name);
+                    if (intfPair.first == pidZoneConfigurationIface)
+                    {
+                        std::string chassis;
+                        if (!dbus::utility::getNthStringFromPath(
+                                pathPair.first.str, 5, chassis))
+                        {
+                            chassis = "#IllegalValue";
+                        }
+                        nlohmann::json& zone = zones[name];
+                        zone["Chassis"] = {
+                            {"@odata.id", "/redfish/v1/Chassis/" + chassis}};
+                        zone["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem/"
+                                            "OpenBmc/Fan/FanZones/" +
+                                            name;
+                        zone["@odata.type"] = "#OemManager.FanZone";
+                        zone["@odata.context"] =
+                            "/redfish/v1/$metadata#OemManager.FanZone";
+                    }
+
+                    for (const auto& propertyPair : intfPair.second)
+                    {
+                        if (propertyPair.first == "Type" ||
+                            propertyPair.first == "Class" ||
+                            propertyPair.first == "Name")
+                        {
+                            continue;
+                        }
+
+                        // zones
+                        if (intfPair.first == pidZoneConfigurationIface)
+                        {
+                            const double* ptr = mapbox::getPtr<const double>(
+                                propertyPair.second);
+                            if (ptr == nullptr)
+                            {
+                                BMCWEB_LOG_ERROR << "Field Illegal "
+                                                 << propertyPair.first;
+                                asyncResp->res.result(
+                                    boost::beast::http::status::
+                                        internal_server_error);
+                                return;
+                            }
+                            zones[name][propertyPair.first] = *ptr;
+                        }
+
+                        // pid and fans are off the same configuration
+                        if (intfPair.first == pidConfigurationIface)
+                        {
+                            const std::string* classPtr = nullptr;
+                            auto findClass = intfPair.second.find("Class");
+                            if (findClass != intfPair.second.end())
+                            {
+                                classPtr = mapbox::getPtr<const std::string>(
+                                    findClass->second);
+                            }
+                            if (classPtr == nullptr)
+                            {
+                                BMCWEB_LOG_ERROR << "Pid Class Field illegal";
+                                asyncResp->res.result(
+                                    boost::beast::http::status::
+                                        internal_server_error);
+                                return;
+                            }
+                            bool isFan = *classPtr == "fan";
+                            nlohmann::json& element =
+                                isFan ? fans[name] : pids[name];
+                            if (isFan)
+                            {
+                                element["@odata.id"] =
+                                    "/redfish/v1/Managers/bmc#/Oem/"
+                                    "OpenBmc/Fan/FanControllers/" +
+                                    std::string(name);
+                                element["@odata.type"] =
+                                    "#OemManager.FanController";
+
+                                element["@odata.context"] =
+                                    "/redfish/v1/"
+                                    "$metadata#OemManager.FanController";
+                            }
+                            else
+                            {
+                                element["@odata.id"] =
+                                    "/redfish/v1/Managers/bmc#/Oem/"
+                                    "OpenBmc/Fan/PidControllers/" +
+                                    std::string(name);
+                                element["@odata.type"] =
+                                    "#OemManager.PidController";
+                                element["@odata.context"] =
+                                    "/redfish/v1/$metadata"
+                                    "#OemManager.PidController";
+                            }
+
+                            if (propertyPair.first == "Zones")
+                            {
+                                const std::vector<std::string>* inputs =
+                                    mapbox::getPtr<
+                                        const std::vector<std::string>>(
+                                        propertyPair.second);
+
+                                if (inputs == nullptr)
+                                {
+                                    BMCWEB_LOG_ERROR
+                                        << "Zones Pid Field Illegal";
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+                                auto& data = element[propertyPair.first];
+                                data = nlohmann::json::array();
+                                for (std::string itemCopy : *inputs)
+                                {
+                                    dbus::utility::escapePathForDbus(itemCopy);
+                                    data.push_back(
+                                        {{"@odata.id",
+                                          "/redfish/v1/Managers/bmc#/Oem/"
+                                          "OpenBmc/Fan/FanZones/" +
+                                              itemCopy}});
+                                }
+                            }
+                            // todo(james): may never happen, but this
+                            // assumes configuration data referenced in the
+                            // PID config is provided by the same daemon, we
+                            // could add another loop to cover all cases,
+                            // but I'm okay kicking this can down the road a
+                            // bit
+
+                            else if (propertyPair.first == "Inputs" ||
+                                     propertyPair.first == "Outputs")
+                            {
+                                auto& data = element[propertyPair.first];
+                                const std::vector<std::string>* inputs =
+                                    mapbox::getPtr<
+                                        const std::vector<std::string>>(
+                                        propertyPair.second);
+
+                                if (inputs == nullptr)
+                                {
+                                    BMCWEB_LOG_ERROR << "Field Illegal "
+                                                     << propertyPair.first;
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+                                data = *inputs;
+                            } // doubles
+                            else if (propertyPair.first ==
+                                         "FFGainCoefficient" ||
+                                     propertyPair.first == "FFOffCoefficient" ||
+                                     propertyPair.first == "ICoefficient" ||
+                                     propertyPair.first == "ILimitMax" ||
+                                     propertyPair.first == "ILimitMin" ||
+                                     propertyPair.first == "OutLimitMax" ||
+                                     propertyPair.first == "OutLimitMin" ||
+                                     propertyPair.first == "PCoefficient" ||
+                                     propertyPair.first == "SlewNeg" ||
+                                     propertyPair.first == "SlewPos")
+                            {
+                                const double* ptr =
+                                    mapbox::getPtr<const double>(
+                                        propertyPair.second);
+                                if (ptr == nullptr)
+                                {
+                                    BMCWEB_LOG_ERROR << "Field Illegal "
+                                                     << propertyPair.first;
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+                                element[propertyPair.first] = *ptr;
+                            }
+                        }
+                    }
+                }
+            }
+        },
+        connection, path, objectManagerIface, "GetManagedObjects");
+}
 
 class Manager : public Node
 {
   public:
-    Manager(CrowApp &app) : Node(app, "/redfish/v1/Managers/openbmc/")
+    Manager(CrowApp& app) : Node(app, "/redfish/v1/Managers/bmc/")
     {
-        Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc";
+        Node::json["@odata.id"] = "/redfish/v1/Managers/bmc";
         Node::json["@odata.type"] = "#Manager.v1_3_0.Manager";
         Node::json["@odata.context"] = "/redfish/v1/$metadata#Manager.Manager";
-        Node::json["Id"] = "openbmc";
+        Node::json["Id"] = "bmc";
         Node::json["Name"] = "OpenBmc Manager";
         Node::json["Description"] = "Baseboard Management Controller";
         Node::json["PowerState"] = "On";
@@ -51,7 +300,7 @@
                 .systemUuid;
         Node::json["Model"] = "OpenBmc"; // TODO(ed), get model
         Node::json["EthernetInterfaces"] = {
-            {"@odata.id", "/redfish/v1/Managers/openbmc/EthernetInterfaces"}};
+            {"@odata.id", "/redfish/v1/Managers/bmc/EthernetInterfaces"}};
 
         entityPrivileges = {
             {boost::beast::http::verb::get, {{"Login"}}},
@@ -60,20 +309,89 @@
             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+
+        // default oem data
+        nlohmann::json& oem = Node::json["Oem"];
+        nlohmann::json& oemOpenbmc = oem["OpenBmc"];
+        oem["@odata.type"] = "#OemManager.Oem";
+        oem["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem";
+        oem["@odata.context"] = "/redfish/v1/$metadata#OemManager.Oem";
+        oemOpenbmc["@odata.type"] = "#OemManager.OpenBmc";
+        oemOpenbmc["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem/OpenBmc";
+        oemOpenbmc["@odata.context"] =
+            "/redfish/v1/$metadata#OemManager.OpenBmc";
     }
 
   private:
-    void doGet(crow::Response &res, const crow::Request &req,
-               const std::vector<std::string> &params) override
+    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;
+                    asyncResp->res.result(
+                        boost::beast::http::status::internal_server_error);
+                    return;
+                }
+
+                // create map of <connection, path to objMgr>>
+                boost::container::flat_map<std::string, std::string>
+                    objectMgrPaths;
+                for (const auto& pathGroup : subtree)
+                {
+                    for (const auto& connectionGroup : pathGroup.second)
+                    {
+                        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)
+                            {
+                                auto findObjMgr =
+                                    objectMgrPaths.find(connectionGroup.first);
+                                if (findObjMgr == objectMgrPaths.end())
+                                {
+                                    BMCWEB_LOG_DEBUG << connectionGroup.first
+                                                     << "Has no Object Manager";
+                                    continue;
+                                }
+                                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*, 3>{pidConfigurationIface,
+                                       pidZoneConfigurationIface,
+                                       objectManagerIface});
+    }
+
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
     {
         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
         asyncResp->res.jsonValue = Node::json;
 
         Node::json["DateTime"] = getDateTime();
         res.jsonValue = Node::json;
+
         crow::connections::systemBus->async_method_call(
             [asyncResp](const boost::system::error_code ec,
-                        const GetManagedObjectsType &resp) {
+                        const dbus::utility::ManagedObjectType& resp) {
                 if (ec)
                 {
                     BMCWEB_LOG_ERROR << "Error while getting Software Version";
@@ -82,9 +400,9 @@
                     return;
                 }
 
-                for (auto &objpath : resp)
+                for (auto& objpath : resp)
                 {
-                    for (auto &interface : objpath.second)
+                    for (auto& interface : objpath.second)
                     {
                         // If interface is xyz.openbmc_project.Software.Version,
                         // this is what we're looking for.
@@ -92,12 +410,12 @@
                             "xyz.openbmc_project.Software.Version")
                         {
                             // Cut out everyting until last "/", ...
-                            const std::string &iface_id = objpath.first;
-                            for (auto &property : interface.second)
+                            const std::string& iface_id = objpath.first;
+                            for (auto& property : interface.second)
                             {
                                 if (property.first == "Version")
                                 {
-                                    const std::string *value =
+                                    const std::string* value =
                                         mapbox::getPtr<const std::string>(
                                             property.second);
                                     if (value == nullptr)
@@ -115,6 +433,12 @@
             "xyz.openbmc_project.Software.BMC.Updater",
             "/xyz/openbmc_project/software",
             "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+        getPidValues(asyncResp);
+    }
+
+    void doPatch(crow::Response& res, const crow::Request& req,
+                 const std::vector<std::string>& params) override
+    {
     }
 
     std::string getDateTime() const
@@ -138,7 +462,7 @@
 class ManagerCollection : public Node
 {
   public:
-    ManagerCollection(CrowApp &app) : Node(app, "/redfish/v1/Managers/")
+    ManagerCollection(CrowApp& app) : Node(app, "/redfish/v1/Managers/")
     {
         Node::json["@odata.id"] = "/redfish/v1/Managers";
         Node::json["@odata.type"] = "#ManagerCollection.ManagerCollection";
@@ -146,8 +470,7 @@
             "/redfish/v1/$metadata#ManagerCollection.ManagerCollection";
         Node::json["Name"] = "Manager Collection";
         Node::json["Members@odata.count"] = 1;
-        Node::json["Members"] = {
-            {{"@odata.id", "/redfish/v1/Managers/openbmc"}}};
+        Node::json["Members"] = {{{"@odata.id", "/redfish/v1/Managers/bmc"}}};
 
         entityPrivileges = {
             {boost::beast::http::verb::get, {{"Login"}}},
@@ -159,8 +482,8 @@
     }
 
   private:
-    void doGet(crow::Response &res, const crow::Request &req,
-               const std::vector<std::string> &params) override
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
     {
         // Collections don't include the static data added by SubRoute because
         // it has a duplicate entry for members
@@ -171,9 +494,8 @@
         res.jsonValue["Name"] = "Manager Collection";
         res.jsonValue["Members@odata.count"] = 1;
         res.jsonValue["Members"] = {
-            {{"@odata.id", "/redfish/v1/Managers/openbmc"}}};
+            {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
         res.end();
     }
 };
-
 } // namespace redfish
