Conditionally add/remove events action
A new action to add or remove events based on the state of all members
of a group. When all members of a group match the state given, the
events will be enabled. At any time a member's property state no longer
matches, all the events will be removed.
For example, to enable an event that changes the fan floor table using
different values based on the selected state of the current thermal
mode.
- name: set_speed_boundaries_based_on_ambient
groups:
- name: zone0_control_mode
interface: xyz.openbmc_project.Control.ThermalMode
property:
name: Current
type: std::string
triggers:
- name: init
method: getProperties
handler: setProperty
- name: signal
signal: propertiesChanged
handler: setProperty
actions:
- name: use_events_on_state
property:
value: DEFAULT
type: std::string
events:
- name: default_fan_speed_boundaries
groups:
- name: zone0_ambient
interface: xyz.openbmc_project.Sensor.Value
property:
name: Value
type: int64_t
triggers:
- name: init
method: getProperties
handler: setProperty
- name: signal
signal: propertiesChanged
handler: setProperty
actions:
- name: set_floor_from_average_sensor_value
map:
value:
- 27000: 3500
- 32000: 4600
- 37000: 5200
- 40000: 5800
type: std::map<int64_t, uint64_t>
- name: use_events_on_state
property:
value: CUSTOM
type: std::string
events:
- name: custom_fan_speed_boundaries
groups:
- name: zone0_ambient
interface: xyz.openbmc_project.Sensor.Value
property:
name: Value
type: int64_t
triggers:
- name: init
method: getProperties
handler: setProperty
- name: signal
signal: propertiesChanged
handler: setProperty
actions:
- name: set_floor_from_average_sensor_value
map:
value:
- 27000: 4600
- 32000: 5000
- 37000: 5400
- 40000: 5800
type: std::map<int64_t, uint64_t>
Tested:
Different fan floor events loaded based on thermal mode state
Change-Id: I85a4718e928996d2063e51eb31bfbb45e0e40c0b
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/actions.hpp b/control/actions.hpp
index c30945a..87e9af2 100644
--- a/control/actions.hpp
+++ b/control/actions.hpp
@@ -416,6 +416,71 @@
};
}
+/**
+ * @brief An action to use a set of events
+ * @details Provides the ability to use a set of events when all members of
+ * a group are at a specified state. When any member of the group no longer
+ * matches the provided state the set of events are removed.
+ *
+ * @param[in] state - State to compare the group's property value to
+ * @param[in] events - The set of events
+ *
+ * @return Lambda function
+ * A lambda function that checks all group members are at a specified state
+ * and initializes the set of events, otherwise removes them.
+ */
+template <typename T>
+auto use_events_on_state(T&& state,
+ std::vector<SetSpeedEvent>&& events)
+{
+ return [state = std::forward<T>(state),
+ events = std::move(events)](auto& zone, auto& group)
+ {
+ // Compare all group entries to the state
+ auto useEvents = std::all_of(
+ group.begin(),
+ group.end(),
+ [&zone, &state](auto const& entry)
+ {
+ try
+ {
+ return zone.template getPropertyValue<T>(
+ std::get<pathPos>(entry),
+ std::get<intfPos>(entry),
+ std::get<propPos>(entry)) == state;
+ }
+ catch (const std::out_of_range& oore)
+ {
+ // Default to property not equal when not found
+ return false;
+ }
+ });
+
+ if (useEvents)
+ {
+ // Init events
+ std::for_each(
+ events.begin(),
+ events.end(),
+ [&zone](auto const& entry)
+ {
+ zone.initEvent(entry);
+ });
+ }
+ else
+ {
+ // Remove events
+ std::for_each(
+ events.begin(),
+ events.end(),
+ [&zone](auto const& entry)
+ {
+ zone.removeEvent(entry);
+ });
+ }
+ };
+}
+
} // namespace action
} // namespace control
} // namespace fan
diff --git a/control/example/events.yaml b/control/example/events.yaml
index ac33ca0..c5b4188 100644
--- a/control/example/events.yaml
+++ b/control/example/events.yaml
@@ -233,6 +233,13 @@
# parameters:
# - property
# - speed
+# - name: use_events_on_state
+# description: >
+# Use a set of events when all the group properties are at a given
+# state, otherwise remove the events
+# parameters:
+# - property
+# - events
#
#events:
# - name: missing_before_high_speed
diff --git a/control/gen-fan-zone-defs.py b/control/gen-fan-zone-defs.py
index 09ff25a..baa0f9b 100755
--- a/control/gen-fan-zone-defs.py
+++ b/control/gen-fan-zone-defs.py
@@ -450,7 +450,7 @@
param += ("make_action(action::" + a['name'])
param += "),"
param += "}"
- elif p == 'defevents' or p == 'altevents':
+ elif p == 'defevents' or p == 'altevents' or p == 'events':
param = "std::vector<SetSpeedEvent>{\n"
for i, e in enumerate(eActions[p]):
aEvent = getEvent(zNum, zCond, e, events)