diff --git a/control/Makefile.am b/control/Makefile.am
index 1114b8f..9ae9b47 100644
--- a/control/Makefile.am
+++ b/control/Makefile.am
@@ -54,7 +54,8 @@
 	json/actions/count_state_target.cpp \
 	json/actions/net_target_increase.cpp \
 	json/actions/net_target_decrease.cpp \
-	json/actions/timer_based_actions.cpp
+	json/actions/timer_based_actions.cpp \
+	json/actions/mapped_floor.cpp
 else
 phosphor_fan_control_SOURCES += \
 	argument.cpp \
diff --git a/control/json/actions/mapped_floor.cpp b/control/json/actions/mapped_floor.cpp
new file mode 100644
index 0000000..bca3bf5
--- /dev/null
+++ b/control/json/actions/mapped_floor.cpp
@@ -0,0 +1,297 @@
+/**
+ * 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 "mapped_floor.hpp"
+
+#include "../manager.hpp"
+#include "../zone.hpp"
+#include "group.hpp"
+#include "sdeventplus.hpp"
+
+#include <fmt/format.h>
+
+#include <nlohmann/json.hpp>
+
+#include <algorithm>
+
+namespace phosphor::fan::control::json
+{
+
+using json = nlohmann::json;
+
+MappedFloor::MappedFloor(const json& jsonObj,
+                         const std::vector<Group>& groups) :
+    ActionBase(jsonObj, groups)
+{
+    setKeyGroup(jsonObj);
+    setFloorTable(jsonObj);
+}
+
+const Group* MappedFloor::getGroup(const std::string& name)
+{
+    auto groupIt =
+        find_if(_groups.begin(), _groups.end(),
+                [name](const auto& group) { return name == group.getName(); });
+
+    if (groupIt == _groups.end())
+    {
+        throw ActionParseError{
+            ActionBase::getName(),
+            fmt::format("Group name {} is not a valid group", name)};
+    }
+
+    return &(*groupIt);
+}
+
+void MappedFloor::setKeyGroup(const json& jsonObj)
+{
+    if (!jsonObj.contains("key_group"))
+    {
+        throw ActionParseError{ActionBase::getName(),
+                               "Missing required 'key_group' entry"};
+    }
+    _keyGroup = getGroup(jsonObj["key_group"].get<std::string>());
+}
+
+void MappedFloor::setFloorTable(const json& jsonObj)
+{
+    if (!jsonObj.contains("fan_floors"))
+    {
+        throw ActionParseError{ActionBase::getName(),
+                               "Missing fan_floors JSON entry"};
+    }
+
+    const auto& fanFloors = jsonObj.at("fan_floors");
+
+    for (const auto& floors : fanFloors)
+    {
+        if (!floors.contains("key") || !floors.contains("floors"))
+        {
+            throw ActionParseError{
+                ActionBase::getName(),
+                "Missing key or floors entries in actions/fan_floors JSON"};
+        }
+
+        FanFloors ff;
+        ff.keyValue = getJsonValue(floors["key"]);
+
+        for (const auto& groupEntry : floors["floors"])
+        {
+            if (!groupEntry.contains("group") || !groupEntry.contains("floors"))
+            {
+                throw ActionParseError{ActionBase::getName(),
+                                       "Missing group or floors entries in "
+                                       "actions/fan_floors/floors JSON"};
+            }
+
+            FloorGroup fg;
+            fg.group = getGroup(groupEntry["group"].get<std::string>());
+
+            for (const auto& floorEntry : groupEntry["floors"])
+            {
+                if (!floorEntry.contains("value") ||
+                    !floorEntry.contains("floor"))
+                {
+
+                    throw ActionParseError{
+                        ActionBase::getName(),
+                        "Missing value or floor entries in "
+                        "actions/fan_floors/floors/floors JSON"};
+                }
+
+                auto value = getJsonValue(floorEntry["value"]);
+                auto floor = floorEntry["floor"].get<uint64_t>();
+
+                fg.floorEntries.emplace_back(std::move(value),
+                                             std::move(floor));
+            }
+
+            ff.floorGroups.push_back(std::move(fg));
+        }
+
+        _fanFloors.push_back(std::move(ff));
+    }
+}
+
+/**
+ * @brief Converts the variant to a double if it's a
+ *        int32_t or int64_t.
+ */
+void tryConvertToDouble(PropertyVariantType& value)
+{
+    std::visit(
+        [&value](auto&& val) {
+            using V = std::decay_t<decltype(val)>;
+            if constexpr (std::is_same_v<int32_t, V> ||
+                          std::is_same_v<int64_t, V>)
+            {
+                value = static_cast<double>(val);
+            }
+        },
+        value);
+}
+
+std::optional<PropertyVariantType>
+    MappedFloor::getMaxGroupValue(const Group& group, const Manager& manager)
+{
+    std::optional<PropertyVariantType> max;
+    bool checked = false;
+
+    for (const auto& member : group.getMembers())
+    {
+        try
+        {
+            auto value = Manager::getObjValueVariant(
+                member, group.getInterface(), group.getProperty());
+
+            // Only allow a group to have multiple members if it's numeric.
+            // Unlike std::is_arithmetic, bools are not considered numeric here.
+            if (!checked && (group.getMembers().size() > 1))
+            {
+                std::visit(
+                    [&group, this](auto&& val) {
+                        using V = std::decay_t<decltype(val)>;
+                        if constexpr (!std::is_same_v<double, V> &&
+                                      !std::is_same_v<int32_t, V> &&
+                                      !std::is_same_v<int64_t, V>)
+                        {
+                            throw std::runtime_error{fmt::format(
+                                "{}: Group {} has more than one member but "
+                                "isn't numeric",
+                                ActionBase::getName(), group.getName())};
+                        }
+                    },
+                    value);
+                checked = true;
+            }
+
+            if (max && (value > max))
+            {
+                max = value;
+            }
+            else if (!max)
+            {
+                max = value;
+            }
+        }
+        catch (const std::out_of_range& e)
+        {
+            // Property not there, continue on
+        }
+    }
+
+    if (max)
+    {
+        tryConvertToDouble(*max);
+    }
+
+    return max;
+}
+
+void MappedFloor::run(Zone& zone)
+{
+    std::optional<uint64_t> newFloor;
+    bool missingGroupProperty = false;
+    auto& manager = *zone.getManager();
+
+    auto keyValue = getMaxGroupValue(*_keyGroup, manager);
+    if (!keyValue)
+    {
+        zone.setFloor(zone.getDefaultFloor());
+        return;
+    }
+
+    for (const auto& floorTable : _fanFloors)
+    {
+        // First, find the floorTable entry to use based on the key value.
+        auto tableKeyValue = floorTable.keyValue;
+
+        // Convert numeric values from the JSON to doubles so they can
+        // be compared to values coming from D-Bus.
+        tryConvertToDouble(tableKeyValue);
+
+        // The key value from D-Bus must be less than the value
+        // in the table for this entry to be valid.
+        if (*keyValue >= tableKeyValue)
+        {
+            continue;
+        }
+
+        // Now check each group in the tables
+        for (const auto& [group, floorGroups] : floorTable.floorGroups)
+        {
+            auto propertyValue = getMaxGroupValue(*group, manager);
+            if (!propertyValue)
+            {
+                // Couldn't successfully get a value.  Results in default floor.
+                missingGroupProperty = true;
+                break;
+            }
+
+            // Do either a <= or an == check depending on the data type to get
+            // the floor value based on this group.
+            std::optional<uint64_t> floor;
+            for (const auto& [tableValue, tableFloor] : floorGroups)
+            {
+                PropertyVariantType value{tableValue};
+                tryConvertToDouble(value);
+
+                if (std::holds_alternative<double>(*propertyValue))
+                {
+                    if (*propertyValue <= value)
+                    {
+                        floor = tableFloor;
+                        break;
+                    }
+                }
+                else if (*propertyValue == value)
+                {
+                    floor = tableFloor;
+                    break;
+                }
+            }
+
+            // Keep track of the highest floor value found across all
+            // entries/groups
+            if (floor)
+            {
+                if ((newFloor && (floor > *newFloor)) || !newFloor)
+                {
+                    newFloor = floor;
+                }
+            }
+            else
+            {
+                // No match found in this group's table.
+                // Results in default floor.
+                missingGroupProperty = true;
+            }
+        }
+
+        // Valid key value for this entry, so done
+        break;
+    }
+
+    if (newFloor && !missingGroupProperty)
+    {
+        zone.setFloor(*newFloor);
+    }
+    else
+    {
+        zone.setFloor(zone.getDefaultFloor());
+    }
+}
+
+} // namespace phosphor::fan::control::json
diff --git a/control/json/actions/mapped_floor.hpp b/control/json/actions/mapped_floor.hpp
new file mode 100644
index 0000000..baf2701
--- /dev/null
+++ b/control/json/actions/mapped_floor.hpp
@@ -0,0 +1,194 @@
+/**
+ * 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 <nlohmann/json.hpp>
+
+namespace phosphor::fan::control::json
+{
+
+using json = nlohmann::json;
+
+/**
+ * @class MappedFloor - Action to set a fan floor based on ranges of
+ *                      multiple sensor values.
+ * For example, consider the following config:
+ *
+ *    {
+ *    "name": "mapped_floor",
+ *    "key_group": "ambient_temp",
+ *    "fan_floors": [
+ *        {
+ *        "key": 27,
+ *        "floors": [
+ *          {
+ *            "group": "altitude",
+ *            "floors": [
+ *               {
+ *                 "value": 5000,
+ *                 "floor": 4500
+ *               }
+ *            ]
+ *          },
+ *          {
+ *            "group": "power_mode",
+ *            "floors": [
+ *               {
+ *                 "value": "MaximumPerformance",
+ *                 "floor": 5000
+ *               }
+ *            ]
+ *          }
+ *        ]
+ *        }
+ *      ]
+ *    }
+ *
+ * When it runs, it will:
+ *
+ * 1. Evaluate the key_group
+ *   - Find the max D-Bus property value (if numeric) of the member properties
+ *     in this group.
+ *   - Check it against each 'key' value in the fan_floor entries until
+ *     the key_group property value < key value, so:
+ *        max ambient temp < 27.
+ *   - If the above check passes, the rest of that entry will be evaluated
+ *     and then the action will be done.
+ *
+ * 2. Evaluate the group values in each floors array entry for this key value.
+ *   - Find the max D-Bus property value (if numeric) of the member properties
+ *     of this group - in this case 'altitude'.
+ *   - Depending on the data type of that group, compare to the 'value' entry:
+ *     - If numeric, check if the group's value is <= the 'value' one
+ *     - Otherwise, check if it is ==
+ *   - If that passes, save the value from the 'floor' entry and continue to
+ *     the next entry in the floors array, which, if present, would specify
+ *     another group to check.  In this case, 'power_mode'.  Repeat the above
+ *     step.
+ *   - After all the group compares are done, choose the largest floor value
+ *     to set the fan floor to.  If any group check results doesn't end in
+ *     a match being found, then the default floor will be set.
+ *
+ * Cases where the default floor will be set:
+ *  - A table entry can't be found based on a key group's value.
+ *  - A table entry can't be found based on a group's value.
+ *  - A value can't be obtained for the 'key_group' D-Bus property group.
+ *  - A value can't be obtained for any of the 'group' property groups.
+ *  - A value is NaN, as no <, <=, or == checks would succeed.
+ *
+ * Other notes:
+ *  - If a group has multiple members, they must be numeric or else
+ *    the code will throw an exception.
+ */
+
+class MappedFloor : public ActionBase, public ActionRegister<MappedFloor>
+{
+  public:
+    /* Name of this action */
+    static constexpr auto name = "mapped_floor";
+
+    MappedFloor() = delete;
+    MappedFloor(const MappedFloor&) = delete;
+    MappedFloor(MappedFloor&&) = delete;
+    MappedFloor& operator=(const MappedFloor&) = delete;
+    MappedFloor& operator=(MappedFloor&&) = delete;
+    ~MappedFloor() = default;
+
+    /**
+     * @brief Parse the JSON to set the members
+     *
+     * @param[in] jsonObj - JSON configuration of this action
+     * @param[in] groups - Groups of dbus objects the action uses
+     */
+    MappedFloor(const json& jsonObj, const std::vector<Group>& groups);
+
+    /**
+     * @brief Run the action.  See description above.
+     *
+     * @param[in] zone - Zone to run the action on
+     */
+    void run(Zone& zone) override;
+
+  private:
+    /**
+     * @brief Parse and set the key group
+     *
+     * @param[in] jsonObj - JSON object for the action
+     */
+    void setKeyGroup(const json& jsonObj);
+
+    /**
+     * @brief Parses and sets the floor group data members
+     *
+     * @param[in] jsonObj - JSON object for the action
+     */
+    void setFloorTable(const json& jsonObj);
+
+    /**
+     * @brief Determines the maximum value of the property specified
+     *        for the group of all members in the group.
+     *
+     * If not numeric, and more than one member, will throw an exception.
+     * Converts numeric values to doubles so they can be compared later.
+     *
+     * If cannot get at least one valid value, returns std::nullopt.
+     *
+     * @param[in] group - The group to get the max value of
+     *
+     * @param[in] manager - The Manager object
+     *
+     * @return optional<PropertyVariantType> - The value, or std::nullopt
+     */
+    std::optional<PropertyVariantType> getMaxGroupValue(const Group& group,
+                                                        const Manager& manager);
+
+    /**
+     * @brief Returns a pointer to the group object specified
+     *
+     * Throws ActionParseError if no group found
+     *
+     * @param[in] name - The group name
+     *
+     * @return const Group* - Pointer to the group
+     */
+    const Group* getGroup(const std::string& name);
+
+    /* Key group pointer */
+    const Group* _keyGroup;
+
+    using FloorEntry = std::tuple<PropertyVariantType, uint64_t>;
+
+    struct FloorGroup
+    {
+        const Group* group;
+        std::vector<FloorEntry> floorEntries;
+    };
+
+    struct FanFloors
+    {
+        PropertyVariantType keyValue;
+        std::vector<FloorGroup> floorGroups;
+    };
+
+    /* The fan floors action data, loaded from JSON */
+    std::vector<FanFloors> _fanFloors;
+};
+
+} // namespace phosphor::fan::control::json
