From 4af419cd334fa1fc182fe0ba608f984d043df5d9 Mon Sep 17 00:00:00 2001 From: Matthew Barth Date: Mon, 12 Jun 2017 13:39:31 -0500 Subject: Allow floor speed changes based on sensor values Given a group of sensor values, the average of those sensor values will be used in selecting the floor speed for the zone. Each time the speed is set/updated, any speed requested lower than the current floor will be overwritten with the floor speed to not allow speeds below the floor. Change-Id: I4c8e8a2cd66892b9fdc2bc5643e907adddff51f8 Signed-off-by: Matthew Barth --- control/actions.hpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ control/zone.cpp | 5 +++++ control/zone.hpp | 15 +++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/control/actions.hpp b/control/actions.hpp index 8a2675b..a99fa97 100644 --- a/control/actions.hpp +++ b/control/actions.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace phosphor { @@ -50,6 +51,55 @@ auto count_state_before_speed(size_t count, T&& state, uint64_t speed) }; } +/** + * @brief An action to set the floor speed on a zone + * @details Based on the average of the defined sensor group values, the floor + * speed is selected from the first map key entry that the average sensor value + * is less than. + * + * @param[in] val_to_speed - Ordered map of sensor value-to-speed + * + * @return Lambda function + * A lambda function to set the zone's floor speed when the average of + * property values within the group is below the lowest sensor value given + */ +auto set_floor_from_average_sensor_value( + std::map&& val_to_speed) +{ + return [val_to_speed = std::move(val_to_speed)](auto& zone, auto& group) + { + auto speed = zone.getDefFloor(); + if (group.size() != 0) + { + auto sumValue = std::accumulate( + group.begin(), + group.end(), + 0, + [&zone](int64_t sum, auto const& entry) + { + return sum + zone.template getPropertyValue( + entry.first, + std::get(entry.second), + std::get(entry.second)); + }); + auto avgValue= sumValue / group.size(); + 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); + }; +} + } // namespace action } // namespace control } // namespace fan diff --git a/control/zone.cpp b/control/zone.cpp index 1a299e2..14bd9d2 100644 --- a/control/zone.cpp +++ b/control/zone.cpp @@ -99,6 +99,11 @@ void Zone::setSpeed(uint64_t speed) { for (auto& fan : _fans) { + //TODO openbmc/openbmc#1626 Move to control algorithm function + if (speed < _floorSpeed) + { + speed = _floorSpeed; + } fan->setSpeed(speed); } } diff --git a/control/zone.hpp b/control/zone.hpp index c524397..24739f8 100644 --- a/control/zone.hpp +++ b/control/zone.hpp @@ -123,6 +123,16 @@ class Zone return _defFloorSpeed; }; + /** + * @brief Set the floor speed to the given speed + * + * @param[in] speed - Speed to set the floor to + */ + inline void setFloor(uint64_t speed) + { + _floorSpeed = speed; + }; + private: /** @@ -145,6 +155,11 @@ class Zone */ const uint64_t _defFloorSpeed; + /** + * The floor speed to not go below + */ + uint64_t _floorSpeed = _defFloorSpeed; + /** * Automatic fan control active state */ -- cgit v1.2.1