summaryrefslogtreecommitdiffstats
path: root/control/actions.hpp
diff options
context:
space:
mode:
authorMatthew Barth <msbarth@us.ibm.com>2017-06-13 16:29:09 -0500
committerPatrick Williams <patrick@stwcx.xyz>2017-06-28 15:59:11 +0000
commite0ca13eb5b2feba044505e3234c8381d3ab03187 (patch)
tree01002dfa5a34d991477e3f3347b8c1e05457c5e8 /control/actions.hpp
parent618027abcf491b0b58f71bfe2b48c55dfb86462e (diff)
downloadphosphor-fan-presence-e0ca13eb5b2feba044505e3234c8381d3ab03187.tar.gz
phosphor-fan-presence-e0ca13eb5b2feba044505e3234c8381d3ab03187.zip
Enable setting/adjusting fan ceiling speed
Set the default ceiling to be what's given as full speed and adjust the ceiling speed based on an average of a given set of sensor values. The ceiling is chosen from a given map's key transition values. The map consists of key, value pairs where each key is the sensor value transition point and the value is the ceiling speed for when that transition occurs. The previous key value is needed to determine the direction in which to chose the appropriate ceiling speed allowing a buffer zone between ceiling changes if defined to. Resolves openbmc/openbmc#1628 Change-Id: I7c9c553b5d0c3219c51b563aec7dd5d5f090916b Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
Diffstat (limited to 'control/actions.hpp')
-rw-r--r--control/actions.hpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/control/actions.hpp b/control/actions.hpp
index a99fa97..4393c4d 100644
--- a/control/actions.hpp
+++ b/control/actions.hpp
@@ -100,6 +100,115 @@ auto set_floor_from_average_sensor_value(
};
}
+/**
+ * @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.
+ *
+ * @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
+ * 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 sumValue = std::accumulate(
+ group.begin(),
+ group.end(),
+ 0,
+ [&zone](int64_t sum, auto const& entry)
+ {
+ return sum + zone.template getPropertyValue<int64_t>(
+ entry.first,
+ std::get<intfPos>(entry.second),
+ std::get<propPos>(entry.second));
+ });
+ auto avgValue = sumValue / group.size();
+ 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
OpenPOWER on IntegriCloud