summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barth <msbarth@us.ibm.com>2017-09-15 09:56:50 -0500
committerMatthew Barth <msbarth@us.ibm.com>2017-09-28 09:26:25 -0500
commitb280bfa4286c708b4bb65d82e3b41cc883b279f0 (patch)
tree02cdd66b269c4b321a914225f6e968b9a9fc5a06
parent4e72854210866ae47b6446dc78df42fff540c68e (diff)
downloadphosphor-fan-presence-b280bfa4286c708b4bb65d82e3b41cc883b279f0.tar.gz
phosphor-fan-presence-b280bfa4286c708b4bb65d82e3b41cc883b279f0.zip
Create set request speed base action function
This action function is intended to allow the base request speed to be set to the max value from a group of properties. The base request speed is the base speed used in requesting a new target speed. By default, the base request speed is the current target speed. For example, this action can be used to set the base request speed used in calculating a new target speed to be based on the max tach feedback speed from a group of fans instead of the current target speed. Adding this action function requires the other non-template functions to also be slightly modified due to linker errors. Change-Id: Ibbe9b33678b10cb49466174088a587b27bf56d62 Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
-rw-r--r--control/Makefile.am1
-rw-r--r--control/actions.cpp207
-rw-r--r--control/actions.hpp193
3 files changed, 235 insertions, 166 deletions
diff --git a/control/Makefile.am b/control/Makefile.am
index 7a970ea..09fb1a2 100644
--- a/control/Makefile.am
+++ b/control/Makefile.am
@@ -9,6 +9,7 @@ phosphor_fan_control_SOURCES = \
fan.cpp \
main.cpp \
manager.cpp \
+ actions.cpp \
zone.cpp
nodist_phosphor_fan_control_SOURCES = \
diff --git a/control/actions.cpp b/control/actions.cpp
new file mode 100644
index 0000000..a608293
--- /dev/null
+++ b/control/actions.cpp
@@ -0,0 +1,207 @@
+#include "actions.hpp"
+
+namespace phosphor
+{
+namespace fan
+{
+namespace control
+{
+namespace action
+{
+
+using namespace phosphor::fan;
+
+void set_request_speed_base_with_max(control::Zone& zone,
+ const Group& group)
+{
+ int64_t base = 0;
+ std::for_each(
+ group.begin(),
+ group.end(),
+ [&zone, &base](auto const& entry)
+ {
+ try
+ {
+ auto value = zone.template getPropertyValue<int64_t>(
+ entry.first,
+ std::get<intfPos>(entry.second),
+ std::get<propPos>(entry.second));
+ base = std::max(base, value);
+ }
+ catch (const std::out_of_range& oore)
+ {
+ // Property value not found, base request speed unchanged
+ }
+ });
+ // A request speed base of 0 defaults to the current target speed
+ zone.setRequestSpeedBase(base);
+}
+
+Action set_floor_from_average_sensor_value(
+ std::map<int64_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](int64_t sum, auto const& entry)
+ {
+ try
+ {
+ return sum +
+ zone.template getPropertyValue<int64_t>(
+ entry.first,
+ std::get<intfPos>(entry.second),
+ std::get<propPos>(entry.second));
+ }
+ 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);
+ };
+}
+
+Action set_ceiling_from_average_sensor_value(
+ std::map<int64_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](int64_t sum, auto const& entry)
+ {
+ try
+ {
+ return sum +
+ zone.template getPropertyValue<int64_t>(
+ entry.first,
+ std::get<intfPos>(entry.second),
+ std::get<propPos>(entry.second));
+ }
+ 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);
+ };
+}
+
+} // namespace action
+} // namespace control
+} // namespace fan
+} // namespace phosphor
diff --git a/control/actions.hpp b/control/actions.hpp
index ecf900e..3061814 100644
--- a/control/actions.hpp
+++ b/control/actions.hpp
@@ -2,6 +2,8 @@
#include <algorithm>
#include <numeric>
+#include "types.hpp"
+#include "zone.hpp"
namespace phosphor
{
@@ -13,6 +15,19 @@ namespace action
{
/**
+ * @brief An action to set the request speed base
+ * @details A new target speed is determined using a speed delta being added
+ * or subtracted, for increases or decrease respectively, from a base speed.
+ * This base speed defaults to be the current target speed or is set to a
+ * different base speed(i.e. the fans' tach feedback speed) to request a new
+ * target from.
+ *
+ * @param[in] zone - Zone containing fans
+ * @param[in] group - Group of sensors to determine base from
+ */
+void set_request_speed_base_with_max(Zone& zone, const Group& group);
+
+/**
* @brief An action to set the speed on a zone
* @details The zone is held at the given speed when a defined number of
* properties in the group are set to the given state
@@ -67,183 +82,29 @@ auto count_state_before_speed(size_t count, T&& state, uint64_t speed)
*
* @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
+ * @return Action lambda function
+ * 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
*/
-auto set_floor_from_average_sensor_value(
- std::map<int64_t, uint64_t>&& 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 count = 0;
- auto sumValue = std::accumulate(
- group.begin(),
- group.end(),
- 0,
- [&zone, &count](int64_t sum, auto const& entry)
- {
- try
- {
- return sum +
- zone.template getPropertyValue<int64_t>(
- entry.first,
- std::get<intfPos>(entry.second),
- std::get<propPos>(entry.second));
- }
- catch (const std::out_of_range& oore)
- {
- count++;
- return sum;
- }
- });
- if ((group.size() - count) > 0)
- {
- auto avgValue = sumValue / (group.size() - 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);
- };
-}
+Action set_floor_from_average_sensor_value(
+ std::map<int64_t, uint64_t>&& val_to_speed);
/**
* @brief An action to set the ceiling speed on a zone
- * @details Based on the average of the defined sensor group values, the ceiling
- * speed is selected from the map key transition point that the average sensor
- * value falls within depending on the key values direction from what was
- * previously read.
+ * @details Based on the average of the defined sensor group values, the
+ * ceiling speed is selected from the map key transition point that the average
+ * sensor value falls within depending on the key values direction from what
+ * was previously read.
*
* @param[in] val_to_speed - Ordered map of sensor value-to-speed transitions
*
- * @return Lambda function
- * A lambda function to set the zone's ceiling speed when the average of
+ * @return Action lambda function
+ * An Action function to set the zone's ceiling speed when the average of
* property values within the group is above(increasing) or
* below(decreasing) the key transition point
*/
-auto set_ceiling_from_average_sensor_value(
- std::map<int64_t, uint64_t>&& val_to_speed)
-{
- return [val_to_speed = std::move(val_to_speed)](auto& zone, auto& group)
- {
- auto speed = zone.getCeiling();
- if (group.size() != 0)
- {
- auto count = 0;
- auto sumValue = std::accumulate(
- group.begin(),
- group.end(),
- 0,
- [&zone, &count](int64_t sum, auto const& entry)
- {
- try
- {
- return sum +
- zone.template getPropertyValue<int64_t>(
- entry.first,
- std::get<intfPos>(entry.second),
- std::get<propPos>(entry.second));
- }
- catch (const std::out_of_range& oore)
- {
- count++;
- return sum;
- }
- });
- if ((group.size() - count) > 0)
- {
- auto avgValue = sumValue / (group.size() - 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);
- };
-}
+Action set_ceiling_from_average_sensor_value(
+ std::map<int64_t, uint64_t>&& val_to_speed);
/**
* @brief An action to set the speed increase delta and request speed change
OpenPOWER on IntegriCloud