diff --git a/redfish-core/lib/power.hpp b/redfish-core/lib/power.hpp
index a39fab7..2a0f300 100644
--- a/redfish-core/lib/power.hpp
+++ b/redfish-core/lib/power.hpp
@@ -30,314 +30,326 @@
 
 namespace redfish
 {
-inline void setPowerCapOverride(
+
+inline void afterGetPowerCapEnable(
     const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp,
-    std::vector<nlohmann::json>& powerControlCollections)
+    uint32_t valueToSet, const boost::system::error_code& ec,
+    bool powerCapEnable)
 {
-    auto getChassisPath =
-        [sensorsAsyncResp, powerControlCollections](
-            const std::optional<std::string>& chassisPath) mutable {
-        if (!chassisPath)
-        {
-            BMCWEB_LOG_WARNING("Don't find valid chassis path ");
-            messages::resourceNotFound(sensorsAsyncResp->asyncResp->res,
-                                       "Chassis", sensorsAsyncResp->chassisId);
-            return;
-        }
+    if (ec)
+    {
+        messages::internalError(sensorsAsyncResp->asyncResp->res);
+        BMCWEB_LOG_ERROR("powerCapEnable Get handler: Dbus error {}", ec);
+        return;
+    }
+    if (!powerCapEnable)
+    {
+        messages::actionNotSupported(
+            sensorsAsyncResp->asyncResp->res,
+            "Setting LimitInWatts when PowerLimit feature is disabled");
+        BMCWEB_LOG_ERROR("PowerLimit feature is disabled ");
+        return;
+    }
 
-        if (powerControlCollections.size() != 1)
+    sdbusplus::asio::setProperty(
+        *crow::connections::systemBus, "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/control/host0/power_cap",
+        "xyz.openbmc_project.Control.Power.Cap", "PowerCap", valueToSet,
+        [sensorsAsyncResp](const boost::system::error_code& ec2) {
+        if (ec2)
         {
-            BMCWEB_LOG_WARNING("Don't support multiple hosts at present ");
-            messages::resourceNotFound(sensorsAsyncResp->asyncResp->res,
-                                       "Power", "PowerControl");
+            BMCWEB_LOG_DEBUG("Power Limit Set: Dbus error: {}", ec2);
+            messages::internalError(sensorsAsyncResp->asyncResp->res);
             return;
         }
-
-        auto& item = powerControlCollections[0];
-
-        std::optional<nlohmann::json> powerLimit;
-        if (!json_util::readJson(item, sensorsAsyncResp->asyncResp->res,
-                                 "PowerLimit", powerLimit))
-        {
-            return;
-        }
-        if (!powerLimit)
-        {
-            return;
-        }
-        std::optional<uint32_t> value;
-        if (!json_util::readJson(*powerLimit, sensorsAsyncResp->asyncResp->res,
-                                 "LimitInWatts", value))
-        {
-            return;
-        }
-        if (!value)
-        {
-            return;
-        }
-        sdbusplus::asio::getProperty<bool>(
-            *crow::connections::systemBus, "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/control/host0/power_cap",
-            "xyz.openbmc_project.Control.Power.Cap", "PowerCapEnable",
-            [value, sensorsAsyncResp](const boost::system::error_code& ec,
-                                      bool powerCapEnable) {
-            if (ec)
-            {
-                messages::internalError(sensorsAsyncResp->asyncResp->res);
-                BMCWEB_LOG_ERROR("powerCapEnable Get handler: Dbus error {}",
-                                 ec);
-                return;
-            }
-            if (!powerCapEnable)
-            {
-                messages::actionNotSupported(
-                    sensorsAsyncResp->asyncResp->res,
-                    "Setting LimitInWatts when PowerLimit feature is disabled");
-                BMCWEB_LOG_ERROR("PowerLimit feature is disabled ");
-                return;
-            }
-
-            sdbusplus::asio::setProperty(
-                *crow::connections::systemBus, "xyz.openbmc_project.Settings",
-                "/xyz/openbmc_project/control/host0/power_cap",
-                "xyz.openbmc_project.Control.Power.Cap", "PowerCap", *value,
-                [sensorsAsyncResp](const boost::system::error_code& ec2) {
-                if (ec2)
-                {
-                    BMCWEB_LOG_DEBUG("Power Limit Set: Dbus error: {}", ec2);
-                    messages::internalError(sensorsAsyncResp->asyncResp->res);
-                    return;
-                }
-                sensorsAsyncResp->asyncResp->res.result(
-                    boost::beast::http::status::no_content);
-            });
-        });
-    };
-    redfish::chassis_utils::getValidChassisPath(sensorsAsyncResp->asyncResp,
-                                                sensorsAsyncResp->chassisId,
-                                                std::move(getChassisPath));
+        sensorsAsyncResp->asyncResp->res.result(
+            boost::beast::http::status::no_content);
+    });
 }
+
+inline void afterGetChassisPath(
+    const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp,
+    std::vector<nlohmann::json>& powerControlCollections,
+    const std::optional<std::string>& chassisPath)
+{
+    if (!chassisPath)
+    {
+        BMCWEB_LOG_WARNING("Don't find valid chassis path ");
+        messages::resourceNotFound(sensorsAsyncResp->asyncResp->res, "Chassis",
+                                   sensorsAsyncResp->chassisId);
+        return;
+    }
+
+    if (powerControlCollections.size() != 1)
+    {
+        BMCWEB_LOG_WARNING("Don't support multiple hosts at present ");
+        messages::resourceNotFound(sensorsAsyncResp->asyncResp->res, "Power",
+                                   "PowerControl");
+        return;
+    }
+
+    auto& item = powerControlCollections[0];
+
+    std::optional<nlohmann::json> powerLimit;
+    if (!json_util::readJson(item, sensorsAsyncResp->asyncResp->res,
+                             "PowerLimit", powerLimit))
+    {
+        return;
+    }
+    if (!powerLimit)
+    {
+        return;
+    }
+    std::optional<uint32_t> value;
+    if (!json_util::readJson(*powerLimit, sensorsAsyncResp->asyncResp->res,
+                             "LimitInWatts", value))
+    {
+        return;
+    }
+    if (!value)
+    {
+        return;
+    }
+    sdbusplus::asio::getProperty<bool>(
+        *crow::connections::systemBus, "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/control/host0/power_cap",
+        "xyz.openbmc_project.Control.Power.Cap", "PowerCapEnable",
+        std::bind_front(afterGetPowerCapEnable, sensorsAsyncResp, *value));
+}
+
+inline void afterPowerCapSettingGet(
+    const std::shared_ptr<SensorsAsyncResp>& sensorAsyncResp,
+    const boost::system::error_code& ec,
+    const dbus::utility::DBusPropertiesMap& properties)
+{
+    if (ec)
+    {
+        messages::internalError(sensorAsyncResp->asyncResp->res);
+        BMCWEB_LOG_ERROR("Power Limit GetAll handler: Dbus error {}", ec);
+        return;
+    }
+
+    nlohmann::json& tempArray =
+        sensorAsyncResp->asyncResp->res.jsonValue["PowerControl"];
+
+    // Put multiple "sensors" into a single PowerControl, 0,
+    // so only create the first one
+    if (tempArray.empty())
+    {
+        // Mandatory properties odata.id and MemberId
+        // A warning without a odata.type
+        nlohmann::json::object_t powerControl;
+        powerControl["@odata.type"] = "#Power.v1_0_0.PowerControl";
+        powerControl["@odata.id"] = "/redfish/v1/Chassis/" +
+                                    sensorAsyncResp->chassisId +
+                                    "/Power#/PowerControl/0";
+        powerControl["Name"] = "Chassis Power Control";
+        powerControl["MemberId"] = "0";
+        tempArray.emplace_back(std::move(powerControl));
+    }
+
+    nlohmann::json& sensorJson = tempArray.back();
+    bool enabled = false;
+    double powerCap = 0.0;
+    int64_t scale = 0;
+
+    for (const std::pair<std::string, dbus::utility::DbusVariantType>&
+             property : properties)
+    {
+        if (property.first == "Scale")
+        {
+            const int64_t* i = std::get_if<int64_t>(&property.second);
+
+            if (i != nullptr)
+            {
+                scale = *i;
+            }
+        }
+        else if (property.first == "PowerCap")
+        {
+            const double* d = std::get_if<double>(&property.second);
+            const int64_t* i = std::get_if<int64_t>(&property.second);
+            const uint32_t* u = std::get_if<uint32_t>(&property.second);
+
+            if (d != nullptr)
+            {
+                powerCap = *d;
+            }
+            else if (i != nullptr)
+            {
+                powerCap = static_cast<double>(*i);
+            }
+            else if (u != nullptr)
+            {
+                powerCap = *u;
+            }
+        }
+        else if (property.first == "PowerCapEnable")
+        {
+            const bool* b = std::get_if<bool>(&property.second);
+
+            if (b != nullptr)
+            {
+                enabled = *b;
+            }
+        }
+    }
+
+    // LimitException is Mandatory attribute as per OCP
+    // Baseline Profile – v1.0.0, so currently making it
+    // "NoAction" as default value to make it OCP Compliant.
+    sensorJson["PowerLimit"]["LimitException"] = "NoAction";
+
+    if (enabled)
+    {
+        // Redfish specification indicates PowerLimit should
+        // be null if the limit is not enabled.
+        sensorJson["PowerLimit"]["LimitInWatts"] = powerCap *
+                                                   std::pow(10, scale);
+    }
+}
+
+using Mapper = dbus::utility::MapperGetSubTreePathsResponse;
+inline void
+    afterGetChassis(const std::shared_ptr<SensorsAsyncResp>& sensorAsyncResp,
+                    const boost::system::error_code& ec2,
+                    const Mapper& chassisPaths)
+{
+    if (ec2)
+    {
+        BMCWEB_LOG_ERROR("Power Limit GetSubTreePaths handler Dbus error {}",
+                         ec2);
+        return;
+    }
+
+    bool found = false;
+    for (const std::string& chassis : chassisPaths)
+    {
+        size_t len = std::string::npos;
+        size_t lastPos = chassis.rfind('/');
+        if (lastPos == std::string::npos)
+        {
+            continue;
+        }
+
+        if (lastPos == chassis.size() - 1)
+        {
+            size_t end = lastPos;
+            lastPos = chassis.rfind('/', lastPos - 1);
+            if (lastPos == std::string::npos)
+            {
+                continue;
+            }
+
+            len = end - (lastPos + 1);
+        }
+
+        std::string interfaceChassisName = chassis.substr(lastPos + 1, len);
+        if (interfaceChassisName == sensorAsyncResp->chassisId)
+        {
+            found = true;
+            break;
+        }
+    }
+
+    if (!found)
+    {
+        BMCWEB_LOG_DEBUG("Power Limit not present for {}",
+                         sensorAsyncResp->chassisId);
+        return;
+    }
+
+    sdbusplus::asio::getAllProperties(
+        *crow::connections::systemBus, "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/control/host0/power_cap",
+        "xyz.openbmc_project.Control.Power.Cap",
+        [sensorAsyncResp](const boost::system::error_code& ec,
+                          const dbus::utility::DBusPropertiesMap& properties
+
+        ) { afterPowerCapSettingGet(sensorAsyncResp, ec, properties); });
+}
+
+inline void
+    handleChassisPowerGet(App& app, const crow::Request& req,
+                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                          const std::string& chassisName)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    asyncResp->res.jsonValue["PowerControl"] = nlohmann::json::array();
+
+    auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
+        asyncResp, chassisName, sensors::dbus::powerPaths,
+        sensors::node::power);
+
+    getChassisData(sensorAsyncResp);
+
+    // This callback verifies that the power limit is only provided
+    // for the chassis that implements the Chassis inventory item.
+    // This prevents things like power supplies providing the
+    // chassis power limit
+
+    constexpr std::array<std::string_view, 2> interfaces = {
+        "xyz.openbmc_project.Inventory.Item.Board",
+        "xyz.openbmc_project.Inventory.Item.Chassis"};
+
+    dbus::utility::getSubTreePaths(
+        "/xyz/openbmc_project/inventory", 0, interfaces,
+        std::bind_front(afterGetChassis, sensorAsyncResp));
+}
+
+inline void
+    handleChassisPowerPatch(App& app, const crow::Request& req,
+                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                            const std::string& chassisName)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
+        asyncResp, chassisName, sensors::dbus::powerPaths,
+        sensors::node::power);
+
+    std::optional<std::vector<nlohmann::json>> voltageCollections;
+    std::optional<std::vector<nlohmann::json>> powerCtlCollections;
+
+    if (!json_util::readJsonPatch(req, sensorAsyncResp->asyncResp->res,
+                                  "PowerControl", powerCtlCollections,
+                                  "Voltages", voltageCollections))
+    {
+        return;
+    }
+
+    if (powerCtlCollections)
+    {
+        redfish::chassis_utils::getValidChassisPath(
+            sensorAsyncResp->asyncResp, sensorAsyncResp->chassisId,
+            std::bind_front(afterGetChassisPath, sensorAsyncResp,
+                            *powerCtlCollections));
+    }
+    if (voltageCollections)
+    {
+        std::unordered_map<std::string, std::vector<nlohmann::json>>
+            allCollections;
+        allCollections.emplace("Voltages", *std::move(voltageCollections));
+        setSensorsOverride(sensorAsyncResp, allCollections);
+    }
+}
+
 inline void requestRoutesPower(App& app)
 {
     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Power/")
         .privileges(redfish::privileges::getPower)
         .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& chassisName) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        asyncResp->res.jsonValue["PowerControl"] = nlohmann::json::array();
