summaryrefslogtreecommitdiffstats
path: root/control/actions.hpp
diff options
context:
space:
mode:
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