Add alternate events action
The alternate events action uses a group of properties to determine
whether a default set of events should be used or an alternate set of
events should be used. When any of the members of the group do not match
the given property state, the default set of events are used. Once all
members of the group match the given state, the alternate set of events
are used. Each time the events used are to change, the current set of
events are removed prior to loading the replacement set of events.
Tested:
Used the 'WaterCooled' property to trigger using the default or
alternate floor speed events.
Verified fan control memory usage doesnt grow by doing multiple
event switching.
Change-Id: Ib8a4b835bf370894c572ccfa8fdc5a4479ef570f
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/actions.hpp b/control/actions.hpp
index cce481c..bb98b7c 100644
--- a/control/actions.hpp
+++ b/control/actions.hpp
@@ -275,6 +275,78 @@
};
}
+/**
+ * @brief An action to use an alternate set of events
+ * @details Provides the ability to replace a default set of events with an
+ * alternate set of events based on all members of a group being at a specified
+ * state. When any member of the group no longer matches the provided state,
+ * the alternate set of events are replaced with the defaults.
+ *
+ * @param[in] state - State to compare the group's property value to
+ * @param[in] defEvents - The default set of events
+ * @param[in] altEvents - The alternate set of events
+ *
+ * @return Lambda function
+ * A lambda function that checks all group members are at a specified state
+ * and replacing the default set of events with an alternate set of events.
+ */
+template <typename T>
+auto use_alternate_events_on_state(T&& state,
+ std::vector<SetSpeedEvent>&& defEvents,
+ std::vector<SetSpeedEvent>&& altEvents)
+{
+ return [state = std::forward<T>(state),
+ defEvents = std::move(defEvents),
+ altEvents = std::move(altEvents)](auto& zone, auto& group)
+ {
+ // Compare all group entries to the state
+ auto useAlt = std::all_of(
+ group.begin(),
+ group.end(),
+ [&zone, &state](auto const& entry)
+ {
+ try
+ {
+ return zone.template getPropertyValue<T>(
+ entry.first,
+ std::get<intfPos>(entry.second),
+ std::get<propPos>(entry.second)) == state;
+ }
+ catch (const std::out_of_range& oore)
+ {
+ // Default to property not equal when not found
+ return false;
+ }
+ });
+
+ const std::vector<SetSpeedEvent> *rmEvents = &altEvents;
+ const std::vector<SetSpeedEvent> *initEvents = &defEvents;
+
+ if (useAlt)
+ {
+ rmEvents = &defEvents;
+ initEvents = &altEvents;
+ }
+
+ // Remove events
+ std::for_each(
+ rmEvents->begin(),
+ rmEvents->end(),
+ [&zone](auto const& entry)
+ {
+ zone.removeEvent(entry);
+ });
+ // Init events
+ std::for_each(
+ initEvents->begin(),
+ initEvents->end(),
+ [&zone](auto const& entry)
+ {
+ zone.initEvent(entry);
+ });
+ };
+}
+
} // namespace action
} // namespace control
} // namespace fan