diff --git a/control/Makefile.am b/control/Makefile.am
index 3cd2c0a..4f68e80 100644
--- a/control/Makefile.am
+++ b/control/Makefile.am
@@ -88,6 +88,7 @@
 	json/actions/set_parameter_from_group_max.cpp \
 	json/actions/count_state_floor.cpp \
 	json/actions/get_managed_objects.cpp \
+	json/actions/pcie_card_floors.cpp \
 	json/utils/flight_recorder.cpp \
 	json/utils/modifier.cpp \
 	json/utils/pcie_card_metadata.cpp
diff --git a/control/json/actions/pcie_card_floors.cpp b/control/json/actions/pcie_card_floors.cpp
new file mode 100644
index 0000000..512c678
--- /dev/null
+++ b/control/json/actions/pcie_card_floors.cpp
@@ -0,0 +1,271 @@
+/**
+ * Copyright © 2021 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 "pcie_card_floors.hpp"
+
+#include "../manager.hpp"
+#include "json_config.hpp"
+#include "sdbusplus.hpp"
+#include "sdeventplus.hpp"
+
+namespace phosphor::fan::control::json
+{
+
+constexpr auto floorIndexParam = "pcie_floor_index";
+constexpr auto pcieDeviceIface =
+    "xyz.openbmc_project.Inventory.Item.PCIeDevice";
+constexpr auto powerStateIface =
+    "xyz.openbmc_project.State.Decorator.PowerState";
+constexpr auto deviceIDProp = "Function0DeviceId";
+constexpr auto vendorIDProp = "Function0VendorId";
+constexpr auto subsystemIDProp = "Function0SubsystemId";
+constexpr auto subsystemVendorIDProp = "Function0SubsystemVendorId";
+
+PCIeCardFloors::PCIeCardFloors(const json& jsonObj,
+                               const std::vector<Group>& groups) :
+    ActionBase(jsonObj, groups)
+{
+    loadCardJSON(jsonObj);
+}
+
+void PCIeCardFloors::run(Zone& zone)
+{
+    if (_settleTimer)
+    {
+        _settleTimer->setEnabled(false);
+    }
+    else
+    {
+        _settleTimer =
+            std::make_unique<Timer>(util::SDEventPlus::getEvent(),
+                                    [&zone, this](Timer&) { execute(zone); });
+    }
+    _settleTimer->restartOnce(_settleTime);
+}
+
+void PCIeCardFloors::execute(Zone& zone)
+{
+    size_t hotCards = 0;
+    size_t numTempSensorCards = 0;
+    size_t uninterestingCards = 0;
+    int32_t floorIndex = -1;
+
+    for (const auto& group : _groups)
+    {
+        if (group.getInterface() != powerStateIface)
+        {
+            log<level::DEBUG>(
+                fmt::format("Wrong interface {} in PCIe card floor group",
+                            group.getInterface())
+                    .c_str());
+            continue;
+        }
+
+        for (const auto& slotPath : group.getMembers())
+        {
+            PropertyVariantType powerState;
+
+            try
+            {
+                powerState = Manager::getObjValueVariant(
+                    slotPath, group.getInterface(), group.getProperty());
+            }
+            catch (const std::out_of_range& oore)
+            {
+                log<level::ERR>(
+                    fmt::format("Could not get power state for {}", slotPath)
+                        .c_str());
+                continue;
+            }
+
+            if (std::get<std::string>(powerState) !=
+                "xyz.openbmc_project.State.Decorator.PowerState.State.On")
+            {
+                continue;
+            }
+
+            auto floorIndexOrTempSensor = getFloorIndexFromSlot(slotPath);
+            if (floorIndexOrTempSensor)
+            {
+                if (std::holds_alternative<int32_t>(*floorIndexOrTempSensor))
+                {
+                    hotCards++;
+                    floorIndex = std::max(
+                        floorIndex, std::get<int32_t>(*floorIndexOrTempSensor));
+                }
+                else
+                {
+                    numTempSensorCards++;
+                }
+            }
+            else
+            {
+                uninterestingCards++;
+            }
+        }
+    }
+
+    auto status = fmt::format(
+        "Found {} hot cards, {} with temp sensors, {} uninteresting", hotCards,
+        numTempSensorCards, uninterestingCards);
+    if (status != _lastStatus)
+    {
+        record(status);
+        _lastStatus = status;
+    }
+
+    int32_t origIndex = -1;
+    auto origIndexVariant = Manager::getParameter(floorIndexParam);
+    if (origIndexVariant)
+    {
+        origIndex = std::get<int32_t>(*origIndexVariant);
+    }
+
+    if (floorIndex != -1)
+    {
+        if (origIndex != floorIndex)
+        {
+            record(fmt::format("Setting {} parameter to {}", floorIndexParam,
+                               floorIndex));
+            Manager::setParameter(floorIndexParam, floorIndex);
+        }
+    }
+    else if (origIndexVariant)
+    {
+        record(fmt::format("Removing parameter {}", floorIndexParam));
+        Manager::setParameter(floorIndexParam, std::nullopt);
+    }
+}
+
+void PCIeCardFloors::loadCardJSON(const json& jsonObj)
+{
+    std::string baseConfigFile;
+    bool useConfigSpecificFiles = false;
+
+    if (jsonObj.contains("settle_time"))
+    {
+        _settleTime =
+            std::chrono::seconds(jsonObj.at("settle_time").get<size_t>());
+    }
+
+    if (jsonObj.contains("use_config_specific_files"))
+    {
+        useConfigSpecificFiles =
+            jsonObj.at("use_config_specific_files").get<bool>();
+    }
+
+    std::vector<std::string> names;
+    if (useConfigSpecificFiles)
+    {
+        names = phosphor::fan::JsonConfig::getCompatValues();
+    }
+
+    _cardMetadata = std::make_unique<PCIeCardMetadata>(names);
+}
+
+uint16_t PCIeCardFloors::getPCIeDeviceProperty(const std::string& objectPath,
+                                               const std::string& propertyName)
+{
+    PropertyVariantType variantValue;
+    uint16_t value{};
+
+    try
+    {
+        variantValue = Manager::getObjValueVariant(objectPath, pcieDeviceIface,
+                                                   propertyName);
+    }
+    catch (const std::out_of_range& oore)
+    {
+        log<level::ERR>(
+            fmt::format(
+                "{}: Could not get PCIeDevice property {} {} from cache ",
+                ActionBase::getName(), objectPath, propertyName)
+                .c_str());
+        throw;
+    }
+
+    try
+    {
+        value = std::stoul(std::get<std::string>(variantValue), nullptr, 0);
+        return value;
+    }
+    catch (const std::invalid_argument& e)
+    {
+        log<level::INFO>(
+            fmt::format("{}: {} has invalid PCIeDevice property {} value: {}",
+                        ActionBase::getName(), objectPath, propertyName,
+                        std::get<std::string>(variantValue))
+                .c_str());
+        throw;
+    }
+}
+
+std::optional<std::variant<int32_t, bool>>
+    PCIeCardFloors::getFloorIndexFromSlot(const std::string& slotPath)
+{
+    const auto& card = getCardFromSlot(slotPath);
+
+    try
+    {
+        auto deviceID = getPCIeDeviceProperty(card, deviceIDProp);
+        auto vendorID = getPCIeDeviceProperty(card, vendorIDProp);
+        auto subsystemID = getPCIeDeviceProperty(card, subsystemIDProp);
+        auto subsystemVendorID =
+            getPCIeDeviceProperty(card, subsystemVendorIDProp);
+
+        return _cardMetadata->lookup(deviceID, vendorID, subsystemID,
+                                     subsystemVendorID);
+    }
+    catch (const std::exception& e)
+    {}
+
+    return std::nullopt;
+}
+
+const std::string& PCIeCardFloors::getCardFromSlot(const std::string& slotPath)
+{
+    auto cardIt = _cards.find(slotPath);
+
+    if (cardIt != _cards.end())
+    {
+        return cardIt->second;
+    }
+
+    // Just the first time, find all the PCIeDevice objects
+    if (_pcieDevices.empty())
+    {
+        _pcieDevices = util::SDBusPlus::getSubTreePaths(
+            util::SDBusPlus::getBus(), "/", pcieDeviceIface, 0);
+    }
+
+    // Find the card that plugs in this slot based on if the
+    // slot is part of the path, like slotA/cardA
+    auto it = std::find_if(
+        _pcieDevices.begin(), _pcieDevices.end(), [slotPath](const auto& path) {
+            return path.find(slotPath + '/') != std::string::npos;
+        });
+
+    if (it == _pcieDevices.end())
+    {
+        throw std::runtime_error(fmt::format(
+            "Could not find PCIe card object path for slot {}", slotPath));
+    }
+
+    _cards.emplace(slotPath, *it);
+
+    return _cards.at(slotPath);
+}
+
+} // namespace phosphor::fan::control::json
diff --git a/control/json/actions/pcie_card_floors.hpp b/control/json/actions/pcie_card_floors.hpp
new file mode 100644
index 0000000..d3b5710
--- /dev/null
+++ b/control/json/actions/pcie_card_floors.hpp
@@ -0,0 +1,170 @@
+/**
+ * Copyright © 2021 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 "../zone.hpp"
+#include "action.hpp"
+#include "group.hpp"
+#include "utils/pcie_card_metadata.hpp"
+
+#include <nlohmann/json.hpp>
+
+namespace phosphor::fan::control::json
+{
+
+using json = nlohmann::json;
+
+class Manager;
+
+/**
+ * @class PCIeCardFloors - Action to set the PCIe card floor index parameter
+ *                          based on the PCIe cards plugged in the system.
+ *
+ *  - Loads PCIe card metadata files using the PCIeCardMetadata class.
+ *  - Watches for PCIe slots to be powered on (or off).
+ *  - Reads four properties off of the PCIeDevice interface on the powered
+ *    on cards.
+ *  - Looks up the floor index for the card by calling PCIeCardMetadata::lookup
+ *    and passing in the PCIeDevice properties.
+ *  - Sets the pcie_floor_index parameter with the highest floor index found.
+ *  - If no PCIe cards are found, it removes the parameter.
+ *  - If a card isn't recognized, it's ignored since it isn't considered a
+ *    hot card.
+ *  - If a powered on card has its own temperature sensor, then it doesn't
+ *    have a floor index.
+ *  - Since the slot powered on indications are all sent at once, it has a
+ *    small delay that gets started in each run() call that must expire
+ *    before the body of the action is run, so it only runs once.
+ *
+ *    The JSON configuration has two entries:
+ *    {
+ *       "settle_time": <time in s>
+ *       "use_config_specific_files": <true/false>
+ *    }
+ *
+ *    settle_time:
+ *      - Specifies how long to wait after run() is called before actually
+ *        running the action as a flurry of propertiesChanged signals
+ *        that trigger the action tend to come at once.
+ *      - Optional.  If not specified it defaults to zero.
+ *
+ *    use_config_specific_files:
+ *      - If true, will look for 'pcie_cards.json' files in the system
+ *        specific directories.
+ *      - See PCIeCardMetadata for details.
+ */
+class PCIeCardFloors : public ActionBase, public ActionRegister<PCIeCardFloors>
+{
+  public:
+    /* Name of this action */
+    static constexpr auto name = "pcie_card_floors";
+
+    PCIeCardFloors() = delete;
+    PCIeCardFloors(const PCIeCardFloors&) = delete;
+    PCIeCardFloors(PCIeCardFloors&&) = delete;
+    PCIeCardFloors& operator=(const PCIeCardFloors&) = delete;
+    PCIeCardFloors& operator=(PCIeCardFloors&&) = delete;
+    ~PCIeCardFloors() = default;
+
+    /**
+     * @brief Read in the action configuration
+     *
+     * @param[in] jsonObj - JSON configuration of this action
+     * @param[in] groups - Groups of dbus objects the action uses
+     */
+    PCIeCardFloors(const json& jsonObj, const std::vector<Group>& groups);
+
+    /**
+     * @brief Run the action.
+     *
+     * Starts/restarts the settle timer and then calls execute()
+     * when it expires.  Done to handle the flood of slot powered
+     * on/off signals.
+     *
+     * @param[in] zone - Zone to run the action on
+     */
+    void run(Zone& zone) override;
+
+  private:
+    /**
+     * @brief Runs the contents of the action when the settle timer expires.
+     *
+     * @param[in] zone - Zone to run the action on
+     */
+    void execute(Zone& zone);
+
+    /**
+     * @brief Constructs the PCIeCardMetadata object to load the PCIe card
+     *        JSON files.
+     *
+     * @param[in] jsonObj - JSON configuration of this action
+     */
+    void loadCardJSON(const json& jsonObj);
+
+    /**
+     * @brief Returns the D-Bus object path of the card plugged into
+     *        the slot represented by the slotPath D-Bus path.
+     *
+     * @param[in] slotPath - The D-Bus path of the PCIe slot object.
+     *
+     * @return const std::string& - The card object path.
+     */
+    const std::string& getCardFromSlot(const std::string& slotPath);
+
+    /**
+     * @brief Returns the floor index (or temp sensor name) for the
+     *        card in the passed in slot.
+     *
+     * @param[in] slotPath - The D-Bus path of the PCIe slot object.
+     *
+     * @return optional<variant<int32_t, string>>
+     *  - The floor index or true for has temp sensor if found,
+     *    std::nullopt else.
+     */
+    std::optional<std::variant<int32_t, bool>>
+        getFloorIndexFromSlot(const std::string& slotPath);
+
+    /**
+     * @brief Gets the hex PCIeDevice property value from the
+     *        manager object cache.
+     *
+     * @param[in] objectPath - The card object path
+     * @param[in] propertyName - The property to read
+     *
+     * @return uint16_t The property value
+     */
+    uint16_t getPCIeDeviceProperty(const std::string& objectPath,
+                                   const std::string& propertyName);
+
+    /* The PCIe card metadata manager */
+    std::unique_ptr<PCIeCardMetadata> _cardMetadata;
+
+    /* Cache map of PCIe slot paths to their plugged card paths */
+    std::unordered_map<std::string, std::string> _cards;
+
+    /* Cache of all objects with a PCIeDevice interface. */
+    std::vector<std::string> _pcieDevices;
+
+    std::chrono::seconds _settleTime{0};
+
+    /* Timer to wait for slot plugs to settle down before running action */
+    std::unique_ptr<Timer> _settleTimer;
+
+    /* Last status printed so only new messages get recorded */
+    std::string _lastStatus;
+};
+
+} // namespace phosphor::fan::control::json
