diff --git a/control/actions.hpp b/control/actions.hpp
index 87e9af2..d33c366 100644
--- a/control/actions.hpp
+++ b/control/actions.hpp
@@ -4,6 +4,7 @@
 #include <numeric>
 #include "types.hpp"
 #include "zone.hpp"
+#include "utility.hpp"
 
 namespace phosphor
 {
@@ -128,8 +129,58 @@
  *     An Action function to set the zone's floor speed when the average of
  *     property values within the group is below the lowest sensor value given
  */
+template <typename T>
 Action set_floor_from_average_sensor_value(
-        std::map<int64_t, uint64_t>&& val_to_speed);
+        std::map<T, uint64_t>&& val_to_speed)
+{
+    return [val_to_speed = std::move(val_to_speed)](control::Zone& zone,
+                                                    const Group& group)
+    {
+        auto speed = zone.getDefFloor();
+        if (group.size() != 0)
+        {
+            auto count = 0;
+            auto sumValue = std::accumulate(
+                    group.begin(),
+                    group.end(),
+                    0,
+                    [&zone, &count](T sum, auto const& entry)
+                    {
+                        try
+                        {
+                            return sum +
+                                zone.template getPropertyValue<T>(
+                                    std::get<pathPos>(entry),
+                                    std::get<intfPos>(entry),
+                                    std::get<propPos>(entry));
+                        }
+                        catch (const std::out_of_range& oore)
+                        {
+                            count++;
+                            return sum;
+                        }
+                    });
+            if ((group.size() - count) > 0)
+            {
+                auto groupSize = static_cast<int64_t>(group.size());
+                auto avgValue = sumValue / (groupSize - count);
+                auto it = std::find_if(
+                    val_to_speed.begin(),
+                    val_to_speed.end(),
+                    [&avgValue](auto const& entry)
+                    {
+                        return avgValue < entry.first;
+                    }
+                );
+                if (it != std::end(val_to_speed))
+                {
+                    speed = (*it).second;
+                }
+            }
+        }
+        zone.setFloor(speed);
+    };
+}
 
 /**
  * @brief An action to set the ceiling speed on a zone
@@ -145,8 +196,118 @@
  *     property values within the group is above(increasing) or
  *     below(decreasing) the key transition point
  */
