summaryrefslogtreecommitdiffstats
path: root/control/actions.cpp
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 /control/actions.cpp
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>
Diffstat (limited to 'control/actions.cpp')
-rw-r--r--control/actions.cpp207
1 files changed, 207 insertions, 0 deletions
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
OpenPOWER on IntegriCloud