-
-        auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
-            asyncResp, chassisName, sensors::dbus::powerPaths,
-            sensors::node::power);
-
-        getChassisData(sensorAsyncResp);
-
-        // This callback verifies that the power limit is only provided
-        // for the chassis that implements the Chassis inventory item.
-        // This prevents things like power supplies providing the
-        // chassis power limit
-
-        using Mapper = dbus::utility::MapperGetSubTreePathsResponse;
-        auto chassisHandler =
-            [sensorAsyncResp](const boost::system::error_code& ec2,
-                              const Mapper& chassisPaths) {
-            if (ec2)
-            {
-                BMCWEB_LOG_ERROR(
-                    "Power Limit GetSubTreePaths handler Dbus error {}", ec2);
-                return;
-            }
-
-            bool found = false;
-            for (const std::string& chassis : chassisPaths)
-            {
-                size_t len = std::string::npos;
-                size_t lastPos = chassis.rfind('/');
-                if (lastPos == std::string::npos)
-                {
-                    continue;
-                }
-
-                if (lastPos == chassis.size() - 1)
-                {
-                    size_t end = lastPos;
-                    lastPos = chassis.rfind('/', lastPos - 1);
-                    if (lastPos == std::string::npos)
-                    {
-                        continue;
-                    }
-
-                    len = end - (lastPos + 1);
-                }
-
-                std::string interfaceChassisName = chassis.substr(lastPos + 1,
-                                                                  len);
-                if (interfaceChassisName == sensorAsyncResp->chassisId)
-                {
-                    found = true;
-                    break;
-                }
-            }
-
-            if (!found)
-            {
-                BMCWEB_LOG_DEBUG("Power Limit not present for {}",
-                                 sensorAsyncResp->chassisId);
-                return;
-            }
-
-            auto valueHandler =
-                [sensorAsyncResp](
-                    const boost::system::error_code& ec,
-                    const dbus::utility::DBusPropertiesMap& properties) {
-                if (ec)
-                {
-                    messages::internalError(sensorAsyncResp->asyncResp->res);
-                    BMCWEB_LOG_ERROR(
-                        "Power Limit GetAll handler: Dbus error {}", ec);
-                    return;
-                }
-
-                nlohmann::json& tempArray =
-                    sensorAsyncResp->asyncResp->res.jsonValue["PowerControl"];
-
-                // Put multiple "sensors" into a single PowerControl, 0,
-                // so only create the first one
-                if (tempArray.empty())
-                {
-                    // Mandatory properties odata.id and MemberId
-                    // A warning without a odata.type
-                    nlohmann::json::object_t powerControl;
-                    powerControl["@odata.type"] = "#Power.v1_0_0.PowerControl";
-                    powerControl["@odata.id"] = "/redfish/v1/Chassis/" +
-                                                sensorAsyncResp->chassisId +
-                                                "/Power#/PowerControl/0";
-                    powerControl["Name"] = "Chassis Power Control";
-                    powerControl["MemberId"] = "0";
-                    tempArray.emplace_back(std::move(powerControl));
-                }
-
-                nlohmann::json& sensorJson = tempArray.back();
-                bool enabled = false;
-                double powerCap = 0.0;
-                int64_t scale = 0;
-
-                for (const std::pair<std::string,
-                                     dbus::utility::DbusVariantType>& property :
-                     properties)
-                {
-                    if (property.first == "Scale")
-                    {
-                        const int64_t* i =
-                            std::get_if<int64_t>(&property.second);
-
-                        if (i != nullptr)
-                        {
-                            scale = *i;
-                        }
-                    }
-                    else if (property.first == "PowerCap")
-                    {
-                        const double* d = std::get_if<double>(&property.second);
-                        const int64_t* i =
-                            std::get_if<int64_t>(&property.second);
-                        const uint32_t* u =
-                            std::get_if<uint32_t>(&property.second);
-
-                        if (d != nullptr)
-                        {
-                            powerCap = *d;
-                        }
-                        else if (i != nullptr)
-                        {
-                            powerCap = static_cast<double>(*i);
-                        }
-                        else if (u != nullptr)
-                        {
-                            powerCap = *u;
-                        }
-                    }
-                    else if (property.first == "PowerCapEnable")
-                    {
-                        const bool* b = std::get_if<bool>(&property.second);
-
-                        if (b != nullptr)
-                        {
-                            enabled = *b;
-                        }
-                    }
-                }
-
-                // LimitException is Mandatory attribute as per OCP
-                // Baseline Profile – v1.0.0, so currently making it
-                // "NoAction" as default value to make it OCP Compliant.
-                sensorJson["PowerLimit"]["LimitException"] = "NoAction";
-
-                if (enabled)
-                {
-                    // Redfish specification indicates PowerLimit should
-                    // be null if the limit is not enabled.
-                    sensorJson["PowerLimit"]["LimitInWatts"] =
-                        powerCap * std::pow(10, scale);
-                }
-            };
-
-            sdbusplus::asio::getAllProperties(
-                *crow::connections::systemBus, "xyz.openbmc_project.Settings",
-                "/xyz/openbmc_project/control/host0/power_cap",
-                "xyz.openbmc_project.Control.Power.Cap",
-                std::move(valueHandler));
-        };
-
-        constexpr std::array<std::string_view, 2> interfaces = {
-            "xyz.openbmc_project.Inventory.Item.Board",
-            "xyz.openbmc_project.Inventory.Item.Chassis"};
-
-        dbus::utility::getSubTreePaths("/xyz/openbmc_project/inventory", 0,
-                                       interfaces, std::move(chassisHandler));
-    });
+            std::bind_front(handleChassisPowerGet, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Power/")
         .privileges(redfish::privileges::patchPower)
         .methods(boost::beast::http::verb::patch)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& chassisName) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
-            asyncResp, chassisName, sensors::dbus::powerPaths,
-            sensors::node::power);
-
-        std::optional<std::vector<nlohmann::json>> voltageCollections;
-        std::optional<std::vector<nlohmann::json>> powerCtlCollections;
-
-        if (!json_util::readJsonPatch(req, sensorAsyncResp->asyncResp->res,
-                                      "PowerControl", powerCtlCollections,
-                                      "Voltages", voltageCollections))
-        {
-            return;
-        }
-
-        if (powerCtlCollections)
-        {
-            setPowerCapOverride(sensorAsyncResp, *powerCtlCollections);
-        }
-        if (voltageCollections)
-        {
-            std::unordered_map<std::string, std::vector<nlohmann::json>>
-                allCollections;
-            allCollections.emplace("Voltages", *std::move(voltageCollections));
-            setSensorsOverride(sensorAsyncResp, allCollections);
-        }
-    });
+            std::bind_front(handleChassisPowerPatch, std::ref(app)));
 }
 
 } // namespace redfish