+template <typename T>
 Action set_ceiling_from_average_sensor_value(
-        std::map<int64_t, uint64_t>&& val_to_speed);
+        std::map<T, uint64_t>&& val_to_speed)
+{
+    return [val_to_speed = std::move(val_to_speed)](Zone& zone,
+                                                    const Group& group)
+    {
+        auto speed = zone.getCeiling();
+        if (group.size() != 0)
+        {
+            auto count = 0;
+            auto sumValue = std::accumulate(
+                    group.begin(),
+                    group.end(),
+                    0,
+                    [&zone, &count](T sum, auto const& entry)
+                    {
+                        try
+                        {
+                            return sum +
+                                zone.template getPropertyValue<T>(
+                                    std::get<pathPos>(entry),
+                                    std::get<intfPos>(entry),
+                                    std::get<propPos>(entry));
+                        }
+                        catch (const std::out_of_range& oore)
+                        {
+                            count++;
+                            return sum;
+                        }
+                    });
+            if ((group.size() - count) > 0)
+            {
+                auto groupSize = static_cast<int64_t>(group.size());
+                auto avgValue = sumValue / (groupSize - count);
+                auto prevValue = zone.swapCeilingKeyValue(avgValue);
+                if (avgValue != prevValue)
+                {// Only check if previous and new values differ
+                    if (avgValue < prevValue)
+                    {// Value is decreasing from previous
+                        for (auto it = val_to_speed.rbegin();
+                             it != val_to_speed.rend();
+                             ++it)
+                        {
+                            if (it == val_to_speed.rbegin() &&
+                                avgValue >= it->first)
+                            {
+                                // Value is at/above last map key, set
+                                // ceiling speed to the last map key's value
+                                speed = it->second;
+                                break;
+                            }
+                            else if (std::next(it, 1) == val_to_speed.rend() &&
+                                     avgValue <= it->first)
+                            {
+                                // Value is at/below first map key, set
+                                // ceiling speed to the first map key's value
+                                speed = it->second;
+                                break;
+                            }
+                            if (avgValue < it->first &&
+                                it->first <= prevValue)
+                            {
+                                // Value decreased & transitioned across
+                                // a map key, update ceiling speed to this
+                                // map key's value when new value is below
+                                // map's key and the key is at/below the
+                                // previous value
+                                speed = it->second;
+                            }
+                        }
+                    }
+                    else
+                    {// Value is increasing from previous
+                        for (auto it = val_to_speed.begin();
+                             it != val_to_speed.end();
+                             ++it)
+                        {
+                            if (it == val_to_speed.begin() &&
+                                avgValue <= it->first)
+                            {
+                                // Value is at/below first map key, set
+                                // ceiling speed to the first map key's value
+                                speed = it->second;
+                                break;
+                            }
+                            else if (std::next(it, 1) == val_to_speed.end() &&
+                                     avgValue >= it->first)
+                            {
+                                // Value is at/above last map key, set
+                                // ceiling speed to the last map key's value
+                                speed = it->second;
+                                break;
+                            }
+                            if (avgValue > it->first &&
+                                it->first >= prevValue)
+                            {
+                                // Value increased & transitioned across
+                                // a map key, update ceiling speed to this
+                                // map key's value when new value is above
+                                // map's key and the key is at/above the
+                                // previous value
+                                speed = it->second;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        zone.setCeiling(speed);
+    };
+}
 
 /**
  * @brief An action to set the speed increase delta and request speed change
@@ -195,7 +356,7 @@
                         // difference times the given speed delta
                         netDelta = std::max(
                             netDelta,
-                            (delta/factor) * speedDelta);
+                            static_cast<uint64_t>((delta/factor) * speedDelta));
                     }
                 }
                 catch (const std::out_of_range& oore)
@@ -253,7 +414,8 @@
                         // difference times the given speed delta
                         netDelta = std::min(
                             netDelta,
-                            ((state - value)/factor) * speedDelta);
+                            static_cast<uint64_t>(
+                                ((state - value)/factor) * speedDelta));
                     }
                 }
                 else
@@ -364,10 +526,75 @@
  *     An Action function to set the zone's floor speed from a resulting group
  * of valid sensor values based on their highest value or median.
  */
+template <typename T>
 Action set_floor_from_median_sensor_value(
-        int64_t lowerBound,
-        int64_t upperBound,
-        std::map<int64_t, uint64_t>&& valueToSpeed);
+        T&& lowerBound,
+        T&& upperBound,
+        std::map<T, uint64_t>&& valueToSpeed)
+{
+    return [lowerBound = std::forward<T>(lowerBound),
+            upperBound = std::forward<T>(upperBound),
+            valueToSpeed = std::move(valueToSpeed)](control::Zone& zone,
+                                                    const Group& group)
+    {
+        auto speed = zone.getDefFloor();
+        if (group.size() != 0)
+        {
+            std::vector<T> validValues;
+            for (auto const& member : group)
+            {
+                try
+                {
+                    auto value = zone.template getPropertyValue<T>(
+                            std::get<pathPos>(member),
+                            std::get<intfPos>(member),
+                            std::get<propPos>(member));
+                    if (value == std::clamp(value, lowerBound, upperBound))
+                    {
+                        // Sensor value is valid
+                        validValues.emplace_back(value);
+                    }
+                }
+                catch (const std::out_of_range& oore)
+                {
+                    continue;
+                }
+            }
+
+            if (!validValues.empty())
+            {
+                auto median = validValues.front();
+                // Get the determined median value
+                if (validValues.size() == 2)
+                {
+                    // For 2 values, use the highest instead of the average
+                    // for a thermally safe floor
+                    median = *std::max_element(validValues.begin(),
+                                               validValues.end());
+                }
+                else if (validValues.size() > 2)
+                {
+                    median = utility::getMedian(validValues);
+                }
+
+                // Use determined median sensor value to find floor speed
+                auto it = std::find_if(
+                    valueToSpeed.begin(),
+                    valueToSpeed.end(),
+                    [&median](auto const& entry)
+                    {
+                        return median < entry.first;
+                    }
+                );
+                if (it != std::end(valueToSpeed))
+                {
+                    speed = (*it).second;
+                }
+            }
+        }
+        zone.setFloor(speed);
+    };
+}
 
 /**
  * @brief An action to update the default floor speed
